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