e93a509efd1160ef1f60dc0b75a14d04a8231db0
[blender.git] / source / blender / render / intern / source / convertblender.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributors: 2004/2005/2006 Blender Foundation, full recode
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <math.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <limits.h>
33
34 #include "blendef.h"
35 #include "MTC_matrixops.h"
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_arithb.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_rand.h"
42 #include "BLI_memarena.h"
43 #include "BLI_ghash.h"
44
45 #include "DNA_armature_types.h"
46 #include "DNA_camera_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_effect_types.h"
50 #include "DNA_group_types.h"
51 #include "DNA_lamp_types.h"
52 #include "DNA_image_types.h"
53 #include "DNA_lattice_types.h"
54 #include "DNA_mesh_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_meta_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_object_force.h"
59 #include "DNA_object_fluidsim.h"
60 #include "DNA_scene_types.h"
61 #include "DNA_texture_types.h"
62 #include "DNA_view3d_types.h"
63
64 #include "BKE_anim.h"
65 #include "BKE_armature.h"
66 #include "BKE_action.h"
67 #include "BKE_curve.h"
68 #include "BKE_customdata.h"
69 #include "BKE_constraint.h"
70 #include "BKE_displist.h"
71 #include "BKE_deform.h"
72 #include "BKE_DerivedMesh.h"
73 #include "BKE_effect.h"
74 #include "BKE_global.h"
75 #include "BKE_group.h"
76 #include "BKE_key.h"
77 #include "BKE_ipo.h"
78 #include "BKE_image.h"
79 #include "BKE_lattice.h"
80 #include "BKE_library.h"
81 #include "BKE_material.h"
82 #include "BKE_main.h"
83 #include "BKE_mball.h"
84 #include "BKE_mesh.h"
85 #include "BKE_node.h"
86 #include "BKE_object.h"
87 #include "BKE_scene.h"
88 #include "BKE_subsurf.h"
89 #include "BKE_texture.h"
90 #include "BKE_utildefines.h"
91 #include "BKE_world.h"
92
93 #include "PIL_time.h"
94 #include "IMB_imbuf_types.h"
95
96 #include "envmap.h"
97 #include "multires.h"
98 #include "render_types.h"
99 #include "rendercore.h"
100 #include "renderdatabase.h"
101 #include "renderpipeline.h"
102 #include "radio.h"
103 #include "shadbuf.h"
104 #include "shading.h"
105 #include "texture.h"
106 #include "zbuf.h"
107
108 #ifndef DISABLE_YAFRAY /* disable yafray */
109
110 #include "YafRay_Api.h"
111
112 /* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world.
113  * Same is true for lamp coords & vec.
114  * Duplicated data objects & dupliframe/duplivert objects are only stored once,
115  * only the matrix is stored for all others, in yafray these objects are instances of the original.
116  * The main changes are in RE_rotateBlenderScene().
117  */
118
119 #endif /* disable yafray */
120
121 /* ------------------------------------------------------------------------- */
122 /* Local functions                                                           */
123 /* ------------------------------------------------------------------------- */
124 static short test_for_displace(Render *re, Object *ob);
125 static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert );
126
127 /* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */
128 /* or for checking vertex normal flips */
129 #define FLT_EPSILON10 1.19209290e-06F
130
131
132 /* ------------------------------------------------------------------------- */
133
134 /* Stuff for stars. This sits here because it uses gl-things. Part of
135 this code may move down to the converter.  */
136 /* ------------------------------------------------------------------------- */
137 /* this is a bad beast, since it is misused by the 3d view drawing as well. */
138
139 static HaloRen *initstar(Render *re, float *vec, float hasize)
140 {
141         HaloRen *har;
142         float hoco[4];
143         
144         projectverto(vec, re->winmat, hoco);
145         
146         har= RE_findOrAddHalo(re, re->tothalo++);
147         
148         /* projectvert is done in function zbufvlaggen again, because of parts */
149         VECCOPY(har->co, vec);
150         har->hasize= hasize;
151         
152         har->zd= 0.0;
153         
154         return har;
155 }
156
157 /* there must be a 'fixed' amount of stars generated between
158 *         near and far
159 * all stars must by preference lie on the far and solely
160 *        differ in clarity/color
161 */
162
163 void RE_make_stars(Render *re, void (*initfunc)(void),
164                                    void (*vertexfunc)(float*),  void (*termfunc)(void))
165 {
166         extern unsigned char hash[512];
167         World *wrld= NULL;
168         HaloRen *har;
169         Scene *scene;
170         Camera *camera;
171         double dblrand, hlfrand;
172         float vec[4], fx, fy, fz;
173         float fac, starmindist, clipend;
174         float mat[4][4], stargrid, maxrand, maxjit, force, alpha;
175         int x, y, z, sx, sy, sz, ex, ey, ez, done = 0;
176         
177         if(initfunc) {
178                 scene= G.scene;
179                 wrld= G.scene->world;
180         }
181         else {
182                 scene= re->scene;
183                 wrld= &(re->wrld);
184         }
185         
186         stargrid = wrld->stardist;                      /* distance between stars */
187         maxrand = 2.0;                                          /* amount a star can be shifted (in grid units) */
188         maxjit = (wrld->starcolnoise);          /* amount a color is being shifted */
189         
190         /* size of stars */
191         force = ( wrld->starsize );
192         
193         /* minimal free space (starting at camera) */
194         starmindist= wrld->starmindist;
195         
196         if (stargrid <= 0.10) return;
197         
198         if (re) re->flag |= R_HALO;
199         else stargrid *= 1.0;                           /* then it draws fewer */
200         
201         if(re) MTC_Mat4Invert(mat, re->viewmat);
202         
203         /* BOUNDING BOX CALCULATION
204                 * bbox goes from z = loc_near_var | loc_far_var,
205                 * x = -z | +z,
206                 * y = -z | +z
207                 */
208         
209         if(scene->camera==NULL)
210                 return;
211         camera = scene->camera->data;
212         clipend = camera->clipend;
213         
214         /* convert to grid coordinates */
215         
216         sx = ((mat[3][0] - clipend) / stargrid) - maxrand;
217         sy = ((mat[3][1] - clipend) / stargrid) - maxrand;
218         sz = ((mat[3][2] - clipend) / stargrid) - maxrand;
219         
220         ex = ((mat[3][0] + clipend) / stargrid) + maxrand;
221         ey = ((mat[3][1] + clipend) / stargrid) + maxrand;
222         ez = ((mat[3][2] + clipend) / stargrid) + maxrand;
223         
224         dblrand = maxrand * stargrid;
225         hlfrand = 2.0 * dblrand;
226         
227         if (initfunc) {
228                 initfunc();     
229         }
230         
231         for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
232                 for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
233                         for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) {
234                                 
235                                 BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
236                                 vec[0] = fx + (hlfrand * BLI_drand()) - dblrand;
237                                 vec[1] = fy + (hlfrand * BLI_drand()) - dblrand;
238                                 vec[2] = fz + (hlfrand * BLI_drand()) - dblrand;
239                                 vec[3] = 1.0;
240                                 
241                                 if (vertexfunc) {
242                                         if(done & 1) vertexfunc(vec);
243                                         done++;
244                                 }
245                                 else {
246                                         MTC_Mat4MulVecfl(re->viewmat, vec);
247                                         
248                                         /* in vec are global coordinates
249                                         * calculate distance to camera
250                                         * and using that, define the alpha
251                                         */
252                                         
253                                         {
254                                                 float tx, ty, tz;
255                                                 
256                                                 tx = vec[0];
257                                                 ty = vec[1];
258                                                 tz = vec[2];
259                                                 
260                                                 alpha = sqrt(tx * tx + ty * ty + tz * tz);
261                                                 
262                                                 if (alpha >= clipend) alpha = 0.0;
263                                                 else if (alpha <= starmindist) alpha = 0.0;
264                                                 else if (alpha <= 2.0 * starmindist) {
265                                                         alpha = (alpha - starmindist) / starmindist;
266                                                 } else {
267                                                         alpha -= 2.0 * starmindist;
268                                                         alpha /= (clipend - 2.0 * starmindist);
269                                                         alpha = 1.0 - alpha;
270                                                 }
271                                         }
272                                         
273                                         
274                                         if (alpha != 0.0) {
275                                                 fac = force * BLI_drand();
276                                                 
277                                                 har = initstar(re, vec, fac);
278                                                 
279                                                 if (har) {
280                                                         har->alfa = sqrt(sqrt(alpha));
281                                                         har->add= 255;
282                                                         har->r = har->g = har->b = 1.0;
283                                                         if (maxjit) {
284                                                                 har->r += ((maxjit * BLI_drand()) ) - maxjit;
285                                                                 har->g += ((maxjit * BLI_drand()) ) - maxjit;
286                                                                 har->b += ((maxjit * BLI_drand()) ) - maxjit;
287                                                         }
288                                                         har->hard = 32;
289                                                         har->lay= -1;
290                                                         har->type |= HA_ONLYSKY;
291                                                         done++;
292                                                 }
293                                         }
294                                 }
295                         }
296                         /* do not call blender_test_break() here, since it is used in UI as well, confusing the callback system */
297                         /* main cause is G.afbreek of course, a global again... (ton) */
298                 }
299         }
300         if (termfunc) termfunc();
301 }
302
303
304 /* ------------------------------------------------------------------------- */
305 /* tool functions/defines for ad hoc simplification and possible future 
306    cleanup      */
307 /* ------------------------------------------------------------------------- */
308
309 #define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
310 /*
311
312 NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
313         
314 ^       ()----p4----p3----()
315 |       |     |     |     |
316 u       |     |  F1 |  F2 |
317         |     |     |     |
318         ()----p1----p2----()
319                v ->
320 */
321
322 /* ------------------------------------------------------------------------- */
323
324 static void split_v_renderfaces(Render *re, int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
325 {
326         int vLen = vsize-1+(!!cyclv);
327         int v;
328
329         for (v=0; v<vLen; v++) {
330                 VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v);
331                 VertRen *vert = RE_vertren_copy(re, vlr->v2);
332
333                 if (cyclv) {
334                         vlr->v2 = vert;
335
336                         if (v==vLen-1) {
337                                 VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + 0);
338                                 vlr->v1 = vert;
339                         } else {
340                                 VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
341                                 vlr->v1 = vert;
342                         }
343                 } else {
344                         vlr->v2 = vert;
345
346                         if (v<vLen-1) {
347                                 VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
348                                 vlr->v1 = vert;
349                         }
350
351                         if (v==0) {
352                                 vlr->v1 = RE_vertren_copy(re, vlr->v1);
353                         } 
354                 }
355         }
356 }
357
358 /* ------------------------------------------------------------------------- */
359
360 static int check_vnormal(float *n, float *veno)
361 {
362         float inp;
363
364         inp=n[0]*veno[0]+n[1]*veno[1]+n[2]*veno[2];
365         if(inp < -FLT_EPSILON10) return 1;
366         return 0;
367 }
368
369 /* ------------------------------------------------------------------------- */
370
371 static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
372 {
373         float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco);
374         float *acc;
375         
376         acc= accum + 2*v1->index;
377         acc[0]+= len;
378         acc[1]+= 1.0f;
379         
380         acc= accum + 2*v2->index;
381         acc[0]+= len;
382         acc[1]+= 1.0f;
383 }
384
385 static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
386 {
387         float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
388         int a;
389         
390         if(startvert==re->totvert) return;
391         
392         mesh_get_texspace(me, loc, NULL, size);
393         
394         accum= MEM_callocN(2*sizeof(float)*(re->totvert-startvert), "temp accum for stress");
395         
396         /* de-normalize orco */
397         for(a=startvert; a<re->totvert; a++) {
398                 VertRen *ver= RE_findOrAddVert(re, a);
399                 if(ver->orco) {
400                         ver->orco[0]= ver->orco[0]*size[0] +loc[0];
401                         ver->orco[1]= ver->orco[1]*size[1] +loc[1];
402                         ver->orco[2]= ver->orco[2]*size[2] +loc[2];
403                 }
404         }
405         
406         /* add stress values */
407         accumoffs= accum - 2*startvert; /* so we can use vertex index */
408         for(a=startvlak; a<re->totvlak; a++) {
409                 VlakRen *vlr= RE_findOrAddVlak(re, a);
410
411                 if(vlr->v1->orco && vlr->v4) {
412                         calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
413                         calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3);
414                         calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1);
415                         if(vlr->v4) {
416                                 calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4);
417                                 calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1);
418                                 calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4);
419                         }
420                 }
421         }
422         
423         for(a=startvert; a<re->totvert; a++) {
424                 VertRen *ver= RE_findOrAddVert(re, a);
425                 if(ver->orco) {
426                         /* find stress value */
427                         acc= accumoffs + 2*ver->index;
428                         if(acc[1]!=0.0f)
429                                 acc[0]/= acc[1];
430                         stress= RE_vertren_get_stress(re, ver, 1);
431                         *stress= *acc;
432                         
433                         /* restore orcos */
434                         ver->orco[0] = (ver->orco[0]-loc[0])/size[0];
435                         ver->orco[1] = (ver->orco[1]-loc[1])/size[1];
436                         ver->orco[2] = (ver->orco[2]-loc[2])/size[2];
437                 }
438         }
439         
440         MEM_freeN(accum);
441 }
442
443 /* gets tangent from tface or orco */
444 static void calc_tangent_vector(Render *re, VlakRen *vlr)
445 {
446         MTFace *tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
447         VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
448         float tang[3], tangv[3], ct[3], e1[3], e2[3], *tav;
449         float *uv1, *uv2, *uv3, *uv4;
450         float s1, s2, t1, t2, det;
451         float uv[4][2];
452         
453         if(tface) {
454                 uv1= tface->uv[0];
455                 uv2= tface->uv[1];
456                 uv3= tface->uv[2];
457                 uv4= tface->uv[3];
458         }
459         else if(v1->orco) {
460                 uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3];
461                 spheremap(v1->orco[0], v1->orco[1], v1->orco[2], &uv[0][0], &uv[0][1]);
462                 spheremap(v2->orco[0], v2->orco[1], v2->orco[2], &uv[1][0], &uv[1][1]);
463                 spheremap(v3->orco[0], v3->orco[1], v3->orco[2], &uv[2][0], &uv[2][1]);
464                 if(v4)
465                         spheremap(v4->orco[0], v4->orco[1], v4->orco[2], &uv[3][0], &uv[3][1]);
466         }
467         else return;
468         
469         s1= uv2[0] - uv1[0];
470         s2= uv3[0] - uv1[0];
471         t1= uv2[1] - uv1[1];
472         t2= uv3[1] - uv1[1];
473         det= 1.0f / (s1 * t2 - s2 * t1);
474         
475         /* normals in render are inversed... */
476         VecSubf(e1, v1->co, v2->co);
477         VecSubf(e2, v1->co, v3->co);
478         tang[0] = (t2*e1[0] - t1*e2[0])*det;
479         tang[1] = (t2*e1[1] - t1*e2[1])*det;
480         tang[2] = (t2*e1[2] - t1*e2[2])*det;
481         tangv[0] = (s1*e2[0] - s2*e1[0])*det;
482         tangv[1] = (s1*e2[1] - s2*e1[1])*det;
483         tangv[2] = (s1*e2[2] - s2*e1[2])*det;
484         Crossf(ct, tang, tangv);
485         /* check flip */
486         if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
487                 VecMulf(tang, -1.f);
488         
489         tav= RE_vertren_get_tangent(re, v1, 1);
490         VECADD(tav, tav, tang);
491         tav= RE_vertren_get_tangent(re, v2, 1);
492         VECADD(tav, tav, tang);
493         tav= RE_vertren_get_tangent(re, v3, 1);
494         VECADD(tav, tav, tang);
495         
496         if(v4) {
497                 s1= uv3[0] - uv1[0];
498                 s2= uv4[0] - uv1[0];
499                 t1= uv3[1] - uv1[1];
500                 t2= uv4[1] - uv1[1];
501                 det= 1.0f / (s1 * t2 - s2 * t1);
502                 
503                 /* normals in render are inversed... */
504                 VecSubf(e1, v1->co, v3->co);
505                 VecSubf(e2, v1->co, v4->co);
506                 tang[0] = (t2*e1[0] - t1*e2[0])*det;
507                 tang[1] = (t2*e1[1] - t1*e2[1])*det;
508                 tang[2] = (t2*e1[2] - t1*e2[2])*det;
509                 tangv[0] = (s1*e2[0] - s2*e1[0])*det;
510                 tangv[1] = (s1*e2[1] - s2*e1[1])*det;
511                 tangv[2] = (s1*e2[2] - s2*e1[2])*det;
512                 Crossf(ct, tang, tangv);
513                 if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
514                         VecMulf(tang, -1.f);
515                 
516                 tav= RE_vertren_get_tangent(re, v1, 1);
517                 VECADD(tav, tav, tang);
518                 tav= RE_vertren_get_tangent(re, v3, 1);
519                 VECADD(tav, tav, tang);
520                 tav= RE_vertren_get_tangent(re, v4, 1);
521                 VECADD(tav, tav, tang);
522         }
523 }
524
525
526 static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_tangent)
527 {
528         int a;
529
530                 /* clear all vertex normals */
531         for(a=startvert; a<re->totvert; a++) {
532                 VertRen *ver= RE_findOrAddVert(re, a);
533                 ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
534         }
535
536                 /* calculate cos of angles and point-masses, use as weight factor to
537                    add face normal to vertex */
538         for(a=startvlak; a<re->totvlak; a++) {
539                 VlakRen *vlr= RE_findOrAddVlak(re, a);
540                 if(vlr->flag & ME_SMOOTH) {
541                         VertRen *v1= vlr->v1;
542                         VertRen *v2= vlr->v2;
543                         VertRen *v3= vlr->v3;
544                         VertRen *v4= vlr->v4;
545                         float n1[3], n2[3], n3[3], n4[3];
546                         float fac1, fac2, fac3, fac4=0.0f;
547                         
548                         if(re->flag & R_GLOB_NOPUNOFLIP)
549                                 vlr->flag |= R_NOPUNOFLIP;
550                         
551                         VecSubf(n1, v2->co, v1->co);
552                         Normalize(n1);
553                         VecSubf(n2, v3->co, v2->co);
554                         Normalize(n2);
555                         if(v4==NULL) {
556                                 VecSubf(n3, v1->co, v3->co);
557                                 Normalize(n3);
558
559                                 fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
560                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
561                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
562                         }
563                         else {
564                                 VecSubf(n3, v4->co, v3->co);
565                                 Normalize(n3);
566                                 VecSubf(n4, v1->co, v4->co);
567                                 Normalize(n4);
568
569                                 fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
570                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
571                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
572                                 fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
573
574                                 if(!(vlr->flag & R_NOPUNOFLIP)) {
575                                         if( check_vnormal(vlr->n, v4->n) ) fac4= -fac4;
576                                 }
577
578                                 v4->n[0] +=fac4*vlr->n[0];
579                                 v4->n[1] +=fac4*vlr->n[1];
580                                 v4->n[2] +=fac4*vlr->n[2];
581                         }
582
583                         if(!(vlr->flag & R_NOPUNOFLIP)) {
584                                 if( check_vnormal(vlr->n, v1->n) ) fac1= -fac1;
585                                 if( check_vnormal(vlr->n, v2->n) ) fac2= -fac2;
586                                 if( check_vnormal(vlr->n, v3->n) ) fac3= -fac3;
587                         }
588
589                         v1->n[0] +=fac1*vlr->n[0];
590                         v1->n[1] +=fac1*vlr->n[1];
591                         v1->n[2] +=fac1*vlr->n[2];
592
593                         v2->n[0] +=fac2*vlr->n[0];
594                         v2->n[1] +=fac2*vlr->n[1];
595                         v2->n[2] +=fac2*vlr->n[2];
596
597                         v3->n[0] +=fac3*vlr->n[0];
598                         v3->n[1] +=fac3*vlr->n[1];
599                         v3->n[2] +=fac3*vlr->n[2];
600                         
601                 }
602                 if(do_tangent) {
603                         /* tangents still need to be calculated for flat faces too */
604                         /* weighting removed, they are not vertexnormals */
605                         calc_tangent_vector(re, vlr);
606                 }
607         }
608
609                 /* do solid faces */
610         for(a=startvlak; a<re->totvlak; a++) {
611                 VlakRen *vlr= RE_findOrAddVlak(re, a);
612                 if((vlr->flag & ME_SMOOTH)==0) {
613                         float *f1= vlr->v1->n;
614                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
615                         f1= vlr->v2->n;
616                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
617                         f1= vlr->v3->n;
618                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
619                         if(vlr->v4) {
620                                 f1= vlr->v4->n;
621                                 if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
622                         }
623                 }
624         }
625         
626                 /* normalize vertex normals */
627         for(a=startvert; a<re->totvert; a++) {
628                 VertRen *ver= RE_findOrAddVert(re, a);
629                 Normalize(ver->n);
630                 if(do_tangent) {
631                         float *tav= RE_vertren_get_tangent(re, ver, 0);
632                         if (tav) {
633                                 /* orthonorm. */
634                                 float tdn = tav[0]*ver->n[0] + tav[1]*ver->n[1] + tav[2]*ver->n[2];
635                                 tav[0] -= ver->n[0]*tdn;
636                                 tav[1] -= ver->n[1]*tdn;
637                                 tav[2] -= ver->n[2]*tdn;
638                                 Normalize(tav);
639                         }
640                 }
641         }
642
643                 /* vertex normal (puno) switch flags for during render */
644         for(a=startvlak; a<re->totvlak; a++) {
645                 VlakRen *vlr= RE_findOrAddVlak(re, a);
646
647                 if((vlr->flag & R_NOPUNOFLIP)==0) {
648                         float *v1= vlr->v1->n;
649                         float *v2= vlr->v2->n;
650                         float *v3= vlr->v3->n;
651                         float *v4= vlr->v4?vlr->v4->n:NULL;
652                         float *nor= vlr->n;
653                         vlr->puno &= ~15;
654                         if ((nor[0]*v1[0] + nor[1]*v1[1] + nor[2]*v1[2]) < -FLT_EPSILON10) vlr->puno= 1;
655                         if ((nor[0]*v2[0] + nor[1]*v2[1] + nor[2]*v2[2]) < -FLT_EPSILON10) vlr->puno+= 2;
656                         if ((nor[0]*v3[0] + nor[1]*v3[1] + nor[2]*v3[2]) < -FLT_EPSILON10) vlr->puno+= 4;
657                         if(v4) {
658                                 if((nor[0]*v4[0] + nor[1]*v4[1] + nor[2]*v4[2]) < -FLT_EPSILON10 ) vlr->puno+= 8;
659                         }
660                 }
661         }
662 }
663
664 // NT same as calc_vertexnormals, but dont modify the existing vertex normals
665 // only recalculate other render data. If this is at some point used for other things than fluidsim,
666 // this could be made on option for the normal calc_vertexnormals
667 static void calc_fluidsimnormals(Render *re, int startvert, int startvlak, int do_tangent)
668 {
669         int a;
670
671         /* dont clear vertex normals here */
672         // OFF for(a=startvert; a<re->totvert; a++) { VertRen *ver= RE_findOrAddVert(re, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
673         /* calculate cos of angles and point-masses, use as weight factor to add face normal to vertex */
674         for(a=startvlak; a<re->totvlak; a++) {
675                 VlakRen *vlr= RE_findOrAddVlak(re, a);
676                 if(vlr->flag & ME_SMOOTH) {
677                         VertRen *v1= vlr->v1;
678                         VertRen *v2= vlr->v2;
679                         VertRen *v3= vlr->v3;
680                         VertRen *v4= vlr->v4;
681                         float n1[3], n2[3], n3[3], n4[3];
682                         float fac1, fac2, fac3, fac4=0.0f;
683
684                         if(re->flag & R_GLOB_NOPUNOFLIP)
685                                 vlr->flag |= R_NOPUNOFLIP;
686                         
687                         VecSubf(n1, v2->co, v1->co);
688                         Normalize(n1);
689                         VecSubf(n2, v3->co, v2->co);
690                         Normalize(n2);
691                         if(v4==NULL) {
692                                 VecSubf(n3, v1->co, v3->co);
693                                 Normalize(n3);
694                                 fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
695                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
696                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
697                         }
698                         else {
699                                 VecSubf(n3, v4->co, v3->co);
700                                 Normalize(n3);
701                                 VecSubf(n4, v1->co, v4->co);
702                                 Normalize(n4);
703
704                                 fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
705                                 fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
706                                 fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
707                                 fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
708
709                                 if(!(vlr->flag & R_NOPUNOFLIP)) {
710                                         if( check_vnormal(vlr->n, v4->n) ) fac4= -fac4;
711                                 }
712                         }
713
714                         //if(do_tangent)
715                         //      calc_tangent_vector(re, vlr, fac1, fac2, fac3, fac4);
716                 }
717                 if(do_tangent) {
718                         /* tangents still need to be calculated for flat faces too */
719                         /* weighting removed, they are not vertexnormals */
720                         calc_tangent_vector(re, vlr);
721                 }
722         }
723
724         /* do solid faces */
725         for(a=startvlak; a<re->totvlak; a++) {
726                 VlakRen *vlr= RE_findOrAddVlak(re, a);
727                 if((vlr->flag & ME_SMOOTH)==0) {
728                         float *f1= vlr->v1->n;
729                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
730                         f1= vlr->v2->n;
731                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
732                         f1= vlr->v3->n;
733                         if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
734                         if(vlr->v4) {
735                                 f1= vlr->v4->n;
736                                 if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
737                         }                       
738                 }
739         }
740         
741         /* normalize vertex normals */
742         for(a=startvert; a<re->totvert; a++) {
743                 VertRen *ver= RE_findOrAddVert(re, a);
744                 Normalize(ver->n);
745                 if(do_tangent) {
746                         float *tav= RE_vertren_get_tangent(re, ver, 0);
747                         if(tav) Normalize(tav);
748                 }
749         }
750
751         /* vertex normal (puno) switch flags for during render */
752         for(a=startvlak; a<re->totvlak; a++) {
753                 VlakRen *vlr= RE_findOrAddVlak(re, a);
754                 if((vlr->flag & R_NOPUNOFLIP)==0) {
755                         VertRen *v1= vlr->v1;
756                         VertRen *v2= vlr->v2;
757                         VertRen *v3= vlr->v3;
758                         VertRen *v4= vlr->v4;
759                         vlr->puno &= ~15;
760                         if ((vlr->n[0]*v1->n[0]+vlr->n[1]*v1->n[1]+vlr->n[2]*v1->n[2])<0.0) vlr->puno= 1;
761                         if ((vlr->n[0]*v2->n[0]+vlr->n[1]*v2->n[1]+vlr->n[2]*v2->n[2])<0.0) vlr->puno+= 2;
762                         if ((vlr->n[0]*v3->n[0]+vlr->n[1]*v3->n[1]+vlr->n[2]*v3->n[2])<0.0) vlr->puno+= 4;
763                         if(v4) {
764                                 if((vlr->n[0]*v4->n[0]+vlr->n[1]*v4->n[1]+vlr->n[2]*v4->n[2])<0.0) vlr->puno+= 8;
765                         }
766                 }
767         }
768 }
769
770 /* ------------------------------------------------------------------------- */
771 /* Autosmoothing:                                                            */
772 /* ------------------------------------------------------------------------- */
773
774 typedef struct ASvert {
775         int totface;
776         ListBase faces;
777 } ASvert;
778
779 typedef struct ASface {
780         struct ASface *next, *prev;
781         VlakRen *vlr[4];
782         VertRen *nver[4];
783 } ASface;
784
785 static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr)
786 {
787         ASface *asf;
788         int a;
789         
790         if(v1 == NULL) return;
791         
792         if(asv->faces.first==NULL) {
793                 asf= MEM_callocN(sizeof(ASface), "asface");
794                 BLI_addtail(&asv->faces, asf);
795         }
796         
797         asf= asv->faces.last;
798         for(a=0; a<4; a++) {
799                 if(asf->vlr[a]==NULL) {
800                         asf->vlr[a]= vlr;
801                         asv->totface++;
802                         break;
803                 }
804         }
805         
806         /* new face struct */
807         if(a==4) {
808                 asf= MEM_callocN(sizeof(ASface), "asface");
809                 BLI_addtail(&asv->faces, asf);
810                 asf->vlr[0]= vlr;
811                 asv->totface++;
812         }
813 }
814
815 static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
816 {
817         /* return 1: vertex needs a copy */
818         ASface *asf;
819         float inp;
820         int a;
821         
822         if(vlr==0) return 0;
823         
824         asf= asv->faces.first;
825         while(asf) {
826                 for(a=0; a<4; a++) {
827                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
828                                 inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
829                                 if(inp < thresh) return 1;
830                         }
831                 }
832                 asf= asf->next;
833         }
834         
835         return 0;
836 }
837
838 static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) 
839 {
840         /* return when new vertex already was made */
841         ASface *asf;
842         float inp;
843         int a;
844         
845         asf= asv->faces.first;
846         while(asf) {
847                 for(a=0; a<4; a++) {
848                         if(asf->vlr[a] && asf->vlr[a]!=vlr) {
849                                 /* this face already made a copy for this vertex! */
850                                 if(asf->nver[a]) {
851                                         inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] );
852                                         if(inp >= thresh) {
853                                                 return asf->nver[a];
854                                         }
855                                 }
856                         }
857                 }
858                 asf= asf->next;
859         }
860         
861         return NULL;
862 }
863
864 /* note; autosmooth happens in object space still, after applying autosmooth we rotate */
865 /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
866 static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak, int degr)
867 {
868         ASvert *asv, *asverts, *asvertoffs;
869         ASface *asf;
870         VertRen *ver, *v1;
871         VlakRen *vlr;
872         float thresh;
873         int a, b, totvert;
874         
875         if(startvert==re->totvert) return;
876         asverts= MEM_callocN(sizeof(ASvert)*(re->totvert-startvert), "all smooth verts");
877         asvertoffs= asverts-startvert;   /* se we can use indices */
878         
879         thresh= cos( M_PI*(0.5f+(float)degr)/180.0 );
880         
881         /* step zero: give faces normals of original mesh, if this is provided */
882         
883         
884         /* step one: construct listbase of all vertices and pointers to faces */
885         for(a=startvlak; a<re->totvlak; a++) {
886                 vlr= RE_findOrAddVlak(re, a);
887                 /* skip wire faces */
888                 if(vlr->v2 != vlr->v3) {
889                         as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr);
890                         as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr);
891                         as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr);
892                         if(vlr->v4) 
893                                 as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr);
894                 }
895         }
896         
897         /* we now test all vertices, when faces have a normal too much different: they get a new vertex */
898         totvert= re->totvert;
899         for(a=startvert, asv=asverts; a<totvert; a++, asv++) {
900                 if(asv && asv->totface>1) {
901                         ver= RE_findOrAddVert(re, a);
902                         
903                         asf= asv->faces.first;
904                         while(asf) {
905                                 for(b=0; b<4; b++) {
906                                 
907                                         /* is there a reason to make a new vertex? */
908                                         vlr= asf->vlr[b];
909                                         if( as_testvertex(vlr, ver, asv, thresh) ) {
910                                                 
911                                                 /* already made a new vertex within threshold? */
912                                                 v1= as_findvertex(vlr, ver, asv, thresh);
913                                                 if(v1==NULL) {
914                                                         /* make a new vertex */
915                                                         v1= RE_vertren_copy(re, ver);
916                                                 }
917                                                 asf->nver[b]= v1;
918                                                 if(vlr->v1==ver) vlr->v1= v1;
919                                                 if(vlr->v2==ver) vlr->v2= v1;
920                                                 if(vlr->v3==ver) vlr->v3= v1;
921                                                 if(vlr->v4==ver) vlr->v4= v1;
922                                         }
923                                 }
924                                 asf= asf->next;
925                         }
926                 }
927         }
928         
929         /* free */
930         for(a=0; a<totvert-startvert; a++) {
931                 BLI_freelistN(&asverts[a].faces);
932         }
933         MEM_freeN(asverts);
934         
935         /* rotate vertices and calculate normal of faces */
936         for(a=startvert; a<re->totvert; a++) {
937                 ver= RE_findOrAddVert(re, a);
938                 MTC_Mat4MulVecfl(mat, ver->co);
939         }
940         for(a=startvlak; a<re->totvlak; a++) {
941                 vlr= RE_findOrAddVlak(re, a);
942                 
943                 /* skip wire faces */
944                 if(vlr->v2 != vlr->v3) {
945                         if(vlr->v4) 
946                                 CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
947                         else 
948                                 CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
949                 }
950         }               
951 }
952
953 /* ------------------------------------------------------------------------- */
954 /* End of autosmoothing:                                                     */
955 /* ------------------------------------------------------------------------- */
956
957 /* ------------------------------------------------------------------------- */
958 /* Orco hash                                                                                                                             */
959 /* ------------------------------------------------------------------------- */
960
961
962 static float *get_object_orco(Render *re, Object *ob)
963 {
964         float *orco;
965         
966         if (!re->orco_hash)
967                 re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
968         
969         orco = BLI_ghash_lookup(re->orco_hash, ob);
970         
971         if (!orco) {
972                 if (ob->type==OB_MESH) {
973                         orco = mesh_create_orco_render(ob);
974                 } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
975                         orco = make_orco_curve(ob);
976                 } else if (ob->type==OB_SURF) {
977                         orco = make_orco_surf(ob);
978                 }
979                 
980                 if (orco)
981                         BLI_ghash_insert(re->orco_hash, ob, orco);
982         }
983         
984         return orco;
985 }
986
987 static void free_mesh_orco_hash(Render *re) 
988 {
989         if (re->orco_hash) {
990                 BLI_ghash_free(re->orco_hash, NULL, (GHashValFreeFP)MEM_freeN);
991                 re->orco_hash = NULL;
992         }
993 }
994
995 /* ******************** END ORCO HASH ***************** */
996
997
998 static void make_render_halos(Render *re, Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
999 {
1000         HaloRen *har;
1001         float xn, yn, zn, nor[3], view[3];
1002         float vec[3], hasize, mat[4][4], imat[3][3];
1003         int a, ok, seed= ma->seed1;
1004
1005         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
1006         MTC_Mat3CpyMat4(imat, ob->imat);
1007
1008         re->flag |= R_HALO;
1009
1010         for(a=0; a<totvert; a++, mvert++) {
1011                 ok= 1;
1012
1013                 if(ok) {
1014                         hasize= ma->hasize;
1015
1016                         VECCOPY(vec, mvert->co);
1017                         MTC_Mat4MulVecfl(mat, vec);
1018
1019                         if(ma->mode & MA_HALOPUNO) {
1020                                 xn= mvert->no[0];
1021                                 yn= mvert->no[1];
1022                                 zn= mvert->no[2];
1023
1024                                 /* transpose ! */
1025                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1026                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1027                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1028                                 Normalize(nor);
1029
1030                                 VECCOPY(view, vec);
1031                                 Normalize(view);
1032
1033                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
1034                                 if(zn>=0.0) hasize= 0.0;
1035                                 else hasize*= zn*zn*zn*zn;
1036                         }
1037
1038                         if(orco) har= RE_inithalo(re, ma, vec, NULL, orco, hasize, 0.0, seed);
1039                         else har= RE_inithalo(re, ma, vec, NULL, mvert->co, hasize, 0.0, seed);
1040                         if(har) har->lay= ob->lay;
1041                 }
1042                 if(orco) orco+= 3;
1043                 seed++;
1044         }
1045 }
1046
1047 /* ------------------------------------------------------------------------- */
1048 static Material *give_render_material(Render *re, Object *ob, int nr)
1049 {
1050         extern Material defmaterial;    /* material.c */
1051         Material *ma;
1052         
1053         ma= give_current_material(ob, nr);
1054         if(ma==NULL) 
1055                 ma= &defmaterial;
1056         else
1057                 if(ma->mode & MA_ZTRA)
1058                         re->flag |= R_ZTRA;
1059         
1060         if(re->r.mode & R_SPEED) ma->texco |= NEED_UV;
1061         
1062         /* for light groups */
1063         ma->flag |= MA_IS_USED;
1064         
1065         return ma;
1066 }
1067
1068
1069
1070 static void render_particle_system(Render *re, Object *ob, Object *par, PartEff *paf)
1071 {
1072         Particle *pa=0;
1073         HaloRen *har=0;
1074         Material *ma=0;
1075         float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
1076         float haloScale = 1.0;  //NT scale halos 
1077         float iniAlpha = 0.0; // restore material alpha 
1078         int a, mat_nr=1, seed;
1079         int useFluidsimParticles = 0; // FSPARTICLE
1080
1081         ma= give_render_material(re, ob, paf->omat);
1082         
1083         if( (ob->fluidsimSettings) && (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)) {
1084                 useFluidsimParticles = 1;
1085                 iniAlpha = ma->alpha;
1086         }
1087         
1088         pa= paf->keys;
1089         if(pa==NULL || paf->disp!=100 || useFluidsimParticles) {
1090                 build_particle_system(ob);
1091                 pa= paf->keys;
1092                 if(pa==NULL) return;
1093         }
1094
1095         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
1096         MTC_Mat4Invert(ob->imat, mat);  /* this is correct, for imat texture */
1097
1098         /* enable duplicators to work */
1099         if(par) {
1100                 Mat4MulMat4(tmat, paf->imat, ob->obmat);
1101                 MTC_Mat4MulMat4(mat, tmat, re->viewmat);
1102                 
1103                 MTC_Mat4Invert(tmat, mat);
1104                 MTC_Mat3CpyMat4(imat, tmat);
1105         }
1106         else {
1107                 MTC_Mat4CpyMat4(mat, re->viewmat);
1108                 
1109                 MTC_Mat4Invert(tmat, re->viewmat);
1110                 MTC_Mat3CpyMat4(imat, tmat);
1111                 
1112         }       
1113
1114         re->flag |= R_HALO;
1115
1116         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
1117         else ptime= 0.0;
1118         ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
1119         seed= ma->seed1;
1120         
1121         for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
1122
1123                 /* offset time for calculating normal */
1124                 stime= ctime;
1125                 ptime= ctime+1.0f;
1126                 if(ctime < pa->time) {
1127                         if(paf->flag & PAF_UNBORN)
1128                                 ptime= pa->time+1.0f;
1129                         else
1130                                 continue;
1131                 }
1132                 if(ctime > pa->time+pa->lifetime) {
1133                         if(paf->flag & PAF_DIED)
1134                                 stime= pa->time+pa->lifetime-1.0f;
1135                         else
1136                                 continue;
1137                 }
1138                 
1139                 /* watch it: also calculate the normal of a particle */
1140                 if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
1141                         where_is_particle(paf, pa, stime, vec);
1142                         MTC_Mat4MulVecfl(mat, vec);
1143                         where_is_particle(paf, pa, ptime, vec1);
1144                         MTC_Mat4MulVecfl(mat, vec1);
1145                 }
1146                 else {
1147                         where_is_particle(paf, pa, ctime, vec);
1148                         MTC_Mat4MulVecfl(mat, vec);
1149                 }
1150
1151                 if(pa->mat_nr != mat_nr) {
1152                         mat_nr= pa->mat_nr;
1153                         ma= give_render_material(re, ob, mat_nr);
1154                 }
1155
1156                 if(ma->ipo) {
1157                         /* correction for lifetime */
1158                         ptime= 100.0*(ctime-pa->time)/pa->lifetime;
1159                         calc_ipo(ma->ipo, ptime);
1160                         execute_ipo((ID *)ma, ma->ipo);
1161                 }
1162
1163                 //NT scale halos FSPARTICLE
1164                 if(useFluidsimParticles) {
1165                         // rescale to 1.0-10.0, then div by 5 afterwards, gives values in range 0.2-2.0
1166                         double fspsize = ((double)pa->rt / 1000.0f) / 5.0 ; 
1167                         haloScale = 1.0/(float)pow(fspsize, (double)ob->fluidsimSettings->particleInfSize);
1168                         ma->alpha = iniAlpha / (float)pow( fspsize, (double)ob->fluidsimSettings->particleInfAlpha);
1169                         if(ma->alpha>1.) ma->alpha = 1.;
1170                 }
1171
1172                 hasize= ma->hasize * haloScale;
1173
1174                 if(ma->mode & MA_HALOPUNO) {
1175                         xn= pa->no[0];
1176                         yn= pa->no[1];
1177                         zn= pa->no[2];
1178
1179                         /* transpose ! */
1180                         nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1181                         nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1182                         nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1183                         Normalize(nor);
1184
1185                         VECCOPY(view, vec);
1186                         Normalize(view);
1187
1188                         zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
1189                         if(zn>=0.0) hasize= 0.0;
1190                         else hasize*= zn*zn*zn*zn;
1191                 }
1192
1193                 if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
1194                 else {
1195                         har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
1196                         if(har && ma->mode & MA_HALO_SHADE) {
1197                                 VecSubf(har->no, vec, vec1);
1198                                 Normalize(har->no);
1199                         }
1200                 }
1201                 if(har) har->lay= ob->lay;
1202         }
1203
1204         /* restore material */
1205         for(a=1; a<=ob->totcol; a++) {
1206                 ma= give_render_material(re, ob, a);
1207                 if(ma) do_mat_ipo(ma);
1208         }
1209         
1210         if(paf->disp!=100) {
1211                 MEM_freeN(paf->keys);
1212                 paf->keys= NULL;
1213         }
1214
1215         if(useFluidsimParticles) { ma->alpha = iniAlpha; }// FSPARTICLE restore...
1216 }
1217
1218
1219 /* ------------------------------------------------------------------------- */
1220
1221 /* future thread problem... */
1222 static void static_particle_strand(Render *re, Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first)
1223 {
1224         static VertRen *v1= NULL, *v2= NULL;
1225         VlakRen *vlr;
1226         float nor[3], cross[3], w, dx, dy, width;
1227         int flag;
1228         
1229         VecSubf(nor, vec, vec1);
1230         Normalize(nor);         // nor needed as tangent 
1231         Crossf(cross, vec, nor);
1232         
1233         /* turn cross in pixelsize */
1234         w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
1235         dx= re->winx*cross[0]*re->winmat[0][0]/w;
1236         dy= re->winy*cross[1]*re->winmat[1][1]/w;
1237         w= sqrt(dx*dx + dy*dy);
1238         if(w!=0.0f) {
1239                 float fac;
1240                 if(ma->strand_ease!=0.0f) {
1241                         if(ma->strand_ease<0.0f)
1242                                 fac= pow(ctime, 1.0+ma->strand_ease);
1243                         else
1244                                 fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
1245                 }
1246                 else fac= ctime;
1247                 
1248                 width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w;
1249                 VecMulf(cross, width);
1250         }
1251         else width= 1.0f;
1252         
1253         if(ma->mode & MA_TANGENT_STR)
1254                 flag= R_SMOOTH|R_NOPUNOFLIP|R_TANGENT;
1255         else
1256                 flag= R_SMOOTH;
1257         
1258         /* only 1 pixel wide strands filled in as quads now, otherwise zbuf errors */
1259         if(ma->strand_sta==1.0f)
1260                 flag |= R_STRAND;
1261         
1262         /* first two vertices */
1263         if(first) {
1264                 v1= RE_findOrAddVert(re, re->totvert++);
1265                 v2= RE_findOrAddVert(re, re->totvert++);
1266                 
1267                 VECCOPY(v1->co, vec);
1268                 VecAddf(v1->co, v1->co, cross);
1269                 VECCOPY(v1->n, nor);
1270                 v1->orco= orco;
1271                 v1->accum= -1.0f;       // accum abuse for strand texco
1272                 
1273                 VECCOPY(v2->co, vec);
1274                 VecSubf(v2->co, v2->co, cross);
1275                 VECCOPY(v2->n, nor);
1276                 v2->orco= orco;
1277                 v2->accum= v1->accum;
1278         }
1279         else {
1280                 
1281                 vlr= RE_findOrAddVlak(re, re->totvlak++);
1282                 vlr->flag= flag;
1283                 vlr->ob= ob;
1284                 vlr->v1= v1;
1285                 vlr->v2= v2;
1286                 vlr->v3= RE_findOrAddVert(re, re->totvert++);
1287                 vlr->v4= RE_findOrAddVert(re, re->totvert++);
1288                 
1289                 v1= vlr->v4; // cycle
1290                 v2= vlr->v3; // cycle
1291                 
1292                 VECCOPY(vlr->v4->co, vec);
1293                 VecAddf(vlr->v4->co, vlr->v4->co, cross);
1294                 VECCOPY(vlr->v4->n, nor);
1295                 vlr->v4->orco= orco;
1296                 vlr->v4->accum= -1.0f + 2.0f*ctime;     // accum abuse for strand texco
1297                 
1298                 VECCOPY(vlr->v3->co, vec);
1299                 VecSubf(vlr->v3->co, vlr->v3->co, cross);
1300                 VECCOPY(vlr->v3->n, nor);
1301                 vlr->v3->orco= orco;
1302                 vlr->v3->accum= vlr->v4->accum;
1303                 
1304                 CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1305                 
1306                 vlr->mat= ma;
1307                 vlr->ec= ME_V2V3;
1308                 vlr->lay= ob->lay;
1309         }
1310 }
1311
1312 static void render_static_particle_system(Render *re, Object *ob, PartEff *paf)
1313 {
1314         Particle *pa=0;
1315         HaloRen *har=0;
1316         Material *ma=0;
1317         VertRen *v1= NULL;
1318         VlakRen *vlr;
1319         float xn, yn, zn, imat[3][3], mat[4][4], hasize;
1320         float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
1321         float *orco= NULL, loc_tex[3], size_tex[3];
1322         int a, mat_nr=1, seed, totvlako, totverto, first;
1323
1324         pa= paf->keys;
1325         if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
1326                 build_particle_system(ob);
1327                 pa= paf->keys;
1328                 if(pa==NULL) return;
1329         }
1330
1331         totvlako= re->totvlak;
1332         totverto= re->totvert;
1333         
1334         ma= give_render_material(re, ob, paf->omat);
1335         if(ma->mode & MA_HALO)
1336                 re->flag |= R_HALO;
1337
1338         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
1339         MTC_Mat4Invert(ob->imat, mat);  /* need to be that way, for imat texture */
1340
1341         MTC_Mat3CpyMat4(imat, ob->imat);
1342         
1343         /* orcos */
1344         if(!(ma->mode & (MA_HALO|MA_WIRE))) {
1345                 orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
1346                 if (!re->orco_hash)
1347                         re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
1348                 BLI_ghash_insert(re->orco_hash, paf, orco);     /* pointer is particles, otherwise object uses it */
1349         }
1350         
1351         mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
1352         
1353         if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
1354         else ptime= 0.0;
1355         ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
1356         seed= ma->seed1;
1357
1358         for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
1359                 
1360                 where_is_particle(paf, pa, pa->time, vec1);
1361                 if(orco) {
1362                         orco[0] = (vec1[0]-loc_tex[0])/size_tex[0];
1363                         orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
1364                         orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
1365                 }
1366                 MTC_Mat4MulVecfl(mat, vec1);
1367                 mtime= pa->time+pa->lifetime+paf->staticstep-1;
1368                 
1369                 first= 1;
1370                 for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
1371                         
1372                         /* make sure hair grows until the end.. */
1373                         if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
1374                         
1375                         /* watch it: also calc the normal of a particle */
1376                         if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
1377                                 where_is_particle(paf, pa, ctime+1.0, vec);
1378                                 MTC_Mat4MulVecfl(mat, vec);
1379                         }
1380                         else {
1381                                 where_is_particle(paf, pa, ctime, vec);
1382                                 MTC_Mat4MulVecfl(mat, vec);
1383                         }
1384
1385                         if(pa->mat_nr != mat_nr) {
1386                                 mat_nr= pa->mat_nr;
1387                                 ma= give_render_material(re, ob, mat_nr);
1388                         }
1389                         
1390                         /* wires */
1391                         if(ma->mode & MA_WIRE) {
1392                                 if(ctime == pa->time) {
1393                                         v1= RE_findOrAddVert(re, re->totvert++);
1394                                         VECCOPY(v1->co, vec);
1395                                 }
1396                                 else {
1397                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
1398                                         vlr->ob= ob;
1399                                         vlr->v1= v1;
1400                                         vlr->v2= RE_findOrAddVert(re, re->totvert++);
1401                                         vlr->v3= vlr->v2;
1402                                         vlr->v4= NULL;
1403                                         
1404                                         v1= vlr->v2; // cycle
1405                                         VECCOPY(v1->co, vec);
1406                                         
1407                                         VecSubf(vlr->n, vec, vec1);
1408                                         Normalize(vlr->n);
1409                                         VECCOPY(v1->n, vlr->n);
1410                                         
1411                                         vlr->mat= ma;
1412                                         vlr->ec= ME_V1V2;
1413                                         vlr->lay= ob->lay;
1414                                 }
1415                         }
1416                         else {
1417                                 if(ma->ipo) {
1418                                         /* correction for lifetime */
1419                                         ptime= 100.0*(ctime-pa->time)/pa->lifetime;
1420                                         calc_ipo(ma->ipo, ptime);
1421                                         execute_ipo((ID *)ma, ma->ipo);
1422                                 }
1423                                 
1424                                 if(ma->mode & MA_HALO) {
1425                                         hasize= ma->hasize;
1426
1427                                         if(ma->mode & MA_HALOPUNO) {
1428                                                 xn= pa->no[0];
1429                                                 yn= pa->no[1];
1430                                                 zn= pa->no[2];
1431
1432                                                 /* transpose ! */
1433                                                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1434                                                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1435                                                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1436                                                 Normalize(nor);
1437
1438                                                 VECCOPY(view, vec);
1439                                                 Normalize(view);
1440
1441                                                 zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
1442                                                 if(zn>=0.0) hasize= 0.0;
1443                                                 else hasize*= zn*zn*zn*zn;
1444                                         }
1445
1446                                         if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
1447                                         else {
1448                                                 har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
1449                                                 if(har && (ma->mode & MA_HALO_SHADE)) {
1450                                                         VecSubf(har->no, vec, vec1);
1451                                                         Normalize(har->no);
1452                                                         har->lay= ob->lay;
1453                                                 }
1454                                         }
1455                                         if(har) har->lay= ob->lay;
1456                                 }
1457                                 else {  /* generate pixel sized hair strand */
1458                                         float strandco= 1.0f;
1459                                         
1460                                         /* last strand, texco to end */
1461                                         if(ctime + paf->staticstep < mtime)
1462                                                 strandco= (ctime-pa->time)/(mtime-pa->time);
1463                                         
1464                                         static_particle_strand(re, ob, ma, orco, vec, vec1, strandco, first);
1465                                 }
1466                         }
1467                         
1468                         VECCOPY(vec1, vec);
1469                         first= 0;
1470                 }
1471                 
1472                 seed++;
1473                 if(orco) orco+=3;
1474         }
1475
1476         if(paf->disp!=100) {
1477                 MEM_freeN(paf->keys);
1478                 paf->keys= NULL;
1479         }
1480
1481         if((ma->mode & MA_TANGENT_STR)==0)
1482                 calc_vertexnormals(re, totverto, totvlako, 0);
1483 }
1484
1485
1486 /* ------------------------------------------------------------------------- */
1487
1488 static int verghalo(const void *a1, const void *a2)
1489 {
1490         const struct halosort *x1=a1, *x2=a2;
1491         
1492         if( x1->z < x2->z ) return 1;
1493         else if( x1->z > x2->z) return -1;
1494         return 0;
1495 }
1496
1497 /* ------------------------------------------------------------------------- */
1498 static void sort_halos(Render *re)
1499 {
1500         struct halosort *hablock, *haso;
1501         HaloRen *har = NULL, **bloha;
1502         int a;
1503
1504         if(re->tothalo==0) return;
1505
1506         /* make datablock with halo pointers, sort */
1507         haso= hablock= MEM_mallocN(sizeof(struct halosort)*re->tothalo, "hablock");
1508
1509         for(a=0; a<re->tothalo; a++) {
1510                 if((a & 255)==0) har= re->bloha[a>>8];
1511                 else har++;
1512                 haso->har= har;
1513                 haso->z= har->zs;
1514                 haso++;
1515         }
1516
1517         qsort(hablock, re->tothalo, sizeof(struct halosort), verghalo);
1518
1519         /* re-assamble re->bloha */
1520
1521         bloha= re->bloha;
1522         re->bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(re->blohalen),"Bloha");
1523
1524         haso= hablock;
1525         for(a=0; a<re->tothalo; a++) {
1526                 har= RE_findOrAddHalo(re, a);
1527                 *har= *(haso->har);
1528
1529                 haso++;
1530         }
1531
1532         /* free */
1533         a= 0;
1534         while(bloha[a]) {
1535                 MEM_freeN(bloha[a]);
1536                 a++;
1537         }
1538         MEM_freeN(bloha);
1539         MEM_freeN(hablock);
1540
1541 }
1542
1543 /* ------------------------------------------------------------------------- */
1544 static void init_render_mball(Render *re, Object *ob)
1545 {
1546         DispList *dl, *dlo;
1547         VertRen *ver;
1548         VlakRen *vlr, *vlr1;
1549         Material *ma;
1550         float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
1551         int a, need_orco, startvert, *index;
1552
1553         if (ob!=find_basis_mball(ob))
1554                 return;
1555
1556         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
1557         MTC_Mat4Invert(ob->imat, mat);
1558         MTC_Mat3CpyMat4(imat, ob->imat);
1559
1560         ma= give_render_material(re, ob, 1);
1561
1562         need_orco= 0;
1563         if(ma->texco & TEXCO_ORCO) {
1564                 need_orco= 1;
1565         }
1566
1567         dlo= ob->disp.first;
1568         if(dlo) BLI_remlink(&ob->disp, dlo);
1569
1570         makeDispListMBall(ob);
1571         dl= ob->disp.first;
1572         if(dl==0) return;
1573
1574         startvert= re->totvert;
1575         data= dl->verts;
1576         nors= dl->nors;
1577
1578         for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
1579
1580                 ver= RE_findOrAddVert(re, re->totvert++);
1581                 VECCOPY(ver->co, data);
1582                 MTC_Mat4MulVecfl(mat, ver->co);
1583
1584                 xn= nors[0];
1585                 yn= nors[1];
1586                 zn= nors[2];
1587
1588                 /* transpose ! */
1589                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1590                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1591                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1592                 Normalize(ver->n);
1593                 //if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0);
1594                 
1595                 if(need_orco) ver->orco= data;
1596         }
1597
1598         index= dl->index;
1599         for(a=0; a<dl->parts; a++, index+=4) {
1600
1601                 vlr= RE_findOrAddVlak(re, re->totvlak++);
1602                 vlr->ob= ob;
1603                 vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
1604                 vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
1605                 vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
1606                 vlr->v4= 0;
1607
1608                 if(ob->transflag & OB_NEG_SCALE) 
1609                         CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
1610                 else
1611                         CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1612
1613                 vlr->mat= ma;
1614                 vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
1615                 vlr->ec= 0;
1616                 vlr->lay= ob->lay;
1617
1618                 /* mball -too bad- always has triangles, because quads can be non-planar */
1619                 if(index[3] && index[3]!=index[2]) {
1620                         vlr1= RE_findOrAddVlak(re, re->totvlak++);
1621                         *vlr1= *vlr;
1622                         vlr1->v2= vlr1->v3;
1623                         vlr1->v3= RE_findOrAddVert(re, startvert+index[3]);
1624                         if(ob->transflag & OB_NEG_SCALE) 
1625                                 CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
1626                         else
1627                                 CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n);
1628                 }
1629         }
1630
1631         if(need_orco) {
1632                 /* store displist and scale */
1633                 make_orco_mball(ob);
1634                 if(dlo) BLI_addhead(&ob->disp, dlo);
1635
1636         }
1637         else {
1638                 freedisplist(&ob->disp);
1639                 if(dlo) BLI_addtail(&ob->disp, dlo);
1640         }
1641 }
1642 /* ------------------------------------------------------------------------- */
1643 /* convert */
1644
1645 static int vlakren_customdata_layer_num(int n, int active)
1646 {
1647         /* make the active layer the first */
1648         if (n == active) return 0;
1649         else if (n < active) return n+1;
1650         else return n;
1651 }
1652
1653 struct edgesort {
1654         int v1, v2;
1655         int f;
1656         int i1, i2;
1657 };
1658
1659 /* edges have to be added with lowest index first for sorting */
1660 static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, int f)
1661 {
1662         if(v1>v2) {
1663                 SWAP(int, v1, v2);
1664                 SWAP(int, i1, i2);
1665         }
1666
1667         ed->v1= v1;
1668         ed->v2= v2;
1669         ed->i1= i1;
1670         ed->i2= i2;
1671         ed->f = f;
1672 }
1673
1674 static int vergedgesort(const void *v1, const void *v2)
1675 {
1676         const struct edgesort *x1=v1, *x2=v2;
1677         
1678         if( x1->v1 > x2->v1) return 1;
1679         else if( x1->v1 < x2->v1) return -1;
1680         else if( x1->v2 > x2->v2) return 1;
1681         else if( x1->v2 < x2->v2) return -1;
1682         
1683         return 0;
1684 }
1685
1686 static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
1687 {
1688         MFace *mf, *mface;
1689         MTFace *tface=NULL;
1690         struct edgesort *edsort, *ed;
1691         unsigned int *mcol=NULL;
1692         int a, totedge=0, totface;
1693         
1694         mface= dm->getFaceArray(dm);
1695         totface= dm->getNumFaces(dm);
1696         tface= dm->getFaceDataArray(dm, CD_MTFACE);
1697         mcol= dm->getFaceDataArray(dm, CD_MCOL);
1698         
1699         if(mcol==NULL && tface==NULL) return NULL;
1700         
1701         /* make sorted table with edges and face indices in it */
1702         for(a= totface, mf= mface; a>0; a--, mf++) {
1703                 if(mf->v4) totedge+=4;
1704                 else if(mf->v3) totedge+=3;
1705         }
1706
1707         if(totedge==0)
1708                 return NULL;
1709         
1710         ed= edsort= MEM_callocN(totedge*sizeof(struct edgesort), "edgesort");
1711         
1712         for(a=0, mf=mface; a<totface; a++, mf++) {
1713                 to_edgesort(ed++, 0, 1, mf->v1, mf->v2, a);
1714                 to_edgesort(ed++, 1, 2, mf->v2, mf->v3, a);
1715                 if(mf->v4) {
1716                         to_edgesort(ed++, 2, 3, mf->v3, mf->v4, a);
1717                         to_edgesort(ed++, 3, 0, mf->v4, mf->v1, a);
1718                 }
1719                 else if(mf->v3)
1720                         to_edgesort(ed++, 2, 3, mf->v3, mf->v1, a);
1721         }
1722         
1723         qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
1724         
1725         *totedgesort= totedge;
1726
1727         return edsort;
1728 }
1729
1730 static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
1731 {
1732         struct edgesort ed, *edp;
1733         CustomDataLayer *layer;
1734         MTFace *mtface, *mtf;
1735         MCol *mcol, *mc;
1736         int index, mtfn, mcn, n;
1737         char *name;
1738         
1739         if(medge->v1 < medge->v2) {
1740                 ed.v1= medge->v1;
1741                 ed.v2= medge->v2;
1742         }
1743         else {
1744                 ed.v1= medge->v2;
1745                 ed.v2= medge->v1;
1746         }
1747         
1748         edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
1749
1750         /* since edges have different index ordering, we have to duplicate mcol and tface */
1751         if(edp) {
1752                 mtfn= mcn= 0;
1753
1754                 for(index=0; index<dm->faceData.totlayer; index++) {
1755                         layer= &dm->faceData.layers[index];
1756                         name= layer->name;
1757
1758                         if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
1759                                 mtface= &((MTFace*)layer->data)[edp->f];
1760                                 n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd);
1761                                 mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1);
1762
1763                                 *mtf= *mtface;
1764
1765                                 memcpy(mtf->uv[0], mtface->uv[edp->i1], sizeof(float)*2);
1766                                 memcpy(mtf->uv[1], mtface->uv[edp->i2], sizeof(float)*2);
1767                                 memcpy(mtf->uv[2], mtface->uv[1], sizeof(float)*2);
1768                                 memcpy(mtf->uv[3], mtface->uv[1], sizeof(float)*2);
1769                         }
1770                         else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
1771                                 mcol= &((MCol*)layer->data)[edp->f*4];
1772                                 n= vlakren_customdata_layer_num(mcn++, layer->active_rnd);
1773                                 mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1);
1774
1775                                 mc[0]= mcol[edp->i1];
1776                                 mc[1]= mc[2]= mc[3]= mcol[edp->i2];
1777                         }
1778                 }
1779         }
1780 }
1781
1782 static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts)
1783 {
1784         Mesh *me;
1785         MVert *mvert = NULL;
1786         MFace *mface;
1787         VlakRen *vlr; //, *vlr1;
1788         VertRen *ver;
1789         Material *ma;
1790         MSticky *ms = NULL;
1791         PartEff *paf;
1792         DerivedMesh *dm;
1793         float xn, yn, zn,  imat[3][3], mat[4][4];  //nor[3],
1794         float *orco=0;
1795         int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
1796         int end, do_autosmooth=0, totvert = 0;
1797         int useFluidmeshNormals= 0; // NT fluidsim, use smoothed normals?
1798         int use_original_normals= 0;
1799
1800         me= ob->data;
1801
1802         paf = give_parteff(ob);
1803         if(paf) {
1804                 /* warning; build_particle_system does modifier calls itself */
1805                 if(paf->flag & PAF_STATIC) render_static_particle_system(re, ob, paf);
1806                 else render_particle_system(re, ob, par, paf);
1807                 if((paf->flag & PAF_SHOWE)==0) return;
1808         }
1809
1810         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
1811         MTC_Mat4Invert(ob->imat, mat);
1812         MTC_Mat3CpyMat4(imat, ob->imat);
1813
1814         if(me->totvert==0) {
1815                 return;
1816         }
1817         
1818         totvlako= re->totvlak;
1819         totverto= re->totvert;
1820         
1821         need_orco= 0;
1822         for(a=1; a<=ob->totcol; a++) {
1823                 ma= give_render_material(re, ob, a);
1824                 if(ma) {
1825                         if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS))
1826                                 need_orco= 1;
1827                         if(ma->texco & TEXCO_STRESS)
1828                                 need_stress= 1;
1829                         /* normalmaps, test if tangents needed, separated from shading */
1830                         if ((ma->mode_l & MA_TANGENT_V) || (ma->mode_l & MA_NORMAP_TANG)) {
1831                                 need_tangent= 1;
1832                                 if(me->mtface==NULL)
1833                                         need_orco= 1;
1834                         }
1835                         /* radio faces need autosmooth, to separate shared vertices in corners */
1836                         if(re->r.mode & R_RADIO)
1837                                 if(ma->mode & MA_RADIO) 
1838                                         do_autosmooth= 1;
1839                 }
1840         }
1841         
1842         /* check autosmooth and displacement, we then have to skip only-verts optimize */
1843         do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
1844         if(do_autosmooth)
1845                 only_verts= 0;
1846         if(test_for_displace(re, ob ) )
1847                 only_verts= 0;
1848         
1849         if(!only_verts)
1850                 if(need_orco) orco = get_object_orco(re, ob);
1851
1852         dm = mesh_create_derived_render(ob,
1853                             CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
1854         
1855         if(dm==NULL) return;    /* in case duplicated object fails? */
1856
1857         if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
1858                  (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
1859            (ob->fluidsimSettings->meshSurface) ) {
1860                 useFluidmeshNormals = 1;
1861         }
1862
1863         mvert= dm->getVertArray(dm);
1864         totvert= dm->getNumVerts(dm);
1865
1866         /* attempt to autsmooth on original mesh, only without subsurf */
1867         if(do_autosmooth && me->totvert==totvert && me->totface==dm->getNumFaces(dm))
1868                 use_original_normals= 1;
1869         
1870         ms = (totvert==me->totvert)?me->msticky:NULL;
1871         
1872         ma= give_render_material(re, ob, 1);
1873
1874         if(ma->mode & MA_HALO) {
1875                 make_render_halos(re, ob, me, totvert, mvert, ma, orco);
1876         }
1877         else {
1878
1879                 for(a=0; a<totvert; a++, mvert++) {
1880                         ver= RE_findOrAddVert(re, re->totvert++);
1881                         VECCOPY(ver->co, mvert->co);
1882                         if(do_autosmooth==0)    /* autosmooth on original unrotated data to prevent differences between frames */
1883                                 MTC_Mat4MulVecfl(mat, ver->co);
1884
1885                         if(useFluidmeshNormals) {
1886                                 xn = mvert->no[0]/ 32767.0;
1887                                 yn = mvert->no[1]/ 32767.0;
1888                                 zn = mvert->no[2]/ 32767.0;
1889                                 /* transfor to cam  space */
1890                                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1891                                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1892                                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1893                         } // useFluidmeshNormals
1894
1895                         if(orco) {
1896                                 ver->orco= orco;
1897                                 orco+=3;
1898                         }
1899                         if(ms) {
1900                                 float *sticky= RE_vertren_get_sticky(re, ver, 1);
1901                                 sticky[0]= ms->co[0];
1902                                 sticky[1]= ms->co[1];
1903                                 ms++;
1904                         }
1905                 }
1906                 
1907                 if(!only_verts) {
1908                         /* store customdata names, because DerivedMesh is freed */
1909                         RE_vlakren_set_customdata_names(re, &dm->faceData);
1910                         
1911                         /* still to do for keys: the correct local texture coordinate */
1912
1913                         /* faces in order of color blocks */
1914                         vertofs= re->totvert - totvert;
1915                         for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
1916
1917                                 ma= give_render_material(re, ob, a1+1);
1918                                 
1919                                 /* test for 100% transparant */
1920                                 ok= 1;
1921                                 if(ma->alpha==0.0 && ma->spectra==0.0) {
1922                                         ok= 0;
1923                                         /* texture on transparency? */
1924                                         for(a=0; a<MAX_MTEX; a++) {
1925                                                 if(ma->mtex[a] && ma->mtex[a]->tex) {
1926                                                         if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
1927                                                 }
1928                                         }
1929                                 }
1930                                 
1931                                 /* if wire material, and we got edges, don't do the faces */
1932                                 if(ma->mode & MA_WIRE) {
1933                                         end= dm->getNumEdges(dm);
1934                                         if(end) ok= 0;
1935                                 }
1936
1937                                 if(ok) {
1938                                         end= dm->getNumFaces(dm);
1939                                         mface= dm->getFaceArray(dm);
1940
1941                                         for(a=0; a<end; a++, mface++) {
1942                                                 int v1, v2, v3, v4, flag;
1943                                                 
1944                                                 if( mface->mat_nr==a1 ) {
1945                                                         float len;
1946                                                                 
1947                                                         v1= mface->v1;
1948                                                         v2= mface->v2;
1949                                                         v3= mface->v3;
1950                                                         v4= mface->v4;
1951                                                         flag= mface->flag & ME_SMOOTH;
1952                                                         
1953                                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
1954                                                         vlr->ob= ob;
1955                                                         vlr->v1= RE_findOrAddVert(re, vertofs+v1);
1956                                                         vlr->v2= RE_findOrAddVert(re, vertofs+v2);
1957                                                         vlr->v3= RE_findOrAddVert(re, vertofs+v3);
1958                                                         if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
1959                                                         else vlr->v4= 0;
1960
1961                                                         /* render normals are inverted in render */
1962                                                         if(use_original_normals) {
1963                                                                 MFace *mf= me->mface+a;
1964                                                                 MVert *mv= me->mvert;
1965                                                                 
1966                                                                 if(vlr->v4) 
1967                                                                         len= CalcNormFloat4( mv[mf->v4].co, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co, vlr->n);
1968                                                                 else 
1969                                                                         len= CalcNormFloat(mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co, vlr->n);
1970                                                         }
1971                                                         else {
1972                                                                 if(vlr->v4) 
1973                                                                         len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1974                                                                 else 
1975                                                                         len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1976                                                         }
1977
1978                                                         vlr->mat= ma;
1979                                                         vlr->flag= flag;
1980                                                         if((me->flag & ME_NOPUNOFLIP) ) {
1981                                                                 vlr->flag |= R_NOPUNOFLIP;
1982                                                         }
1983                                                         vlr->ec= 0; /* mesh edges rendered separately */
1984                                                         vlr->lay= ob->lay;
1985
1986                                                         if(len==0) re->totvlak--;
1987                                                         else {
1988                                                                 CustomDataLayer *layer;
1989                                                                 MTFace *mtface, *mtf;
1990                                                                 MCol *mcol, *mc;
1991                                                                 int index, mtfn= 0, mcn= 0, n;
1992                                                                 char *name;
1993
1994                                                                 for(index=0; index<dm->faceData.totlayer; index++) {
1995                                                                         layer= &dm->faceData.layers[index];
1996                                                                         name= layer->name;
1997                                                                         
1998                                                                         if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
1999                                                                                 n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd);
2000                                                                                 mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1);
2001                                                                                 mtface= (MTFace*)layer->data;
2002                                                                                 *mtf= mtface[a];
2003                                                                         }
2004                                                                         else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
2005                                                                                 n= vlakren_customdata_layer_num(mcn++, layer->active_rnd);
2006                                                                                 mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1);
2007                                                                                 mcol= (MCol*)layer->data;
2008                                                                                 memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
2009                                                                         }
2010                                                                 }
2011                                                         }
2012                                                 }
2013                                         }
2014                                 }
2015                         }
2016                         
2017                         /* exception... we do edges for wire mode. potential conflict when faces exist... */
2018                         end= dm->getNumEdges(dm);
2019                         mvert= dm->getVertArray(dm);
2020                         ma= give_render_material(re, ob, 1);
2021                         if(end && (ma->mode & MA_WIRE)) {
2022                                 MEdge *medge;
2023                                 struct edgesort *edgetable;
2024                                 int totedge= 0;
2025                                 
2026                                 medge= dm->getEdgeArray(dm);
2027                                 
2028                                 /* we want edges to have UV and vcol too... */
2029                                 edgetable= make_mesh_edge_lookup(dm, &totedge);
2030                                 
2031                                 for(a1=0; a1<end; a1++, medge++) {
2032                                         if (medge->flag&ME_EDGERENDER) {
2033                                                 MVert *v0 = &mvert[medge->v1];
2034                                                 MVert *v1 = &mvert[medge->v2];
2035
2036                                                 vlr= RE_findOrAddVlak(re, re->totvlak++);
2037                                                 vlr->ob= ob;
2038                                                 vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
2039                                                 vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
2040                                                 vlr->v3= vlr->v2;
2041                                                 vlr->v4= NULL;
2042                                                 
2043                                                 if(edgetable) {
2044                                                         use_mesh_edge_lookup(re, dm, medge, vlr, edgetable, totedge);
2045                                                 }
2046                                                 
2047                                                 xn= -(v0->no[0]+v1->no[0]);
2048                                                 yn= -(v0->no[1]+v1->no[1]);
2049                                                 zn= -(v0->no[2]+v1->no[2]);
2050                                                 /* transpose ! */
2051                                                 vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
2052                                                 vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
2053                                                 vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
2054                                                 Normalize(vlr->n);
2055                                                 
2056                                                 vlr->mat= ma;
2057                                                 vlr->flag= 0;
2058                                                 vlr->ec= ME_V1V2;
2059                                                 vlr->lay= ob->lay;
2060                                         }
2061                                 }
2062                                 if(edgetable)
2063                                         MEM_freeN(edgetable);
2064                         }
2065                 }
2066         }
2067         
2068         if(!only_verts) {
2069                 if (test_for_displace(re, ob ) ) {
2070                         calc_vertexnormals(re, totverto, totvlako, 0);
2071                         do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
2072                 }
2073
2074                 if(do_autosmooth) {
2075                         autosmooth(re, mat, totverto, totvlako, me->smoothresh);
2076                 }
2077
2078                 if(useFluidmeshNormals) {
2079                         // do not recalculate, only init render data
2080                         calc_fluidsimnormals(re, totverto, totvlako, need_tangent);
2081                 } else {
2082                         calc_vertexnormals(re, totverto, totvlako, need_tangent);
2083                 }
2084
2085                 if(need_stress)
2086                         calc_edge_stress(re, me, totverto, totvlako);
2087         }
2088
2089         dm->release(dm);
2090 }
2091
2092 /* ------------------------------------------------------------------------- */
2093
2094 static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
2095 {
2096         struct ShadBuf *shb;
2097         float viewinv[4][4];
2098         
2099         /* if(la->spsi<16) return; */
2100         
2101         /* memory alloc */
2102         shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
2103         lar->shb= shb;
2104         
2105         if(shb==NULL) return;
2106         
2107         VECCOPY(shb->co, lar->co);
2108         
2109         /* percentage render: keep track of min and max */
2110         shb->size= (lar->bufsize*re->r.size)/100;
2111         
2112         if(lar->buffers>1) shb->size/= 2;
2113         
2114         if(shb->size<512) shb->size= 512;
2115         else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
2116         
2117         shb->size &= ~15;       /* make sure its multiples of 16 */
2118         
2119         shb->samp= lar->samp;
2120         shb->soft= lar->soft;
2121         shb->shadhalostep= lar->shadhalostep;
2122         
2123         MTC_Mat4Ortho(mat);
2124         MTC_Mat4Invert(shb->winmat, mat);       /* winmat is temp */
2125         
2126         /* matrix: combination of inverse view and lampmat */
2127         /* calculate again: the ortho-render has no correct viewinv */
2128         MTC_Mat4Invert(viewinv, re->viewmat);
2129         MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat);
2130         
2131         /* projection */
2132         shb->d= lar->clipsta;
2133         shb->clipend= lar->clipend;
2134         
2135         /* bias is percentage, made 2x larger because of correction for angle of incidence */
2136         /* when a ray is closer to parallel of a face, bias value is increased during render */
2137         shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
2138         shb->bias= shb->bias*(100/re->r.size);
2139         
2140         /* halfway method (average of first and 2nd z) reduces bias issues */
2141         if(lar->buftype==LA_SHADBUF_HALFWAY)
2142                 shb->bias= 0.1f*shb->bias;
2143         
2144 }
2145
2146
2147 static void area_lamp_vectors(LampRen *lar)
2148 {
2149         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
2150
2151         /* corner vectors */
2152         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
2153         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
2154         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
2155
2156         /* corner vectors */
2157         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
2158         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
2159         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
2160
2161         /* corner vectors */
2162         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
2163         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
2164         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
2165
2166         /* corner vectors */
2167         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
2168         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
2169         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
2170         /* only for correction button size, matrix size works on energy */
2171         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
2172 }
2173
2174 /* If lar takes more lamp data, the decoupling will be better. */
2175 static GroupObject *add_render_lamp(Render *re, Object *ob)
2176 {
2177         Lamp *la= ob->data;
2178         LampRen *lar;
2179         GroupObject *go;
2180         float mat[4][4], angle, xn, yn;
2181         int c;
2182
2183         /* previewrender sets this to zero... prevent accidents */
2184         if(la==NULL) return NULL;
2185         
2186         /* prevent only shadow from rendering light */
2187         if(la->mode & LA_ONLYSHADOW)
2188                 if((re->r.mode & R_SHADOW)==0)
2189                         return NULL;
2190         
2191         re->totlamp++;
2192         
2193         /* groups is used to unify support for lightgroups, this is the global lightgroup */
2194         go= MEM_callocN(sizeof(GroupObject), "groupobject");
2195         BLI_addtail(&re->lights, go);
2196         go->ob= ob;
2197         /* lamprens are in own list, for freeing */
2198         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
2199         BLI_addtail(&re->lampren, lar);
2200         go->lampren= lar;
2201
2202         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2203         MTC_Mat4Invert(ob->imat, mat);
2204
2205         MTC_Mat3CpyMat4(lar->mat, mat);
2206         MTC_Mat3CpyMat4(lar->imat, ob->imat);
2207
2208         lar->bufsize = la->bufsize;
2209         lar->samp = la->samp;
2210         lar->buffers= la->buffers;
2211         if(lar->buffers==0) lar->buffers= 1;
2212         lar->buftype= la->buftype;
2213         lar->filtertype= la->filtertype;
2214         lar->soft = la->soft;
2215         lar->shadhalostep = la->shadhalostep;
2216         lar->clipsta = la->clipsta;
2217         lar->clipend = la->clipend;
2218         
2219         lar->bias = la->bias;
2220
2221         lar->type= la->type;
2222         lar->mode= la->mode;
2223
2224         lar->energy= la->energy;
2225         lar->energy= la->energy;
2226         if(la->mode & LA_NEG) lar->energy= -lar->energy;
2227
2228         lar->vec[0]= -mat[2][0];
2229         lar->vec[1]= -mat[2][1];
2230         lar->vec[2]= -mat[2][2];
2231         Normalize(lar->vec);
2232         lar->co[0]= mat[3][0];
2233         lar->co[1]= mat[3][1];
2234         lar->co[2]= mat[3][2];
2235         lar->dist= la->dist;
2236         lar->haint= la->haint;
2237         lar->distkw= lar->dist*lar->dist;
2238         lar->r= lar->energy*la->r;
2239         lar->g= lar->energy*la->g;
2240         lar->b= lar->energy*la->b;
2241         lar->k= la->k;
2242
2243         // area
2244         lar->ray_samp= la->ray_samp;
2245         lar->ray_sampy= la->ray_sampy;
2246         lar->ray_sampz= la->ray_sampz;
2247
2248         lar->area_size= la->area_size;
2249         lar->area_sizey= la->area_sizey;
2250         lar->area_sizez= la->area_sizez;
2251
2252         lar->area_shape= la->area_shape;
2253         lar->ray_samp_type= la->ray_samp_type;
2254
2255         if(lar->type==LA_AREA) {
2256                 switch(lar->area_shape) {
2257                 case LA_AREA_SQUARE:
2258                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
2259                         lar->ray_sampy= lar->ray_samp;
2260                         lar->area_sizey= lar->area_size;
2261                         break;
2262                 case LA_AREA_RECT:
2263                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
2264                         break;
2265                 case LA_AREA_CUBE:
2266                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
2267                         lar->ray_sampy= lar->ray_samp;
2268                         lar->ray_sampz= lar->ray_samp;
2269                         lar->area_sizey= lar->area_size;
2270                         lar->area_sizez= lar->area_size;
2271                         break;
2272                 case LA_AREA_BOX:
2273                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
2274                         break;
2275                 }
2276
2277                 area_lamp_vectors(lar);
2278         }
2279         else lar->ray_totsamp= 0;
2280         
2281 #ifndef DISABLE_YAFRAY
2282         /* yafray: photonlight and other params */
2283         if (re->r.renderer==R_YAFRAY) {
2284                 lar->YF_numphotons = la->YF_numphotons;
2285                 lar->YF_numsearch = la->YF_numsearch;
2286                 lar->YF_phdepth = la->YF_phdepth;
2287                 lar->YF_useqmc = la->YF_useqmc;
2288                 lar->YF_causticblur = la->YF_causticblur;
2289                 lar->YF_ltradius = la->YF_ltradius;
2290                 lar->YF_bufsize = la->YF_bufsize;
2291                 lar->YF_glowint = la->YF_glowint;
2292                 lar->YF_glowofs = la->YF_glowofs;
2293                 lar->YF_glowtype = la->YF_glowtype;
2294         }
2295 #endif /* disable yafray */
2296
2297         lar->spotsi= la->spotsize;
2298         if(lar->mode & LA_HALO) {
2299                 if(lar->spotsi>170.0) lar->spotsi= 170.0;
2300         }
2301         lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
2302         lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
2303
2304         memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
2305
2306         lar->lay= ob->lay & 0xFFFFFF;   // higher 8 bits are localview layers
2307
2308         lar->ld1= la->att1;
2309         lar->ld2= la->att2;
2310
2311         if(lar->type==LA_SPOT) {
2312
2313                 Normalize(lar->imat[0]);
2314                 Normalize(lar->imat[1]);
2315                 Normalize(lar->imat[2]);
2316
2317                 xn= saacos(lar->spotsi);
2318                 xn= sin(xn)/cos(xn);
2319                 lar->spottexfac= 1.0/(xn);
2320
2321                 if(lar->mode & LA_ONLYSHADOW) {
2322                         if((lar->mode & (LA_SHAD_BUF|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
2323                 }
2324
2325         }
2326
2327         /* set flag for spothalo en initvars */
2328         if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
2329                 if(la->haint>0.0) {
2330                         re->flag |= R_LAMPHALO;
2331
2332                         /* camera position (0,0,0) rotate around lamp */
2333                         lar->sh_invcampos[0]= -lar->co[0];
2334                         lar->sh_invcampos[1]= -lar->co[1];
2335                         lar->sh_invcampos[2]= -lar->co[2];
2336                         MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
2337
2338                         /* z factor, for a normalized volume */
2339                         angle= saacos(lar->spotsi);
2340                         xn= lar->spotsi;
2341                         yn= sin(angle);
2342                         lar->sh_zfac= yn/xn;
2343                         /* pre-scale */
2344                         lar->sh_invcampos[2]*= lar->sh_zfac;
2345
2346                 }
2347         }
2348         else if(la->type==LA_HEMI) {
2349                 lar->mode &= ~(LA_SHAD_RAY|LA_SHAD_BUF);
2350         }
2351
2352         for(c=0; c<MAX_MTEX; c++) {
2353                 if(la->mtex[c] && la->mtex[c]->tex) {
2354                         lar->mode |= LA_TEXTURE;
2355
2356                         if(G.rendering) {
2357                                 if(re->osa) {
2358                                         if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
2359                                 }
2360                         }
2361                 }
2362         }
2363         /* yafray: shadow flag should not be cleared, only used with internal renderer */
2364         if (re->r.renderer==R_INTERN) {
2365                 /* to make sure we can check ray shadow easily in the render code */
2366                 if(lar->mode & LA_SHAD_RAY) {
2367                         if( (re->r.mode & R_RAYTRACE)==0)
2368                                 lar->mode &= ~LA_SHAD_RAY;
2369                 }
2370         
2371
2372                 if(re->r.mode & R_SHADOW) {
2373                         if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
2374                                 /* Per lamp, one shadow buffer is made. */
2375                                 lar->bufflag= la->bufflag;
2376                                 Mat4CpyMat4(mat, ob->obmat);
2377                                 initshadowbuf(re, lar, mat);    // mat is altered
2378                         }
2379                         else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
2380                                 init_jitter_plane(lar);
2381                         }
2382                         
2383                         /* this is the way used all over to check for shadow */
2384                         if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
2385                                 LampShadowSubSample *lss;
2386                                 int a, b, tot= re->r.threads*re->r.osa;
2387                                 
2388                                 lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
2389                                 lss= lar->shadsamp[0].s;
2390                                 /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
2391                                 for(a=0; a<tot; a++, lss++) {
2392                                         for(b=0; b<4; b++) {
2393                                                 lss->samplenr= -1;      /* used to detect whether we store or read */
2394                                                 lss->shadfac[b]= 1.0f;
2395                                         }
2396                                 }
2397                         }
2398                 }
2399         }
2400         
2401         return go;
2402 }
2403
2404 /* ------------------------------------------------------------------------- */
2405
2406 /* returns amount of vertices added for orco */
2407 static int dl_surf_to_renderdata(Render *re, Object *ob, DispList *dl, Material **matar, float *orco, float mat[4][4])
2408 {
2409         VertRen *v1, *v2, *v3, *v4, *ver;
2410         VlakRen *vlr, *vlr1, *vlr2, *vlr3;
2411         Curve *cu= ob->data;
2412         float *data, n1[3], flen;
2413         int u, v, orcoret= 0;
2414         int p1, p2, p3, p4, a;
2415         int sizeu, nsizeu, sizev, nsizev;
2416         int startvert, startvlak;
2417         
2418         startvert= re->totvert;
2419         nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr; 
2420         
2421         data= dl->verts;
2422         for (u = 0; u < sizeu; u++) {
2423                 v1 = RE_findOrAddVert(re, re->totvert++); /* save this for possible V wrapping */
2424                 VECCOPY(v1->co, data); data += 3;
2425                 if(orco) {
2426                         v1->orco= orco; orco+= 3; orcoret++;
2427                 }       
2428                 MTC_Mat4MulVecfl(mat, v1->co);
2429                 
2430                 for (v = 1; v < sizev; v++) {
2431                         ver= RE_findOrAddVert(re, re->totvert++);
2432                         VECCOPY(ver->co, data); data += 3;
2433                         if(orco) {
2434                                 ver->orco= orco; orco+= 3; orcoret++;
2435                         }       
2436                         MTC_Mat4MulVecfl(mat, ver->co);
2437                 }
2438                 /* if V-cyclic, add extra vertices at end of the row */
2439                 if (dl->flag & DL_CYCL_U) {
2440                         ver= RE_findOrAddVert(re, re->totvert++);
2441                         VECCOPY(ver->co, v1->co);
2442                         if(orco) {
2443                                 ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
2444                         }
2445                 }       
2446         }       
2447         
2448         /* Done before next loop to get corner vert */
2449         if (dl->flag & DL_CYCL_U) nsizev++;
2450         if (dl->flag & DL_CYCL_V) nsizeu++;
2451         
2452         /* if U cyclic, add extra row at end of column */
2453         if (dl->flag & DL_CYCL_V) {
2454                 for (v = 0; v < nsizev; v++) {
2455                         v1= RE_findOrAddVert(re, startvert + v);
2456                         ver= RE_findOrAddVert(re, re->totvert++);
2457                         VECCOPY(ver->co, v1->co);
2458                         if(orco) {
2459                                 ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v);
2460                         }
2461                 }
2462         }
2463         
2464         sizeu = nsizeu;
2465         sizev = nsizev;
2466         
2467         startvlak= re->totvlak;
2468         
2469         for(u = 0; u < sizeu - 1; u++) {
2470                 p1 = startvert + u * sizev; /* walk through face list */
2471                 p2 = p1 + 1;
2472                 p3 = p2 + sizev;
2473                 p4 = p3 - 1;
2474                 
2475                 for(v = 0; v < sizev - 1; v++) {
2476                         v1= RE_findOrAddVert(re, p1);
2477                         v2= RE_findOrAddVert(re, p2);
2478                         v3= RE_findOrAddVert(re, p3);
2479                         v4= RE_findOrAddVert(re, p4);
2480                         
2481                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2482                         vlr->ob= ob;
2483                         vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
2484                         
2485                         flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
2486                         VECCOPY(vlr->n, n1);
2487                         
2488                         vlr->lay= ob->lay;
2489                         vlr->mat= matar[ dl->col];
2490                         vlr->ec= ME_V1V2+ME_V2V3;
2491                         vlr->flag= dl->rt;
2492                         if( (cu->flag & CU_NOPUNOFLIP) ) {
2493                                 vlr->flag |= R_NOPUNOFLIP;
2494                         }
2495                         
2496                         VecAddf(v1->n, v1->n, n1);
2497                         VecAddf(v2->n, v2->n, n1);
2498                         VecAddf(v3->n, v3->n, n1);
2499                         VecAddf(v4->n, v4->n, n1);
2500                         
2501                         p1++; p2++; p3++; p4++;
2502                 }
2503         }       
2504         /* fix normals for U resp. V cyclic faces */
2505         sizeu--; sizev--;  /* dec size for face array */
2506         if (dl->flag & DL_CYCL_V) {
2507                 
2508                 for (v = 0; v < sizev; v++)
2509                 {
2510                         /* optimize! :*/
2511                         vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, v));
2512                         vlr1= RE_findOrAddVlak(re, UVTOINDEX(0, v));
2513                         VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
2514                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2515                         VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
2516                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2517                 }
2518         }
2519         if (dl->flag & DL_CYCL_U) {
2520                 
2521                 for (u = 0; u < sizeu; u++)
2522                 {
2523                         /* optimize! :*/
2524                         vlr= RE_findOrAddVlak(re, UVTOINDEX(u, 0));
2525                         vlr1= RE_findOrAddVlak(re, UVTOINDEX(u, sizev-1));
2526                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2527                         VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
2528                         VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
2529                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2530                 }
2531         }
2532         /* last vertex is an extra case: 
2533                 
2534                 ^       ()----()----()----()
2535                 |       |     |     ||     |
2536                 u       |     |(0,n)||(0,0)|
2537                 |     |     ||     |
2538                 ()====()====[]====()
2539                 |     |     ||     |
2540                 |     |(m,n)||(m,0)|
2541                 |     |     ||     |
2542                 ()----()----()----()
2543                 v ->
2544                 
2545                 vertex [] is no longer shared, therefore distribute
2546                 normals of the surrounding faces to all of the duplicates of []
2547                 */
2548         
2549         if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
2550         {
2551                 vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
2552                 vlr1= RE_findOrAddVlak(re, UVTOINDEX(0,0));  /* (0,0) */
2553                 VecAddf(n1, vlr->n, vlr1->n);
2554                 vlr2= RE_findOrAddVlak(re, UVTOINDEX(0, sizev-1)); /* (0,n) */
2555                 VecAddf(n1, n1, vlr2->n);
2556                 vlr3= RE_findOrAddVlak(re, UVTOINDEX(sizeu-1, 0)); /* (m,0) */
2557                 VecAddf(n1, n1, vlr3->n);
2558                 VECCOPY(vlr->v3->n, n1);
2559                 VECCOPY(vlr1->v1->n, n1);
2560                 VECCOPY(vlr2->v2->n, n1);
2561                 VECCOPY(vlr3->v4->n, n1);
2562         }
2563         for(a = startvert; a < re->totvert; a++) {
2564                 ver= RE_findOrAddVert(re, a);
2565                 Normalize(ver->n);
2566         }
2567         
2568         
2569         return orcoret;
2570 }
2571
2572 static void init_render_surf(Render *re, Object *ob)
2573 {
2574         Nurb *nu=0;
2575         Curve *cu;
2576         ListBase displist;
2577         DispList *dl;
2578         Material *matar[32];
2579         float *orco=NULL, *orcobase=NULL, mat[4][4];
2580         int a, need_orco=0;
2581
2582         cu= ob->data;
2583         nu= cu->nurb.first;
2584         if(nu==0) return;
2585
2586         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2587         MTC_Mat4Invert(ob->imat, mat);
2588
2589         /* material array */
2590         memset(matar, 0, 4*32);
2591         matar[0]= give_render_material(re, ob, 0);
2592         for(a=0; a<ob->totcol; a++) {
2593                 matar[a]= give_render_material(re, ob, a+1);
2594                 if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
2595                         need_orco= 1;
2596                 }
2597         }
2598
2599         if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
2600
2601         if(need_orco) orcobase= orco= get_object_orco(re, ob);
2602
2603         displist.first= displist.last= 0;
2604         makeDispListSurf(ob, &displist, 1);
2605
2606         dl= displist.first;
2607         /* walk along displaylist and create rendervertices/-faces */
2608         while(dl) {
2609                         /* watch out: u ^= y, v ^= x !! */
2610                 if(dl->type==DL_SURF) {
2611                         orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
2612                 }
2613
2614                 dl= dl->next;
2615         }
2616         freedisplist(&displist);
2617 }
2618
2619 static void init_render_curve(Render *re, Object *ob, int only_verts)
2620 {
2621         Curve *cu;
2622         VertRen *ver;
2623         VlakRen *vlr;
2624         DispList *dl;
2625         ListBase olddl={NULL, NULL};
2626         Material *matar[32];
2627         float len, *data, *fp, *orco=NULL, *orcobase= NULL;
2628         float n[3], mat[4][4];
2629         int nr, startvert, startvlak, a, b;
2630         int frontside, need_orco=0;
2631
2632         cu= ob->data;
2633         if(cu->nurb.first==NULL) return;
2634
2635         /* no modifier call here, is in makedisp */
2636
2637         if(cu->resolu_ren) 
2638                 SWAP(ListBase, olddl, cu->disp);
2639         
2640         /* test displist */
2641         if(cu->disp.first==NULL) 
2642                 makeDispListCurveTypes(ob, 0);
2643         dl= cu->disp.first;
2644         if(cu->disp.first==NULL) return;
2645         
2646         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2647         MTC_Mat4Invert(ob->imat, mat);
2648
2649         /* material array */
2650         memset(matar, 0, 4*32);
2651         matar[0]= give_render_material(re, ob, 0);
2652         for(a=0; a<ob->totcol; a++) {
2653                 matar[a]= give_render_material(re, ob, a+1);
2654                 if(matar[a]->texco & TEXCO_ORCO) {
2655                         need_orco= 1;
2656                 }
2657         }
2658
2659         if(need_orco) orcobase=orco= get_object_orco(re, ob);
2660
2661         dl= cu->disp.first;
2662         while(dl) {
2663                 if(dl->type==DL_INDEX3) {
2664                         int *index;
2665
2666                         startvert= re->totvert;
2667                         data= dl->verts;
2668
2669                         n[0]= ob->imat[0][2];
2670                         n[1]= ob->imat[1][2];
2671                         n[2]= ob->imat[2][2];
2672                         Normalize(n);
2673
2674                         for(a=0; a<dl->nr; a++, data+=3) {
2675                                 ver= RE_findOrAddVert(re, re->totvert++);
2676                                 VECCOPY(ver->co, data);
2677
2678                                 /* flip normal if face is backfacing, also used in face loop below */
2679                                 if(ver->co[2] < 0.0) {
2680                                         VECCOPY(ver->n, n);
2681                                         ver->flag = 1;
2682                                 }
2683                                 else {
2684                                         ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
2685                                         ver->flag = 0;
2686                                 }
2687
2688                                 MTC_Mat4MulVecfl(mat, ver->co);
2689                                 
2690                                 if (orco) {
2691                                         ver->orco = orco;
2692                                         orco += 3;
2693                                 }
2694                         }
2695                         
2696                         if(only_verts==0) {
2697                                 startvlak= re->totvlak;
2698                                 index= dl->index;
2699                                 for(a=0; a<dl->parts; a++, index+=3) {
2700
2701                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2702                                         vlr->ob = ob;
2703                                         vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
2704                                         vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
2705                                         vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
2706                                         vlr->v4= NULL;
2707                                         
2708                                         if(vlr->v1->flag) {
2709                                                 VECCOPY(vlr->n, n);
2710                                         }
2711                                         else {
2712                                                 vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
2713                                         }
2714                                         
2715                                         vlr->mat= matar[ dl->col ];
2716                                         vlr->flag= 0;
2717                                         if( (cu->flag & CU_NOPUNOFLIP) ) {
2718                                                 vlr->flag |= R_NOPUNOFLIP;
2719                                         }
2720                                         vlr->ec= 0;
2721                                         vlr->lay= ob->lay;
2722                                 }
2723                         }
2724                 }
2725                 else if (dl->type==DL_SURF) {
2726                         
2727                         /* cyclic U means an extruded full circular curve, we skip bevel splitting then */
2728                         if (dl->flag & DL_CYCL_U) {
2729                                 orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
2730                         }
2731                         else {
2732                                 int p1,p2,p3,p4;
2733
2734                                 fp= dl->verts;
2735                                 startvert= re->totvert;
2736                                 nr= dl->nr*dl->parts;
2737
2738                                 while(nr--) {
2739                                         ver= RE_findOrAddVert(re, re->totvert++);
2740                                                 
2741                                         VECCOPY(ver->co, fp);
2742                                         MTC_Mat4MulVecfl(mat, ver->co);
2743                                         fp+= 3;
2744
2745                                         if (orco) {
2746                                                 ver->orco = orco;
2747                                                 orco += 3;
2748                                         }
2749                                 }
2750
2751                                 if(dl->bevelSplitFlag || only_verts==0) {
2752                                         startvlak= re->totvlak;
2753
2754                                         for(a=0; a<dl->parts; a++) {
2755
2756                                                 frontside= (a >= dl->nr/2);
2757
2758                                                 DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
2759                                                 p1+= startvert;
2760                                                 p2+= startvert;
2761                                                 p3+= startvert;
2762                                                 p4+= startvert;
2763
2764                                                 for(; b<dl->nr; b++) {
2765                                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2766                                                         vlr->ob= ob;
2767                                                         vlr->v1= RE_findOrAddVert(re, p2);
2768                                                         vlr->v2= RE_findOrAddVert(re, p1);
2769                                                         vlr->v3= RE_findOrAddVert(re, p3);
2770                                                         vlr->v4= RE_findOrAddVert(re, p4);
2771                                                         vlr->ec= ME_V2V3+ME_V3V4;
2772                                                         if(a==0) vlr->ec+= ME_V1V2;
2773
2774                                                         vlr->flag= dl->rt;
2775                                                         vlr->lay= ob->lay;
2776
2777                                                         /* this is not really scientific: the vertices
2778                                                                 * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
2779                                                                 * front and backside treated different!!
2780                                                                 */
2781
2782                                                         if(frontside)
2783                                                                 CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
2784                                                         else 
2785                                                                 CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
2786
2787                                                         vlr->mat= matar[ dl->col ];
2788
2789                                                         p4= p3;
2790                                                         p3++;
2791                                                         p2= p1;
2792                                                         p1++;
2793                                                 }
2794                                         }
2795
2796                                         if (dl->bevelSplitFlag) {
2797                                                 for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
2798                                                         if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
2799                                                                 split_v_renderfaces(re, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
2800                                         }
2801
2802                                         /* vertex normals */
2803                                         for(a= startvlak; a<re->totvlak; a++) {
2804                                                 vlr= RE_findOrAddVlak(re, a);
2805
2806                                                 VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
2807                                                 VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
2808                                                 VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
2809                                                 VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
2810                                         }
2811                                         for(a=startvert; a<re->totvert; a++) {
2812                                                 ver= RE_findOrAddVert(re, a);
2813                                                 len= Normalize(ver->n);
2814                                                 if(len==0.0) ver->flag= 1;      /* flag abuse, its only used in zbuf now  */
2815                                                 else ver->flag= 0;
2816                                         }
2817                                         for(a= startvlak; a<re->totvlak; a++) {
2818                                                 vlr= RE_findOrAddVlak(re, a);
2819                                                 if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
2820                                                 if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
2821                                                 if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
2822                                                 if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
2823                                         }
2824                                 }
2825                         }
2826                 }
2827
2828                 dl= dl->next;
2829         }
2830         
2831         /* not very elegant... but we want original displist in UI */
2832         if(cu->resolu_ren) {
2833                 freedisplist(&cu->disp);
2834                 SWAP(ListBase, olddl, cu->disp);
2835         }
2836 }
2837
2838 /* prevent phong interpolation for giving ray shadow errors (terminator problem) */