= Multires =
[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;
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         dm = mesh_create_derived_render(ob,
1838                             CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
1839         
1840         if(dm==NULL) return;    /* in case duplicated object fails? */
1841
1842         if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
1843                  (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
1844            (ob->fluidsimSettings->meshSurface) ) {
1845                 useFluidmeshNormals = 1;
1846         }
1847
1848         mvert= dm->getVertArray(dm);
1849         totvert= dm->getNumVerts(dm);
1850
1851         /* attempt to autsmooth on original mesh, only without subsurf */
1852         if(do_autosmooth && me->totvert==totvert && me->totface==dm->getNumFaces(dm))
1853                 use_original_normals= 1;
1854         
1855         ms = (totvert==me->totvert)?me->msticky:NULL;
1856         
1857         ma= give_render_material(re, ob, 1);
1858
1859         if(ma->mode & MA_HALO) {
1860                 make_render_halos(re, ob, me, totvert, mvert, ma, orco);
1861         }
1862         else {
1863
1864                 for(a=0; a<totvert; a++, mvert++) {
1865                         ver= RE_findOrAddVert(re, re->totvert++);
1866                         VECCOPY(ver->co, mvert->co);
1867                         if(do_autosmooth==0)    /* autosmooth on original unrotated data to prevent differences between frames */
1868                                 MTC_Mat4MulVecfl(mat, ver->co);
1869
1870                         if(useFluidmeshNormals) {
1871                                 xn = mvert->no[0]/ 32767.0;
1872                                 yn = mvert->no[1]/ 32767.0;
1873                                 zn = mvert->no[2]/ 32767.0;
1874                                 /* transfor to cam  space */
1875                                 ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
1876                                 ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
1877                                 ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
1878                         } // useFluidmeshNormals
1879
1880                         if(orco) {
1881                                 ver->orco= orco;
1882                                 orco+=3;
1883                         }
1884                         if(ms) {
1885                                 float *sticky= RE_vertren_get_sticky(re, ver, 1);
1886                                 sticky[0]= ms->co[0];
1887                                 sticky[1]= ms->co[1];
1888                                 ms++;
1889                         }
1890                 }
1891                 
1892                 if(!only_verts) {
1893                         /* store customdata names, because DerivedMesh is freed */
1894                         RE_vlakren_set_customdata_names(re, &dm->faceData);
1895                         
1896                         /* still to do for keys: the correct local texture coordinate */
1897
1898                         /* faces in order of color blocks */
1899                         vertofs= re->totvert - totvert;
1900                         for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
1901
1902                                 ma= give_render_material(re, ob, a1+1);
1903                                 
1904                                 /* test for 100% transparant */
1905                                 ok= 1;
1906                                 if(ma->alpha==0.0 && ma->spectra==0.0) {
1907                                         ok= 0;
1908                                         /* texture on transparency? */
1909                                         for(a=0; a<MAX_MTEX; a++) {
1910                                                 if(ma->mtex[a] && ma->mtex[a]->tex) {
1911                                                         if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1;
1912                                                 }
1913                                         }
1914                                 }
1915                                 
1916                                 /* if wire material, and we got edges, don't do the faces */
1917                                 if(ma->mode & MA_WIRE) {
1918                                         end= dm->getNumEdges(dm);
1919                                         if(end) ok= 0;
1920                                 }
1921
1922                                 if(ok) {
1923                                         end= dm->getNumFaces(dm);
1924                                         mface= dm->getFaceArray(dm);
1925
1926                                         for(a=0; a<end; a++, mface++) {
1927                                                 int v1, v2, v3, v4, flag;
1928                                                 
1929                                                 if( mface->mat_nr==a1 ) {
1930                                                         float len;
1931                                                                 
1932                                                         v1= mface->v1;
1933                                                         v2= mface->v2;
1934                                                         v3= mface->v3;
1935                                                         v4= mface->v4;
1936                                                         flag= mface->flag & ME_SMOOTH;
1937                                                         
1938                                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
1939                                                         vlr->ob= ob;
1940                                                         vlr->v1= RE_findOrAddVert(re, vertofs+v1);
1941                                                         vlr->v2= RE_findOrAddVert(re, vertofs+v2);
1942                                                         vlr->v3= RE_findOrAddVert(re, vertofs+v3);
1943                                                         if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
1944                                                         else vlr->v4= 0;
1945
1946                                                         /* render normals are inverted in render */
1947                                                         if(use_original_normals) {
1948                                                                 MFace *mf= me->mface+a;
1949                                                                 MVert *mv= me->mvert;
1950                                                                 
1951                                                                 if(vlr->v4) 
1952                                                                         len= CalcNormFloat4( mv[mf->v4].co, mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co, vlr->n);
1953                                                                 else 
1954                                                                         len= CalcNormFloat(mv[mf->v3].co, mv[mf->v2].co, mv[mf->v1].co, vlr->n);
1955                                                         }
1956                                                         else {
1957                                                                 if(vlr->v4) 
1958                                                                         len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1959                                                                 else 
1960                                                                         len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
1961                                                         }
1962
1963                                                         vlr->mat= ma;
1964                                                         vlr->flag= flag;
1965                                                         if((me->flag & ME_NOPUNOFLIP) ) {
1966                                                                 vlr->flag |= R_NOPUNOFLIP;
1967                                                         }
1968                                                         vlr->ec= 0; /* mesh edges rendered separately */
1969                                                         vlr->lay= ob->lay;
1970
1971                                                         if(len==0) re->totvlak--;
1972                                                         else {
1973                                                                 CustomDataLayer *layer;
1974                                                                 MTFace *mtface, *mtf;
1975                                                                 MCol *mcol, *mc;
1976                                                                 int index, mtfn= 0, mcn= 0, n;
1977                                                                 char *name;
1978
1979                                                                 for(index=0; index<dm->faceData.totlayer; index++) {
1980                                                                         layer= &dm->faceData.layers[index];
1981                                                                         name= layer->name;
1982                                                                         
1983                                                                         if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
1984                                                                                 n= vlakren_customdata_layer_num(mtfn++, layer->active);
1985                                                                                 mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1);
1986                                                                                 mtface= (MTFace*)layer->data;
1987                                                                                 *mtf= mtface[a];
1988                                                                         }
1989                                                                         else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
1990                                                                                 n= vlakren_customdata_layer_num(mcn++, layer->active);
1991                                                                                 mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1);
1992                                                                                 mcol= (MCol*)layer->data;
1993                                                                                 memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
1994                                                                         }
1995                                                                 }
1996                                                         }
1997                                                 }
1998                                         }
1999                                 }
2000                         }
2001                         
2002                         /* exception... we do edges for wire mode. potential conflict when faces exist... */
2003                         end= dm->getNumEdges(dm);
2004                         mvert= dm->getVertArray(dm);
2005                         ma= give_render_material(re, ob, 1);
2006                         if(end && (ma->mode & MA_WIRE)) {
2007                                 MEdge *medge;
2008                                 struct edgesort *edgetable;
2009                                 int totedge= 0;
2010                                 
2011                                 medge= dm->getEdgeArray(dm);
2012                                 
2013                                 /* we want edges to have UV and vcol too... */
2014                                 edgetable= make_mesh_edge_lookup(dm, &totedge);
2015                                 
2016                                 for(a1=0; a1<end; a1++, medge++) {
2017                                         if (medge->flag&ME_EDGERENDER) {
2018                                                 MVert *v0 = &mvert[medge->v1];
2019                                                 MVert *v1 = &mvert[medge->v2];
2020
2021                                                 vlr= RE_findOrAddVlak(re, re->totvlak++);
2022                                                 vlr->ob= ob;
2023                                                 vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
2024                                                 vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
2025                                                 vlr->v3= vlr->v2;
2026                                                 vlr->v4= NULL;
2027                                                 
2028                                                 if(edgetable) {
2029                                                         use_mesh_edge_lookup(re, dm, medge, vlr, edgetable, totedge);
2030                                                 }
2031                                                 
2032                                                 xn= -(v0->no[0]+v1->no[0]);
2033                                                 yn= -(v0->no[1]+v1->no[1]);
2034                                                 zn= -(v0->no[2]+v1->no[2]);
2035                                                 /* transpose ! */
2036                                                 vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
2037                                                 vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
2038                                                 vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
2039                                                 Normalise(vlr->n);
2040                                                 
2041                                                 vlr->mat= ma;
2042                                                 vlr->flag= 0;
2043                                                 vlr->ec= ME_V1V2;
2044                                                 vlr->lay= ob->lay;
2045                                         }
2046                                 }
2047                                 if(edgetable)
2048                                         MEM_freeN(edgetable);
2049                         }
2050                 }
2051         }
2052         
2053         if(!only_verts) {
2054                 if (test_for_displace(re, ob ) ) {
2055                         calc_vertexnormals(re, totverto, totvlako, 0);
2056                         do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
2057                 }
2058
2059                 if(do_autosmooth) {
2060                         autosmooth(re, mat, totverto, totvlako, me->smoothresh);
2061                 }
2062
2063                 if(useFluidmeshNormals) {
2064                         // do not recalculate, only init render data
2065                         calc_fluidsimnormals(re, totverto, totvlako, need_tangent);
2066                 } else {
2067                         calc_vertexnormals(re, totverto, totvlako, need_tangent);
2068                 }
2069
2070                 if(need_stress)
2071                         calc_edge_stress(re, me, totverto, totvlako);
2072         }
2073
2074         dm->release(dm);
2075 }
2076
2077 /* ------------------------------------------------------------------------- */
2078
2079 static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
2080 {
2081         struct ShadBuf *shb;
2082         float viewinv[4][4];
2083         
2084         /* if(la->spsi<16) return; */
2085         
2086         /* memory alloc */
2087         shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf");
2088         lar->shb= shb;
2089         
2090         if(shb==NULL) return;
2091         
2092         VECCOPY(shb->co, lar->co);
2093         
2094         /* percentage render: keep track of min and max */
2095         shb->size= (lar->bufsize*re->r.size)/100;
2096         
2097         if(lar->buffers>1) shb->size/= 2;
2098         
2099         if(shb->size<512) shb->size= 512;
2100         else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
2101         
2102         shb->size &= ~15;       /* make sure its multiples of 16 */
2103         
2104         shb->samp= lar->samp;
2105         shb->soft= lar->soft;
2106         shb->shadhalostep= lar->shadhalostep;
2107         
2108         MTC_Mat4Ortho(mat);
2109         MTC_Mat4Invert(shb->winmat, mat);       /* winmat is temp */
2110         
2111         /* matrix: combination of inverse view and lampmat */
2112         /* calculate again: the ortho-render has no correct viewinv */
2113         MTC_Mat4Invert(viewinv, re->viewmat);
2114         MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat);
2115         
2116         /* projection */
2117         shb->d= lar->clipsta;
2118         shb->clipend= lar->clipend;
2119         
2120         /* bias is percentage, made 2x larger because of correction for angle of incidence */
2121         /* when a ray is closer to parallel of a face, bias value is increased during render */
2122         shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
2123         shb->bias= shb->bias*(100/re->r.size);
2124         
2125         /* halfway method (average of first and 2nd z) reduces bias issues */
2126         if(lar->buftype==LA_SHADBUF_HALFWAY)
2127                 shb->bias= 0.1f*shb->bias;
2128         
2129 }
2130
2131
2132 static void area_lamp_vectors(LampRen *lar)
2133 {
2134         float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
2135
2136         /* corner vectors */
2137         lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
2138         lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
2139         lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
2140
2141         /* corner vectors */
2142         lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
2143         lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
2144         lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
2145
2146         /* corner vectors */
2147         lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
2148         lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
2149         lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];      
2150
2151         /* corner vectors */
2152         lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
2153         lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
2154         lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];      
2155         /* only for correction button size, matrix size works on energy */
2156         lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
2157 }
2158
2159 /* If lar takes more lamp data, the decoupling will be better. */
2160 static GroupObject *add_render_lamp(Render *re, Object *ob)
2161 {
2162         Lamp *la= ob->data;
2163         LampRen *lar;
2164         GroupObject *go;
2165         float mat[4][4], angle, xn, yn;
2166         int c;
2167
2168         /* previewrender sets this to zero... prevent accidents */
2169         if(la==NULL) return NULL;
2170         
2171         /* prevent only shadow from rendering light */
2172         if(la->mode & LA_ONLYSHADOW)
2173                 if((re->r.mode & R_SHADOW)==0)
2174                         return NULL;
2175         
2176         re->totlamp++;
2177         
2178         /* groups is used to unify support for lightgroups, this is the global lightgroup */
2179         go= MEM_callocN(sizeof(GroupObject), "groupobject");
2180         BLI_addtail(&re->lights, go);
2181         go->ob= ob;
2182         /* lamprens are in own list, for freeing */
2183         lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren");
2184         BLI_addtail(&re->lampren, lar);
2185         go->lampren= lar;
2186
2187         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2188         MTC_Mat4Invert(ob->imat, mat);
2189
2190         MTC_Mat3CpyMat4(lar->mat, mat);
2191         MTC_Mat3CpyMat4(lar->imat, ob->imat);
2192
2193         lar->bufsize = la->bufsize;
2194         lar->samp = la->samp;
2195         lar->buffers= la->buffers;
2196         if(lar->buffers==0) lar->buffers= 1;
2197         lar->buftype= la->buftype;
2198         lar->filtertype= la->filtertype;
2199         lar->soft = la->soft;
2200         lar->shadhalostep = la->shadhalostep;
2201         lar->clipsta = la->clipsta;
2202         lar->clipend = la->clipend;
2203         
2204         lar->bias = la->bias;
2205
2206         lar->type= la->type;
2207         lar->mode= la->mode;
2208
2209         lar->energy= la->energy;
2210         lar->energy= la->energy;
2211         if(la->mode & LA_NEG) lar->energy= -lar->energy;
2212
2213         lar->vec[0]= -mat[2][0];
2214         lar->vec[1]= -mat[2][1];
2215         lar->vec[2]= -mat[2][2];
2216         Normalise(lar->vec);
2217         lar->co[0]= mat[3][0];
2218         lar->co[1]= mat[3][1];
2219         lar->co[2]= mat[3][2];
2220         lar->dist= la->dist;
2221         lar->haint= la->haint;
2222         lar->distkw= lar->dist*lar->dist;
2223         lar->r= lar->energy*la->r;
2224         lar->g= lar->energy*la->g;
2225         lar->b= lar->energy*la->b;
2226         lar->k= la->k;
2227
2228         // area
2229         lar->ray_samp= la->ray_samp;
2230         lar->ray_sampy= la->ray_sampy;
2231         lar->ray_sampz= la->ray_sampz;
2232
2233         lar->area_size= la->area_size;
2234         lar->area_sizey= la->area_sizey;
2235         lar->area_sizez= la->area_sizez;
2236
2237         lar->area_shape= la->area_shape;
2238         lar->ray_samp_type= la->ray_samp_type;
2239
2240         if(lar->type==LA_AREA) {
2241                 switch(lar->area_shape) {
2242                 case LA_AREA_SQUARE:
2243                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
2244                         lar->ray_sampy= lar->ray_samp;
2245                         lar->area_sizey= lar->area_size;
2246                         break;
2247                 case LA_AREA_RECT:
2248                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy;
2249                         break;
2250                 case LA_AREA_CUBE:
2251                         lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp;
2252                         lar->ray_sampy= lar->ray_samp;
2253                         lar->ray_sampz= lar->ray_samp;
2254                         lar->area_sizey= lar->area_size;
2255                         lar->area_sizez= lar->area_size;
2256                         break;
2257                 case LA_AREA_BOX:
2258                         lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz;
2259                         break;
2260                 }
2261
2262                 area_lamp_vectors(lar);
2263         }
2264         else lar->ray_totsamp= 0;
2265         
2266 #ifndef DISABLE_YAFRAY
2267         /* yafray: photonlight and other params */
2268         if (re->r.renderer==R_YAFRAY) {
2269                 lar->YF_numphotons = la->YF_numphotons;
2270                 lar->YF_numsearch = la->YF_numsearch;
2271                 lar->YF_phdepth = la->YF_phdepth;
2272                 lar->YF_useqmc = la->YF_useqmc;
2273                 lar->YF_causticblur = la->YF_causticblur;
2274                 lar->YF_ltradius = la->YF_ltradius;
2275                 lar->YF_bufsize = la->YF_bufsize;
2276                 lar->YF_glowint = la->YF_glowint;
2277                 lar->YF_glowofs = la->YF_glowofs;
2278                 lar->YF_glowtype = la->YF_glowtype;
2279         }
2280 #endif /* disable yafray */
2281
2282         lar->spotsi= la->spotsize;
2283         if(lar->mode & LA_HALO) {
2284                 if(lar->spotsi>170.0) lar->spotsi= 170.0;
2285         }
2286         lar->spotsi= cos( M_PI*lar->spotsi/360.0 );
2287         lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
2288
2289         memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *));
2290
2291         lar->lay= ob->lay & 0xFFFFFF;   // higher 8 bits are localview layers
2292
2293         lar->ld1= la->att1;
2294         lar->ld2= la->att2;
2295
2296         if(lar->type==LA_SPOT) {
2297
2298                 Normalise(lar->imat[0]);
2299                 Normalise(lar->imat[1]);
2300                 Normalise(lar->imat[2]);
2301
2302                 xn= saacos(lar->spotsi);
2303                 xn= sin(xn)/cos(xn);
2304                 lar->spottexfac= 1.0/(xn);
2305
2306                 if(lar->mode & LA_ONLYSHADOW) {
2307                         if((lar->mode & (LA_SHAD_BUF|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW;
2308                 }
2309
2310         }
2311
2312         /* set flag for spothalo en initvars */
2313         if(la->type==LA_SPOT && (la->mode & LA_HALO)) {
2314                 if(la->haint>0.0) {
2315                         re->flag |= R_LAMPHALO;
2316
2317                         /* camera position (0,0,0) rotate around lamp */
2318                         lar->sh_invcampos[0]= -lar->co[0];
2319                         lar->sh_invcampos[1]= -lar->co[1];
2320                         lar->sh_invcampos[2]= -lar->co[2];
2321                         MTC_Mat3MulVecfl(lar->imat, lar->sh_invcampos);
2322
2323                         /* z factor, for a normalized volume */
2324                         angle= saacos(lar->spotsi);
2325                         xn= lar->spotsi;
2326                         yn= sin(angle);
2327                         lar->sh_zfac= yn/xn;
2328                         /* pre-scale */
2329                         lar->sh_invcampos[2]*= lar->sh_zfac;
2330
2331                 }
2332         }
2333         else if(la->type==LA_HEMI) {
2334                 lar->mode &= ~(LA_SHAD_RAY|LA_SHAD_BUF);
2335         }
2336
2337         for(c=0; c<MAX_MTEX; c++) {
2338                 if(la->mtex[c] && la->mtex[c]->tex) {
2339                         lar->mode |= LA_TEXTURE;
2340
2341                         if(G.rendering) {
2342                                 if(re->osa) {
2343                                         if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX;
2344                                 }
2345                         }
2346                 }
2347         }
2348         /* yafray: shadow flag should not be cleared, only used with internal renderer */
2349         if (re->r.renderer==R_INTERN) {
2350                 /* to make sure we can check ray shadow easily in the render code */
2351                 if(lar->mode & LA_SHAD_RAY) {
2352                         if( (re->r.mode & R_RAYTRACE)==0)
2353                                 lar->mode &= ~LA_SHAD_RAY;
2354                 }
2355         
2356
2357                 if(re->r.mode & R_SHADOW) {
2358                         if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
2359                                 /* Per lamp, one shadow buffer is made. */
2360                                 lar->bufflag= la->bufflag;
2361                                 Mat4CpyMat4(mat, ob->obmat);
2362                                 initshadowbuf(re, lar, mat);    // mat is altered
2363                         }
2364                         else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
2365                                 init_jitter_plane(lar);
2366                         }
2367                         
2368                         /* this is the way used all over to check for shadow */
2369                         if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
2370                                 LampShadowSubSample *lss;
2371                                 int a, b, tot= re->r.threads*re->r.osa;
2372                                 
2373                                 lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
2374                                 lss= lar->shadsamp[0].s;
2375                                 /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
2376                                 for(a=0; a<tot; a++, lss++) {
2377                                         for(b=0; b<4; b++) {
2378                                                 lss->samplenr= -1;      /* used to detect whether we store or read */
2379                                                 lss->shadfac[b]= 1.0f;
2380                                         }
2381                                 }
2382                         }
2383                 }
2384         }
2385         
2386         return go;
2387 }
2388
2389 /* ------------------------------------------------------------------------- */
2390
2391 /* returns amount of vertices added for orco */
2392 static int dl_surf_to_renderdata(Render *re, Object *ob, DispList *dl, Material **matar, float *orco, float mat[4][4])
2393 {
2394         VertRen *v1, *v2, *v3, *v4, *ver;
2395         VlakRen *vlr, *vlr1, *vlr2, *vlr3;
2396         Curve *cu= ob->data;
2397         float *data, n1[3], flen;
2398         int u, v, orcoret= 0;
2399         int p1, p2, p3, p4, a;
2400         int sizeu, nsizeu, sizev, nsizev;
2401         int startvert, startvlak;
2402         
2403         startvert= re->totvert;
2404         nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr; 
2405         
2406         data= dl->verts;
2407         for (u = 0; u < sizeu; u++) {
2408                 v1 = RE_findOrAddVert(re, re->totvert++); /* save this for possible V wrapping */
2409                 VECCOPY(v1->co, data); data += 3;
2410                 if(orco) {
2411                         v1->orco= orco; orco+= 3; orcoret++;
2412                 }       
2413                 MTC_Mat4MulVecfl(mat, v1->co);
2414                 
2415                 for (v = 1; v < sizev; v++) {
2416                         ver= RE_findOrAddVert(re, re->totvert++);
2417                         VECCOPY(ver->co, data); data += 3;
2418                         if(orco) {
2419                                 ver->orco= orco; orco+= 3; orcoret++;
2420                         }       
2421                         MTC_Mat4MulVecfl(mat, ver->co);
2422                 }
2423                 /* if V-cyclic, add extra vertices at end of the row */
2424                 if (dl->flag & DL_CYCL_U) {
2425                         ver= RE_findOrAddVert(re, re->totvert++);
2426                         VECCOPY(ver->co, v1->co);
2427                         if(orco) {
2428                                 ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
2429                         }
2430                 }       
2431         }       
2432         
2433         /* Done before next loop to get corner vert */
2434         if (dl->flag & DL_CYCL_U) nsizev++;
2435         if (dl->flag & DL_CYCL_V) nsizeu++;
2436         
2437         /* if U cyclic, add extra row at end of column */
2438         if (dl->flag & DL_CYCL_V) {
2439                 for (v = 0; v < nsizev; v++) {
2440                         v1= RE_findOrAddVert(re, startvert + v);
2441                         ver= RE_findOrAddVert(re, re->totvert++);
2442                         VECCOPY(ver->co, v1->co);
2443                         if(orco) {
2444                                 ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v);
2445                         }
2446                 }
2447         }
2448         
2449         sizeu = nsizeu;
2450         sizev = nsizev;
2451         
2452         startvlak= re->totvlak;
2453         
2454         for(u = 0; u < sizeu - 1; u++) {
2455                 p1 = startvert + u * sizev; /* walk through face list */
2456                 p2 = p1 + 1;
2457                 p3 = p2 + sizev;
2458                 p4 = p3 - 1;
2459                 
2460                 for(v = 0; v < sizev - 1; v++) {
2461                         v1= RE_findOrAddVert(re, p1);
2462                         v2= RE_findOrAddVert(re, p2);
2463                         v3= RE_findOrAddVert(re, p3);
2464                         v4= RE_findOrAddVert(re, p4);
2465                         
2466                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2467                         vlr->ob= ob;
2468                         vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
2469                         
2470                         flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
2471                         VECCOPY(vlr->n, n1);
2472                         
2473                         vlr->lay= ob->lay;
2474                         vlr->mat= matar[ dl->col];
2475                         vlr->ec= ME_V1V2+ME_V2V3;
2476                         vlr->flag= dl->rt;
2477                         if( (cu->flag & CU_NOPUNOFLIP) ) {
2478                                 vlr->flag |= R_NOPUNOFLIP;
2479                         }
2480                         
2481                         VecAddf(v1->n, v1->n, n1);
2482                         VecAddf(v2->n, v2->n, n1);
2483                         VecAddf(v3->n, v3->n, n1);
2484                         VecAddf(v4->n, v4->n, n1);
2485                         
2486                         p1++; p2++; p3++; p4++;
2487                 }
2488         }       
2489         /* fix normals for U resp. V cyclic faces */
2490         sizeu--; sizev--;  /* dec size for face array */
2491         if (dl->flag & DL_CYCL_V) {
2492                 
2493                 for (v = 0; v < sizev; v++)
2494                 {
2495                         /* optimize! :*/
2496                         vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, v));
2497                         vlr1= RE_findOrAddVlak(re, UVTOINDEX(0, v));
2498                         VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
2499                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2500                         VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
2501                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2502                 }
2503         }
2504         if (dl->flag & DL_CYCL_U) {
2505                 
2506                 for (u = 0; u < sizeu; u++)
2507                 {
2508                         /* optimize! :*/
2509                         vlr= RE_findOrAddVlak(re, UVTOINDEX(u, 0));
2510                         vlr1= RE_findOrAddVlak(re, UVTOINDEX(u, sizev-1));
2511                         VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
2512                         VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
2513                         VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
2514                         VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
2515                 }
2516         }
2517         /* last vertex is an extra case: 
2518                 
2519                 ^       ()----()----()----()
2520                 |       |     |     ||     |
2521                 u       |     |(0,n)||(0,0)|
2522                 |     |     ||     |
2523                 ()====()====[]====()
2524                 |     |     ||     |
2525                 |     |(m,n)||(m,0)|
2526                 |     |     ||     |
2527                 ()----()----()----()
2528                 v ->
2529                 
2530                 vertex [] is no longer shared, therefore distribute
2531                 normals of the surrounding faces to all of the duplicates of []
2532                 */
2533         
2534         if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
2535         {
2536                 vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
2537                 vlr1= RE_findOrAddVlak(re, UVTOINDEX(0,0));  /* (0,0) */
2538                 VecAddf(n1, vlr->n, vlr1->n);
2539                 vlr2= RE_findOrAddVlak(re, UVTOINDEX(0, sizev-1)); /* (0,n) */
2540                 VecAddf(n1, n1, vlr2->n);
2541                 vlr3= RE_findOrAddVlak(re, UVTOINDEX(sizeu-1, 0)); /* (m,0) */
2542                 VecAddf(n1, n1, vlr3->n);
2543                 VECCOPY(vlr->v3->n, n1);
2544                 VECCOPY(vlr1->v1->n, n1);
2545                 VECCOPY(vlr2->v2->n, n1);
2546                 VECCOPY(vlr3->v4->n, n1);
2547         }
2548         for(a = startvert; a < re->totvert; a++) {
2549                 ver= RE_findOrAddVert(re, a);
2550                 Normalise(ver->n);
2551         }
2552         
2553         
2554         return orcoret;
2555 }
2556
2557 static void init_render_surf(Render *re, Object *ob)
2558 {
2559         Nurb *nu=0;
2560         Curve *cu;
2561         ListBase displist;
2562         DispList *dl;
2563         Material *matar[32];
2564         float *orco=NULL, *orcobase=NULL, mat[4][4];
2565         int a, need_orco=0;
2566
2567         cu= ob->data;
2568         nu= cu->nurb.first;
2569         if(nu==0) return;
2570
2571         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2572         MTC_Mat4Invert(ob->imat, mat);
2573
2574         /* material array */
2575         memset(matar, 0, 4*32);
2576         matar[0]= give_render_material(re, ob, 0);
2577         for(a=0; a<ob->totcol; a++) {
2578                 matar[a]= give_render_material(re, ob, a+1);
2579                 if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
2580                         need_orco= 1;
2581                 }
2582         }
2583
2584         if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
2585
2586         if(need_orco) orcobase= orco= get_object_orco(re, ob);
2587
2588         displist.first= displist.last= 0;
2589         makeDispListSurf(ob, &displist, 1);
2590
2591         dl= displist.first;
2592         /* walk along displaylist and create rendervertices/-faces */
2593         while(dl) {
2594                         /* watch out: u ^= y, v ^= x !! */
2595                 if(dl->type==DL_SURF) {
2596                         orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
2597                 }
2598
2599                 dl= dl->next;
2600         }
2601         freedisplist(&displist);
2602 }
2603
2604 static void init_render_curve(Render *re, Object *ob, int only_verts)
2605 {
2606         Curve *cu;
2607         VertRen *ver;
2608         VlakRen *vlr;
2609         DispList *dl;
2610         ListBase olddl={NULL, NULL};
2611         Material *matar[32];
2612         float len, *data, *fp, *orco=NULL, *orcobase= NULL;
2613         float n[3], mat[4][4];
2614         int nr, startvert, startvlak, a, b;
2615         int frontside, need_orco=0;
2616
2617         cu= ob->data;
2618         if(cu->nurb.first==NULL) return;
2619
2620         /* no modifier call here, is in makedisp */
2621
2622         if(cu->resolu_ren) 
2623                 SWAP(ListBase, olddl, cu->disp);
2624         
2625         /* test displist */
2626         if(cu->disp.first==NULL) 
2627                 makeDispListCurveTypes(ob, 0);
2628         dl= cu->disp.first;
2629         if(cu->disp.first==NULL) return;
2630         
2631         MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
2632         MTC_Mat4Invert(ob->imat, mat);
2633
2634         /* material array */
2635         memset(matar, 0, 4*32);
2636         matar[0]= give_render_material(re, ob, 0);
2637         for(a=0; a<ob->totcol; a++) {
2638                 matar[a]= give_render_material(re, ob, a+1);
2639                 if(matar[a]->texco & TEXCO_ORCO) {
2640                         need_orco= 1;
2641                 }
2642         }
2643
2644         if(need_orco) orcobase=orco= get_object_orco(re, ob);
2645
2646         dl= cu->disp.first;
2647         while(dl) {
2648                 if(dl->type==DL_INDEX3) {
2649                         int *index;
2650
2651                         startvert= re->totvert;
2652                         data= dl->verts;
2653
2654                         n[0]= ob->imat[0][2];
2655                         n[1]= ob->imat[1][2];
2656                         n[2]= ob->imat[2][2];
2657                         Normalise(n);
2658
2659                         for(a=0; a<dl->nr; a++, data+=3) {
2660                                 ver= RE_findOrAddVert(re, re->totvert++);
2661                                 VECCOPY(ver->co, data);
2662
2663                                 /* flip normal if face is backfacing, also used in face loop below */
2664                                 if(ver->co[2] < 0.0) {
2665                                         VECCOPY(ver->n, n);
2666                                         ver->flag = 1;
2667                                 }
2668                                 else {
2669                                         ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
2670                                         ver->flag = 0;
2671                                 }
2672
2673                                 MTC_Mat4MulVecfl(mat, ver->co);
2674                                 
2675                                 if (orco) {
2676                                         ver->orco = orco;
2677                                         orco += 3;
2678                                 }
2679                         }
2680                         
2681                         if(only_verts==0) {
2682                                 startvlak= re->totvlak;
2683                                 index= dl->index;
2684                                 for(a=0; a<dl->parts; a++, index+=3) {
2685
2686                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2687                                         vlr->ob = ob;
2688                                         vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
2689                                         vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
2690                                         vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
2691                                         vlr->v4= NULL;
2692                                         
2693                                         if(vlr->v1->flag) {
2694                                                 VECCOPY(vlr->n, n);
2695                                         }
2696                                         else {
2697                                                 vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
2698                                         }
2699                                         
2700                                         vlr->mat= matar[ dl->col ];
2701                                         vlr->flag= 0;
2702                                         if( (cu->flag & CU_NOPUNOFLIP) ) {
2703                                                 vlr->flag |= R_NOPUNOFLIP;
2704                                         }
2705                                         vlr->ec= 0;
2706                                         vlr->lay= ob->lay;
2707                                 }
2708                         }
2709                 }
2710                 else if (dl->type==DL_SURF) {
2711                         
2712                         /* cyclic U means an extruded full circular curve, we skip bevel splitting then */
2713                         if (dl->flag & DL_CYCL_U) {
2714                                 orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
2715                         }
2716                         else {
2717                                 int p1,p2,p3,p4;
2718
2719                                 fp= dl->verts;
2720                                 startvert= re->totvert;
2721                                 nr= dl->nr*dl->parts;
2722
2723                                 while(nr--) {
2724                                         ver= RE_findOrAddVert(re, re->totvert++);
2725                                                 
2726                                         VECCOPY(ver->co, fp);
2727                                         MTC_Mat4MulVecfl(mat, ver->co);
2728                                         fp+= 3;
2729
2730                                         if (orco) {
2731                                                 ver->orco = orco;
2732                                                 orco += 3;
2733                                         }
2734                                 }
2735
2736                                 if(dl->bevelSplitFlag || only_verts==0) {
2737                                         startvlak= re->totvlak;
2738
2739                                         for(a=0; a<dl->parts; a++) {
2740
2741                                                 frontside= (a >= dl->nr/2);
2742
2743                                                 DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
2744                                                 p1+= startvert;
2745                                                 p2+= startvert;
2746                                                 p3+= startvert;
2747                                                 p4+= startvert;
2748
2749                                                 for(; b<dl->nr; b++) {
2750                                                         vlr= RE_findOrAddVlak(re, re->totvlak++);
2751                                                         vlr->ob= ob;
2752                                                         vlr->v1= RE_findOrAddVert(re, p2);
2753                                                         vlr->v2= RE_findOrAddVert(re, p1);
2754                                                         vlr->v3= RE_findOrAddVert(re, p3);
2755                                                         vlr->v4= RE_findOrAddVert(re, p4);
2756                                                         vlr->ec= ME_V2V3+ME_V3V4;
2757                                                         if(a==0) vlr->ec+= ME_V1V2;
2758
2759                                                         vlr->flag= dl->rt;
2760                                                         vlr->lay= ob->lay;
2761
2762                                                         /* this is not really scientific: the vertices
2763                                                                 * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
2764                                                                 * front and backside treated different!!
2765                                                                 */
2766
2767                                                         if(frontside)
2768                                                                 CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
2769                                                         else 
2770                                                                 CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
2771
2772                                                         vlr->mat= matar[ dl->col ];
2773
2774                                                         p4= p3;
2775                                                         p3++;
2776                                                         p2= p1;
2777                                                         p1++;
2778                                                 }
2779                                         }
2780
2781                                         if (dl->bevelSplitFlag) {
2782                                                 for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
2783                                                         if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
2784                                                                 split_v_renderfaces(re, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
2785                                         }
2786
2787                                         /* vertex normals */
2788                                         for(a= startvlak; a<re->totvlak; a++) {
2789                                                 vlr= RE_findOrAddVlak(re, a);
2790
2791                                                 VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
2792                                                 VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
2793                                                 VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
2794                                                 VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
2795                                         }
2796                                         for(a=startvert; a<re->totvert; a++) {
2797                                                 ver= RE_findOrAddVert(re, a);
2798                                                 len= Normalise(ver->n);
2799                                                 if(len==0.0) ver->flag= 1;      /* flag abuse, its only used in zbuf now  */
2800                                                 else ver->flag= 0;
2801                                         }
2802                                         for(a= startvlak; a<re->totvlak; a++) {
2803                                                 vlr= RE_findOrAddVlak(re, a);
2804                                                 if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
2805                                                 if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
2806                                                 if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
2807                                                 if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
2808                                         }
2809                                 }
2810                         }
2811                 }
2812
2813                 dl= dl->next;
2814         }
2815         
2816         /* not very elegant... but we want original displist in UI */
2817         if(cu->resolu_ren) {
2818                 freedisplist(&cu->disp);
2819                 SWAP(ListBase, olddl, cu->disp);
2820         }
2821 }
2822
2823 /* prevent phong interpolation for giving ray shadow errors (terminator problem) */
2824 static void set_phong_threshold(Render *re, Object *ob, int startface, int numface, int startvert, int numvert )
2825 {
2826 //      VertRen *ver;
2827         VlakRen *vlr;
2828         float thresh= 0.0, dot;
2829         int tot=0, i;
2830         
2831         /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger 
2832            are taken into account. This threshold is meant to work on smooth geometry, not
2833            for extreme cases (ton) */
2834         
2835         for(i=startface; i<startface+numface; i++) {
2836                 vlr= RE_findOrAddVlak(re, i);
2837                 if(vlr->flag & R_SMOOTH) {
2838                         dot= INPR(vlr->n, vlr->v1->n);
2839                         dot= ABS(dot);
2840                         if(dot>0.9) {
2841                                 thresh+= dot; tot++;
2842                         }
2843                         dot= INPR(vlr->n, vlr->v2->n);
2844 &