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