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