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