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