Approximate Ambient Occlusion
[blender-staging.git] / source / blender / render / intern / source / renderdatabase.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 2004-2006, Blender Foundation, full recode
24  *
25  * ***** END GPL/BL DUAL LICENSE BLOCK *****
26  */
27
28 /*
29  * Storage, retrieval and query of render specific data.
30  *
31  * All data from a Blender scene is converted by the renderconverter/
32  * into a special format that is used by the render module to make
33  * images out of. These functions interface to the render-specific
34  * database.  
35  *
36  * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data
37  * entries each.
38  *
39  * The index of an entry is >>8 (the highest 24 * bits), to find an
40  * offset in a 256-entry block.
41  *
42  * - If the 256-entry block entry has an entry in the
43  * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in
44  * that block is allocated to this entry.
45  *
46  * - If the entry has no block allocated for it yet, memory is
47  * allocated.
48  *
49  * The pointer to the correct entry is returned. Memory is guarateed
50  * to exist (as long as the malloc does not break). Since guarded
51  * allocation is used, memory _must_ be available. Otherwise, an
52  * exit(0) would occur.
53  * 
54  */
55
56 #include <limits.h>
57 #include <math.h>
58 #include <string.h>
59
60 #include "MEM_guardedalloc.h"
61 #include "BKE_utildefines.h"
62
63 #include "BLI_arithb.h"
64 #include "BLI_blenlib.h"
65 #include "BLI_ghash.h"
66 #include "BLI_memarena.h"
67
68 #include "DNA_material_types.h" 
69 #include "DNA_mesh_types.h" 
70 #include "DNA_meshdata_types.h" 
71 #include "DNA_texture_types.h" 
72
73 #include "BKE_customdata.h"
74 #include "BKE_texture.h" 
75 #include "BKE_DerivedMesh.h"
76
77 #include "RE_render_ext.h"      /* externtex */
78
79 #include "renderpipeline.h"
80 #include "render_types.h"
81 #include "renderdatabase.h"
82 #include "texture.h"
83 #include "strand.h"
84 #include "zbuf.h"
85
86 /* ------------------------------------------------------------------------- */
87
88 /* More dynamic allocation of options for render vertices and faces, so we dont
89    have to reserve this space inside vertices.
90    Important; vertices and faces, should have been created already (to get tables
91    checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not
92    the index */
93
94 /* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */
95
96 #define RE_STICKY_ELEMS         2
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_STRESS_ELEMS         1
102 #define RE_WINSPEED_ELEMS       4
103 #define RE_MTFACE_ELEMS         1
104 #define RE_MCOL_ELEMS           4
105 #define RE_UV_ELEMS                     2
106 #define RE_SURFNOR_ELEMS        3
107 #define RE_SIMPLIFY_ELEMS       2
108 #define RE_FACE_ELEMS   1
109
110 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
111 {
112         float *sticky;
113         int nr= ver->index>>8;
114         
115         sticky= obr->vertnodes[nr].sticky;
116         if(sticky==NULL) {
117                 if(verify) 
118                         sticky= obr->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
119                 else
120                         return NULL;
121         }
122         return sticky + (ver->index & 255)*RE_STICKY_ELEMS;
123 }
124
125 float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify)
126 {
127         float *stress;
128         int nr= ver->index>>8;
129         
130         stress= obr->vertnodes[nr].stress;
131         if(stress==NULL) {
132                 if(verify) 
133                         stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
134                 else
135                         return NULL;
136         }
137         return stress + (ver->index & 255)*RE_STRESS_ELEMS;
138 }
139
140 /* this one callocs! */
141 float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify)
142 {
143         float *rad;
144         int nr= ver->index>>8;
145         
146         rad= obr->vertnodes[nr].rad;
147         if(rad==NULL) {
148                 if(verify) 
149                         rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
150                 else
151                         return NULL;
152         }
153         return rad + (ver->index & 255)*RE_RAD_ELEMS;
154 }
155
156 float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify)
157 {
158         float *strand;
159         int nr= ver->index>>8;
160         
161         strand= obr->vertnodes[nr].strand;
162         if(strand==NULL) {
163                 if(verify) 
164                         strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
165                 else
166                         return NULL;
167         }
168         return strand + (ver->index & 255)*RE_STRAND_ELEMS;
169 }
170
171 /* needs calloc */
172 float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify)
173 {
174         float *tangent;
175         int nr= ver->index>>8;
176         
177         tangent= obr->vertnodes[nr].tangent;
178         if(tangent==NULL) {
179                 if(verify) 
180                         tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
181                 else
182                         return NULL;
183         }
184         return tangent + (ver->index & 255)*RE_TANGENT_ELEMS;
185 }
186
187 /* needs calloc! not all renderverts have them */
188 /* also winspeed is exception, it is stored per instance */
189 float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
190 {
191         float *winspeed;
192         int totvector;
193         
194         winspeed= obi->vectors;
195         if(winspeed==NULL) {
196                 if(verify) {
197                         totvector= obi->obr->totvert + obi->obr->totstrand;
198                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
199                 }
200                 else
201                         return NULL;
202         }
203         return winspeed + ver->index*RE_WINSPEED_ELEMS;
204 }
205
206 VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
207 {
208         VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
209         float *fp1, *fp2;
210         int index= v1->index;
211         
212         *v1= *ver;
213         v1->index= index;
214         
215         fp1= RE_vertren_get_sticky(obr, ver, 0);
216         if(fp1) {
217                 fp2= RE_vertren_get_sticky(obr, v1, 1);
218                 memcpy(fp2, fp1, RE_STICKY_ELEMS*sizeof(float));
219         }
220         fp1= RE_vertren_get_stress(obr, ver, 0);
221         if(fp1) {
222                 fp2= RE_vertren_get_stress(obr, v1, 1);
223                 memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float));
224         }
225         fp1= RE_vertren_get_rad(obr, ver, 0);
226         if(fp1) {
227                 fp2= RE_vertren_get_rad(obr, v1, 1);
228                 memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float));
229         }
230         fp1= RE_vertren_get_strand(obr, ver, 0);
231         if(fp1) {
232                 fp2= RE_vertren_get_strand(obr, v1, 1);
233                 memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float));
234         }
235         fp1= RE_vertren_get_tangent(obr, ver, 0);
236         if(fp1) {
237                 fp2= RE_vertren_get_tangent(obr, v1, 1);
238                 memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
239         }
240         return v1;
241 }
242
243 VertRen *RE_findOrAddVert(ObjectRen *obr, int nr)
244 {
245         VertTableNode *temp;
246         VertRen *v;
247         int a;
248
249         if(nr<0) {
250                 printf("error in findOrAddVert: %d\n",nr);
251                 return NULL;
252         }
253         a= nr>>8;
254         
255         if (a>=obr->vertnodeslen-1) {  /* Need to allocate more columns..., and keep last element NULL for free loop */
256                 temp= obr->vertnodes;
257                 
258                 obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE) , "vertnodes");
259                 if(temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode));
260                 memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
261                 
262                 obr->vertnodeslen+=TABLEINITSIZE; 
263                 if(temp) MEM_freeN(temp);       
264         }
265         
266         v= obr->vertnodes[a].vert;
267         if(v==NULL) {
268                 int i;
269                 
270                 v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert");
271                 obr->vertnodes[a].vert= v;
272                 
273                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
274                         v[a].index= i;
275                 }
276         }
277         v+= (nr & 255);
278         return v;
279 }
280
281 /* ------------------------------------------------------------------------ */
282
283 MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
284 {
285         VlakTableNode *node;
286         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
287         int index= (n<<8) + vlakindex;
288
289         node= &obr->vlaknodes[nr];
290
291         if(verify) {
292                 if(n>=node->totmtface) {
293                         MTFace *mtface= node->mtface;
294                         int size= size= (n+1)*256;
295
296                         node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
297
298                         if(mtface) {
299                                 size= node->totmtface*256;
300                                 memcpy(node->mtface, mtface, size*sizeof(MTFace));
301                                 MEM_freeN(mtface);
302                         }
303
304                         node->totmtface= n+1;
305                 }
306         }
307         else {
308                 if(n>=node->totmtface)
309                         return NULL;
310
311                 if(name) *name= obr->mtface[n];
312         }
313
314         return node->mtface + index;
315 }
316
317 MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
318 {
319         VlakTableNode *node;
320         int nr= vlr->index>>8, vlakindex= (vlr->index&255);
321         int index= (n<<8) + vlakindex;
322
323         node= &obr->vlaknodes[nr];
324
325         if(verify) {
326                 if(n>=node->totmcol) {
327                         MCol *mcol= node->mcol;
328                         int size= (n+1)*256;
329
330                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol");
331
332                         if(mcol) {
333                                 size= node->totmcol*256;
334                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
335                                 MEM_freeN(mcol);
336                         }
337
338                         node->totmcol= n+1;
339                 }
340         }
341         else {
342                 if(n>=node->totmcol)
343                         return NULL;
344
345                 if(name) *name= obr->mcol[n];
346         }
347
348         return node->mcol + index*RE_MCOL_ELEMS;
349 }
350
351 float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
352 {
353         float *surfnor;
354         int nr= vlak->index>>8;
355         
356         surfnor= obr->vlaknodes[nr].surfnor;
357         if(surfnor==NULL) {
358                 if(verify) 
359                         surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
360                 else
361                         return NULL;
362         }
363         return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
364 }
365
366 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
367 {
368         VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
369         MTFace *mtface, *mtface1;
370         MCol *mcol, *mcol1;
371         float *surfnor, *surfnor1;
372         int i, index = vlr1->index;
373         char *name;
374
375         *vlr1= *vlr;
376         vlr1->index= index;
377
378         for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) {
379                 mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1);
380                 memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS);
381         }
382
383         for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) {
384                 mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1);
385                 memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
386         }
387
388         surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
389         if(surfnor) {
390                 surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
391                 VECCOPY(surfnor1, surfnor);
392         }
393
394         return vlr1;
395 }
396
397 int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor)
398 {
399         float xn, yn, zn, v1[3];
400         float (*imat)[3]= obi->imat;
401         int flipped= 0;
402
403         if(obi->flag & R_TRANSFORMED) {
404                 xn= vlr->n[0];
405                 yn= vlr->n[1];
406                 zn= vlr->n[2];
407                 
408                 /* transpose! */
409                 nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
410                 nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
411                 nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
412                 Normalize(nor);
413         }
414         else
415                 VECCOPY(nor, vlr->n);
416
417         if((vlr->flag & R_NOPUNOFLIP)==0) {
418                 if(re->r.mode & R_ORTHO) {
419                         if(nor[2] > 0.0f)
420                                 flipped= 1;
421                 }
422                 else {
423                         VECCOPY(v1, vlr->v1->co);
424                         if(obi->flag & R_TRANSFORMED)
425                                 Mat4MulVecfl(obi->mat, v1);
426                         if(INPR(v1, nor) < 0.0f) {
427                                 flipped= 1;
428                         }
429                 }
430
431                 if(flipped) {
432                         nor[0]= -nor[0];
433                         nor[1]= -nor[1];
434                         nor[2]= -nor[2];
435                 }
436         }
437
438         return flipped;
439 }
440
441 void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
442 {
443         /* CustomData layer names are stored per object here, because the
444            DerivedMesh which stores the layers is freed */
445         
446         CustomDataLayer *layer;
447         int numlayers, i, mtfn, mcn;
448
449         if (CustomData_has_layer(data, CD_MTFACE)) {
450                 numlayers= CustomData_number_of_layers(data, CD_MTFACE);
451                 obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numlayers, "mtfacenames");
452         }
453
454         if (CustomData_has_layer(data, CD_MCOL)) {
455                 numlayers= CustomData_number_of_layers(data, CD_MCOL);
456                 obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numlayers, "mcolnames");
457         }
458
459         for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
460                 layer= &data->layers[i];
461
462                 if (layer->type == CD_MTFACE) {
463                         strcpy(obr->mtface[mtfn++], layer->name);
464                         obr->actmtface= layer->active_rnd;
465                 }
466                 else if (layer->type == CD_MCOL) {
467                         strcpy(obr->mcol[mcn++], layer->name);
468                         obr->actmcol= layer->active_rnd;
469                 }
470         }
471 }
472
473 VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr)
474 {
475         VlakTableNode *temp;
476         VlakRen *v;
477         int a;
478
479         if(nr<0) {
480                 printf("error in findOrAddVlak: %d\n",nr);
481                 return obr->vlaknodes[0].vlak;
482         }
483         a= nr>>8;
484         
485         if (a>=obr->vlaknodeslen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
486                 temp= obr->vlaknodes;
487                 
488                 obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE) , "vlaknodes");
489                 if(temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode));
490                 memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
491
492                 obr->vlaknodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
493                 if(temp) MEM_freeN(temp);       
494         }
495
496         v= obr->vlaknodes[a].vlak;
497         
498         if(v==NULL) {
499                 int i;
500
501                 v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak");
502                 obr->vlaknodes[a].vlak= v;
503
504                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
505                         v[a].index= i;
506         }
507         v+= (nr & 255);
508         return v;
509 }
510
511 /* ------------------------------------------------------------------------ */
512
513 float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
514 {
515         float *surfnor;
516         int nr= strand->index>>8;
517         
518         surfnor= obr->strandnodes[nr].surfnor;
519         if(surfnor==NULL) {
520                 if(verify) 
521                         surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
522                 else
523                         return NULL;
524         }
525         return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS;
526 }
527
528 float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
529 {
530         StrandTableNode *node;
531         int nr= strand->index>>8, strandindex= (strand->index&255);
532         int index= (n<<8) + strandindex;
533
534         node= &obr->strandnodes[nr];
535
536         if(verify) {
537                 if(n>=node->totuv) {
538                         float *uv= node->uv;
539                         int size= (n+1)*256;
540
541                         node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "Strand uv");
542
543                         if(uv) {
544                                 size= node->totuv*256;
545                                 memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS);
546                                 MEM_freeN(uv);
547                         }
548
549                         node->totuv= n+1;
550                 }
551         }
552         else {
553                 if(n>=node->totuv)
554                         return NULL;
555
556                 if(name) *name= obr->mtface[n];
557         }
558
559         return node->uv + index*RE_UV_ELEMS;
560 }
561
562 MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
563 {
564         StrandTableNode *node;
565         int nr= strand->index>>8, strandindex= (strand->index&255);
566         int index= (n<<8) + strandindex;
567
568         node= &obr->strandnodes[nr];
569
570         if(verify) {
571                 if(n>=node->totmcol) {
572                         MCol *mcol= node->mcol;
573                         int size= (n+1)*256;
574
575                         node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Strand mcol");
576
577                         if(mcol) {
578                                 size= node->totmcol*256;
579                                 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
580                                 MEM_freeN(mcol);
581                         }
582
583                         node->totmcol= n+1;
584                 }
585         }
586         else {
587                 if(n>=node->totmcol)
588                         return NULL;
589
590                 if(name) *name= obr->mcol[n];
591         }
592
593         return node->mcol + index*RE_MCOL_ELEMS;
594 }
595
596 float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify)
597 {
598         float *simplify;
599         int nr= strand->index>>8;
600         
601         simplify= obr->strandnodes[nr].simplify;
602         if(simplify==NULL) {
603                 if(verify) 
604                         simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify table");
605                 else
606                         return NULL;
607         }
608         return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
609 }
610
611 int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
612 {
613         int *face;
614         int nr= strand->index>>8;
615         
616         face= obr->strandnodes[nr].face;
617         if(face==NULL) {
618                 if(verify) 
619                         face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face table");
620                 else
621                         return NULL;
622         }
623         return face + (strand->index & 255)*RE_FACE_ELEMS;
624 }
625
626 /* winspeed is exception, it is stored per instance */
627 float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
628 {
629         float *winspeed;
630         int totvector;
631         
632         winspeed= obi->vectors;
633         if(winspeed==NULL) {
634                 if(verify) {
635                         totvector= obi->obr->totvert + obi->obr->totstrand;
636                         winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
637                 }
638                 else
639                         return NULL;
640         }
641         return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS;
642 }
643
644 StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr)
645 {
646         StrandTableNode *temp;
647         StrandRen *v;
648         int a;
649
650         if(nr<0) {
651                 printf("error in findOrAddStrand: %d\n",nr);
652                 return obr->strandnodes[0].strand;
653         }
654         a= nr>>8;
655         
656         if (a>=obr->strandnodeslen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
657                 temp= obr->strandnodes;
658                 
659                 obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE) , "strandnodes");
660                 if(temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode));
661                 memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode));
662
663                 obr->strandnodeslen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
664                 if(temp) MEM_freeN(temp);       
665         }
666
667         v= obr->strandnodes[a].strand;
668         
669         if(v==NULL) {
670                 int i;
671
672                 v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen),"findOrAddStrand");
673                 obr->strandnodes[a].strand= v;
674
675                 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
676                         v[a].index= i;
677         }
678         v+= (nr & 255);
679         return v;
680 }
681
682 StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
683 {
684         StrandBuffer *strandbuf;
685
686         strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer");
687         strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert");
688         strandbuf->totvert= totvert;
689         strandbuf->obr= obr;
690
691         BLI_addtail(&obr->strandbufs, strandbuf);
692
693         return strandbuf;
694 }
695
696 /* ------------------------------------------------------------------------ */
697
698 ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex)
699 {
700         ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
701         
702         BLI_addtail(&re->objecttable, obr);
703         obr->ob= ob;
704         obr->par= par;
705         obr->index= index;
706         obr->psysindex= psysindex;
707
708         return obr;
709 }
710
711 void free_renderdata_vertnodes(VertTableNode *vertnodes)
712 {
713         int a;
714         
715         if(vertnodes==NULL) return;
716         
717         for(a=0; vertnodes[a].vert; a++) {
718                 MEM_freeN(vertnodes[a].vert);
719                 
720                 if(vertnodes[a].rad)
721                         MEM_freeN(vertnodes[a].rad);
722                 if(vertnodes[a].sticky)
723                         MEM_freeN(vertnodes[a].sticky);
724                 if(vertnodes[a].strand)
725                         MEM_freeN(vertnodes[a].strand);
726                 if(vertnodes[a].tangent)
727                         MEM_freeN(vertnodes[a].tangent);
728                 if(vertnodes[a].stress)
729                         MEM_freeN(vertnodes[a].stress);
730                 if(vertnodes[a].winspeed)
731                         MEM_freeN(vertnodes[a].winspeed);
732         }
733         
734         MEM_freeN(vertnodes);
735 }
736
737 void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
738 {
739         int a;
740         
741         if(vlaknodes==NULL) return;
742         
743         for(a=0; vlaknodes[a].vlak; a++) {
744                 MEM_freeN(vlaknodes[a].vlak);
745                 
746                 if(vlaknodes[a].mtface)
747                         MEM_freeN(vlaknodes[a].mtface);
748                 if(vlaknodes[a].mcol)
749                         MEM_freeN(vlaknodes[a].mcol);
750                 if(vlaknodes[a].surfnor)
751                         MEM_freeN(vlaknodes[a].surfnor);
752         }
753         
754         MEM_freeN(vlaknodes);
755 }
756
757 void free_renderdata_strandnodes(StrandTableNode *strandnodes)
758 {
759         int a;
760         
761         if(strandnodes==NULL) return;
762         
763         for(a=0; strandnodes[a].strand; a++) {
764                 MEM_freeN(strandnodes[a].strand);
765                 
766                 if(strandnodes[a].uv)
767                         MEM_freeN(strandnodes[a].uv);
768                 if(strandnodes[a].mcol)
769                         MEM_freeN(strandnodes[a].mcol);
770                 if(strandnodes[a].winspeed)
771                         MEM_freeN(strandnodes[a].winspeed);
772                 if(strandnodes[a].surfnor)
773                         MEM_freeN(strandnodes[a].surfnor);
774                 if(strandnodes[a].simplify)
775                         MEM_freeN(strandnodes[a].simplify);
776                 if(strandnodes[a].face)
777                         MEM_freeN(strandnodes[a].face);
778         }
779         
780         MEM_freeN(strandnodes);
781 }
782
783 void free_renderdata_tables(Render *re)
784 {
785         ObjectInstanceRen *obi;
786         ObjectRen *obr;
787         StrandBuffer *strandbuf;
788         int a=0;
789         
790         for(obr=re->objecttable.first; obr; obr=obr->next) {
791                 if(obr->vertnodes) {
792                         free_renderdata_vertnodes(obr->vertnodes);
793                         obr->vertnodes= NULL;
794                         obr->vertnodeslen= 0;
795                 }
796
797                 if(obr->vlaknodes) {
798                         free_renderdata_vlaknodes(obr->vlaknodes);
799                         obr->vlaknodes= NULL;
800                         obr->vlaknodeslen= 0;
801                         obr->totvlak= 0;
802                 }
803
804                 if(obr->bloha) {
805                         for(a=0; obr->bloha[a]; a++)
806                                 MEM_freeN(obr->bloha[a]);
807
808                         MEM_freeN(obr->bloha);
809                         obr->bloha= NULL;
810                         obr->blohalen= 0;
811                 }
812
813                 if(obr->strandnodes) {
814                         free_renderdata_strandnodes(obr->strandnodes);
815                         obr->strandnodes= NULL;
816                         obr->strandnodeslen= 0;
817                 }
818
819                 for(strandbuf=obr->strandbufs.first; strandbuf; strandbuf=strandbuf->next)
820                         if(strandbuf->vert) MEM_freeN(strandbuf->vert);
821                 BLI_freelistN(&obr->strandbufs);
822
823                 if(obr->mtface)
824                         MEM_freeN(obr->mtface);
825                 if(obr->mcol)
826                         MEM_freeN(obr->mcol);
827         }
828
829         if(re->objectinstance) {
830                 for(obi=re->instancetable.first; obi; obi=obi->next)
831                         if(obi->vectors)
832                                 MEM_freeN(obi->vectors);
833
834                 MEM_freeN(re->objectinstance);
835                 re->objectinstance= NULL;
836                 re->totinstance= 0;
837                 re->instancetable.first= re->instancetable.last= NULL;
838         }
839
840         if(re->sortedhalos) {
841                 MEM_freeN(re->sortedhalos);
842                 re->sortedhalos= NULL;
843         }
844
845         if(re->strandbuckets) {
846                 free_buckets(re->strandbuckets);
847                 re->strandbuckets= NULL;
848         }
849
850         BLI_freelistN(&re->customdata_names);
851         BLI_freelistN(&re->objecttable);
852         BLI_freelistN(&re->instancetable);
853 }
854
855 /* ------------------------------------------------------------------------ */
856
857 HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
858 {
859         HaloRen *h, **temp;
860         int a;
861
862         if(nr<0) {
863                 printf("error in findOrAddHalo: %d\n",nr);
864                 return NULL;
865         }
866         a= nr>>8;
867         
868         if (a>=obr->blohalen-1){  /* Need to allocate more columns..., and keep last element NULL for free loop */
869                 //printf("Allocating %i more halo groups.  %i total.\n", 
870                 //      TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
871                 temp=obr->bloha;
872                 
873                 obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE) , "Bloha");
874                 if(temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
875                 memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
876                 obr->blohalen+=TABLEINITSIZE;  /*Does this really need to be power of 2?*/
877                 if(temp) MEM_freeN(temp);       
878         }
879         
880         h= obr->bloha[a];
881         if(h==NULL) {
882                 h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo");
883                 obr->bloha[a]= h;
884         }
885         h+= (nr & 255);
886         return h;
887 }
888
889 /* ------------------------------------------------------------------------- */
890
891 HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   float *vec1, 
892                                   float *orco,   float hasize,   float vectsize, int seed)
893 {
894         HaloRen *har;
895         MTex *mtex;
896         float tin, tr, tg, tb, ta;
897         float xn, yn, zn, texvec[3], hoco[4], hoco1[4];
898
899         if(hasize==0.0) return NULL;
900
901         projectverto(vec, re->winmat, hoco);
902         if(hoco[3]==0.0) return NULL;
903         if(vec1) {
904                 projectverto(vec1, re->winmat, hoco1);
905                 if(hoco1[3]==0.0) return NULL;
906         }
907
908         har= RE_findOrAddHalo(obr, obr->tothalo++);
909         VECCOPY(har->co, vec);
910         har->hasize= hasize;
911
912         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
913         /* we do it here for sorting of halos */
914         zn= hoco[3];
915         har->xs= 0.5*re->winx*(hoco[0]/zn);
916         har->ys= 0.5*re->winy*(hoco[1]/zn);
917         har->zs= 0x7FFFFF*(hoco[2]/zn);
918         
919         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
920         
921         /* halovect */
922         if(vec1) {
923
924                 har->type |= HA_VECT;
925
926                 xn=  har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
927                 yn=  har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
928                 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
929                 else zn= atan2(yn, xn);
930
931                 har->sin= sin(zn);
932                 har->cos= cos(zn);
933                 zn= VecLenf(vec1, vec);
934
935                 har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
936                 
937                 VecSubf(har->no, vec, vec1);
938                 Normalize(har->no);
939         }
940
941         if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
942
943         har->alfa= ma->alpha;
944         har->r= ma->r;
945         har->g= ma->g;
946         har->b= ma->b;
947         har->add= (255.0*ma->add);
948         har->mat= ma;
949         har->hard= ma->har;
950         har->seed= seed % 256;
951
952         if(ma->mode & MA_STAR) har->starpoints= ma->starc;
953         if(ma->mode & MA_HALO_LINES) har->linec= ma->linec;
954         if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
955         if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
956
957
958         if(ma->mtex[0]) {
959
960                 if( (ma->mode & MA_HALOTEX) ) har->tex= 1;
961                 else {
962
963                         mtex= ma->mtex[0];
964                         VECCOPY(texvec, vec);
965
966                         if(mtex->texco & TEXCO_NORM) {
967                                 ;
968                         }
969                         else if(mtex->texco & TEXCO_OBJECT) {
970                                 /* texvec[0]+= imatbase->ivec[0]; */
971                                 /* texvec[1]+= imatbase->ivec[1]; */
972                                 /* texvec[2]+= imatbase->ivec[2]; */
973                                 /* Mat3MulVecfl(imatbase->imat, texvec); */
974                         }
975                         else {
976                                 if(orco) {
977                                         VECCOPY(texvec, orco);
978                                 }
979                         }
980
981                         externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
982
983                         yn= tin*mtex->colfac;
984                         zn= tin*mtex->varfac;
985
986                         if(mtex->mapto & MAP_COL) {
987                                 zn= 1.0-yn;
988                                 har->r= (yn*tr+ zn*ma->r);
989                                 har->g= (yn*tg+ zn*ma->g);
990                                 har->b= (yn*tb+ zn*ma->b);
991                         }
992                         if(mtex->texco & 16) {
993                                 har->alfa= tin;
994                         }
995                 }
996         }
997
998         return har;
999 }
1000
1001 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,   float *vec,   float *vec1, 
1002                                   float *orco, float *uvco, float hasize, float vectsize, int seed)
1003 {
1004         HaloRen *har;
1005         MTex *mtex;
1006         float tin, tr, tg, tb, ta;
1007         float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3];
1008         int i;
1009
1010         if(hasize==0.0) return NULL;
1011
1012         projectverto(vec, re->winmat, hoco);
1013         if(hoco[3]==0.0) return NULL;
1014         if(vec1) {
1015                 projectverto(vec1, re->winmat, hoco1);
1016                 if(hoco1[3]==0.0) return NULL;
1017         }
1018
1019         har= RE_findOrAddHalo(obr, obr->tothalo++);
1020         VECCOPY(har->co, vec);
1021         har->hasize= hasize;
1022
1023         /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
1024         /* we do it here for sorting of halos */
1025         zn= hoco[3];
1026         har->xs= 0.5*re->winx*(hoco[0]/zn);
1027         har->ys= 0.5*re->winy*(hoco[1]/zn);
1028         har->zs= 0x7FFFFF*(hoco[2]/zn);
1029         
1030         har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 
1031         
1032         /* halovect */
1033         if(vec1) {
1034
1035                 har->type |= HA_VECT;
1036
1037                 xn=  har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
1038                 yn=  har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
1039                 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
1040                 else zn= atan2(yn, xn);
1041
1042                 har->sin= sin(zn);
1043                 har->cos= cos(zn);
1044                 zn= VecLenf(vec1, vec)*0.5;
1045
1046                 har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
1047                 
1048                 VecSubf(har->no, vec, vec1);
1049                 Normalize(har->no);
1050         }
1051
1052         if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
1053
1054         har->alfa= ma->alpha;
1055         har->r= ma->r;
1056         har->g= ma->g;
1057         har->b= ma->b;
1058         har->add= (255.0*ma->add);
1059         har->mat= ma;
1060         har->hard= ma->har;
1061         har->seed= seed % 256;
1062
1063         if(ma->mode & MA_STAR) har->starpoints= ma->starc;
1064         if(ma->mode & MA_HALO_LINES) har->linec= ma->linec;
1065         if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
1066         if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
1067
1068         if((ma->mode & MA_HALOTEX) && ma->mtex[0]){
1069                 har->tex= 1;
1070                 i=1;
1071         }
1072         
1073         for(i=0; i<MAX_MTEX; i++)
1074                 if(ma->mtex[i] && (ma->septex & (1<<i))==0) {
1075                         mtex= ma->mtex[i];
1076                         VECCOPY(texvec, vec);
1077
1078                         if(mtex->texco & TEXCO_NORM) {
1079                                 ;
1080                         }
1081                         else if(mtex->texco & TEXCO_OBJECT) {
1082                                 if(mtex->object){
1083                                         float imat[4][4];
1084                                         /* imat should really be cached somewhere before this */
1085                                         Mat4Invert(imat,mtex->object->obmat);
1086                                         Mat4MulVecfl(imat,texvec);
1087                                 }
1088                                 /* texvec[0]+= imatbase->ivec[0]; */
1089                                 /* texvec[1]+= imatbase->ivec[1]; */
1090                                 /* texvec[2]+= imatbase->ivec[2]; */
1091                                 /* Mat3MulVecfl(imatbase->imat, texvec); */
1092                         }
1093                         else if(mtex->texco & TEXCO_GLOB){
1094                                 VECCOPY(texvec,vec);
1095                         }
1096                         else if(mtex->texco & TEXCO_UV && uvco){
1097                                 int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname);
1098                                 if(uv_index<0)
1099                                         uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
1100
1101                                 uv_index-=CustomData_get_layer_index(&dm->faceData,CD_MTFACE);
1102
1103                                 texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
1104                                 texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
1105                                 texvec[2]=0.0f;
1106                         }
1107                         else if(orco) {
1108                                 VECCOPY(texvec, orco);
1109                         }
1110
1111                         externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
1112
1113                         //yn= tin*mtex->colfac;
1114                         //zn= tin*mtex->varfac;
1115                         if(mtex->mapto & MAP_COL) {
1116                                 tex[0]=tr;
1117                                 tex[1]=tg;
1118                                 tex[2]=tb;
1119                                 out[0]=har->r;
1120                                 out[1]=har->g;
1121                                 out[2]=har->b;
1122
1123                                 texture_rgb_blend(in,tex,out,tin,mtex->colfac,mtex->blendtype);
1124                         //      zn= 1.0-yn;
1125                                 //har->r= (yn*tr+ zn*ma->r);
1126                                 //har->g= (yn*tg+ zn*ma->g);
1127                                 //har->b= (yn*tb+ zn*ma->b);
1128                                 har->r= in[0];
1129                                 har->g= in[1];
1130                                 har->b= in[2];
1131                         }
1132                         if(mtex->mapto & MAP_ALPHA)
1133                                 har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_ALPHA);
1134                         if(mtex->mapto & MAP_HAR)
1135                                 har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_HAR);
1136                         if(mtex->mapto & MAP_RAYMIRR)
1137                                 har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->varfac,mtex->blendtype,mtex->maptoneg & MAP_RAYMIRR);
1138                         /* now what on earth is this good for?? */
1139                         //if(mtex->texco & 16) {
1140                         //      har->alfa= tin;
1141                         //}
1142                 }
1143
1144         return har;
1145 }
1146
1147 /* -------------------------- operations on entire database ----------------------- */
1148
1149 /* ugly function for halos in panorama */
1150 static int panotestclip(Render *re, int do_pano, float *v)
1151 {
1152         /* to be used for halos en infos */
1153         float abs4;
1154         short c=0;
1155
1156         if(do_pano==0) return testclip(v);
1157
1158         abs4= fabs(v[3]);
1159
1160         if(v[2]< -abs4) c=16;           /* this used to be " if(v[2]<0) ", see clippz() */
1161         else if(v[2]> abs4) c+= 32;
1162
1163         if( v[1]>abs4) c+=4;
1164         else if( v[1]< -abs4) c+=8;
1165
1166         abs4*= re->xparts;
1167         if( v[0]>abs4) c+=2;
1168         else if( v[0]< -abs4) c+=1;
1169
1170         return c;
1171 }
1172
1173 /*
1174   This adds the hcs coordinates to vertices. It iterates over all
1175   vertices, halos and faces. After the conversion, we clip in hcs.
1176
1177   Elsewhere, all primites are converted to vertices. 
1178   Called in 
1179   - envmapping (envmap.c)
1180   - shadow buffering (shadbuf.c)
1181 */
1182
1183 void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *),  int do_pano, float xoffs, int do_buckets)
1184 {
1185         ObjectRen *obr;
1186         HaloRen *har = NULL;
1187         float zn, vec[3], hoco[4];
1188         int a;
1189
1190         if(do_pano) {
1191                 float panophi= xoffs;
1192                 
1193                 re->panosi= sin(panophi);
1194                 re->panoco= cos(panophi);
1195         }
1196
1197         for(obr=re->objecttable.first; obr; obr=obr->next) {
1198                 /* calculate view coordinates (and zbuffer value) */
1199                 for(a=0; a<obr->tothalo; a++) {
1200                         if((a & 255)==0) har= obr->bloha[a>>8];
1201                         else har++;
1202
1203                         if(do_pano) {
1204                                 vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
1205                                 vec[1]= har->co[1];
1206                                 vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
1207                         }
1208                         else {
1209                                 VECCOPY(vec, har->co);
1210                         }
1211
1212                         projectfunc(vec, re->winmat, hoco);
1213                         
1214                         /* we clip halos less critical, but not for the Z */
1215                         hoco[0]*= 0.5;
1216                         hoco[1]*= 0.5;
1217                         
1218                         if( panotestclip(re, do_pano, hoco) ) {
1219                                 har->miny= har->maxy= -10000;   /* that way render clips it */
1220                         }
1221                         else if(hoco[3]<0.0) {
1222                                 har->miny= har->maxy= -10000;   /* render clips it */
1223                         }
1224                         else /* do the projection...*/
1225                         {
1226                                 /* bring back hocos */
1227                                 hoco[0]*= 2.0;
1228                                 hoco[1]*= 2.0;
1229                                 
1230                                 zn= hoco[3];
1231                                 har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
1232                                 har->ys= 0.5*re->winy*(1.0+hoco[1]/zn);
1233                         
1234                                 /* this should be the zbuffer coordinate */
1235                                 har->zs= 0x7FFFFF*(hoco[2]/zn);
1236                                 /* taking this from the face clip functions? seems ok... */
1237                                 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
1238                                 
1239                                 vec[0]+= har->hasize;
1240                                 projectfunc(vec, re->winmat, hoco);
1241                                 vec[0]-= har->hasize;
1242                                 zn= hoco[3];
1243                                 har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn));
1244                         
1245                                 /* this clip is not really OK, to prevent stars to become too large */
1246                                 if(har->type & HA_ONLYSKY) {
1247                                         if(har->rad>3.0) har->rad= 3.0;
1248                                 }
1249                         
1250                                 har->radsq= har->rad*har->rad;
1251                         
1252                                 har->miny= har->ys - har->rad/re->ycor;
1253                                 har->maxy= har->ys + har->rad/re->ycor;
1254                         
1255                                 /* the Zd value is still not really correct for pano */
1256                         
1257                                 vec[2]-= har->hasize;   /* z negative, otherwise it's clipped */
1258                                 projectfunc(vec, re->winmat, hoco);
1259                                 zn= hoco[3];
1260                                 zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
1261                                 har->zd= CLAMPIS(zn, 0, INT_MAX);
1262                         
1263                         }
1264                         
1265                 }
1266         }
1267
1268         project_strands(re, projectfunc, do_pano, do_buckets);
1269 }
1270
1271 /* ------------------------------------------------------------------------- */
1272
1273 ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
1274 {
1275         ObjectInstanceRen *obi;
1276         float mat3[3][3];
1277
1278         obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen");
1279         obi->obr= obr;
1280         obi->ob= ob;
1281         obi->par= par;
1282         obi->index= index;
1283         obi->psysindex= psysindex;
1284
1285         if(mat) {
1286                 Mat4CpyMat4(obi->mat, mat);
1287                 Mat3CpyMat4(mat3, mat);
1288                 Mat3Inv(obi->imat, mat3);
1289                 obi->flag |= R_DUPLI_TRANSFORMED;
1290         }
1291
1292         BLI_addtail(&re->instancetable, obi);
1293
1294         return obi;
1295 }
1296
1297 void RE_makeRenderInstances(Render *re)
1298 {
1299         ObjectInstanceRen *obi, *oldobi;
1300         ListBase newlist;
1301         int tot;
1302
1303         /* convert list of object instances to an array for index based lookup */
1304         tot= BLI_countlist(&re->instancetable);
1305         re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
1306         re->totinstance= tot;
1307         newlist.first= newlist.last= NULL;
1308
1309         obi= re->objectinstance;
1310         for(oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
1311                 *obi= *oldobi;
1312
1313                 if(obi->obr) {
1314                         obi->prev= obi->next= NULL;
1315                         BLI_addtail(&newlist, obi);
1316                         obi++;
1317                 }
1318                 else
1319                         re->totinstance--;
1320         }
1321
1322         BLI_freelistN(&re->instancetable);
1323         re->instancetable= newlist;
1324 }
1325