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