Fix build error on Windows 32 bit.
[blender-staging.git] / source / blender / render / intern / source / renderdatabase.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): 2004-2006, Blender Foundation, full recode
22  *
23  * ***** END GPL/BL DUAL LICENSE BLOCK *****
24  */
25
26 /** \file blender/render/intern/source/renderdatabase.c
27  *  \ingroup render
28  */
29
30
31 /*
32  * Storage, retrieval and query of render specific data.
33  *
34  * All data from a Blender scene is converted by the renderconverter/
35  * into a special format that is used by the render module to make
36  * images out of. These functions interface to the render-specific
37  * database.  
38  *
39  * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data
40  * entries each.
41  *
42  * The index of an entry is >>8 (the highest 24 * bits), to find an
43  * offset in a 256-entry block.
44  *
45  * - If the 256-entry block entry has an entry in the
46  * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in
47  * that block is allocated to this entry.
48  *
49  * - If the entry has no block allocated for it yet, memory is
50  * allocated.
51  *
52  * The pointer to the correct entry is returned. Memory is guaranteed
53  * to exist (as long as the malloc does not break). Since guarded
54  * allocation is used, memory _must_ be available. Otherwise, an
55  * exit(0) would occur.
56  * 
57  */
58
59 #include <limits.h>
60 #include <math.h>
61 #include <string.h>
62
63 #include "MEM_guardedalloc.h"
64
65
66 #include "BLI_math.h"
67 #include "BLI_blenlib.h"
68 #include "BLI_utildefines.h"
69 #include "BLI_hash.h"
70
71 #include "DNA_material_types.h" 
72 #include "DNA_meshdata_types.h" 
73 #include "DNA_texture_types.h"
74 #include "DNA_listBase.h"
75 #include "DNA_particle_types.h"
76
77 #include "BKE_customdata.h"
78 #include "BKE_DerivedMesh.h"
79
80 #include "RE_render_ext.h"      /* externtex */
81
82 #include "rayintersection.h"
83 #include "rayobject.h"
84 #include "render_types.h"
85 #include "renderdatabase.h"
86 #include "zbuf.h"
87
88 /* ------------------------------------------------------------------------- */
89
90 /* More dynamic allocation of options for render vertices and faces, so we don't
91  * have to reserve this space inside vertices.
92  * Important; vertices and faces, should have been created already (to get tables
93  * checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not
94  * the index */
95
96 /* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */
97 #define RE_STRESS_ELEMS         1
98 #define RE_RAD_ELEMS            4
99 #define RE_STRAND_ELEMS         1
100 #define RE_TANGENT_ELEMS        3
101 #define RE_WINSPEED_ELEMS       4
102 #define RE_MTFACE_ELEMS         1
103 #define RE_MCOL_ELEMS           4
104 #define RE_UV_ELEMS                     2
105 #define RE_VLAK_ORIGINDEX_ELEMS 1
106 #define RE_VERT_ORIGINDEX_ELEMS 1
107 #define RE_SURFNOR_ELEMS        3
108 #define RE_RADFACE_ELEMS        1
109 #define RE_SIMPLIFY_ELEMS       2
110 #define RE_FACE_ELEMS           1
111 #define RE_NMAP_TANGENT_ELEMS   16
112
113 float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify)
114 {
115         float *stress;
116         int nr= ver->index>>8;
117         
118         stress= obr->vertnodes[nr].stress;
119         if (stress==NULL) {
120                 if (verify) 
121                         stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
122                 else
123                         return NULL;
124         }
125         return stress + (ver->index & 255)*RE_STRESS_ELEMS;
126 }
127
128 /* this one callocs! */
129 float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify)
130 {
131         float *rad;
132         int nr= ver->index>>8;
133         
134         rad= obr->vertnodes[nr].rad;
135         if (rad==NULL) {
136                 if (verify) 
137                         rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
138                 else
139                         return NULL;
140         }
141         return rad + (ver->index & 255)*RE_RAD_ELEMS;
142 }
143
144 float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify)
145 {
146         float *strand;
147         int nr= ver->index>>8;
148         
149         strand= obr->vertnodes[nr].strand;
150         if (strand==NULL) {
151                 if (verify) 
152                         strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
153                 else
154                         return NULL;
155         }
156         return strand + (ver->index & 255)*RE_STRAND_ELEMS;
157 }
158
159 /* needs calloc */
160 float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify)
161 {
162         float *tangent;
163         int nr= ver->index>>8;
164         
165         tangent= obr->vertnodes[nr].tangent;
166         if (tangent==NULL) {
167                 if (verify) 
168                         tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
169                 else
170                         return NULL;
171         }
172         return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
173 }
174
175 /* needs calloc! not all renderverts have them */
176 /* also winspeed is exception, it is stored per instance */
177 float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
178 {
179         float *winspeed;
180         int totvector;
181         
182         winspeed= obi->vectors;
183         if (winspeed==NULL) {
184                 if (verify) {
185                         totvector= obi->obr->totvert + obi->obr->totstrand;
186                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
187                 }
188                 else
189                         return NULL;
190         }
191         return winspeed + ver->index*RE_WINSPEED_ELEMS;
192 }
193
194 int *RE_vertren_get_origindex(ObjectRen *obr, VertRen *ver, int verify)
195 {
196         int *origindex;
197         int nr= ver->index>>8;
198
199         origindex= obr->vertnodes[nr].origindex;
200         if (origindex==NULL) {
201                 if (verify)
202                         origindex= obr->vertnodes[nr].origindex= MEM_mallocN(256*RE_VERT_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
203                 else
204                         return NULL;
205         }
206         return origindex + (ver->index & 255)*RE_VERT_ORIGINDEX_ELEMS;
207 }
208
209 VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
210 {
211         VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
212         float *fp1, *fp2;
213         int *int1, *int2;
214         int index= v1->index;
215         
216         *v1= *ver;
217         v1->index= index;
218
219         fp1= RE_vertren_get_stress(obr, ver, 0);
220         if (fp1) {
221                 fp2= RE_vertren_get_stress(obr, v1, 1);
222                 memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float));
223         }
224         fp1= RE_vertren_get_rad(obr, ver, 0);
225         if (fp1) {
226                 fp2= RE_vertren_get_rad(obr, v1, 1);
227                 memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float));
228         }
229         fp1= RE_vertren_get_strand(obr, ver, 0);
230         if (fp1) {
231                 fp2= RE_vertren_get_strand(obr, v1, 1);
232                 memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float));
233         }
234         fp1= RE_vertren_get_tangent(obr, ver, 0);
235         if (fp1) {
236                 fp2= RE_vertren_get_tangent(obr, v1, 1);
237                 memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
238         }
239         int1= RE_vertren_get_origindex(obr, ver, 0);
240         if (int1) {
241                 int2= RE_vertren_get_origindex(obr, v1, 1);
242                 memcpy(int2, int1, RE_VERT_ORIGINDEX_ELEMS*sizeof(int));
243         }
244         return v1;
245 }
246
247 VertRen *RE_findOrAddVert(ObjectRen *obr, int nr)
248 {
249         VertTableNode *temp;
250         VertRen *v;
251         int a;
252
253         if (nr<0) {
254                 printf("error in findOrAddVert: %d\n", nr);
255                 return NULL;
256         }
257         a= nr>>8;
258         
259         if (a>=obr->vertnodeslen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
260                 temp= obr->vertnodes;
261                 
262                 obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE), "vertnodes");
263                 if (temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode));
264                 memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
265                 
266                 obr->vertnodeslen+=TABLEINITSIZE; 
267                 if (temp) MEM_freeN(temp);
268         }
269         
270         v= obr->vertnodes[a].vert;
271         if (v==NULL) {
272                 int i;
273                 
274                 v= (VertRen *)MEM_callocN(256*sizeof(VertRen), "findOrAddVert");
275                 obr->vertnodes[a].vert= v;
276                 
277                 for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
278                         v[a].index= i;
279                 }
280         }
281         v+= (nr & 255);
282         return v;
283 }
284
285 /* ------------------------------------------------------------------------ */
286
287 MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
288 {
289         VlakTableNode *node;
290         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
291         int index= (n<<8) + vlakindex;
292
293         node= &obr->vlaknodes[nr];
294
295         if (verify) {
296                 if (n>=node->totmtface) {
297                         MTFace *mtface= node->mtface;
298                         int size= (n+1)*256;
299
300                         node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
301
302                         if (mtface) {
303                                 size= node->totmtface*256;
304                                 memcpy(node->mtface, mtface, size*sizeof(MTFace));
305                                 MEM_freeN(mtface);
306                         }
307
308                         node->totmtface= n+1;
309                 }
310         }
311         else {
312                 if (n>=node->totmtface)
313                         return NULL;
314
315                 if (name) *name= obr->mtface[n];
316         }
317
318         return node->mtface + index;
319 }
320
321 MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
322 {
323         VlakTableNode *node;
324         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
325         int index= (n<<8) + vlakindex;
326
327         node= &obr->vlaknodes[nr];
328
329         if (verify) {
330                 if (n>=node->totmcol) {
331                         MCol *mcol= node->mcol;
332                         int size= (n+1)*256;
333
334                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol");
335
336                         if (mcol) {
337                                 size= node->totmcol*256;
338                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
339                                 MEM_freeN(mcol);
340                         }
341
342                         node->totmcol= n+1;
343                 }
344         }
345         else {
346                 if (n>=node->totmcol)
347                         return NULL;
348
349                 if (name) *name= obr->mcol[n];
350         }
351
352         return node->mcol + index*RE_MCOL_ELEMS;
353 }
354
355 int *RE_vlakren_get_origindex(ObjectRen *obr, VlakRen *vlak, int verify)
356 {
357         int *origindex;
358         int nr= vlak->index>>8;
359
360         origindex= obr->vlaknodes[nr].origindex;
361         if (origindex==NULL) {
362                 if (verify)
363                         origindex= obr->vlaknodes[nr].origindex= MEM_callocN(256*RE_VLAK_ORIGINDEX_ELEMS*sizeof(int), "origindex table");
364                 else
365                         return NULL;
366         }
367         return origindex + (vlak->index & 255)*RE_VLAK_ORIGINDEX_ELEMS;
368 }
369
370 float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
371 {
372         float *surfnor;
373         int nr= vlak->index>>8;
374         
375         surfnor= obr->vlaknodes[nr].surfnor;
376         if (surfnor==NULL) {
377                 if (verify) 
378                         surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
379                 else
380                         return NULL;
381         }
382         return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
383 }
384
385 float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int index, bool verify)
386 {
387         float **tangents;
388         int nr= vlak->index>>8;
389
390         tangents = obr->vlaknodes[nr].tangent_arrays;
391
392         if (index + 1 > 8) {
393                 return NULL;
394         }
395
396         index = index < 0 ? 0: index;
397
398         if (tangents[index] == NULL) {
399                 if (verify) {
400                         tangents[index] = MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
401                 }
402                 else
403                         return NULL;
404         }
405
406         return tangents[index] + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
407 }
408
409 RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
410 {
411         RadFace **radface;
412         int nr= vlak->index>>8;
413         
414         radface= obr->vlaknodes[nr].radface;
415         if (radface==NULL) {
416                 if (verify) 
417                         radface = obr->vlaknodes[nr].radface= MEM_callocN(256 * RE_RADFACE_ELEMS * sizeof(void *), "radface table");
418                 else
419                         return NULL;
420         }
421         return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
422 }
423
424 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
425 {
426         VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
427         MTFace *mtface, *mtface1;
428         MCol *mcol, *mcol1;
429         float *surfnor, *surfnor1;
430         float *tangent, *tangent1;
431         int *origindex, *origindex1;
432         RadFace **radface, **radface1;
433         int i, index = vlr1->index;
434         char *name;
435
436         *vlr1= *vlr;
437         vlr1->index= index;
438
439         for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) {
440                 mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1);
441                 memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS);
442         }
443
444         for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) {
445                 mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1);
446                 memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
447         }
448
449         origindex= RE_vlakren_get_origindex(obr, vlr, 0);
450         if (origindex) {
451                 origindex1= RE_vlakren_get_origindex(obr, vlr1, 1);
452                 /* Just an int, but memcpy for consistency. */
453                 memcpy(origindex1, origindex, sizeof(int)*RE_VLAK_ORIGINDEX_ELEMS);
454         }
455
456         surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
457         if (surfnor) {
458                 surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
459                 copy_v3_v3(surfnor1, surfnor);
460         }
461
462         for (i=0; i < MAX_MTFACE; i++) {
463                 tangent = RE_vlakren_get_nmap_tangent(obr, vlr, i, false);
464                 if (!tangent)
465                         continue;
466                 tangent1 = RE_vlakren_get_nmap_tangent(obr, vlr1, i, true);
467                 memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS);
468         }
469
470         radface= RE_vlakren_get_radface(obr, vlr, 0);
471         if (radface) {
472                 radface1= RE_vlakren_get_radface(obr, vlr1, 1);
473                 *radface1= *radface;
474         }
475
476         return vlr1;
477 }
478
479 void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float r_nor[3])
480 {
481         float (*nmat)[3]= obi->nmat;
482
483         if (obi->flag & R_TRANSFORMED) {
484                 mul_v3_m3v3(r_nor, nmat, vlr->n);
485                 normalize_v3(r_nor);
486         }
487         else {
488                 copy_v3_v3(r_nor, vlr->n);
489         }
490 }
491
492 void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
493 {
494         /* CustomData layer names are stored per object here, because the
495          * DerivedMesh which stores the layers is freed */
496         
497         CustomDataLayer *layer;
498         int numtf = 0, numcol = 0, i, mtfn, mcn;
499
500         if (CustomData_has_layer(data, CD_MTFACE)) {
501                 numtf= CustomData_number_of_layers(data, CD_MTFACE);
502                 obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames");
503         }
504
505         if (CustomData_has_layer(data, CD_MCOL)) {
506                 numcol= CustomData_number_of_layers(data, CD_MCOL);
507                 obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames");
508         }
509
510         for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
511                 layer= &data->layers[i];
512
513                 if (layer->type == CD_MTFACE) {
514                         BLI_strncpy(obr->mtface[mtfn++], layer->name, sizeof(layer->name));
515                         obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf);
516                         obr->bakemtface= layer->active;
517                 }
518                 else if (layer->type == CD_MCOL) {
519                         BLI_strncpy(obr->mcol[mcn++], layer->name, sizeof(layer->name));
520                         obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol);
521                 }
522         }
523 }
524
525 VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr)
526 {
527         VlakTableNode *temp;
528         VlakRen *v;
529         int a;
530
531         if (nr<0) {
532                 printf("error in findOrAddVlak: %d\n", nr);
533                 return obr->vlaknodes[0].vlak;
534         }
535         a= nr>>8;
536         
537         if (a>=obr->vlaknodeslen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
538                 temp= obr->vlaknodes;
539                 
540                 obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE), "vlaknodes");
541                 if (temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode));
542                 memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
543
544                 obr->vlaknodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
545                 if (temp) MEM_freeN(temp);
546         }
547
548         v= obr->vlaknodes[a].vlak;
549         
550         if (v==NULL) {
551                 int i;
552
553                 v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen), "findOrAddVlak");
554                 obr->vlaknodes[a].vlak= v;
555
556                 for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
557                         v[a].index= i;
558         }
559         v+= (nr & 255);
560         return v;
561 }
562
563 /* ------------------------------------------------------------------------ */
564
565 float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
566 {
567         float *surfnor;
568         int nr= strand->index>>8;
569         
570         surfnor= obr->strandnodes[nr].surfnor;
571         if (surfnor==NULL) {
572                 if (verify) 
573                         surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table");
574                 else
575                         return NULL;
576         }
577         return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS;
578 }
579
580 float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
581 {
582         StrandTableNode *node;
583         int nr= strand->index>>8, strandindex= (strand->index&255);
584         int index= (n<<8) + strandindex;
585
586         node= &obr->strandnodes[nr];
587
588         if (verify) {
589                 if (n>=node->totuv) {
590                         float *uv= node->uv;
591                         int size= (n+1)*256;
592
593                         node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table");
594
595                         if (uv) {
596                                 size= node->totuv*256;
597                                 memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS);
598                                 MEM_freeN(uv);
599                         }
600
601                         node->totuv= n+1;
602                 }
603         }
604         else {
605                 if (n>=node->totuv)
606                         return NULL;
607
608                 if (name) *name= obr->mtface[n];
609         }
610
611         return node->uv + index*RE_UV_ELEMS;
612 }
613
614 MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
615 {
616         StrandTableNode *node;
617         int nr= strand->index>>8, strandindex= (strand->index&255);
618         int index= (n<<8) + strandindex;
619
620         node= &obr->strandnodes[nr];
621
622         if (verify) {
623                 if (n>=node->totmcol) {
624                         MCol *mcol= node->mcol;
625                         int size= (n+1)*256;
626
627                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table");
628
629                         if (mcol) {
630                                 size= node->totmcol*256;
631                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
632                                 MEM_freeN(mcol);
633                         }
634
635                         node->totmcol= n+1;
636                 }
637         }
638         else {
639                 if (n>=node->totmcol)
640                         return NULL;
641
642                 if (name) *name= obr->mcol[n];
643         }
644
645         return node->mcol + index*RE_MCOL_ELEMS;
646 }
647
648 float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify)
649 {
650         float *simplify;
651         int nr= strand->index>>8;
652         
653         simplify= obr->strandnodes[nr].simplify;
654         if (simplify==NULL) {
655                 if (verify) 
656                         simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table");
657                 else
658                         return NULL;
659         }
660         return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
661 }
662
663 int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
664 {
665         int *face;
666         int nr= strand->index>>8;
667         
668         face= obr->strandnodes[nr].face;
669         if (face==NULL) {
670                 if (verify) 
671                         face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table");
672                 else
673                         return NULL;
674         }
675         return face + (strand->index & 255)*RE_FACE_ELEMS;
676 }
677
678 /* winspeed is exception, it is stored per instance */
679 float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
680 {
681         float *winspeed;
682         int totvector;
683         
684         winspeed= obi->vectors;
685         if (winspeed==NULL) {
686                 if (verify) {
687                         totvector= obi->obr->totvert + obi->obr->totstrand;
688                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table");
689                 }
690                 else
691                         return NULL;
692         }
693         return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS;
694 }
695
696 StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr)
697 {
698         StrandTableNode *temp;
699         StrandRen *v;
700         int a;
701
702         if (nr<0) {
703                 printf("error in findOrAddStrand: %d\n", nr);
704                 return obr->strandnodes[0].strand;
705         }
706         a= nr>>8;
707         
708         if (a>=obr->strandnodeslen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
709                 temp= obr->strandnodes;
710                 
711                 obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE), "strandnodes");
712                 if (temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode));
713                 memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode));
714
715                 obr->strandnodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
716                 if (temp) MEM_freeN(temp);
717         }
718
719         v= obr->strandnodes[a].strand;
720         
721         if (v==NULL) {
722                 int i;
723
724                 v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen), "findOrAddStrand");
725                 obr->strandnodes[a].strand= v;
726
727                 for (i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
728                         v[a].index= i;
729         }
730         v+= (nr & 255);
731         return v;
732 }
733
734 StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
735 {
736         StrandBuffer *strandbuf;
737
738         strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer");
739         strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert");
740         strandbuf->totvert= totvert;
741         strandbuf->obr= obr;
742
743         obr->strandbuf= strandbuf;
744
745         return strandbuf;
746 }
747
748 /* ------------------------------------------------------------------------ */
749
750 ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
751 {
752         ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
753         
754         BLI_addtail(&re->objecttable, obr);
755         obr->ob= ob;
756         obr->par= par;
757         obr->index= index;
758         obr->psysindex= psysindex;
759         obr->lay= lay;
760
761         return obr;
762 }
763
764 void free_renderdata_vertnodes(VertTableNode *vertnodes)
765 {
766         int a;
767         
768         if (vertnodes==NULL) return;
769         
770         for (a=0; vertnodes[a].vert; a++) {
771                 MEM_freeN(vertnodes[a].vert);
772                 
773                 if (vertnodes[a].rad)
774                         MEM_freeN(vertnodes[a].rad);
775                 if (vertnodes[a].strand)
776                         MEM_freeN(vertnodes[a].strand);
777                 if (vertnodes[a].tangent)
778                         MEM_freeN(vertnodes[a].tangent);
779                 if (vertnodes[a].stress)
780                         MEM_freeN(vertnodes[a].stress);
781                 if (vertnodes[a].winspeed)
782                         MEM_freeN(vertnodes[a].winspeed);
783                 if (vertnodes[a].origindex)
784                         MEM_freeN(vertnodes[a].origindex);
785         }
786         
787         MEM_freeN(vertnodes);
788 }
789
790 void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
791 {
792         int a;
793         
794         if (vlaknodes==NULL) return;
795         
796         for (a=0; vlaknodes[a].vlak; a++) {
797                 MEM_freeN(vlaknodes[a].vlak);
798                 
799                 if (vlaknodes[a].mtface)
800                         MEM_freeN(vlaknodes[a].mtface);
801                 if (vlaknodes[a].mcol)
802                         MEM_freeN(vlaknodes[a].mcol);
803                 if (vlaknodes[a].origindex)
804                         MEM_freeN(vlaknodes[a].origindex);
805                 if (vlaknodes[a].surfnor)
806                         MEM_freeN(vlaknodes[a].surfnor);
807                 for (int b = 0; b < MAX_MTFACE; b++) {
808                         if (vlaknodes[a].tangent_arrays[b])
809                                 MEM_freeN(vlaknodes[a].tangent_arrays[b]);
810                 }
811                 if (vlaknodes[a].radface)
812                         MEM_freeN(vlaknodes[a].radface);
813         }
814         
815         MEM_freeN(vlaknodes);
816 }
817
818 static void free_renderdata_strandnodes(StrandTableNode *strandnodes)
819 {
820         int a;
821         
822         if (strandnodes==NULL) return;
823         
824         for (a=0; strandnodes[a].strand; a++) {
825                 MEM_freeN(strandnodes[a].strand);
826                 
827                 if (strandnodes[a].uv)
828                         MEM_freeN(strandnodes[a].uv);
829                 if (strandnodes[a].mcol)
830                         MEM_freeN(strandnodes[a].mcol);
831                 if (strandnodes[a].winspeed)
832                         MEM_freeN(strandnodes[a].winspeed);
833                 if (strandnodes[a].surfnor)
834                         MEM_freeN(strandnodes[a].surfnor);
835                 if (strandnodes[a].simplify)
836                         MEM_freeN(strandnodes[a].simplify);
837                 if (strandnodes[a].face)
838                         MEM_freeN(strandnodes[a].face);
839         }
840         
841         MEM_freeN(strandnodes);
842 }
843
844 void free_renderdata_tables(Render *re)
845 {
846         ObjectInstanceRen *obi;
847         ObjectRen *obr;
848         StrandBuffer *strandbuf;
849         int a=0;
850         
851         for (obr=re->objecttable.first; obr; obr=obr->next) {
852                 if (obr->vertnodes) {
853                         free_renderdata_vertnodes(obr->vertnodes);
854                         obr->vertnodes= NULL;
855                         obr->vertnodeslen= 0;
856                 }
857
858                 if (obr->vlaknodes) {
859                         free_renderdata_vlaknodes(obr->vlaknodes);
860                         obr->vlaknodes= NULL;
861                         obr->vlaknodeslen= 0;
862                         obr->totvlak= 0;
863                 }
864
865                 if (obr->bloha) {
866                         for (a=0; obr->bloha[a]; a++)
867                                 MEM_freeN(obr->bloha[a]);
868
869                         MEM_freeN(obr->bloha);
870                         obr->bloha= NULL;
871                         obr->blohalen= 0;
872                 }
873
874                 if (obr->strandnodes) {
875                         free_renderdata_strandnodes(obr->strandnodes);
876                         obr->strandnodes= NULL;
877                         obr->strandnodeslen= 0;
878                 }
879
880                 strandbuf= obr->strandbuf;
881                 if (strandbuf) {
882                         if (strandbuf->vert) MEM_freeN(strandbuf->vert);
883                         if (strandbuf->bound) MEM_freeN(strandbuf->bound);
884                         MEM_freeN(strandbuf);
885                 }
886
887                 if (obr->mtface)
888                         MEM_freeN(obr->mtface);
889
890                 if (obr->mcol)
891                         MEM_freeN(obr->mcol);
892                         
893                 if (obr->rayfaces) {
894                         MEM_freeN(obr->rayfaces);
895                         obr->rayfaces = NULL;
896                 }
897
898                 if (obr->rayprimitives) {
899                         MEM_freeN(obr->rayprimitives);
900                         obr->rayprimitives = NULL;
901                 }
902
903                 if (obr->raytree) {
904                         RE_rayobject_free(obr->raytree);
905                         obr->raytree = NULL;
906                 }
907         }
908
909         if (re->objectinstance) {
910                 for (obi=re->instancetable.first; obi; obi=obi->next) {
911                         if (obi->vectors)
912                                 MEM_freeN(obi->vectors);
913
914                         if (obi->raytree)
915                                 RE_rayobject_free(obi->raytree);
916                 }
917
918                 MEM_freeN(re->objectinstance);
919                 re->objectinstance= NULL;
920                 re->totinstance= 0;
921                 re->instancetable.first= re->instancetable.last= NULL;
922         }
923
924         if (re->sortedhalos) {
925                 MEM_freeN(re->sortedhalos);
926                 re->sortedhalos= NULL;
927         }
928
929         BLI_freelistN(&re->customdata_names);
930         BLI_freelistN(&re->objecttable);
931         BLI_freelistN(&re->instancetable);
932 }
933
934 /* ------------------------------------------------------------------------ */
935
936 HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
937 {
938         HaloRen *h, **temp;
939         int a;
940
941         if (nr<0) {
942                 printf("error in findOrAddHalo: %d\n", nr);
943                 return NULL;
944         }
945         a= nr>>8;
946         
947         if (a>=obr->blohalen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
948                 //printf("Allocating %i more halo groups.  %i total.\n", 
949                 //      TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
950                 temp=obr->bloha;
951                 
952                 obr->bloha = (HaloRen **)MEM_callocN(sizeof(void *) * (obr->blohalen + TABLEINITSIZE), "Bloha");
953                 if (temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void *));
954                 memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE * sizeof(void *));
955                 obr->blohalen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
956                 if (temp) MEM_freeN(temp);
957         }
958         
959         h= obr->bloha[a];
960         if (h==NULL) {
961                 h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen), "findOrAdHalo");
962                 obr->bloha[a]= h;
963         }
964         h+= (nr & 255);
965         return h;
966 }
967
968 /* ------------------------------------------------------------------------- */
969
970 HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
971                      const float vec[3], const float vec1[3],
972                      const float *orco, float hasize, float vectsize, int seed)
973 {
974         const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
975         const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
976         HaloRen *har;
977         MTex *mtex;
978         float tin, tr, tg, tb, ta;
979         float xn, yn, zn, texvec[3], hoco[4], hoco1[4];
980
981         if (hasize==0.0f) return NULL;
982
983         projectverto(vec, re->winmat, hoco);
984         if (hoco[3]==0.0f) return NULL;
985         if (vec1) {
986                 projectverto(vec1, re->winmat, hoco1);
987                 if (hoco1[3]==0.0f) return NULL;
988         }
989
990         har= RE_findOrAddHalo(obr, obr->tothalo++);
991         copy_v3_v3(har->co, vec);
992         har->hasize= hasize;
993
994         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
995         /* we do it here for sorting of halos */
996         zn= hoco[3];
997         har->xs= 0.5f*re->winx*(hoco[0]/zn);
998         har->ys= 0.5f*re->winy*(hoco[1]/zn);
999         har->zs= 0x7FFFFF*(hoco[2]/zn);
1000         
1001         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
1002         
1003         /* halovect */
1004         if (vec1) {
1005
1006                 har->type |= HA_VECT;
1007
1008                 xn=  har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
1009                 yn=  har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
1010                 if (yn == 0.0f && xn >= 0.0f) zn = 0.0f;
1011                 else zn = atan2f(yn, xn);
1012
1013                 har->sin = sinf(zn);
1014                 har->cos = cosf(zn);
1015                 zn= len_v3v3(vec1, vec);
1016
1017                 har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
1018                 
1019                 sub_v3_v3v3(har->no, vec, vec1);
1020                 normalize_v3(har->no);
1021         }
1022
1023         if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
1024
1025         har->alfa= ma->alpha;
1026         har->r= ma->r;
1027         har->g= ma->g;
1028         har->b= ma->b;
1029         har->add= (255.0f*ma->add);
1030         har->mat= ma;
1031         har->hard= ma->har;
1032         har->seed= seed % 256;
1033
1034         if (ma->mode & MA_STAR) har->starpoints= ma->starc;
1035         if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
1036         if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
1037         if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
1038
1039
1040         if (ma->mtex[0]) {
1041
1042                 if (ma->mode & MA_HALOTEX) {
1043                         har->tex = 1;
1044                 }
1045                 else if (har->mat->septex & (1 << 0)) {
1046                         /* only 1 level textures */
1047                 }
1048                 else {
1049                         mtex= ma->mtex[0];
1050                         copy_v3_v3(texvec, vec);
1051
1052                         if (mtex->texco & TEXCO_NORM) {
1053                                 ;
1054                         }
1055                         else if (mtex->texco & TEXCO_OBJECT) {
1056                                 /* texvec[0]+= imatbase->ivec[0]; */
1057                                 /* texvec[1]+= imatbase->ivec[1]; */
1058                                 /* texvec[2]+= imatbase->ivec[2]; */
1059                                 /* mul_m3_v3(imatbase->imat, texvec); */
1060                         }
1061                         else {
1062                                 if (orco) {
1063                                         copy_v3_v3(texvec, orco);
1064                                 }
1065                         }
1066
1067                         externtex(mtex,
1068                                   texvec,
1069                                   &tin, &tr, &tg, &tb, &ta,
1070                                   0,
1071                                   re->pool,
1072                                   skip_load_image,
1073                                   texnode_preview);
1074
1075                         yn= tin*mtex->colfac;
1076                         //zn= tin*mtex->alphafac;
1077
1078                         if (mtex->mapto & MAP_COL) {
1079                                 zn= 1.0f-yn;
1080                                 har->r= (yn*tr+ zn*ma->r);
1081                                 har->g= (yn*tg+ zn*ma->g);
1082                                 har->b= (yn*tb+ zn*ma->b);
1083                         }
1084                         if (mtex->texco & TEXCO_UV) {
1085                                 har->alfa= tin;
1086                         }
1087                         if (mtex->mapto & MAP_ALPHA)
1088                                 har->alfa= tin;
1089                 }
1090         }
1091
1092         har->pool = re->pool;
1093         har->skip_load_image = skip_load_image;
1094         har->texnode_preview = texnode_preview;
1095
1096         return har;
1097 }
1098
1099 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,
1100                               const float vec[3], const float vec1[3],
1101                               const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3])
1102 {
1103         const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
1104         const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
1105         HaloRen *har;
1106         MTex *mtex;
1107         float tin, tr, tg, tb, ta;
1108         float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3], tex[3], out[3];
1109         int i, hasrgb;
1110
1111         if (hasize==0.0f) return NULL;
1112
1113         projectverto(vec, re->winmat, hoco);
1114         if (hoco[3]==0.0f) return NULL;
1115         if (vec1) {
1116                 projectverto(vec1, re->winmat, hoco1);
1117                 if (hoco1[3]==0.0f) return NULL;
1118         }
1119
1120         har= RE_findOrAddHalo(obr, obr->tothalo++);
1121         copy_v3_v3(har->co, vec);
1122         har->hasize= hasize;
1123
1124         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
1125         /* we do it here for sorting of halos */
1126         zn= hoco[3];
1127         har->xs= 0.5f*re->winx*(hoco[0]/zn);
1128         har->ys= 0.5f*re->winy*(hoco[1]/zn);
1129         har->zs= 0x7FFFFF*(hoco[2]/zn);
1130         
1131         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
1132         
1133         /* halovect */
1134         if (vec1) {
1135
1136                 har->type |= HA_VECT;
1137
1138                 xn=  har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
1139                 yn=  har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
1140                 if (yn == 0.0f && xn >= 0.0f) zn = 0.0f;
1141                 else zn = atan2f(yn, xn);
1142
1143                 har->sin = sinf(zn);
1144                 har->cos = cosf(zn);
1145                 zn= len_v3v3(vec1, vec)*0.5f;
1146
1147                 har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
1148                 
1149                 sub_v3_v3v3(har->no, vec, vec1);
1150                 normalize_v3(har->no);
1151         }
1152
1153         if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
1154
1155         har->alfa= ma->alpha;
1156         har->r= ma->r;
1157         har->g= ma->g;
1158         har->b= ma->b;
1159         har->add= (255.0f*ma->add);
1160         har->mat= ma;
1161         har->hard= ma->har;
1162         har->seed= seed % 256;
1163
1164         if (ma->mode & MA_STAR) har->starpoints= ma->starc;
1165         if (ma->mode & MA_HALO_LINES) har->linec= ma->linec;
1166         if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
1167         if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
1168
1169         if ((ma->mode & MA_HALOTEX) && ma->mtex[0])
1170                 har->tex= 1;
1171         
1172         for (i=0; i<MAX_MTEX; i++)
1173                 if (ma->mtex[i] && (ma->septex & (1<<i))==0) {
1174                         mtex= ma->mtex[i];
1175                         copy_v3_v3(texvec, vec);
1176
1177                         if (mtex->texco & TEXCO_NORM) {
1178                                 ;
1179                         }
1180                         else if (mtex->texco & TEXCO_OBJECT) {
1181                                 if (mtex->object)
1182                                         mul_m4_v3(mtex->object->imat_ren, texvec);
1183                         }
1184                         else if (mtex->texco & TEXCO_GLOB) {
1185                                 copy_v3_v3(texvec, vec);
1186                         }
1187                         else if (mtex->texco & TEXCO_UV && uvco) {
1188                                 int uv_index=CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, mtex->uvname);
1189                                 if (uv_index<0)
1190                                         uv_index=CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE);
1191
1192                                 uv_index-=CustomData_get_layer_index(&dm->faceData, CD_MTFACE);
1193
1194                                 texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
1195                                 texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
1196                                 texvec[2]=0.0f;
1197                         }
1198                         else if (mtex->texco & TEXCO_PARTICLE) {
1199                                 /* particle coordinates in range [0, 1] */
1200                                 texvec[0] = 2.f * pa_co[0] - 1.f;
1201                                 texvec[1] = 2.f * pa_co[1] - 1.f;
1202                                 texvec[2] = pa_co[2];
1203                         }
1204                         else if (orco) {
1205                                 copy_v3_v3(texvec, orco);
1206                         }
1207
1208                         hasrgb = externtex(mtex,
1209                                            texvec,
1210                                            &tin, &tr, &tg, &tb, &ta,
1211                                            0,
1212                                            re->pool,
1213                                            skip_load_image,
1214                                            texnode_preview);
1215
1216                         //yn= tin*mtex->colfac;
1217                         //zn= tin*mtex->alphafac;
1218                         if (mtex->mapto & MAP_COL) {
1219                                 tex[0]=tr;
1220                                 tex[1]=tg;
1221                                 tex[2]=tb;
1222                                 out[0]=har->r;
1223                                 out[1]=har->g;
1224                                 out[2]=har->b;
1225
1226                                 texture_rgb_blend(in, tex, out, tin, mtex->colfac, mtex->blendtype);
1227                         //      zn= 1.0-yn;
1228                                 //har->r= (yn*tr+ zn*ma->r);
1229                                 //har->g= (yn*tg+ zn*ma->g);
1230                                 //har->b= (yn*tb+ zn*ma->b);
1231                                 har->r= in[0];
1232                                 har->g= in[1];
1233                                 har->b= in[2];
1234                         }
1235
1236                         /* alpha returned, so let's use it instead of intensity */
1237                         if (hasrgb)
1238                                 tin = ta;
1239
1240                         if (mtex->mapto & MAP_ALPHA)
1241                                 har->alfa = texture_value_blend(mtex->def_var, har->alfa, tin, mtex->alphafac, mtex->blendtype);
1242                         if (mtex->mapto & MAP_HAR)
1243                                 har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var, ((float)har->hard)/127.0f, tin, mtex->hardfac, mtex->blendtype);
1244                         if (mtex->mapto & MAP_RAYMIRR)
1245                                 har->hasize = 100.0f*texture_value_blend(mtex->def_var, har->hasize/100.0f, tin, mtex->raymirrfac, mtex->blendtype);
1246                         if (mtex->mapto & MAP_TRANSLU) {
1247                                 float add = texture_value_blend(mtex->def_var, (float)har->add/255.0f, tin, mtex->translfac, mtex->blendtype);
1248                                 CLAMP(add, 0.f, 1.f);
1249                                 har->add = 255.0f*add;
1250                         }
1251                         /* now what on earth is this good for?? */
1252                         //if (mtex->texco & 16) {
1253                         //      har->alfa= tin;
1254                         //}
1255                 }
1256
1257         har->pool = re->pool;
1258         har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
1259         har->texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
1260
1261         return har;
1262 }
1263
1264 /* -------------------------- operations on entire database ----------------------- */
1265
1266 /* ugly function for halos in panorama */
1267 static int panotestclip(Render *re, bool do_pano, float v[4])
1268 {
1269         /* part size (ensure we run RE_parts_clamp first) */
1270         BLI_assert(re->partx == min_ii(re->r.tilex, re->rectx));
1271         BLI_assert(re->party == min_ii(re->r.tiley, re->recty));
1272
1273         if (do_pano == false) {
1274                 return testclip(v);
1275         }
1276         else {
1277                 /* to be used for halos en infos */
1278                 float abs4;
1279                 short c = 0;
1280
1281                 int xparts = (re->rectx + re->partx - 1) / re->partx;
1282
1283                 abs4= fabsf(v[3]);
1284
1285                 if (v[2]< -abs4) c=16;          /* this used to be " if (v[2]<0) ", see clippz() */
1286                 else if (v[2]> abs4) c+= 32;
1287
1288                 if ( v[1]>abs4) c+=4;
1289                 else if ( v[1]< -abs4) c+=8;
1290
1291                 abs4*= xparts;
1292                 if ( v[0]>abs4) c+=2;
1293                 else if ( v[0]< -abs4) c+=1;
1294
1295                 return c;
1296         }
1297 }
1298
1299 /**
1300  * This adds the hcs coordinates to vertices. It iterates over all
1301  * vertices, halos and faces. After the conversion, we clip in hcs.
1302  *
1303  * Elsewhere, all primites are converted to vertices.
1304  * Called in
1305  * - envmapping (envmap.c)
1306  * - shadow buffering (shadbuf.c)
1307  */
1308
1309 void project_renderdata(Render *re,
1310                         void (*projectfunc)(const float *, float mat[4][4], float *),
1311                         bool do_pano, float xoffs, bool UNUSED(do_buckets))
1312 {
1313         ObjectRen *obr;
1314         HaloRen *har = NULL;
1315         float zn, vec[3], hoco[4];
1316         int a;
1317
1318         if (do_pano) {
1319                 float panophi= xoffs;
1320                 
1321                 re->panosi = sinf(panophi);
1322                 re->panoco = cosf(panophi);
1323         }
1324
1325         for (obr=re->objecttable.first; obr; obr=obr->next) {
1326                 /* calculate view coordinates (and zbuffer value) */
1327                 for (a=0; a<obr->tothalo; a++) {
1328                         if ((a & 255)==0) har= obr->bloha[a>>8];
1329                         else har++;
1330
1331                         if (do_pano) {
1332                                 vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
1333                                 vec[1]= har->co[1];
1334                                 vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
1335                         }
1336                         else {
1337                                 copy_v3_v3(vec, har->co);
1338                         }
1339
1340                         projectfunc(vec, re->winmat, hoco);
1341                         
1342                         /* we clip halos less critical, but not for the Z */
1343                         hoco[0]*= 0.5f;
1344                         hoco[1]*= 0.5f;
1345                         
1346                         if ( panotestclip(re, do_pano, hoco) ) {
1347                                 har->miny= har->maxy= -10000;   /* that way render clips it */
1348                         }
1349                         else if (hoco[3]<0.0f) {
1350                                 har->miny= har->maxy= -10000;   /* render clips it */
1351                         }
1352                         else { /* do the projection...*/
1353                                 /* bring back hocos */
1354                                 hoco[0]*= 2.0f;
1355                                 hoco[1]*= 2.0f;
1356                                 
1357                                 zn= hoco[3];
1358                                 har->xs= 0.5f*re->winx*(1.0f+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
1359                                 har->ys= 0.5f*re->winy*(1.0f+hoco[1]/zn);
1360                         
1361                                 /* this should be the zbuffer coordinate */
1362                                 har->zs= 0x7FFFFF*(hoco[2]/zn);
1363                                 /* taking this from the face clip functions? seems ok... */
1364                                 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
1365                                 
1366                                 vec[0]+= har->hasize;
1367                                 projectfunc(vec, re->winmat, hoco);
1368                                 vec[0]-= har->hasize;
1369                                 zn= hoco[3];
1370                                 har->rad= fabsf(har->xs- 0.5f*re->winx*(1.0f+hoco[0]/zn));
1371                         
1372                                 /* this clip is not really OK, to prevent stars to become too large */
1373                                 if (har->type & HA_ONLYSKY) {
1374                                         if (har->rad>3.0f) har->rad= 3.0f;
1375                                 }
1376                         
1377                                 har->radsq= har->rad*har->rad;
1378                         
1379                                 har->miny= har->ys - har->rad/re->ycor;
1380                                 har->maxy= har->ys + har->rad/re->ycor;
1381                         
1382                                 /* the Zd value is still not really correct for pano */
1383                         
1384                                 vec[2] -= har->hasize;  /* z negative, otherwise it's clipped */
1385                                 projectfunc(vec, re->winmat, hoco);
1386                                 zn = hoco[3];
1387                                 zn = fabsf((float)har->zs - 0x7FFFFF * (hoco[2] / zn));
1388                                 har->zd = CLAMPIS(zn, 0, INT_MAX);
1389                         
1390                         }
1391                         
1392                 }
1393         }
1394 }
1395
1396 /* ------------------------------------------------------------------------- */
1397
1398 void RE_updateRenderInstance(Render *re, ObjectInstanceRen *obi, int flag)
1399 {
1400         /* flag specifies what things have changed. */
1401         if (flag & RE_OBJECT_INSTANCES_UPDATE_OBMAT) {
1402                 copy_m4_m4(obi->obmat, obi->ob->obmat);
1403                 invert_m4_m4(obi->obinvmat, obi->obmat);
1404         }
1405         if (flag & RE_OBJECT_INSTANCES_UPDATE_VIEW) {
1406                 mul_m4_m4m4(obi->localtoviewmat, re->viewmat, obi->obmat);
1407                 mul_m4_m4m4(obi->localtoviewinvmat, obi->obinvmat, re->viewinv);
1408         }
1409 }
1410
1411 void RE_updateRenderInstances(Render *re, int flag)
1412 {
1413         int i = 0;
1414         for (i = 0; i < re->totinstance; i++)
1415                 RE_updateRenderInstance(re, &re->objectinstance[i], flag);
1416 }
1417
1418 ObjectInstanceRen *RE_addRenderInstance(
1419         Render *re, ObjectRen *obr, Object *ob, Object *par,
1420         int index, int psysindex, float mat[4][4], int lay, const DupliObject *dob)
1421 {
1422         ObjectInstanceRen *obi;
1423         float mat3[3][3];
1424
1425         obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen");
1426         obi->obr= obr;
1427         obi->ob= ob;
1428         obi->par= par;
1429         obi->index= index;
1430         obi->psysindex= psysindex;
1431         obi->lay= lay;
1432
1433         /* Fill particle info */
1434         if (par && dob) {
1435                 const ParticleSystem *psys = dob->particle_system;
1436                 if (psys) {
1437                         int part_index;
1438                         if (obi->index < psys->totpart) {
1439                                 part_index = obi->index;
1440                         }
1441                         else if (psys->child) {
1442                                 part_index = psys->child[obi->index - psys->totpart].parent;
1443                         }
1444                         else {
1445                                 part_index = -1;
1446                         }
1447
1448                         if (part_index >= 0) {
1449                                 const ParticleData *p = &psys->particles[part_index];
1450                                 obi->part_index = part_index;
1451                                 obi->part_size = p->size;
1452                                 obi->part_age = RE_GetStats(re)->cfra - p->time;
1453                                 obi->part_lifetime = p->lifetime;
1454
1455                                 copy_v3_v3(obi->part_co, p->state.co);
1456                                 copy_v3_v3(obi->part_vel, p->state.vel);
1457                                 copy_v3_v3(obi->part_avel, p->state.ave);
1458                         }
1459                 }
1460         }
1461
1462         /* Fill object info */
1463         if (dob) {
1464                 obi->random_id = dob->random_id;
1465         }
1466         else {
1467                 obi->random_id = BLI_hash_int_2d(BLI_hash_string(obi->ob->id.name + 2), 0);
1468         }
1469
1470         RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW);
1471
1472         if (mat) {
1473                 copy_m4_m4(obi->mat, mat);
1474                 copy_m3_m4(mat3, mat);
1475                 invert_m3_m3(obi->nmat, mat3);
1476                 transpose_m3(obi->nmat);
1477                 obi->flag |= R_DUPLI_TRANSFORMED;
1478         }
1479
1480         BLI_addtail(&re->instancetable, obi);
1481
1482         return obi;
1483 }
1484
1485 void RE_instance_get_particle_info(struct ObjectInstanceRen *obi, float *index, float *random, float *age, float *lifetime, float co[3], float *size, float vel[3], float angvel[3])
1486 {
1487         *index = obi->part_index;
1488         *random = BLI_hash_int_01(obi->part_index);
1489         *age = obi->part_age;
1490         *lifetime = obi->part_lifetime;
1491         copy_v3_v3(co, obi->part_co);
1492         *size = obi->part_size;
1493         copy_v3_v3(vel, obi->part_vel);
1494         copy_v3_v3(angvel, obi->part_avel);
1495 }
1496
1497
1498 void RE_makeRenderInstances(Render *re)
1499 {
1500         ObjectInstanceRen *obi, *oldobi;
1501         ListBase newlist;
1502         int tot;
1503
1504         /* convert list of object instances to an array for index based lookup */
1505         tot= BLI_listbase_count(&re->instancetable);
1506         re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
1507         re->totinstance= tot;
1508         newlist.first= newlist.last= NULL;
1509
1510         obi= re->objectinstance;
1511         for (oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
1512                 *obi= *oldobi;
1513
1514                 if (obi->obr) {
1515                         obi->prev= obi->next= NULL;
1516                         BLI_addtail(&newlist, obi);
1517                         obi++;
1518                 }
1519                 else
1520                         re->totinstance--;
1521         }
1522
1523         BLI_freelistN(&re->instancetable);
1524         re->instancetable= newlist;
1525 }
1526
1527 /* four functions to facilitate envmap rotation for raytrace */
1528 void RE_instance_rotate_ray_start(ObjectInstanceRen *obi, Isect *is)
1529 {
1530         if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
1531                 copy_v3_v3(is->origstart, is->start);
1532                 mul_m4_v3(obi->imat, is->start);
1533         }
1534 }
1535
1536 void RE_instance_rotate_ray_dir(ObjectInstanceRen *obi, Isect *is)
1537 {
1538         if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
1539                 float end[3];
1540
1541                 copy_v3_v3(is->origdir, is->dir);
1542                 add_v3_v3v3(end, is->origstart, is->dir);
1543
1544                 mul_m4_v3(obi->imat, end);
1545                 sub_v3_v3v3(is->dir, end, is->start);
1546         }
1547 }
1548
1549 void RE_instance_rotate_ray(ObjectInstanceRen *obi, Isect *is)
1550 {
1551         RE_instance_rotate_ray_start(obi, is);
1552         RE_instance_rotate_ray_dir(obi, is);
1553 }
1554
1555 void RE_instance_rotate_ray_restore(ObjectInstanceRen *obi, Isect *is)
1556 {
1557         if (obi && (obi->flag & R_ENV_TRANSFORMED)) {
1558                 copy_v3_v3(is->start, is->origstart);
1559                 copy_v3_v3(is->dir, is->origdir);
1560         }
1561 }
1562
1563 int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4])
1564 {
1565         float mat[4][4], vec[4];
1566         int a, fl, flag = -1;
1567
1568         copy_m4_m4(mat, winmat);
1569
1570         for (a=0; a < 8; a++) {
1571                 vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
1572                 vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
1573                 vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
1574                 vec[3]= 1.0;
1575                 mul_m4_v4(mat, vec);
1576
1577                 fl = 0;
1578                 if (bounds) {
1579                         if      (vec[0] < bounds[0] * vec[3]) fl |= 1;
1580                         else if (vec[0] > bounds[1] * vec[3]) fl |= 2;
1581                         
1582                         if      (vec[1] > bounds[3] * vec[3]) fl |= 4;
1583                         else if (vec[1] < bounds[2] * vec[3]) fl |= 8;
1584                 }
1585                 else {
1586                         if      (vec[0] < -vec[3]) fl |= 1;
1587                         else if (vec[0] >  vec[3]) fl |= 2;
1588                         
1589                         if      (vec[1] >  vec[3]) fl |= 4;
1590                         else if (vec[1] < -vec[3]) fl |= 8;
1591                 }
1592                 if      (vec[2] < -vec[3]) fl |= 16;
1593                 else if (vec[2] >  vec[3]) fl |= 32;
1594
1595                 flag &= fl;
1596                 if (flag == 0) {
1597                         return 0;
1598                 }
1599         }
1600
1601         return flag;
1602 }
1603