|
Blender
V2.59
|
00001 /* 00002 * $Id: renderdatabase.c 37667 2011-06-20 15:17:02Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): 2004-2006, Blender Foundation, full recode 00024 * 00025 * ***** END GPL/BL DUAL LICENSE BLOCK ***** 00026 */ 00027 00033 /* 00034 * Storage, retrieval and query of render specific data. 00035 * 00036 * All data from a Blender scene is converted by the renderconverter/ 00037 * into a special format that is used by the render module to make 00038 * images out of. These functions interface to the render-specific 00039 * database. 00040 * 00041 * The blo{ha/ve/vl} arrays store pointers to blocks of 256 data 00042 * entries each. 00043 * 00044 * The index of an entry is >>8 (the highest 24 * bits), to find an 00045 * offset in a 256-entry block. 00046 * 00047 * - If the 256-entry block entry has an entry in the 00048 * vertnodes/vlaknodes/bloha array of the current block, the i-th entry in 00049 * that block is allocated to this entry. 00050 * 00051 * - If the entry has no block allocated for it yet, memory is 00052 * allocated. 00053 * 00054 * The pointer to the correct entry is returned. Memory is guarateed 00055 * to exist (as long as the malloc does not break). Since guarded 00056 * allocation is used, memory _must_ be available. Otherwise, an 00057 * exit(0) would occur. 00058 * 00059 */ 00060 00061 #include <limits.h> 00062 #include <math.h> 00063 #include <string.h> 00064 00065 #include "MEM_guardedalloc.h" 00066 00067 00068 #include "BLI_math.h" 00069 #include "BLI_blenlib.h" 00070 #include "BLI_utildefines.h" 00071 #include "BLI_ghash.h" 00072 #include "BLI_memarena.h" 00073 00074 #include "DNA_material_types.h" 00075 #include "DNA_mesh_types.h" 00076 #include "DNA_meshdata_types.h" 00077 #include "DNA_texture_types.h" 00078 00079 #include "BKE_customdata.h" 00080 #include "BKE_texture.h" 00081 #include "BKE_DerivedMesh.h" 00082 00083 #include "RE_render_ext.h" /* externtex */ 00084 00085 #include "rayobject.h" 00086 #include "renderpipeline.h" 00087 #include "render_types.h" 00088 #include "renderdatabase.h" 00089 #include "texture.h" 00090 #include "strand.h" 00091 #include "zbuf.h" 00092 00093 /* ------------------------------------------------------------------------- */ 00094 00095 /* More dynamic allocation of options for render vertices and faces, so we dont 00096 have to reserve this space inside vertices. 00097 Important; vertices and faces, should have been created already (to get tables 00098 checked) that's a reason why the calls demand VertRen/VlakRen * as arg, not 00099 the index */ 00100 00101 /* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */ 00102 00103 #define RE_STICKY_ELEMS 2 00104 #define RE_STRESS_ELEMS 1 00105 #define RE_RAD_ELEMS 4 00106 #define RE_STRAND_ELEMS 1 00107 #define RE_TANGENT_ELEMS 3 00108 #define RE_STRESS_ELEMS 1 00109 #define RE_WINSPEED_ELEMS 4 00110 #define RE_MTFACE_ELEMS 1 00111 #define RE_MCOL_ELEMS 4 00112 #define RE_UV_ELEMS 2 00113 #define RE_SURFNOR_ELEMS 3 00114 #define RE_RADFACE_ELEMS 1 00115 #define RE_SIMPLIFY_ELEMS 2 00116 #define RE_FACE_ELEMS 1 00117 #define RE_NMAP_TANGENT_ELEMS 16 00118 00119 float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify) 00120 { 00121 float *sticky; 00122 int nr= ver->index>>8; 00123 00124 sticky= obr->vertnodes[nr].sticky; 00125 if(sticky==NULL) { 00126 if(verify) 00127 sticky= obr->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table"); 00128 else 00129 return NULL; 00130 } 00131 return sticky + (ver->index & 255)*RE_STICKY_ELEMS; 00132 } 00133 00134 float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify) 00135 { 00136 float *stress; 00137 int nr= ver->index>>8; 00138 00139 stress= obr->vertnodes[nr].stress; 00140 if(stress==NULL) { 00141 if(verify) 00142 stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table"); 00143 else 00144 return NULL; 00145 } 00146 return stress + (ver->index & 255)*RE_STRESS_ELEMS; 00147 } 00148 00149 /* this one callocs! */ 00150 float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify) 00151 { 00152 float *rad; 00153 int nr= ver->index>>8; 00154 00155 rad= obr->vertnodes[nr].rad; 00156 if(rad==NULL) { 00157 if(verify) 00158 rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table"); 00159 else 00160 return NULL; 00161 } 00162 return rad + (ver->index & 255)*RE_RAD_ELEMS; 00163 } 00164 00165 float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify) 00166 { 00167 float *strand; 00168 int nr= ver->index>>8; 00169 00170 strand= obr->vertnodes[nr].strand; 00171 if(strand==NULL) { 00172 if(verify) 00173 strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table"); 00174 else 00175 return NULL; 00176 } 00177 return strand + (ver->index & 255)*RE_STRAND_ELEMS; 00178 } 00179 00180 /* needs calloc */ 00181 float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify) 00182 { 00183 float *tangent; 00184 int nr= ver->index>>8; 00185 00186 tangent= obr->vertnodes[nr].tangent; 00187 if(tangent==NULL) { 00188 if(verify) 00189 tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); 00190 else 00191 return NULL; 00192 } 00193 return tangent + (ver->index & 255)*RE_TANGENT_ELEMS; 00194 } 00195 00196 /* needs calloc! not all renderverts have them */ 00197 /* also winspeed is exception, it is stored per instance */ 00198 float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify) 00199 { 00200 float *winspeed; 00201 int totvector; 00202 00203 winspeed= obi->vectors; 00204 if(winspeed==NULL) { 00205 if(verify) { 00206 totvector= obi->obr->totvert + obi->obr->totstrand; 00207 winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table"); 00208 } 00209 else 00210 return NULL; 00211 } 00212 return winspeed + ver->index*RE_WINSPEED_ELEMS; 00213 } 00214 00215 VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver) 00216 { 00217 VertRen *v1= RE_findOrAddVert(obr, obr->totvert++); 00218 float *fp1, *fp2; 00219 int index= v1->index; 00220 00221 *v1= *ver; 00222 v1->index= index; 00223 00224 fp1= RE_vertren_get_sticky(obr, ver, 0); 00225 if(fp1) { 00226 fp2= RE_vertren_get_sticky(obr, v1, 1); 00227 memcpy(fp2, fp1, RE_STICKY_ELEMS*sizeof(float)); 00228 } 00229 fp1= RE_vertren_get_stress(obr, ver, 0); 00230 if(fp1) { 00231 fp2= RE_vertren_get_stress(obr, v1, 1); 00232 memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float)); 00233 } 00234 fp1= RE_vertren_get_rad(obr, ver, 0); 00235 if(fp1) { 00236 fp2= RE_vertren_get_rad(obr, v1, 1); 00237 memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float)); 00238 } 00239 fp1= RE_vertren_get_strand(obr, ver, 0); 00240 if(fp1) { 00241 fp2= RE_vertren_get_strand(obr, v1, 1); 00242 memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float)); 00243 } 00244 fp1= RE_vertren_get_tangent(obr, ver, 0); 00245 if(fp1) { 00246 fp2= RE_vertren_get_tangent(obr, v1, 1); 00247 memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float)); 00248 } 00249 return v1; 00250 } 00251 00252 VertRen *RE_findOrAddVert(ObjectRen *obr, int nr) 00253 { 00254 VertTableNode *temp; 00255 VertRen *v; 00256 int a; 00257 00258 if(nr<0) { 00259 printf("error in findOrAddVert: %d\n",nr); 00260 return NULL; 00261 } 00262 a= nr>>8; 00263 00264 if (a>=obr->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ 00265 temp= obr->vertnodes; 00266 00267 obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE) , "vertnodes"); 00268 if(temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode)); 00269 memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode)); 00270 00271 obr->vertnodeslen+=TABLEINITSIZE; 00272 if(temp) MEM_freeN(temp); 00273 } 00274 00275 v= obr->vertnodes[a].vert; 00276 if(v==NULL) { 00277 int i; 00278 00279 v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert"); 00280 obr->vertnodes[a].vert= v; 00281 00282 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) { 00283 v[a].index= i; 00284 } 00285 } 00286 v+= (nr & 255); 00287 return v; 00288 } 00289 00290 /* ------------------------------------------------------------------------ */ 00291 00292 MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify) 00293 { 00294 VlakTableNode *node; 00295 int nr= vlr->index>>8, vlakindex= (vlr->index&255); 00296 int index= (n<<8) + vlakindex; 00297 00298 node= &obr->vlaknodes[nr]; 00299 00300 if(verify) { 00301 if(n>=node->totmtface) { 00302 MTFace *mtface= node->mtface; 00303 int size= (n+1)*256; 00304 00305 node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface"); 00306 00307 if(mtface) { 00308 size= node->totmtface*256; 00309 memcpy(node->mtface, mtface, size*sizeof(MTFace)); 00310 MEM_freeN(mtface); 00311 } 00312 00313 node->totmtface= n+1; 00314 } 00315 } 00316 else { 00317 if(n>=node->totmtface) 00318 return NULL; 00319 00320 if(name) *name= obr->mtface[n]; 00321 } 00322 00323 return node->mtface + index; 00324 } 00325 00326 MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify) 00327 { 00328 VlakTableNode *node; 00329 int nr= vlr->index>>8, vlakindex= (vlr->index&255); 00330 int index= (n<<8) + vlakindex; 00331 00332 node= &obr->vlaknodes[nr]; 00333 00334 if(verify) { 00335 if(n>=node->totmcol) { 00336 MCol *mcol= node->mcol; 00337 int size= (n+1)*256; 00338 00339 node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol"); 00340 00341 if(mcol) { 00342 size= node->totmcol*256; 00343 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS); 00344 MEM_freeN(mcol); 00345 } 00346 00347 node->totmcol= n+1; 00348 } 00349 } 00350 else { 00351 if(n>=node->totmcol) 00352 return NULL; 00353 00354 if(name) *name= obr->mcol[n]; 00355 } 00356 00357 return node->mcol + index*RE_MCOL_ELEMS; 00358 } 00359 00360 float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify) 00361 { 00362 float *surfnor; 00363 int nr= vlak->index>>8; 00364 00365 surfnor= obr->vlaknodes[nr].surfnor; 00366 if(surfnor==NULL) { 00367 if(verify) 00368 surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table"); 00369 else 00370 return NULL; 00371 } 00372 return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS; 00373 } 00374 00375 float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int verify) 00376 { 00377 float *tangent; 00378 int nr= vlak->index>>8; 00379 00380 tangent= obr->vlaknodes[nr].tangent; 00381 if(tangent==NULL) { 00382 if(verify) 00383 tangent= obr->vlaknodes[nr].tangent= MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table"); 00384 else 00385 return NULL; 00386 } 00387 return tangent + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS; 00388 } 00389 00390 RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify) 00391 { 00392 RadFace **radface; 00393 int nr= vlak->index>>8; 00394 00395 radface= obr->vlaknodes[nr].radface; 00396 if(radface==NULL) { 00397 if(verify) 00398 radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table"); 00399 else 00400 return NULL; 00401 } 00402 return radface + (vlak->index & 255)*RE_RADFACE_ELEMS; 00403 } 00404 00405 VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) 00406 { 00407 VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++); 00408 MTFace *mtface, *mtface1; 00409 MCol *mcol, *mcol1; 00410 float *surfnor, *surfnor1, *tangent, *tangent1; 00411 RadFace **radface, **radface1; 00412 int i, index = vlr1->index; 00413 char *name; 00414 00415 *vlr1= *vlr; 00416 vlr1->index= index; 00417 00418 for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) { 00419 mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1); 00420 memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS); 00421 } 00422 00423 for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) { 00424 mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1); 00425 memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS); 00426 } 00427 00428 surfnor= RE_vlakren_get_surfnor(obr, vlr, 0); 00429 if(surfnor) { 00430 surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1); 00431 VECCOPY(surfnor1, surfnor); 00432 } 00433 00434 tangent= RE_vlakren_get_nmap_tangent(obr, vlr, 0); 00435 if(tangent) { 00436 tangent1= RE_vlakren_get_nmap_tangent(obr, vlr1, 1); 00437 memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS); 00438 } 00439 00440 radface= RE_vlakren_get_radface(obr, vlr, 0); 00441 if(radface) { 00442 radface1= RE_vlakren_get_radface(obr, vlr1, 1); 00443 *radface1= *radface; 00444 } 00445 00446 return vlr1; 00447 } 00448 00449 void RE_vlakren_get_normal(Render *UNUSED(re), ObjectInstanceRen *obi, VlakRen *vlr, float *nor) 00450 { 00451 float (*nmat)[3]= obi->nmat; 00452 00453 if(obi->flag & R_TRANSFORMED) { 00454 VECCOPY(nor, vlr->n); 00455 00456 mul_m3_v3(nmat, nor); 00457 normalize_v3(nor); 00458 } 00459 else 00460 VECCOPY(nor, vlr->n); 00461 } 00462 00463 void RE_set_customdata_names(ObjectRen *obr, CustomData *data) 00464 { 00465 /* CustomData layer names are stored per object here, because the 00466 DerivedMesh which stores the layers is freed */ 00467 00468 CustomDataLayer *layer; 00469 int numtf = 0, numcol = 0, i, mtfn, mcn; 00470 00471 if (CustomData_has_layer(data, CD_MTFACE)) { 00472 numtf= CustomData_number_of_layers(data, CD_MTFACE); 00473 obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames"); 00474 } 00475 00476 if (CustomData_has_layer(data, CD_MCOL)) { 00477 numcol= CustomData_number_of_layers(data, CD_MCOL); 00478 obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames"); 00479 } 00480 00481 for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) { 00482 layer= &data->layers[i]; 00483 00484 if (layer->type == CD_MTFACE) { 00485 strcpy(obr->mtface[mtfn++], layer->name); 00486 obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf); 00487 obr->bakemtface= layer->active; 00488 } 00489 else if (layer->type == CD_MCOL) { 00490 strcpy(obr->mcol[mcn++], layer->name); 00491 obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol); 00492 } 00493 } 00494 } 00495 00496 VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr) 00497 { 00498 VlakTableNode *temp; 00499 VlakRen *v; 00500 int a; 00501 00502 if(nr<0) { 00503 printf("error in findOrAddVlak: %d\n",nr); 00504 return obr->vlaknodes[0].vlak; 00505 } 00506 a= nr>>8; 00507 00508 if (a>=obr->vlaknodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ 00509 temp= obr->vlaknodes; 00510 00511 obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE) , "vlaknodes"); 00512 if(temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode)); 00513 memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode)); 00514 00515 obr->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ 00516 if(temp) MEM_freeN(temp); 00517 } 00518 00519 v= obr->vlaknodes[a].vlak; 00520 00521 if(v==NULL) { 00522 int i; 00523 00524 v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak"); 00525 obr->vlaknodes[a].vlak= v; 00526 00527 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) 00528 v[a].index= i; 00529 } 00530 v+= (nr & 255); 00531 return v; 00532 } 00533 00534 /* ------------------------------------------------------------------------ */ 00535 00536 float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify) 00537 { 00538 float *surfnor; 00539 int nr= strand->index>>8; 00540 00541 surfnor= obr->strandnodes[nr].surfnor; 00542 if(surfnor==NULL) { 00543 if(verify) 00544 surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table"); 00545 else 00546 return NULL; 00547 } 00548 return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS; 00549 } 00550 00551 float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify) 00552 { 00553 StrandTableNode *node; 00554 int nr= strand->index>>8, strandindex= (strand->index&255); 00555 int index= (n<<8) + strandindex; 00556 00557 node= &obr->strandnodes[nr]; 00558 00559 if(verify) { 00560 if(n>=node->totuv) { 00561 float *uv= node->uv; 00562 int size= (n+1)*256; 00563 00564 node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table"); 00565 00566 if(uv) { 00567 size= node->totuv*256; 00568 memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS); 00569 MEM_freeN(uv); 00570 } 00571 00572 node->totuv= n+1; 00573 } 00574 } 00575 else { 00576 if(n>=node->totuv) 00577 return NULL; 00578 00579 if(name) *name= obr->mtface[n]; 00580 } 00581 00582 return node->uv + index*RE_UV_ELEMS; 00583 } 00584 00585 MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify) 00586 { 00587 StrandTableNode *node; 00588 int nr= strand->index>>8, strandindex= (strand->index&255); 00589 int index= (n<<8) + strandindex; 00590 00591 node= &obr->strandnodes[nr]; 00592 00593 if(verify) { 00594 if(n>=node->totmcol) { 00595 MCol *mcol= node->mcol; 00596 int size= (n+1)*256; 00597 00598 node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table"); 00599 00600 if(mcol) { 00601 size= node->totmcol*256; 00602 memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS); 00603 MEM_freeN(mcol); 00604 } 00605 00606 node->totmcol= n+1; 00607 } 00608 } 00609 else { 00610 if(n>=node->totmcol) 00611 return NULL; 00612 00613 if(name) *name= obr->mcol[n]; 00614 } 00615 00616 return node->mcol + index*RE_MCOL_ELEMS; 00617 } 00618 00619 float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify) 00620 { 00621 float *simplify; 00622 int nr= strand->index>>8; 00623 00624 simplify= obr->strandnodes[nr].simplify; 00625 if(simplify==NULL) { 00626 if(verify) 00627 simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table"); 00628 else 00629 return NULL; 00630 } 00631 return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS; 00632 } 00633 00634 int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify) 00635 { 00636 int *face; 00637 int nr= strand->index>>8; 00638 00639 face= obr->strandnodes[nr].face; 00640 if(face==NULL) { 00641 if(verify) 00642 face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table"); 00643 else 00644 return NULL; 00645 } 00646 return face + (strand->index & 255)*RE_FACE_ELEMS; 00647 } 00648 00649 /* winspeed is exception, it is stored per instance */ 00650 float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify) 00651 { 00652 float *winspeed; 00653 int totvector; 00654 00655 winspeed= obi->vectors; 00656 if(winspeed==NULL) { 00657 if(verify) { 00658 totvector= obi->obr->totvert + obi->obr->totstrand; 00659 winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table"); 00660 } 00661 else 00662 return NULL; 00663 } 00664 return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS; 00665 } 00666 00667 StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr) 00668 { 00669 StrandTableNode *temp; 00670 StrandRen *v; 00671 int a; 00672 00673 if(nr<0) { 00674 printf("error in findOrAddStrand: %d\n",nr); 00675 return obr->strandnodes[0].strand; 00676 } 00677 a= nr>>8; 00678 00679 if (a>=obr->strandnodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ 00680 temp= obr->strandnodes; 00681 00682 obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE) , "strandnodes"); 00683 if(temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode)); 00684 memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode)); 00685 00686 obr->strandnodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ 00687 if(temp) MEM_freeN(temp); 00688 } 00689 00690 v= obr->strandnodes[a].strand; 00691 00692 if(v==NULL) { 00693 int i; 00694 00695 v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen),"findOrAddStrand"); 00696 obr->strandnodes[a].strand= v; 00697 00698 for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) 00699 v[a].index= i; 00700 } 00701 v+= (nr & 255); 00702 return v; 00703 } 00704 00705 StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert) 00706 { 00707 StrandBuffer *strandbuf; 00708 00709 strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer"); 00710 strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert"); 00711 strandbuf->totvert= totvert; 00712 strandbuf->obr= obr; 00713 00714 obr->strandbuf= strandbuf; 00715 00716 return strandbuf; 00717 } 00718 00719 /* ------------------------------------------------------------------------ */ 00720 00721 ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay) 00722 { 00723 ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct"); 00724 00725 BLI_addtail(&re->objecttable, obr); 00726 obr->ob= ob; 00727 obr->par= par; 00728 obr->index= index; 00729 obr->psysindex= psysindex; 00730 obr->lay= lay; 00731 00732 return obr; 00733 } 00734 00735 void free_renderdata_vertnodes(VertTableNode *vertnodes) 00736 { 00737 int a; 00738 00739 if(vertnodes==NULL) return; 00740 00741 for(a=0; vertnodes[a].vert; a++) { 00742 MEM_freeN(vertnodes[a].vert); 00743 00744 if(vertnodes[a].rad) 00745 MEM_freeN(vertnodes[a].rad); 00746 if(vertnodes[a].sticky) 00747 MEM_freeN(vertnodes[a].sticky); 00748 if(vertnodes[a].strand) 00749 MEM_freeN(vertnodes[a].strand); 00750 if(vertnodes[a].tangent) 00751 MEM_freeN(vertnodes[a].tangent); 00752 if(vertnodes[a].stress) 00753 MEM_freeN(vertnodes[a].stress); 00754 if(vertnodes[a].winspeed) 00755 MEM_freeN(vertnodes[a].winspeed); 00756 } 00757 00758 MEM_freeN(vertnodes); 00759 } 00760 00761 void free_renderdata_vlaknodes(VlakTableNode *vlaknodes) 00762 { 00763 int a; 00764 00765 if(vlaknodes==NULL) return; 00766 00767 for(a=0; vlaknodes[a].vlak; a++) { 00768 MEM_freeN(vlaknodes[a].vlak); 00769 00770 if(vlaknodes[a].mtface) 00771 MEM_freeN(vlaknodes[a].mtface); 00772 if(vlaknodes[a].mcol) 00773 MEM_freeN(vlaknodes[a].mcol); 00774 if(vlaknodes[a].surfnor) 00775 MEM_freeN(vlaknodes[a].surfnor); 00776 if(vlaknodes[a].tangent) 00777 MEM_freeN(vlaknodes[a].tangent); 00778 if(vlaknodes[a].radface) 00779 MEM_freeN(vlaknodes[a].radface); 00780 } 00781 00782 MEM_freeN(vlaknodes); 00783 } 00784 00785 static void free_renderdata_strandnodes(StrandTableNode *strandnodes) 00786 { 00787 int a; 00788 00789 if(strandnodes==NULL) return; 00790 00791 for(a=0; strandnodes[a].strand; a++) { 00792 MEM_freeN(strandnodes[a].strand); 00793 00794 if(strandnodes[a].uv) 00795 MEM_freeN(strandnodes[a].uv); 00796 if(strandnodes[a].mcol) 00797 MEM_freeN(strandnodes[a].mcol); 00798 if(strandnodes[a].winspeed) 00799 MEM_freeN(strandnodes[a].winspeed); 00800 if(strandnodes[a].surfnor) 00801 MEM_freeN(strandnodes[a].surfnor); 00802 if(strandnodes[a].simplify) 00803 MEM_freeN(strandnodes[a].simplify); 00804 if(strandnodes[a].face) 00805 MEM_freeN(strandnodes[a].face); 00806 } 00807 00808 MEM_freeN(strandnodes); 00809 } 00810 00811 void free_renderdata_tables(Render *re) 00812 { 00813 ObjectInstanceRen *obi; 00814 ObjectRen *obr; 00815 StrandBuffer *strandbuf; 00816 int a=0; 00817 00818 for(obr=re->objecttable.first; obr; obr=obr->next) { 00819 if(obr->vertnodes) { 00820 free_renderdata_vertnodes(obr->vertnodes); 00821 obr->vertnodes= NULL; 00822 obr->vertnodeslen= 0; 00823 } 00824 00825 if(obr->vlaknodes) { 00826 free_renderdata_vlaknodes(obr->vlaknodes); 00827 obr->vlaknodes= NULL; 00828 obr->vlaknodeslen= 0; 00829 obr->totvlak= 0; 00830 } 00831 00832 if(obr->bloha) { 00833 for(a=0; obr->bloha[a]; a++) 00834 MEM_freeN(obr->bloha[a]); 00835 00836 MEM_freeN(obr->bloha); 00837 obr->bloha= NULL; 00838 obr->blohalen= 0; 00839 } 00840 00841 if(obr->strandnodes) { 00842 free_renderdata_strandnodes(obr->strandnodes); 00843 obr->strandnodes= NULL; 00844 obr->strandnodeslen= 0; 00845 } 00846 00847 strandbuf= obr->strandbuf; 00848 if(strandbuf) { 00849 if(strandbuf->vert) MEM_freeN(strandbuf->vert); 00850 if(strandbuf->bound) MEM_freeN(strandbuf->bound); 00851 MEM_freeN(strandbuf); 00852 } 00853 00854 if(obr->mtface) 00855 MEM_freeN(obr->mtface); 00856 if(obr->mcol) 00857 MEM_freeN(obr->mcol); 00858 00859 if(obr->rayfaces) 00860 { 00861 MEM_freeN(obr->rayfaces); 00862 obr->rayfaces = NULL; 00863 } 00864 if(obr->rayprimitives) 00865 { 00866 MEM_freeN(obr->rayprimitives); 00867 obr->rayprimitives = NULL; 00868 } 00869 if(obr->raytree) 00870 { 00871 RE_rayobject_free(obr->raytree); 00872 obr->raytree = NULL; 00873 } 00874 } 00875 00876 if(re->objectinstance) { 00877 for(obi=re->instancetable.first; obi; obi=obi->next) 00878 { 00879 if(obi->vectors) 00880 MEM_freeN(obi->vectors); 00881 00882 if(obi->raytree) 00883 RE_rayobject_free(obi->raytree); 00884 } 00885 00886 MEM_freeN(re->objectinstance); 00887 re->objectinstance= NULL; 00888 re->totinstance= 0; 00889 re->instancetable.first= re->instancetable.last= NULL; 00890 } 00891 00892 if(re->sortedhalos) { 00893 MEM_freeN(re->sortedhalos); 00894 re->sortedhalos= NULL; 00895 } 00896 00897 BLI_freelistN(&re->customdata_names); 00898 BLI_freelistN(&re->objecttable); 00899 BLI_freelistN(&re->instancetable); 00900 } 00901 00902 /* ------------------------------------------------------------------------ */ 00903 00904 HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr) 00905 { 00906 HaloRen *h, **temp; 00907 int a; 00908 00909 if(nr<0) { 00910 printf("error in findOrAddHalo: %d\n",nr); 00911 return NULL; 00912 } 00913 a= nr>>8; 00914 00915 if (a>=obr->blohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ 00916 //printf("Allocating %i more halo groups. %i total.\n", 00917 // TABLEINITSIZE, obr->blohalen+TABLEINITSIZE ); 00918 temp=obr->bloha; 00919 00920 obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE) , "Bloha"); 00921 if(temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*)); 00922 memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*)); 00923 obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ 00924 if(temp) MEM_freeN(temp); 00925 } 00926 00927 h= obr->bloha[a]; 00928 if(h==NULL) { 00929 h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo"); 00930 obr->bloha[a]= h; 00931 } 00932 h+= (nr & 255); 00933 return h; 00934 } 00935 00936 /* ------------------------------------------------------------------------- */ 00937 00938 HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, float *vec1, 00939 float *orco, float hasize, float vectsize, int seed) 00940 { 00941 HaloRen *har; 00942 MTex *mtex; 00943 float tin, tr, tg, tb, ta; 00944 float xn, yn, zn, texvec[3], hoco[4], hoco1[4]; 00945 00946 if(hasize==0.0) return NULL; 00947 00948 projectverto(vec, re->winmat, hoco); 00949 if(hoco[3]==0.0) return NULL; 00950 if(vec1) { 00951 projectverto(vec1, re->winmat, hoco1); 00952 if(hoco1[3]==0.0) return NULL; 00953 } 00954 00955 har= RE_findOrAddHalo(obr, obr->tothalo++); 00956 VECCOPY(har->co, vec); 00957 har->hasize= hasize; 00958 00959 /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ 00960 /* we do it here for sorting of halos */ 00961 zn= hoco[3]; 00962 har->xs= 0.5*re->winx*(hoco[0]/zn); 00963 har->ys= 0.5*re->winy*(hoco[1]/zn); 00964 har->zs= 0x7FFFFF*(hoco[2]/zn); 00965 00966 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 00967 00968 /* halovect */ 00969 if(vec1) { 00970 00971 har->type |= HA_VECT; 00972 00973 xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]); 00974 yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]); 00975 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0; 00976 else zn= atan2(yn, xn); 00977 00978 har->sin= sin(zn); 00979 har->cos= cos(zn); 00980 zn= len_v3v3(vec1, vec); 00981 00982 har->hasize= vectsize*zn + (1.0-vectsize)*hasize; 00983 00984 sub_v3_v3v3(har->no, vec, vec1); 00985 normalize_v3(har->no); 00986 } 00987 00988 if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; 00989 00990 har->alfa= ma->alpha; 00991 har->r= ma->r; 00992 har->g= ma->g; 00993 har->b= ma->b; 00994 har->add= (255.0*ma->add); 00995 har->mat= ma; 00996 har->hard= ma->har; 00997 har->seed= seed % 256; 00998 00999 if(ma->mode & MA_STAR) har->starpoints= ma->starc; 01000 if(ma->mode & MA_HALO_LINES) har->linec= ma->linec; 01001 if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; 01002 if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; 01003 01004 01005 if(ma->mtex[0]) { 01006 01007 if( (ma->mode & MA_HALOTEX) ) har->tex= 1; 01008 else if(har->mat->septex & (1<<0)); /* only 1 level textures */ 01009 else { 01010 01011 mtex= ma->mtex[0]; 01012 VECCOPY(texvec, vec); 01013 01014 if(mtex->texco & TEXCO_NORM) { 01015 ; 01016 } 01017 else if(mtex->texco & TEXCO_OBJECT) { 01018 /* texvec[0]+= imatbase->ivec[0]; */ 01019 /* texvec[1]+= imatbase->ivec[1]; */ 01020 /* texvec[2]+= imatbase->ivec[2]; */ 01021 /* mul_m3_v3(imatbase->imat, texvec); */ 01022 } 01023 else { 01024 if(orco) { 01025 VECCOPY(texvec, orco); 01026 } 01027 } 01028 01029 externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0); 01030 01031 yn= tin*mtex->colfac; 01032 zn= tin*mtex->alphafac; 01033 01034 if(mtex->mapto & MAP_COL) { 01035 zn= 1.0-yn; 01036 har->r= (yn*tr+ zn*ma->r); 01037 har->g= (yn*tg+ zn*ma->g); 01038 har->b= (yn*tb+ zn*ma->b); 01039 } 01040 if(mtex->texco & TEXCO_UV) { 01041 har->alfa= tin; 01042 } 01043 if(mtex->mapto & MAP_ALPHA) 01044 har->alfa= tin; 01045 } 01046 } 01047 01048 return har; 01049 } 01050 01051 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, float *vec, float *vec1, 01052 float *orco, float *uvco, float hasize, float vectsize, int seed, float *pa_co) 01053 { 01054 HaloRen *har; 01055 MTex *mtex; 01056 float tin, tr, tg, tb, ta; 01057 float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3]; 01058 int i, hasrgb; 01059 01060 if(hasize==0.0) return NULL; 01061 01062 projectverto(vec, re->winmat, hoco); 01063 if(hoco[3]==0.0) return NULL; 01064 if(vec1) { 01065 projectverto(vec1, re->winmat, hoco1); 01066 if(hoco1[3]==0.0) return NULL; 01067 } 01068 01069 har= RE_findOrAddHalo(obr, obr->tothalo++); 01070 VECCOPY(har->co, vec); 01071 har->hasize= hasize; 01072 01073 /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ 01074 /* we do it here for sorting of halos */ 01075 zn= hoco[3]; 01076 har->xs= 0.5*re->winx*(hoco[0]/zn); 01077 har->ys= 0.5*re->winy*(hoco[1]/zn); 01078 har->zs= 0x7FFFFF*(hoco[2]/zn); 01079 01080 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 01081 01082 /* halovect */ 01083 if(vec1) { 01084 01085 har->type |= HA_VECT; 01086 01087 xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]); 01088 yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]); 01089 if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0; 01090 else zn= atan2(yn, xn); 01091 01092 har->sin= sin(zn); 01093 har->cos= cos(zn); 01094 zn= len_v3v3(vec1, vec)*0.5; 01095 01096 har->hasize= vectsize*zn + (1.0-vectsize)*hasize; 01097 01098 sub_v3_v3v3(har->no, vec, vec1); 01099 normalize_v3(har->no); 01100 } 01101 01102 if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; 01103 01104 har->alfa= ma->alpha; 01105 har->r= ma->r; 01106 har->g= ma->g; 01107 har->b= ma->b; 01108 har->add= (255.0*ma->add); 01109 har->mat= ma; 01110 har->hard= ma->har; 01111 har->seed= seed % 256; 01112 01113 if(ma->mode & MA_STAR) har->starpoints= ma->starc; 01114 if(ma->mode & MA_HALO_LINES) har->linec= ma->linec; 01115 if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; 01116 if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; 01117 01118 if((ma->mode & MA_HALOTEX) && ma->mtex[0]){ 01119 har->tex= 1; 01120 i=1; 01121 } 01122 01123 for(i=0; i<MAX_MTEX; i++) 01124 if(ma->mtex[i] && (ma->septex & (1<<i))==0) { 01125 mtex= ma->mtex[i]; 01126 VECCOPY(texvec, vec); 01127 01128 if(mtex->texco & TEXCO_NORM) { 01129 ; 01130 } 01131 else if(mtex->texco & TEXCO_OBJECT) { 01132 if(mtex->object) 01133 mul_m4_v3(mtex->object->imat_ren,texvec); 01134 } 01135 else if(mtex->texco & TEXCO_GLOB){ 01136 VECCOPY(texvec,vec); 01137 } 01138 else if(mtex->texco & TEXCO_UV && uvco){ 01139 int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname); 01140 if(uv_index<0) 01141 uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE); 01142 01143 uv_index-=CustomData_get_layer_index(&dm->faceData,CD_MTFACE); 01144 01145 texvec[0]=2.0f*uvco[2*uv_index]-1.0f; 01146 texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f; 01147 texvec[2]=0.0f; 01148 } 01149 else if(mtex->texco & TEXCO_PARTICLE) { 01150 /* particle coordinates in range [0,1] */ 01151 texvec[0] = 2.f * pa_co[0] - 1.f; 01152 texvec[1] = 2.f * pa_co[1] - 1.f; 01153 texvec[2] = pa_co[2]; 01154 } 01155 else if(orco) { 01156 VECCOPY(texvec, orco); 01157 } 01158 01159 hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0); 01160 01161 //yn= tin*mtex->colfac; 01162 //zn= tin*mtex->alphafac; 01163 if(mtex->mapto & MAP_COL) { 01164 tex[0]=tr; 01165 tex[1]=tg; 01166 tex[2]=tb; 01167 out[0]=har->r; 01168 out[1]=har->g; 01169 out[2]=har->b; 01170 01171 texture_rgb_blend(in,tex,out,tin,mtex->colfac,mtex->blendtype); 01172 // zn= 1.0-yn; 01173 //har->r= (yn*tr+ zn*ma->r); 01174 //har->g= (yn*tg+ zn*ma->g); 01175 //har->b= (yn*tb+ zn*ma->b); 01176 har->r= in[0]; 01177 har->g= in[1]; 01178 har->b= in[2]; 01179 } 01180 01181 /* alpha returned, so let's use it instead of intensity */ 01182 if(hasrgb) 01183 tin = ta; 01184 01185 if(mtex->mapto & MAP_ALPHA) 01186 har->alfa = texture_value_blend(mtex->def_var,har->alfa,tin,mtex->alphafac,mtex->blendtype); 01187 if(mtex->mapto & MAP_HAR) 01188 har->hard = 1.0+126.0*texture_value_blend(mtex->def_var,((float)har->hard)/127.0,tin,mtex->hardfac,mtex->blendtype); 01189 if(mtex->mapto & MAP_RAYMIRR) 01190 har->hasize = 100.0*texture_value_blend(mtex->def_var,har->hasize/100.0,tin,mtex->raymirrfac,mtex->blendtype); 01191 if(mtex->mapto & MAP_TRANSLU) { 01192 float add = texture_value_blend(mtex->def_var,(float)har->add/255.0,tin,mtex->translfac,mtex->blendtype); 01193 CLAMP(add, 0.f, 1.f); 01194 har->add = 255.0*add; 01195 } 01196 /* now what on earth is this good for?? */ 01197 //if(mtex->texco & 16) { 01198 // har->alfa= tin; 01199 //} 01200 } 01201 01202 return har; 01203 } 01204 01205 /* -------------------------- operations on entire database ----------------------- */ 01206 01207 /* ugly function for halos in panorama */ 01208 static int panotestclip(Render *re, int do_pano, float *v) 01209 { 01210 /* to be used for halos en infos */ 01211 float abs4; 01212 short c=0; 01213 01214 if(do_pano==0) return testclip(v); 01215 01216 abs4= fabs(v[3]); 01217 01218 if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */ 01219 else if(v[2]> abs4) c+= 32; 01220 01221 if( v[1]>abs4) c+=4; 01222 else if( v[1]< -abs4) c+=8; 01223 01224 abs4*= re->xparts; 01225 if( v[0]>abs4) c+=2; 01226 else if( v[0]< -abs4) c+=1; 01227 01228 return c; 01229 } 01230 01231 /* 01232 This adds the hcs coordinates to vertices. It iterates over all 01233 vertices, halos and faces. After the conversion, we clip in hcs. 01234 01235 Elsewhere, all primites are converted to vertices. 01236 Called in 01237 - envmapping (envmap.c) 01238 - shadow buffering (shadbuf.c) 01239 */ 01240 01241 void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) 01242 { 01243 ObjectRen *obr; 01244 HaloRen *har = NULL; 01245 float zn, vec[3], hoco[4]; 01246 int a; 01247 01248 if(do_pano) { 01249 float panophi= xoffs; 01250 01251 re->panosi= sin(panophi); 01252 re->panoco= cos(panophi); 01253 } 01254 01255 for(obr=re->objecttable.first; obr; obr=obr->next) { 01256 /* calculate view coordinates (and zbuffer value) */ 01257 for(a=0; a<obr->tothalo; a++) { 01258 if((a & 255)==0) har= obr->bloha[a>>8]; 01259 else har++; 01260 01261 if(do_pano) { 01262 vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2]; 01263 vec[1]= har->co[1]; 01264 vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2]; 01265 } 01266 else { 01267 VECCOPY(vec, har->co); 01268 } 01269 01270 projectfunc(vec, re->winmat, hoco); 01271 01272 /* we clip halos less critical, but not for the Z */ 01273 hoco[0]*= 0.5; 01274 hoco[1]*= 0.5; 01275 01276 if( panotestclip(re, do_pano, hoco) ) { 01277 har->miny= har->maxy= -10000; /* that way render clips it */ 01278 } 01279 else if(hoco[3]<0.0) { 01280 har->miny= har->maxy= -10000; /* render clips it */ 01281 } 01282 else /* do the projection...*/ 01283 { 01284 /* bring back hocos */ 01285 hoco[0]*= 2.0; 01286 hoco[1]*= 2.0; 01287 01288 zn= hoco[3]; 01289 har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ 01290 har->ys= 0.5*re->winy*(1.0+hoco[1]/zn); 01291 01292 /* this should be the zbuffer coordinate */ 01293 har->zs= 0x7FFFFF*(hoco[2]/zn); 01294 /* taking this from the face clip functions? seems ok... */ 01295 har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); 01296 01297 vec[0]+= har->hasize; 01298 projectfunc(vec, re->winmat, hoco); 01299 vec[0]-= har->hasize; 01300 zn= hoco[3]; 01301 har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn)); 01302 01303 /* this clip is not really OK, to prevent stars to become too large */ 01304 if(har->type & HA_ONLYSKY) { 01305 if(har->rad>3.0) har->rad= 3.0; 01306 } 01307 01308 har->radsq= har->rad*har->rad; 01309 01310 har->miny= har->ys - har->rad/re->ycor; 01311 har->maxy= har->ys + har->rad/re->ycor; 01312 01313 /* the Zd value is still not really correct for pano */ 01314 01315 vec[2]-= har->hasize; /* z negative, otherwise it's clipped */ 01316 projectfunc(vec, re->winmat, hoco); 01317 zn= hoco[3]; 01318 zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn)); 01319 har->zd= CLAMPIS(zn, 0, INT_MAX); 01320 01321 } 01322 01323 } 01324 } 01325 } 01326 01327 /* ------------------------------------------------------------------------- */ 01328 01329 ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay) 01330 { 01331 ObjectInstanceRen *obi; 01332 float mat3[3][3]; 01333 01334 obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen"); 01335 obi->obr= obr; 01336 obi->ob= ob; 01337 obi->par= par; 01338 obi->index= index; 01339 obi->psysindex= psysindex; 01340 obi->lay= lay; 01341 01342 if(mat) { 01343 copy_m4_m4(obi->mat, mat); 01344 copy_m3_m4(mat3, mat); 01345 invert_m3_m3(obi->nmat, mat3); 01346 transpose_m3(obi->nmat); 01347 obi->flag |= R_DUPLI_TRANSFORMED; 01348 } 01349 01350 BLI_addtail(&re->instancetable, obi); 01351 01352 return obi; 01353 } 01354 01355 void RE_makeRenderInstances(Render *re) 01356 { 01357 ObjectInstanceRen *obi, *oldobi; 01358 ListBase newlist; 01359 int tot; 01360 01361 /* convert list of object instances to an array for index based lookup */ 01362 tot= BLI_countlist(&re->instancetable); 01363 re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance"); 01364 re->totinstance= tot; 01365 newlist.first= newlist.last= NULL; 01366 01367 obi= re->objectinstance; 01368 for(oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) { 01369 *obi= *oldobi; 01370 01371 if(obi->obr) { 01372 obi->prev= obi->next= NULL; 01373 BLI_addtail(&newlist, obi); 01374 obi++; 01375 } 01376 else 01377 re->totinstance--; 01378 } 01379 01380 BLI_freelistN(&re->instancetable); 01381 re->instancetable= newlist; 01382 } 01383 01384 int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4]) 01385 { 01386 float mat[4][4], vec[4]; 01387 int a, fl, flag= -1; 01388 01389 copy_m4_m4(mat, winmat); 01390 01391 for(a=0; a<8; a++) { 01392 vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; 01393 vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; 01394 vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; 01395 vec[3]= 1.0; 01396 mul_m4_v4(mat, vec); 01397 01398 fl= 0; 01399 if(bounds) { 01400 if(vec[0] < bounds[0]*vec[3]) fl |= 1; 01401 else if(vec[0] > bounds[1]*vec[3]) fl |= 2; 01402 01403 if(vec[1] > bounds[3]*vec[3]) fl |= 4; 01404 else if(vec[1]< bounds[2]*vec[3]) fl |= 8; 01405 } 01406 else { 01407 if(vec[0] < -vec[3]) fl |= 1; 01408 else if(vec[0] > vec[3]) fl |= 2; 01409 01410 if(vec[1] > vec[3]) fl |= 4; 01411 else if(vec[1] < -vec[3]) fl |= 8; 01412 } 01413 if(vec[2] < -vec[3]) fl |= 16; 01414 else if(vec[2] > vec[3]) fl |= 32; 01415 01416 flag &= fl; 01417 if(flag==0) return 0; 01418 } 01419 01420 return flag; 01421 } 01422