|
Blender
V2.59
|
00001 /* 00002 * $Id: envmap.c 37401 2011-06-11 08:55:29Z 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 * Contributors: 2004/2005/2006 Blender Foundation, full recode 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <math.h> 00034 #include <string.h> 00035 00036 /* external modules: */ 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_math.h" 00040 #include "BLI_blenlib.h" 00041 #include "BLI_threads.h" 00042 #include "BLI_utildefines.h" 00043 00044 #include "IMB_imbuf_types.h" 00045 #include "IMB_imbuf.h" /* for rectcpy */ 00046 00047 #include "DNA_group_types.h" 00048 #include "DNA_image_types.h" 00049 #include "DNA_object_types.h" 00050 #include "DNA_scene_types.h" 00051 #include "DNA_texture_types.h" 00052 00053 #include "BKE_library.h" 00054 #include "BKE_main.h" 00055 #include "BKE_image.h" // BKE_write_ibuf 00056 #include "BKE_texture.h" 00057 00058 00059 00060 00061 /* this module */ 00062 #include "render_types.h" 00063 #include "renderpipeline.h" 00064 #include "envmap.h" 00065 #include "rendercore.h" 00066 #include "renderdatabase.h" 00067 #include "texture.h" 00068 #include "zbuf.h" 00069 #include "initrender.h" 00070 00071 00072 /* ------------------------------------------------------------------------- */ 00073 00074 static void envmap_split_ima(EnvMap *env, ImBuf *ibuf) 00075 { 00076 int dx, part; 00077 00078 /* after lock we test cube[1], if set the other thread has done it fine */ 00079 BLI_lock_thread(LOCK_IMAGE); 00080 if(env->cube[1]==NULL) { 00081 00082 BKE_free_envmapdata(env); 00083 00084 dx= ibuf->y; 00085 dx/= 2; 00086 if (3*dx == ibuf->x) { 00087 env->type = ENV_CUBE; 00088 env->ok= ENV_OSA; 00089 } else if (ibuf->x == ibuf->y) { 00090 env->type = ENV_PLANE; 00091 env->ok= ENV_OSA; 00092 } else { 00093 printf("Incorrect envmap size\n"); 00094 env->ok= 0; 00095 env->ima->ok= 0; 00096 } 00097 00098 if(env->ok) { 00099 if (env->type == ENV_CUBE) { 00100 for(part=0; part<6; part++) { 00101 env->cube[part]= IMB_allocImBuf(dx, dx, 24, IB_rect|IB_rectfloat); 00102 } 00103 IMB_float_from_rect(ibuf); 00104 00105 IMB_rectcpy(env->cube[0], ibuf, 00106 0, 0, 0, 0, dx, dx); 00107 IMB_rectcpy(env->cube[1], ibuf, 00108 0, 0, dx, 0, dx, dx); 00109 IMB_rectcpy(env->cube[2], ibuf, 00110 0, 0, 2*dx, 0, dx, dx); 00111 IMB_rectcpy(env->cube[3], ibuf, 00112 0, 0, 0, dx, dx, dx); 00113 IMB_rectcpy(env->cube[4], ibuf, 00114 0, 0, dx, dx, dx, dx); 00115 IMB_rectcpy(env->cube[5], ibuf, 00116 0, 0, 2*dx, dx, dx, dx); 00117 00118 } 00119 else { /* ENV_PLANE */ 00120 env->cube[1]= IMB_dupImBuf(ibuf); 00121 IMB_float_from_rect(env->cube[1]); 00122 } 00123 } 00124 } 00125 BLI_unlock_thread(LOCK_IMAGE); 00126 } 00127 00128 /* ------------------------------------------------------------------------- */ 00129 /* ****************** RENDER ********************** */ 00130 00131 /* copy current render */ 00132 static Render *envmap_render_copy(Render *re, EnvMap *env) 00133 { 00134 Render *envre; 00135 int cuberes; 00136 00137 envre= RE_NewRender("Envmap"); 00138 00139 env->lastsize= re->r.size; 00140 cuberes = (env->cuberes * re->r.size) / 100; 00141 cuberes &= 0xFFFC; 00142 00143 /* this flag has R_ZTRA in it for example */ 00144 envre->flag= re->flag; 00145 00146 /* set up renderdata */ 00147 envre->r= re->r; 00148 envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); 00149 envre->r.layers.first= envre->r.layers.last= NULL; 00150 envre->r.filtertype= 0; 00151 envre->r.xparts= envre->r.yparts= 2; 00152 envre->r.size= 100; 00153 envre->r.yasp= envre->r.xasp= 1; 00154 00155 RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); 00156 envre->scene= re->scene; /* unsure about this... */ 00157 envre->lay= re->lay; 00158 00159 /* view stuff in env render */ 00160 envre->lens= 16.0f; 00161 if(env->type==ENV_PLANE) 00162 envre->lens*= env->viewscale; 00163 envre->ycor= 1.0f; 00164 envre->clipsta= env->clipsta; /* render_scene_set_window() respects this for now */ 00165 envre->clipend= env->clipend; 00166 00167 RE_SetCamera(envre, env->object); 00168 00169 /* callbacks */ 00170 envre->display_draw= re->display_draw; 00171 envre->ddh= re->ddh; 00172 envre->test_break= re->test_break; 00173 envre->tbh= re->tbh; 00174 00175 /* and for the evil stuff; copy the database... */ 00176 envre->totvlak= re->totvlak; 00177 envre->totvert= re->totvert; 00178 envre->tothalo= re->tothalo; 00179 envre->totstrand= re->totstrand; 00180 envre->totlamp= re->totlamp; 00181 envre->sortedhalos= re->sortedhalos; 00182 envre->lights= re->lights; 00183 envre->objecttable= re->objecttable; 00184 envre->customdata_names= re->customdata_names; 00185 envre->raytree= re->raytree; 00186 envre->totinstance= re->totinstance; 00187 envre->instancetable= re->instancetable; 00188 envre->objectinstance= re->objectinstance; 00189 envre->qmcsamplers= re->qmcsamplers; 00190 00191 return envre; 00192 } 00193 00194 static void envmap_free_render_copy(Render *envre) 00195 { 00196 00197 envre->totvlak= 0; 00198 envre->totvert= 0; 00199 envre->tothalo= 0; 00200 envre->totstrand= 0; 00201 envre->totlamp= 0; 00202 envre->totinstance= 0; 00203 envre->sortedhalos= NULL; 00204 envre->lights.first= envre->lights.last= NULL; 00205 envre->objecttable.first= envre->objecttable.last= NULL; 00206 envre->customdata_names.first= envre->customdata_names.last= NULL; 00207 envre->raytree= NULL; 00208 envre->instancetable.first= envre->instancetable.last= NULL; 00209 envre->objectinstance= NULL; 00210 envre->qmcsamplers= NULL; 00211 00212 RE_FreeRender(envre); 00213 } 00214 00215 /* ------------------------------------------------------------------------- */ 00216 00217 static void envmap_transmatrix(float mat[][4], int part) 00218 { 00219 float tmat[4][4], eul[3], rotmat[4][4]; 00220 00221 eul[0]= eul[1]= eul[2]= 0.0; 00222 00223 if(part==0) { /* neg z */ 00224 ; 00225 } else if(part==1) { /* pos z */ 00226 eul[0]= M_PI; 00227 } else if(part==2) { /* pos y */ 00228 eul[0]= M_PI/2.0; 00229 } else if(part==3) { /* neg x */ 00230 eul[0]= M_PI/2.0; 00231 eul[2]= M_PI/2.0; 00232 } else if(part==4) { /* neg y */ 00233 eul[0]= M_PI/2.0; 00234 eul[2]= M_PI; 00235 } else { /* pos x */ 00236 eul[0]= M_PI/2.0; 00237 eul[2]= -M_PI/2.0; 00238 } 00239 00240 copy_m4_m4(tmat, mat); 00241 eul_to_mat4( rotmat,eul); 00242 mul_serie_m4(mat, tmat, rotmat, 00243 0, 0, 0, 00244 0, 0, 0); 00245 } 00246 00247 /* ------------------------------------------------------------------------- */ 00248 00249 static void env_rotate_scene(Render *re, float mat[][4], int mode) 00250 { 00251 GroupObject *go; 00252 ObjectRen *obr; 00253 ObjectInstanceRen *obi; 00254 LampRen *lar = NULL; 00255 HaloRen *har = NULL; 00256 float imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4]; 00257 int a; 00258 00259 if(mode==0) { 00260 invert_m4_m4(tmat, mat); 00261 copy_m3_m4(imat, tmat); 00262 } 00263 else { 00264 copy_m4_m4(tmat, mat); 00265 copy_m3_m4(imat, mat); 00266 } 00267 00268 for(obi=re->instancetable.first; obi; obi=obi->next) { 00269 /* append or set matrix depending on dupli */ 00270 if(obi->flag & R_DUPLI_TRANSFORMED) { 00271 copy_m4_m4(tmpmat, obi->mat); 00272 mul_m4_m4m4(obi->mat, tmpmat, tmat); 00273 } 00274 else if(mode==1) 00275 copy_m4_m4(obi->mat, tmat); 00276 else 00277 unit_m4(obi->mat); 00278 00279 copy_m3_m4(cmat, obi->mat); 00280 invert_m3_m3(obi->nmat, cmat); 00281 transpose_m3(obi->nmat); 00282 00283 /* indicate the renderer has to use transform matrices */ 00284 if(mode==0) 00285 obi->flag &= ~R_ENV_TRANSFORMED; 00286 else 00287 obi->flag |= R_ENV_TRANSFORMED; 00288 } 00289 00290 00291 for(obr=re->objecttable.first; obr; obr=obr->next) { 00292 for(a=0; a<obr->tothalo; a++) { 00293 if((a & 255)==0) har= obr->bloha[a>>8]; 00294 else har++; 00295 00296 mul_m4_v3(tmat, har->co); 00297 } 00298 } 00299 00300 for(go=re->lights.first; go; go= go->next) { 00301 lar= go->lampren; 00302 00303 /* removed here some horrible code of someone in NaN who tried to fix 00304 prototypes... just solved by introducing a correct cmat[3][3] instead 00305 of using smat. this works, check square spots in reflections (ton) */ 00306 copy_m3_m3(cmat, lar->imat); 00307 mul_m3_m3m3(lar->imat, cmat, imat); 00308 00309 mul_m3_v3(imat, lar->vec); 00310 mul_m4_v3(tmat, lar->co); 00311 00312 lar->sh_invcampos[0]= -lar->co[0]; 00313 lar->sh_invcampos[1]= -lar->co[1]; 00314 lar->sh_invcampos[2]= -lar->co[2]; 00315 mul_m3_v3(lar->imat, lar->sh_invcampos); 00316 lar->sh_invcampos[2]*= lar->sh_zfac; 00317 00318 if(lar->shb) { 00319 if(mode==1) { 00320 invert_m4_m4(pmat, mat); 00321 mul_m4_m4m4(smat, pmat, lar->shb->viewmat); 00322 mul_m4_m4m4(lar->shb->persmat, smat, lar->shb->winmat); 00323 } 00324 else mul_m4_m4m4(lar->shb->persmat, lar->shb->viewmat, lar->shb->winmat); 00325 } 00326 } 00327 00328 } 00329 00330 /* ------------------------------------------------------------------------- */ 00331 00332 static void env_layerflags(Render *re, unsigned int notlay) 00333 { 00334 ObjectRen *obr; 00335 VlakRen *vlr = NULL; 00336 int a; 00337 00338 /* invert notlay, so if face is in multiple layers it will still be visible, 00339 unless all 'notlay' bits match the face bits. 00340 face: 0110 00341 not: 0100 00342 ~not: 1011 00343 now (face & ~not) is true 00344 */ 00345 00346 notlay= ~notlay; 00347 00348 for(obr=re->objecttable.first; obr; obr=obr->next) { 00349 if((obr->lay & notlay)==0) { 00350 for(a=0; a<obr->totvlak; a++) { 00351 if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; 00352 else vlr++; 00353 00354 vlr->flag |= R_HIDDEN; 00355 } 00356 } 00357 } 00358 } 00359 00360 static void env_hideobject(Render *re, Object *ob) 00361 { 00362 ObjectRen *obr; 00363 VlakRen *vlr = NULL; 00364 int a; 00365 00366 for(obr=re->objecttable.first; obr; obr=obr->next) { 00367 for(a=0; a<obr->totvlak; a++) { 00368 if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; 00369 else vlr++; 00370 00371 if(obr->ob == ob) 00372 vlr->flag |= R_HIDDEN; 00373 } 00374 } 00375 } 00376 00377 static void env_showobjects(Render *re) 00378 { 00379 ObjectRen *obr; 00380 VlakRen *vlr = NULL; 00381 int a; 00382 00383 for(obr=re->objecttable.first; obr; obr=obr->next) { 00384 for(a=0; a<obr->totvlak; a++) { 00385 if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; 00386 else vlr++; 00387 00388 vlr->flag &= ~R_HIDDEN; 00389 } 00390 } 00391 } 00392 00393 /* ------------------------------------------------------------------------- */ 00394 00395 static void env_set_imats(Render *re) 00396 { 00397 Base *base; 00398 float mat[4][4]; 00399 00400 base= re->scene->base.first; 00401 while(base) { 00402 mul_m4_m4m4(mat, base->object->obmat, re->viewmat); 00403 invert_m4_m4(base->object->imat, mat); 00404 00405 base= base->next; 00406 } 00407 00408 } 00409 00410 /* ------------------------------------------------------------------------- */ 00411 00412 static void render_envmap(Render *re, EnvMap *env) 00413 { 00414 /* only the cubemap and planar map is implemented */ 00415 Render *envre; 00416 ImBuf *ibuf; 00417 float orthmat[4][4]; 00418 float oldviewinv[4][4], mat[4][4], tmat[4][4]; 00419 short part; 00420 00421 /* need a recalc: ortho-render has no correct viewinv */ 00422 invert_m4_m4(oldviewinv, re->viewmat); 00423 00424 envre= envmap_render_copy(re, env); 00425 00426 /* precalc orthmat for object */ 00427 copy_m4_m4(orthmat, env->object->obmat); 00428 normalize_m4(orthmat); 00429 00430 /* need imat later for texture imat */ 00431 mul_m4_m4m4(mat, orthmat, re->viewmat); 00432 invert_m4_m4(tmat, mat); 00433 copy_m3_m4(env->obimat, tmat); 00434 00435 for(part=0; part<6; part++) { 00436 if(env->type==ENV_PLANE && part!=1) 00437 continue; 00438 00439 re->display_clear(re->dch, envre->result); 00440 00441 copy_m4_m4(tmat, orthmat); 00442 envmap_transmatrix(tmat, part); 00443 invert_m4_m4(mat, tmat); 00444 /* mat now is the camera 'viewmat' */ 00445 00446 copy_m4_m4(envre->viewmat, mat); 00447 copy_m4_m4(envre->viewinv, tmat); 00448 00449 /* we have to correct for the already rotated vertexcoords */ 00450 mul_m4_m4m4(tmat, oldviewinv, envre->viewmat); 00451 invert_m4_m4(env->imat, tmat); 00452 00453 env_rotate_scene(envre, tmat, 1); 00454 init_render_world(envre); 00455 project_renderdata(envre, projectverto, 0, 0, 1); 00456 env_layerflags(envre, env->notlay); 00457 env_hideobject(envre, env->object); 00458 env_set_imats(envre); 00459 00460 if(re->test_break(re->tbh)==0) { 00461 RE_TileProcessor(envre); 00462 } 00463 00464 /* rotate back */ 00465 env_showobjects(envre); 00466 env_rotate_scene(envre, tmat, 0); 00467 00468 if(re->test_break(re->tbh)==0) { 00469 RenderLayer *rl= envre->result->layers.first; 00470 int y; 00471 float *alpha; 00472 00473 ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect|IB_rectfloat); 00474 memcpy(ibuf->rect_float, rl->rectf, ibuf->channels * ibuf->x * ibuf->y * sizeof(float)); 00475 00476 if (re->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) 00477 ibuf->profile = IB_PROFILE_LINEAR_RGB; 00478 00479 /* envmap renders without alpha */ 00480 alpha= ((float *)ibuf->rect_float)+3; 00481 for(y= ibuf->x*ibuf->y - 1; y>=0; y--, alpha+=4) 00482 *alpha= 1.0; 00483 00484 env->cube[part]= ibuf; 00485 } 00486 00487 if(re->test_break(re->tbh)) break; 00488 00489 } 00490 00491 if(re->test_break(re->tbh)) BKE_free_envmapdata(env); 00492 else { 00493 if(envre->r.mode & R_OSA) env->ok= ENV_OSA; 00494 else env->ok= ENV_NORMAL; 00495 env->lastframe= re->scene->r.cfra; 00496 } 00497 00498 /* restore */ 00499 envmap_free_render_copy(envre); 00500 env_set_imats(re); 00501 00502 } 00503 00504 /* ------------------------------------------------------------------------- */ 00505 00506 void make_envmaps(Render *re) 00507 { 00508 Tex *tex; 00509 int do_init= 0, depth= 0, trace; 00510 00511 if (!(re->r.mode & R_ENVMAP)) return; 00512 00513 /* we dont raytrace, disabling the flag will cause ray_transp render solid */ 00514 trace= (re->r.mode & R_RAYTRACE); 00515 re->r.mode &= ~R_RAYTRACE; 00516 00517 re->i.infostr= "Creating Environment maps"; 00518 re->stats_draw(re->sdh, &re->i); 00519 00520 /* 5 = hardcoded max recursion level */ 00521 while(depth<5) { 00522 tex= re->main->tex.first; 00523 while(tex) { 00524 if(tex->id.us && tex->type==TEX_ENVMAP) { 00525 if(tex->env && tex->env->object) { 00526 EnvMap *env= tex->env; 00527 00528 if(env->object->lay & re->lay) { 00529 if(env->stype==ENV_LOAD) { 00530 float orthmat[4][4], mat[4][4], tmat[4][4]; 00531 00532 /* precalc orthmat for object */ 00533 copy_m4_m4(orthmat, env->object->obmat); 00534 normalize_m4(orthmat); 00535 00536 /* need imat later for texture imat */ 00537 mul_m4_m4m4(mat, orthmat, re->viewmat); 00538 invert_m4_m4(tmat, mat); 00539 copy_m3_m4(env->obimat, tmat); 00540 } 00541 else { 00542 00543 /* decide if to render an envmap (again) */ 00544 if(env->depth >= depth) { 00545 00546 /* set 'recalc' to make sure it does an entire loop of recalcs */ 00547 00548 if(env->ok) { 00549 /* free when OSA, and old one isn't OSA */ 00550 if((re->r.mode & R_OSA) && env->ok==ENV_NORMAL) 00551 BKE_free_envmapdata(env); 00552 /* free when size larger */ 00553 else if(env->lastsize < re->r.size) 00554 BKE_free_envmapdata(env); 00555 /* free when env is in recalcmode */ 00556 else if(env->recalc) 00557 BKE_free_envmapdata(env); 00558 } 00559 00560 if(env->ok==0 && depth==0) env->recalc= 1; 00561 00562 if(env->ok==0) { 00563 do_init= 1; 00564 render_envmap(re, env); 00565 00566 if(depth==env->depth) env->recalc= 0; 00567 } 00568 } 00569 } 00570 } 00571 } 00572 } 00573 tex= tex->id.next; 00574 } 00575 depth++; 00576 } 00577 00578 if(do_init) { 00579 re->display_init(re->dih, re->result); 00580 re->display_clear(re->dch, re->result); 00581 // re->flag |= R_REDRAW_PRV; 00582 } 00583 // restore 00584 re->r.mode |= trace; 00585 00586 } 00587 00588 /* ------------------------------------------------------------------------- */ 00589 00590 static int envcube_isect(EnvMap *env, float *vec, float *answ) 00591 { 00592 float labda; 00593 int face; 00594 00595 if(env->type==ENV_PLANE) { 00596 face= 1; 00597 00598 labda= 1.0/vec[2]; 00599 answ[0]= env->viewscale*labda*vec[0]; 00600 answ[1]= -env->viewscale*labda*vec[1]; 00601 } 00602 else { 00603 /* which face */ 00604 if( vec[2]<=-fabs(vec[0]) && vec[2]<=-fabs(vec[1]) ) { 00605 face= 0; 00606 labda= -1.0/vec[2]; 00607 answ[0]= labda*vec[0]; 00608 answ[1]= labda*vec[1]; 00609 } 00610 else if( vec[2]>=fabs(vec[0]) && vec[2]>=fabs(vec[1]) ) { 00611 face= 1; 00612 labda= 1.0/vec[2]; 00613 answ[0]= labda*vec[0]; 00614 answ[1]= -labda*vec[1]; 00615 } 00616 else if( vec[1]>=fabs(vec[0]) ) { 00617 face= 2; 00618 labda= 1.0/vec[1]; 00619 answ[0]= labda*vec[0]; 00620 answ[1]= labda*vec[2]; 00621 } 00622 else if( vec[0]<=-fabs(vec[1]) ) { 00623 face= 3; 00624 labda= -1.0/vec[0]; 00625 answ[0]= labda*vec[1]; 00626 answ[1]= labda*vec[2]; 00627 } 00628 else if( vec[1]<=-fabs(vec[0]) ) { 00629 face= 4; 00630 labda= -1.0/vec[1]; 00631 answ[0]= -labda*vec[0]; 00632 answ[1]= labda*vec[2]; 00633 } 00634 else { 00635 face= 5; 00636 labda= 1.0/vec[0]; 00637 answ[0]= -labda*vec[1]; 00638 answ[1]= labda*vec[2]; 00639 } 00640 } 00641 00642 answ[0]= 0.5+0.5*answ[0]; 00643 answ[1]= 0.5+0.5*answ[1]; 00644 return face; 00645 } 00646 00647 /* ------------------------------------------------------------------------- */ 00648 00649 static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face) 00650 { 00651 if(face==2 || face==4) { 00652 dxts[0]= dxt[0]; 00653 dyts[0]= dyt[0]; 00654 dxts[1]= dxt[2]; 00655 dyts[1]= dyt[2]; 00656 } 00657 else if(face==3 || face==5) { 00658 dxts[0]= dxt[1]; 00659 dxts[1]= dxt[2]; 00660 dyts[0]= dyt[1]; 00661 dyts[1]= dyt[2]; 00662 } 00663 else { 00664 dxts[0]= dxt[0]; 00665 dyts[0]= dyt[0]; 00666 dxts[1]= dxt[1]; 00667 dyts[1]= dyt[1]; 00668 } 00669 } 00670 00671 /* ------------------------------------------------------------------------- */ 00672 00673 int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) 00674 { 00675 extern Render R; /* only in this call */ 00676 /* texvec should be the already reflected normal */ 00677 EnvMap *env; 00678 ImBuf *ibuf; 00679 float fac, vec[3], sco[3], dxts[3], dyts[3]; 00680 int face, face1; 00681 00682 env= tex->env; 00683 if(env==NULL || (env->stype!=ENV_LOAD && env->object==NULL)) { 00684 texres->tin= 0.0; 00685 return 0; 00686 } 00687 00688 if(env->stype==ENV_LOAD) { 00689 env->ima= tex->ima; 00690 if(env->ima && env->ima->ok) { 00691 if(env->cube[1]==NULL) { 00692 ImBuf *ibuf= BKE_image_get_ibuf(env->ima, NULL); 00693 if(ibuf) 00694 envmap_split_ima(env, ibuf); 00695 else 00696 env->ok= 0; 00697 } 00698 } 00699 } 00700 00701 if(env->ok==0) { 00702 texres->tin= 0.0; 00703 return 0; 00704 } 00705 00706 /* rotate to envmap space, if object is set */ 00707 VECCOPY(vec, texvec); 00708 if(env->object) mul_m3_v3(env->obimat, vec); 00709 else mul_mat3_m4_v3(R.viewinv, vec); 00710 00711 face= envcube_isect(env, vec, sco); 00712 ibuf= env->cube[face]; 00713 00714 if(osatex) { 00715 if(env->object) { 00716 mul_m3_v3(env->obimat, dxt); 00717 mul_m3_v3(env->obimat, dyt); 00718 } 00719 else { 00720 mul_mat3_m4_v3(R.viewinv, dxt); 00721 mul_mat3_m4_v3(R.viewinv, dyt); 00722 } 00723 set_dxtdyt(dxts, dyts, dxt, dyt, face); 00724 imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres); 00725 00726 /* edges? */ 00727 00728 if(texres->ta<1.0) { 00729 TexResult texr1, texr2; 00730 00731 texr1.nor= texr2.nor= NULL; 00732 texr1.talpha= texr2.talpha= texres->talpha; /* boxclip expects this initialized */ 00733 00734 add_v3_v3(vec, dxt); 00735 face1= envcube_isect(env, vec, sco); 00736 sub_v3_v3(vec, dxt); 00737 00738 if(face!=face1) { 00739 ibuf= env->cube[face1]; 00740 set_dxtdyt(dxts, dyts, dxt, dyt, face1); 00741 imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1); 00742 } 00743 else texr1.tr= texr1.tg= texr1.tb= texr1.ta= 0.0; 00744 00745 /* here was the nasty bug! results were not zero-ed. FPE! */ 00746 00747 add_v3_v3(vec, dyt); 00748 face1= envcube_isect(env, vec, sco); 00749 sub_v3_v3(vec, dyt); 00750 00751 if(face!=face1) { 00752 ibuf= env->cube[face1]; 00753 set_dxtdyt(dxts, dyts, dxt, dyt, face1); 00754 imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2); 00755 } 00756 else texr2.tr= texr2.tg= texr2.tb= texr2.ta= 0.0; 00757 00758 fac= (texres->ta+texr1.ta+texr2.ta); 00759 if(fac!=0.0) { 00760 fac= 1.0/fac; 00761 00762 texres->tr= fac*(texres->ta*texres->tr + texr1.ta*texr1.tr + texr2.ta*texr2.tr ); 00763 texres->tg= fac*(texres->ta*texres->tg + texr1.ta*texr1.tg + texr2.ta*texr2.tg ); 00764 texres->tb= fac*(texres->ta*texres->tb + texr1.ta*texr1.tb + texr2.ta*texr2.tb ); 00765 } 00766 texres->ta= 1.0; 00767 } 00768 } 00769 else { 00770 imagewrap(tex, NULL, ibuf, sco, texres); 00771 } 00772 00773 return 1; 00774 } 00775 00776 /* ------------------------------------------------------------------------- */ 00777 00778 /* eof */