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