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