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