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