Blender V2.61 - r43446

render_texture.c

Go to the documentation of this file.
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 LICENSE BLOCK *****
00024  */
00025 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <math.h>
00035 
00036 #include "BLI_blenlib.h"
00037 #include "BLI_math.h"
00038 #include "BLI_rand.h"
00039 #include "BLI_utildefines.h"
00040 
00041 #include "DNA_anim_types.h"
00042 #include "DNA_texture_types.h"
00043 #include "DNA_object_types.h"
00044 #include "DNA_lamp_types.h"
00045 #include "DNA_mesh_types.h"
00046 #include "DNA_meshdata_types.h"
00047 #include "DNA_material_types.h"
00048 #include "DNA_image_types.h"
00049 #include "DNA_node_types.h"
00050 
00051 #include "IMB_imbuf_types.h"
00052 #include "IMB_imbuf.h"
00053 
00054 #include "BKE_colortools.h"
00055 #include "BKE_image.h"
00056 #include "BKE_node.h"
00057 #include "BKE_plugin_types.h"
00058 
00059 #include "BKE_animsys.h"
00060 #include "BKE_DerivedMesh.h"
00061 #include "BKE_global.h"
00062 #include "BKE_main.h"
00063 #include "BKE_material.h"
00064 #include "BKE_scene.h"
00065 
00066 #include "BKE_library.h"
00067 #include "BKE_image.h"
00068 #include "BKE_texture.h"
00069 #include "BKE_key.h"
00070 #include "BKE_ipo.h"
00071 
00072 #include "MEM_guardedalloc.h"
00073 
00074 #include "envmap.h"
00075 #include "pointdensity.h"
00076 #include "voxeldata.h"
00077 #include "renderpipeline.h"
00078 #include "render_types.h"
00079 #include "rendercore.h"
00080 #include "shading.h"
00081 #include "texture.h"
00082 #include "texture_ocean.h"
00083 
00084 #include "renderdatabase.h" /* needed for UV */
00085 
00086 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00087 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
00088 /* only to be used here in this file, it's for speed */
00089 extern struct Render R;
00090 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
00091 
00092 
00093 
00094 
00095 static void init_render_texture(Render *re, Tex *tex)
00096 {
00097     int cfra= re->scene->r.cfra;
00098     
00099     if(re) cfra= re->r.cfra;
00100     
00101     /* imap test */
00102     if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
00103         BKE_image_user_calc_frame(&tex->iuser, cfra, re?re->flag & R_SEC_FIELD:0);
00104     }
00105     
00106     if(tex->type==TEX_PLUGIN) {
00107         if(tex->plugin && tex->plugin->doit) {
00108             if(tex->plugin->cfra) {
00109                 *(tex->plugin->cfra)= (float)cfra; //BKE_curframe(re->scene); // XXX old animsys - timing stuff to be fixed 
00110             }
00111         }
00112     }
00113     else if(tex->type==TEX_ENVMAP) {
00114         /* just in case */
00115         tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP;
00116         tex->extend= TEX_CLIP;
00117         
00118         if(tex->env) {
00119             if(tex->env->type==ENV_PLANE)
00120                 tex->extend= TEX_EXTEND;
00121             
00122             /* only free envmap when rendermode was set to render envmaps, for previewrender */
00123             if(G.rendering && re) {
00124                 if (re->r.mode & R_ENVMAP)
00125                     if(tex->env->stype==ENV_ANIM) 
00126                         BKE_free_envmapdata(tex->env);
00127             }
00128         }
00129     }
00130     
00131     if(tex->nodetree && tex->use_nodes) {
00132         ntreeTexBeginExecTree(tex->nodetree, 1); /* has internal flag to detect it only does it once */
00133     }
00134 }
00135 
00136 /* ------------------------------------------------------------------------- */
00137 
00138 void init_render_textures(Render *re)
00139 {
00140     Tex *tex;
00141     
00142     tex= re->main->tex.first;
00143     while(tex) {
00144         if(tex->id.us) init_render_texture(re, tex);
00145         tex= tex->id.next;
00146     }
00147 }
00148 
00149 static void end_render_texture(Tex *tex)
00150 {
00151     if(tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
00152         ntreeTexEndExecTree(tex->nodetree->execdata, 1);
00153 }
00154 
00155 void end_render_textures(Render *re)
00156 {
00157     Tex *tex;
00158     for(tex= re->main->tex.first; tex; tex= tex->id.next)
00159         if(tex->id.us)
00160             end_render_texture(tex);
00161 }
00162 
00163 /* ------------------------------------------------------------------------- */
00164 
00165 
00166 /* this allows colorbanded textures to control normals as well */
00167 static void tex_normal_derivate(Tex *tex, TexResult *texres)
00168 {
00169     if (tex->flag & TEX_COLORBAND) {
00170         float col[4];
00171         if (do_colorband(tex->coba, texres->tin, col)) {
00172             float fac0, fac1, fac2, fac3;
00173             
00174             fac0= (col[0]+col[1]+col[2]);
00175             do_colorband(tex->coba, texres->nor[0], col);
00176             fac1= (col[0]+col[1]+col[2]);
00177             do_colorband(tex->coba, texres->nor[1], col);
00178             fac2= (col[0]+col[1]+col[2]);
00179             do_colorband(tex->coba, texres->nor[2], col);
00180             fac3= (col[0]+col[1]+col[2]);
00181             
00182             texres->nor[0]= 0.3333f*(fac0 - fac1);
00183             texres->nor[1]= 0.3333f*(fac0 - fac2);
00184             texres->nor[2]= 0.3333f*(fac0 - fac3);
00185             
00186             return;
00187         }
00188     }
00189     texres->nor[0]= texres->tin - texres->nor[0];
00190     texres->nor[1]= texres->tin - texres->nor[1];
00191     texres->nor[2]= texres->tin - texres->nor[2];
00192 }
00193 
00194 
00195 
00196 static int blend(Tex *tex, float *texvec, TexResult *texres)
00197 {
00198     float x, y, t;
00199 
00200     if(tex->flag & TEX_FLIPBLEND) {
00201         x= texvec[1];
00202         y= texvec[0];
00203     }
00204     else {
00205         x= texvec[0];
00206         y= texvec[1];
00207     }
00208 
00209     if(tex->stype==TEX_LIN) {   /* lin */
00210         texres->tin= (1.0f+x)/2.0f;
00211     }
00212     else if(tex->stype==TEX_QUAD) { /* quad */
00213         texres->tin= (1.0f+x)/2.0f;
00214         if(texres->tin<0.0f) texres->tin= 0.0f;
00215         else texres->tin*= texres->tin;
00216     }
00217     else if(tex->stype==TEX_EASE) { /* ease */
00218         texres->tin= (1.0f+x)/2.0f;
00219         if(texres->tin<=0.0f) texres->tin= 0.0f;
00220         else if(texres->tin>=1.0f) texres->tin= 1.0f;
00221         else {
00222             t= texres->tin*texres->tin;
00223             texres->tin= (3.0f*t-2.0f*t*texres->tin);
00224         }
00225     }
00226     else if(tex->stype==TEX_DIAG) { /* diag */
00227         texres->tin= (2.0f+x+y)/4.0f;
00228     }
00229     else if(tex->stype==TEX_RAD) { /* radial */
00230         texres->tin= (atan2(y,x) / (2*M_PI) + 0.5);
00231     }
00232     else {  /* sphere TEX_SPHERE */
00233         texres->tin= 1.0-sqrt(x*x+  y*y+texvec[2]*texvec[2]);
00234         if(texres->tin<0.0f) texres->tin= 0.0f;
00235         if(tex->stype==TEX_HALO) texres->tin*= texres->tin;  /* halo */
00236     }
00237 
00238     BRICONT;
00239 
00240     return TEX_INT;
00241 }
00242 
00243 /* ------------------------------------------------------------------------- */
00244 /* ************************************************************************* */
00245 
00246 /* newnoise: all noisebased types now have different noisebases to choose from */
00247 
00248 static int clouds(Tex *tex, float *texvec, TexResult *texres)
00249 {
00250     int rv = TEX_INT;
00251     
00252     texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00253 
00254     if (texres->nor!=NULL) {
00255         // calculate bumpnormal
00256         texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00257         texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00258         texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00259         
00260         tex_normal_derivate(tex, texres);
00261         rv |= TEX_NOR;
00262     }
00263 
00264     if (tex->stype==TEX_COLOR) {
00265         // in this case, int. value should really be computed from color,
00266         // and bumpnormal from that, would be too slow, looks ok as is
00267         texres->tr = texres->tin;
00268         texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00269         texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00270         BRICONTRGB;
00271         texres->ta = 1.0;
00272         return (rv | TEX_RGB);
00273     }
00274 
00275     BRICONT;
00276 
00277     return rv;
00278 
00279 }
00280 
00281 /* creates a sine wave */
00282 static float tex_sin(float a)
00283 {
00284     a = 0.5 + 0.5*sin(a);
00285         
00286     return a;
00287 }
00288 
00289 /* creates a saw wave */
00290 static float tex_saw(float a)
00291 {
00292     const float b = 2*M_PI;
00293     
00294     int n = (int)(a / b);
00295     a -= n*b;
00296     if (a < 0) a += b;
00297     return a / b;
00298 }
00299 
00300 /* creates a triangle wave */
00301 static float tex_tri(float a)
00302 {
00303     const float b = 2*M_PI;
00304     const float rmax = 1.0;
00305     
00306     a = rmax - 2.0f*fabsf(floorf((a*(1.0f/b))+0.5f) - (a*(1.0f/b)));
00307     
00308     return a;
00309 }
00310 
00311 /* computes basic wood intensity value at x,y,z */
00312 static float wood_int(Tex *tex, float x, float y, float z)
00313 {
00314     float wi=0;                     
00315     short wf = tex->noisebasis2;    /* wave form:   TEX_SIN=0,  TEX_SAW=1,  TEX_TRI=2                        */
00316     short wt = tex->stype;          /* wood type:   TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3 */
00317 
00318     float (*waveform[3])(float);    /* create array of pointers to waveform functions */
00319     waveform[0] = tex_sin;          /* assign address of tex_sin() function to pointer array */
00320     waveform[1] = tex_saw;
00321     waveform[2] = tex_tri;
00322     
00323     if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */
00324         
00325     if (wt==TEX_BAND) {
00326         wi = waveform[wf]((x + y + z)*10.0f);
00327     }
00328     else if (wt==TEX_RING) {
00329         wi = waveform[wf](sqrtf(x*x + y*y + z*z)*20.0f);
00330     }
00331     else if (wt==TEX_BANDNOISE) {
00332         wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00333         wi = waveform[wf]((x + y + z)*10.0f + wi);
00334     }
00335     else if (wt==TEX_RINGNOISE) {
00336         wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00337         wi = waveform[wf](sqrtf(x*x + y*y + z*z)*20.0f + wi);
00338     }
00339     
00340     return wi;
00341 }
00342 
00343 static int wood(Tex *tex, float *texvec, TexResult *texres)
00344 {
00345     int rv=TEX_INT;
00346 
00347     texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
00348     if (texres->nor!=NULL) {
00349         /* calculate bumpnormal */
00350         texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
00351         texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
00352         texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
00353         
00354         tex_normal_derivate(tex, texres);
00355         rv |= TEX_NOR;
00356     }
00357 
00358     BRICONT;
00359 
00360     return rv;
00361 }
00362 
00363 /* computes basic marble intensity at x,y,z */
00364 static float marble_int(Tex *tex, float x, float y, float z)
00365 {
00366     float n, mi;
00367     short wf = tex->noisebasis2;    /* wave form:   TEX_SIN=0,  TEX_SAW=1,  TEX_TRI=2                       */
00368     short mt = tex->stype;          /* marble type: TEX_SOFT=0, TEX_SHARP=1,TEX_SHAPER=2                    */
00369     
00370     float (*waveform[3])(float);    /* create array of pointers to waveform functions */
00371     waveform[0] = tex_sin;          /* assign address of tex_sin() function to pointer array */
00372     waveform[1] = tex_saw;
00373     waveform[2] = tex_tri;
00374     
00375     if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */
00376     
00377     n = 5.0f * (x + y + z);
00378     
00379     mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT),  tex->noisebasis);
00380 
00381     if (mt>=TEX_SOFT) {  /* TEX_SOFT always true */
00382         mi = waveform[wf](mi);
00383         if (mt==TEX_SHARP) {
00384             mi = sqrt(mi);
00385         } 
00386         else if (mt==TEX_SHARPER) {
00387             mi = sqrt(sqrt(mi));
00388         }
00389     }
00390 
00391     return mi;
00392 }
00393 
00394 static int marble(Tex *tex, float *texvec, TexResult *texres)
00395 {
00396     int rv=TEX_INT;
00397 
00398     texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
00399 
00400     if (texres->nor!=NULL) {
00401         /* calculate bumpnormal */
00402         texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
00403         texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
00404         texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
00405         
00406         tex_normal_derivate(tex, texres);
00407         
00408         rv |= TEX_NOR;
00409     }
00410 
00411     BRICONT;
00412 
00413     return rv;
00414 }
00415 
00416 /* ------------------------------------------------------------------------- */
00417 
00418 static int magic(Tex *tex, float *texvec, TexResult *texres)
00419 {
00420     float x, y, z, turb=1.0;
00421     int n;
00422 
00423     n= tex->noisedepth;
00424     turb= tex->turbul/5.0f;
00425 
00426     x=  sin( ( texvec[0]+texvec[1]+texvec[2])*5.0f );
00427     y=  cos( (-texvec[0]+texvec[1]-texvec[2])*5.0f );
00428     z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0f );
00429     if(n>0) {
00430         x*= turb;
00431         y*= turb;
00432         z*= turb;
00433         y= -cos(x-y+z);
00434         y*= turb;
00435         if(n>1) {
00436             x= cos(x-y-z);
00437             x*= turb;
00438             if(n>2) {
00439                 z= sin(-x-y-z);
00440                 z*= turb;
00441                 if(n>3) {
00442                     x= -cos(-x+y-z);
00443                     x*= turb;
00444                     if(n>4) {
00445                         y= -sin(-x+y+z);
00446                         y*= turb;
00447                         if(n>5) {
00448                             y= -cos(-x+y+z);
00449                             y*= turb;
00450                             if(n>6) {
00451                                 x= cos(x+y+z);
00452                                 x*= turb;
00453                                 if(n>7) {
00454                                     z= sin(x+y-z);
00455                                     z*= turb;
00456                                     if(n>8) {
00457                                         x= -cos(-x-y+z);
00458                                         x*= turb;
00459                                         if(n>9) {
00460                                             y= -sin(x-y+z);
00461                                             y*= turb;
00462                                         }
00463                                     }
00464                                 }
00465                             }
00466                         }
00467                     }
00468                 }
00469             }
00470         }
00471     }
00472 
00473     if(turb!=0.0f) {
00474         turb*= 2.0f;
00475         x/= turb; 
00476         y/= turb; 
00477         z/= turb;
00478     }
00479     texres->tr= 0.5f-x;
00480     texres->tg= 0.5f-y;
00481     texres->tb= 0.5f-z;
00482 
00483     texres->tin= 0.3333f*(texres->tr+texres->tg+texres->tb);
00484     
00485     BRICONTRGB;
00486     texres->ta= 1.0;
00487     
00488     return TEX_RGB;
00489 }
00490 
00491 /* ------------------------------------------------------------------------- */
00492 
00493 /* newnoise: stucci also modified to use different noisebasis */
00494 static int stucci(Tex *tex, float *texvec, TexResult *texres)
00495 {
00496     float nor[3], b2, ofs;
00497     int retval= TEX_INT;
00498     
00499     b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00500     
00501     ofs= tex->turbul/200.0f;
00502 
00503     if(tex->stype) ofs*=(b2*b2);
00504     nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00505     nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 
00506     nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
00507 
00508     texres->tin= nor[2];
00509     
00510     if(texres->nor) { 
00511         
00512         copy_v3_v3(texres->nor, nor);
00513         tex_normal_derivate(tex, texres);
00514         
00515         if(tex->stype==TEX_WALLOUT) {
00516             texres->nor[0]= -texres->nor[0];
00517             texres->nor[1]= -texres->nor[1];
00518             texres->nor[2]= -texres->nor[2];
00519         }
00520         
00521         retval |= TEX_NOR;
00522     }
00523     
00524     if(tex->stype==TEX_WALLOUT) 
00525         texres->tin= 1.0f-texres->tin;
00526     
00527     if(texres->tin<0.0f)
00528         texres->tin= 0.0f;
00529     
00530     return retval;
00531 }
00532 
00533 /* ------------------------------------------------------------------------- */
00534 /* newnoise: musgrave terrain noise types */
00535 
00536 static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres)
00537 {
00538     int rv = TEX_INT;
00539     float (*mgravefunc)(float, float, float, float, float, float, int);
00540 
00541     if (tex->stype==TEX_MFRACTAL)
00542         mgravefunc = mg_MultiFractal;
00543     else
00544         mgravefunc = mg_fBm;
00545 
00546     texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
00547 
00548     if (texres->nor!=NULL) {
00549         float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
00550         
00551         /* calculate bumpnormal */
00552         texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
00553         texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
00554         texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
00555         
00556         tex_normal_derivate(tex, texres);
00557         rv |= TEX_NOR;
00558     }
00559 
00560     BRICONT;
00561 
00562     return rv;
00563 
00564 }
00565 
00566 static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres)
00567 {
00568     int rv = TEX_INT;
00569     float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
00570 
00571     if (tex->stype==TEX_RIDGEDMF)
00572         mgravefunc = mg_RidgedMultiFractal;
00573     else
00574         mgravefunc = mg_HybridMultiFractal;
00575 
00576     texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
00577 
00578     if (texres->nor!=NULL) {
00579         float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
00580         
00581         /* calculate bumpnormal */
00582         texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
00583         texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
00584         texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis);
00585         
00586         tex_normal_derivate(tex, texres);
00587         rv |= TEX_NOR;
00588     }
00589 
00590     BRICONT;
00591 
00592     return rv;
00593 
00594 }
00595 
00596 
00597 static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres)
00598 {
00599     int rv = TEX_INT;
00600 
00601     texres->tin = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
00602 
00603     if (texres->nor!=NULL) {
00604         float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
00605         
00606         /* calculate bumpnormal */
00607         texres->nor[0] = tex->ns_outscale*mg_HeteroTerrain(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
00608         texres->nor[1] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
00609         texres->nor[2] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis);
00610         
00611         tex_normal_derivate(tex, texres);
00612         rv |= TEX_NOR;
00613     }
00614 
00615     BRICONT;
00616 
00617     return rv;
00618 
00619 }
00620 
00621 
00622 static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres)
00623 {
00624     int rv = TEX_INT;
00625 
00626     texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
00627 
00628     if (texres->nor!=NULL) {
00629         float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
00630         
00631         /* calculate bumpnormal */
00632         texres->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
00633         texres->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
00634         texres->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2);
00635 
00636         tex_normal_derivate(tex, texres);
00637         rv |= TEX_NOR;
00638     }
00639 
00640     BRICONT;
00641 
00642 
00643     return rv;
00644 
00645 }
00646 
00647 
00648 /* ------------------------------------------------------------------------- */
00649 /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */
00650 
00651 static float voronoiTex(Tex *tex, float *texvec, TexResult *texres)
00652 {
00653     int rv = TEX_INT;
00654     float da[4], pa[12];    /* distance and point coordinate arrays of 4 nearest neighbours */
00655     float aw1 = fabs(tex->vn_w1);
00656     float aw2 = fabs(tex->vn_w2);
00657     float aw3 = fabs(tex->vn_w3);
00658     float aw4 = fabs(tex->vn_w4);
00659     float sc = (aw1 + aw2 + aw3 + aw4);
00660     if (sc!=0.f) sc =  tex->ns_outscale/sc;
00661 
00662     voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
00663     texres->tin = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
00664 
00665     if (tex->vn_coltype) {
00666         float ca[3];    /* cell color */
00667         cellNoiseV(pa[0], pa[1], pa[2], ca);
00668         texres->tr = aw1*ca[0];
00669         texres->tg = aw1*ca[1];
00670         texres->tb = aw1*ca[2];
00671         cellNoiseV(pa[3], pa[4], pa[5], ca);
00672         texres->tr += aw2*ca[0];
00673         texres->tg += aw2*ca[1];
00674         texres->tb += aw2*ca[2];
00675         cellNoiseV(pa[6], pa[7], pa[8], ca);
00676         texres->tr += aw3*ca[0];
00677         texres->tg += aw3*ca[1];
00678         texres->tb += aw3*ca[2];
00679         cellNoiseV(pa[9], pa[10], pa[11], ca);
00680         texres->tr += aw4*ca[0];
00681         texres->tg += aw4*ca[1];
00682         texres->tb += aw4*ca[2];
00683         if (tex->vn_coltype>=2) {
00684             float t1 = (da[1]-da[0])*10;
00685             if (t1>1) t1=1;
00686             if (tex->vn_coltype==3) t1*=texres->tin; else t1*=sc;
00687             texres->tr *= t1;
00688             texres->tg *= t1;
00689             texres->tb *= t1;
00690         }
00691         else {
00692             texres->tr *= sc;
00693             texres->tg *= sc;
00694             texres->tb *= sc;
00695         }
00696     }
00697 
00698     if (texres->nor!=NULL) {
00699         float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
00700 
00701         /* calculate bumpnormal */
00702         voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
00703         texres->nor[0] = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
00704         voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
00705         texres->nor[1] = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
00706         voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp,  tex->vn_distm);
00707         texres->nor[2] = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
00708         
00709         tex_normal_derivate(tex, texres);
00710         rv |= TEX_NOR;
00711     }
00712 
00713     if (tex->vn_coltype) {
00714         BRICONTRGB;
00715         texres->ta = 1.0;
00716         return (rv | TEX_RGB);
00717     }
00718     
00719     BRICONT;
00720 
00721     return rv;
00722 
00723 }
00724 
00725 /* ------------------------------------------------------------------------- */
00726 
00727 static int texnoise(Tex *tex, TexResult *texres)
00728 {
00729     float div=3.0;
00730     int val, ran, loop;
00731     
00732     ran= BLI_rand();
00733     val= (ran & 3);
00734     
00735     loop= tex->noisedepth;
00736     while(loop--) {
00737         ran= (ran>>2);
00738         val*= (ran & 3);
00739         div*= 3.0f;
00740     }
00741     
00742     texres->tin= ((float)val)/div;
00743 
00744     BRICONT;
00745     return TEX_INT;
00746 }
00747 
00748 /* ------------------------------------------------------------------------- */
00749 
00750 static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
00751 {
00752     PluginTex *pit;
00753     int rgbnor=0;
00754     float result[8]= {0.0f};
00755 
00756     texres->tin= 0.0;
00757 
00758     pit= tex->plugin;
00759     if(pit && pit->doit) {
00760         if(texres->nor) {
00761             if (pit->version < 6) {
00762                 copy_v3_v3(pit->result+5, texres->nor);
00763             } else {
00764                 copy_v3_v3(result+5, texres->nor);
00765             }
00766         }
00767         if (pit->version < 6) {
00768             if(osatex) rgbnor= ((TexDoitold)pit->doit)(tex->stype, 
00769                 pit->data, texvec, dxt, dyt);
00770             else rgbnor= ((TexDoitold)pit->doit)(tex->stype, 
00771                 pit->data, texvec, NULL, NULL);
00772         } else {
00773             if(osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, 
00774                 pit->data, texvec, dxt, dyt, result);
00775             else rgbnor= ((TexDoit)pit->doit)(tex->stype, 
00776                 pit->data, texvec, NULL, NULL, result);
00777         }
00778 
00779         if (pit->version < 6) {
00780             texres->tin = pit->result[0];
00781         } else {
00782             texres->tin = result[0]; /* XXX, assigning garbage value, fixme! */
00783         }
00784 
00785         if(rgbnor & TEX_NOR) {
00786             if(texres->nor) {
00787                 if (pit->version < 6) {
00788                     copy_v3_v3(texres->nor, pit->result+5);
00789                 } else {
00790                     copy_v3_v3(texres->nor, result+5);
00791                 }
00792             }
00793         }
00794         
00795         if(rgbnor & TEX_RGB) {
00796             if (pit->version < 6) {
00797                 texres->tr = pit->result[1];
00798                 texres->tg = pit->result[2];
00799                 texres->tb = pit->result[3];
00800                 texres->ta = pit->result[4];
00801             } else {
00802                 texres->tr = result[1];
00803                 texres->tg = result[2];
00804                 texres->tb = result[3];
00805                 texres->ta = result[4];
00806             }
00807 
00808             BRICONTRGB;
00809         }
00810         
00811         BRICONT;
00812     }
00813 
00814     return rgbnor;
00815 }
00816 
00817 
00818 static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float *adr2)
00819 {
00820     float x1, y1, z1, nor[3];
00821     int ret;
00822     
00823     if(n==NULL) {
00824         nor[0]= x; nor[1]= y; nor[2]= z;    // use local render coord
00825     }
00826     else {
00827         copy_v3_v3(nor, n);
00828     }
00829     mul_mat3_m4_v3(R.viewinv, nor);
00830 
00831     x1= fabs(nor[0]);
00832     y1= fabs(nor[1]);
00833     z1= fabs(nor[2]);
00834     
00835     if(z1>=x1 && z1>=y1) {
00836         *adr1 = (x + 1.0f) / 2.0f;
00837         *adr2 = (y + 1.0f) / 2.0f;
00838         ret= 0;
00839     }
00840     else if(y1>=x1 && y1>=z1) {
00841         *adr1 = (x + 1.0f) / 2.0f;
00842         *adr2 = (z + 1.0f) / 2.0f;
00843         ret= 1;
00844     }
00845     else {
00846         *adr1 = (y + 1.0f) / 2.0f;
00847         *adr2 = (z + 1.0f) / 2.0f;
00848         ret= 2;     
00849     }
00850     return ret;
00851 }
00852 
00853 /* ------------------------------------------------------------------------- */
00854 
00855 /* mtex argument only for projection switches */
00856 static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z, float *adr1, float *adr2)
00857 {
00858     int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
00859     
00860     if(vlr) {
00861         int index;
00862         
00863         /* Mesh vertices have such flags, for others we calculate it once based on orco */
00864         if((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) {
00865             /* test for v1, vlr can be faked for baking */
00866             if(vlr->v1 && vlr->v1->orco) {
00867                 float nor[3];
00868                 normal_tri_v3( nor,vlr->v1->orco, vlr->v2->orco, vlr->v3->orco);
00869                 
00870                 if( fabs(nor[0])<fabs(nor[2]) && fabs(nor[1])<fabs(nor[2]) ) vlr->puno |= ME_PROJXY;
00871                 else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
00872                 else vlr->puno |= ME_PROJYZ;
00873             }
00874             else return cubemap_glob(n, x, y, z, adr1, adr2);
00875         }
00876         
00877         if(mtex) {
00878             /* the mtex->proj{xyz} have type char. maybe this should be wider? */
00879             /* casting to int ensures that the index type is right.            */
00880             index = (int) mtex->projx;
00881             proj[index]= ME_PROJXY;
00882 
00883             index = (int) mtex->projy;
00884             proj[index]= ME_PROJXZ;
00885 
00886             index = (int) mtex->projz;
00887             proj[index]= ME_PROJYZ;
00888         }
00889         
00890         if(vlr->puno & proj[1]) {
00891             *adr1 = (x + 1.0f) / 2.0f;
00892             *adr2 = (y + 1.0f) / 2.0f;
00893         }
00894         else if(vlr->puno & proj[2]) {
00895             *adr1 = (x + 1.0f) / 2.0f;
00896             *adr2 = (z + 1.0f) / 2.0f;
00897             ret= 1;
00898         }
00899         else {
00900             *adr1 = (y + 1.0f) / 2.0f;
00901             *adr2 = (z + 1.0f) / 2.0f;
00902             ret= 2;
00903         }       
00904     } 
00905     else {
00906         return cubemap_glob(n, x, y, z, adr1, adr2);
00907     }
00908     
00909     return ret;
00910 }
00911 
00912 /* ------------------------------------------------------------------------- */
00913 
00914 static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *adr1, float *adr2)
00915 {
00916     float x1, y1, z1, nor[3];
00917     int ret;
00918     
00919     if(n==NULL) return 0;
00920     
00921     copy_v3_v3(nor, n);
00922     if(ob) mul_mat3_m4_v3(ob->imat, nor);
00923     
00924     x1= fabs(nor[0]);
00925     y1= fabs(nor[1]);
00926     z1= fabs(nor[2]);
00927     
00928     if(z1>=x1 && z1>=y1) {
00929         *adr1 = (x + 1.0f) / 2.0f;
00930         *adr2 = (y + 1.0f) / 2.0f;
00931         ret= 0;
00932     }
00933     else if(y1>=x1 && y1>=z1) {
00934         *adr1 = (x + 1.0f) / 2.0f;
00935         *adr2 = (z + 1.0f) / 2.0f;
00936         ret= 1;
00937     }
00938     else {
00939         *adr1 = (y + 1.0f) / 2.0f;
00940         *adr2 = (z + 1.0f) / 2.0f;
00941         ret= 2;     
00942     }
00943     return ret;
00944 }
00945 
00946 /* ------------------------------------------------------------------------- */
00947 
00948 static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *dxt, float *dyt)
00949 {
00950     Tex *tex;
00951     Object *ob= NULL;
00952     float fx, fy, fac1, area[8];
00953     int ok, proj, areaflag= 0, wrap, texco;
00954     
00955     /* mtex variables localized, only cubemap doesn't cooperate yet... */
00956     wrap= mtex->mapping;
00957     tex= mtex->tex;
00958     ob= mtex->object;
00959     texco= mtex->texco;
00960 
00961     if(R.osa==0) {
00962         
00963         if(wrap==MTEX_FLAT) {
00964             fx = (t[0] + 1.0f) / 2.0f;
00965             fy = (t[1] + 1.0f) / 2.0f;
00966         }
00967         else if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]);
00968         else if(wrap==MTEX_SPHERE) map_to_sphere( &fx, &fy,t[0], t[1], t[2]);
00969         else {
00970             if(texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
00971             else if(texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
00972             else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
00973         }
00974         
00975         /* repeat */
00976         if(tex->extend==TEX_REPEAT) {
00977             if(tex->xrepeat>1) {
00978                 float origf= fx *= tex->xrepeat;
00979                 
00980                 if(fx>1.0f) fx -= (int)(fx);
00981                 else if(fx<0.0f) fx+= 1-(int)(fx);
00982                 
00983                 if(tex->flag & TEX_REPEAT_XMIR) {
00984                     int orig= (int)floor(origf);
00985                     if(orig & 1)
00986                         fx= 1.0f-fx;
00987                 }
00988             }
00989             if(tex->yrepeat>1) {
00990                 float origf= fy *= tex->yrepeat;
00991                 
00992                 if(fy>1.0f) fy -= (int)(fy);
00993                 else if(fy<0.0f) fy+= 1-(int)(fy);
00994                 
00995                 if(tex->flag & TEX_REPEAT_YMIR) {
00996                     int orig= (int)floor(origf);
00997                     if(orig & 1) 
00998                         fy= 1.0f-fy;
00999                 }
01000             }
01001         }
01002         /* crop */
01003         if(tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) {
01004             fac1= tex->cropxmax - tex->cropxmin;
01005             fx= tex->cropxmin+ fx*fac1;
01006         }
01007         if(tex->cropymin!=0.0f || tex->cropymax!=1.0f) {
01008             fac1= tex->cropymax - tex->cropymin;
01009             fy= tex->cropymin+ fy*fac1;
01010         }
01011 
01012         t[0]= fx;
01013         t[1]= fy;
01014     }
01015     else {
01016         
01017         if(wrap==MTEX_FLAT) {
01018             fx= (t[0] + 1.0f) / 2.0f;
01019             fy= (t[1] + 1.0f) / 2.0f;
01020             dxt[0]/= 2.0f;
01021             dxt[1]/= 2.0f;
01022             dxt[2]/= 2.0f;
01023             dyt[0]/= 2.0f;
01024             dyt[1]/= 2.0f;
01025             dyt[2]/= 2.0f;
01026         }
01027         else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) {
01028             /* exception: the seam behind (y<0.0) */
01029             ok= 1;
01030             if(t[1]<=0.0f) {
01031                 fx= t[0]+dxt[0];
01032                 fy= t[0]+dyt[0];
01033                 if(fx>=0.0f && fy>=0.0f && t[0]>=0.0f);
01034                 else if(fx<=0.0f && fy<=0.0f && t[0]<=0.0f);
01035                 else ok= 0;
01036             }
01037             if(ok) {
01038                 if(wrap==MTEX_TUBE) {
01039                     map_to_tube( area, area+1,t[0], t[1], t[2]);
01040                     map_to_tube( area+2, area+3,t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2]);
01041                     map_to_tube( area+4, area+5,t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2]);
01042                 }
01043                 else { 
01044                     map_to_sphere(area,area+1,t[0], t[1], t[2]);
01045                     map_to_sphere( area+2, area+3,t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2]);
01046                     map_to_sphere( area+4, area+5,t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2]);
01047                 }
01048                 areaflag= 1;
01049             }
01050             else {
01051                 if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]);
01052                 else map_to_sphere( &fx, &fy,t[0], t[1], t[2]);
01053                 dxt[0]/= 2.0f;
01054                 dxt[1]/= 2.0f;
01055                 dyt[0]/= 2.0f;
01056                 dyt[1]/= 2.0f;
01057             }
01058         }
01059         else {
01060 
01061             if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
01062             else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
01063             else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
01064 
01065             if(proj==1) {
01066                 SWAP(float, dxt[1], dxt[2]);
01067                 SWAP(float, dyt[1], dyt[2]);
01068             }
01069             else if(proj==2) {
01070                 float f1= dxt[0], f2= dyt[0];
01071                 dxt[0]= dxt[1];
01072                 dyt[0]= dyt[1];
01073                 dxt[1]= dxt[2];
01074                 dyt[1]= dyt[2];
01075                 dxt[2]= f1;
01076                 dyt[2]= f2;
01077             }
01078 
01079             dxt[0] *= 0.5f;
01080             dxt[1] *= 0.5f;
01081             dxt[2] *= 0.5f;
01082 
01083             dyt[0] *= 0.5f;
01084             dyt[1] *= 0.5f;
01085             dyt[2] *= 0.5f;
01086 
01087         }
01088         
01089         /* if area, then reacalculate dxt[] and dyt[] */
01090         if(areaflag) {
01091             fx= area[0]; 
01092             fy= area[1];
01093             dxt[0]= area[2]-fx;
01094             dxt[1]= area[3]-fy;
01095             dyt[0]= area[4]-fx;
01096             dyt[1]= area[5]-fy;
01097         }
01098         
01099         /* repeat */
01100         if(tex->extend==TEX_REPEAT) {
01101             float max= 1.0f;
01102             if(tex->xrepeat>1) {
01103                 float origf= fx *= tex->xrepeat;
01104                 
01105                 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
01106                 if (tex->texfilter == TXF_BOX) {
01107                     if(fx>1.0f) fx -= (int)(fx);
01108                     else if(fx<0.0f) fx+= 1-(int)(fx);
01109                 
01110                     if(tex->flag & TEX_REPEAT_XMIR) {
01111                         int orig= (int)floor(origf);
01112                         if(orig & 1) 
01113                             fx= 1.0f-fx;
01114                     }
01115                 }
01116                 
01117                 max= tex->xrepeat;
01118                 
01119                 dxt[0]*= tex->xrepeat;
01120                 dyt[0]*= tex->xrepeat;
01121             }
01122             if(tex->yrepeat>1) {
01123                 float origf= fy *= tex->yrepeat;
01124                 
01125                 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
01126                 if (tex->texfilter == TXF_BOX) {
01127                     if(fy>1.0f) fy -= (int)(fy);
01128                     else if(fy<0.0f) fy+= 1-(int)(fy);
01129                 
01130                     if(tex->flag & TEX_REPEAT_YMIR) {
01131                         int orig= (int)floor(origf);
01132                         if(orig & 1) 
01133                             fy= 1.0f-fy;
01134                     }
01135                 }
01136                 
01137                 if(max<tex->yrepeat)
01138                     max= tex->yrepeat;
01139 
01140                 dxt[1]*= tex->yrepeat;
01141                 dyt[1]*= tex->yrepeat;
01142             }
01143             if(max!=1.0f) {
01144                 dxt[2]*= max;
01145                 dyt[2]*= max;
01146             }
01147             
01148         }
01149         /* crop */
01150         if(tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) {
01151             fac1= tex->cropxmax - tex->cropxmin;
01152             fx= tex->cropxmin+ fx*fac1;
01153             dxt[0]*= fac1;
01154             dyt[0]*= fac1;
01155         }
01156         if(tex->cropymin!=0.0f || tex->cropymax!=1.0f) {
01157             fac1= tex->cropymax - tex->cropymin;
01158             fy= tex->cropymin+ fy*fac1;
01159             dxt[1]*= fac1;
01160             dyt[1]*= fac1;
01161         }
01162         
01163         t[0]= fx;
01164         t[1]= fy;
01165 
01166     }
01167 }
01168 
01169 /* ************************************** */
01170 
01171 static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
01172 {
01173     float tmpvec[3];
01174     int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
01175 
01176     texres->talpha= 0;  /* is set when image texture returns alpha (considered premul) */
01177     
01178     if(tex->use_nodes && tex->nodetree) {
01179         retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
01180             tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL);
01181     }
01182     else
01183     switch(tex->type) {
01184     
01185     case 0:
01186         texres->tin= 0.0f;
01187         return 0;
01188     case TEX_CLOUDS:
01189         retval= clouds(tex, texvec, texres);
01190         break;
01191     case TEX_WOOD:
01192         retval= wood(tex, texvec, texres); 
01193         break;
01194     case TEX_MARBLE:
01195         retval= marble(tex, texvec, texres); 
01196         break;
01197     case TEX_MAGIC:
01198         retval= magic(tex, texvec, texres); 
01199         break;
01200     case TEX_BLEND:
01201         retval= blend(tex, texvec, texres);
01202         break;
01203     case TEX_STUCCI:
01204         retval= stucci(tex, texvec, texres); 
01205         break;
01206     case TEX_NOISE:
01207         retval= texnoise(tex, texres); 
01208         break;
01209     case TEX_IMAGE:
01210         if(osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres);
01211         else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); 
01212         tag_image_time(tex->ima); /* tag image as having being used */
01213         break;
01214     case TEX_PLUGIN:
01215         retval= plugintex(tex, texvec, dxt, dyt, osatex, texres);
01216         break;
01217     case TEX_ENVMAP:
01218         retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres);
01219         break;
01220     case TEX_MUSGRAVE:
01221         /* newnoise: musgrave types */
01222         
01223         /* ton: added this, for Blender convention reason. 
01224          * artificer: added the use of tmpvec to avoid scaling texvec
01225          */
01226         copy_v3_v3(tmpvec, texvec);
01227         mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
01228         
01229         switch(tex->stype) {
01230         case TEX_MFRACTAL:
01231         case TEX_FBM:
01232             retval= mg_mFractalOrfBmTex(tex, tmpvec, texres);
01233             break;
01234         case TEX_RIDGEDMF:
01235         case TEX_HYBRIDMF:
01236             retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres);
01237             break;
01238         case TEX_HTERRAIN:
01239             retval= mg_HTerrainTex(tex, tmpvec, texres);
01240             break;
01241         }
01242         break;
01243     /* newnoise: voronoi type */
01244     case TEX_VORONOI:
01245         /* ton: added this, for Blender convention reason.
01246          * artificer: added the use of tmpvec to avoid scaling texvec
01247          */
01248         copy_v3_v3(tmpvec, texvec);
01249         mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
01250         
01251         retval= voronoiTex(tex, tmpvec, texres);
01252         break;
01253     case TEX_DISTNOISE:
01254         /* ton: added this, for Blender convention reason.
01255          * artificer: added the use of tmpvec to avoid scaling texvec
01256          */
01257         copy_v3_v3(tmpvec, texvec);
01258         mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
01259         
01260         retval= mg_distNoiseTex(tex, tmpvec, texres);
01261         break;
01262     case TEX_POINTDENSITY:
01263         retval= pointdensitytex(tex, texvec, texres);
01264         break;
01265     case TEX_VOXELDATA:
01266         retval= voxeldatatex(tex, texvec, texres);  
01267         break;
01268     case TEX_OCEAN:
01269         retval= ocean_texture(tex, texvec, texres);  
01270         break;
01271     }
01272 
01273     if (tex->flag & TEX_COLORBAND) {
01274         float col[4];
01275         if (do_colorband(tex->coba, texres->tin, col)) {
01276             texres->talpha= 1;
01277             texres->tr= col[0];
01278             texres->tg= col[1];
01279             texres->tb= col[2];
01280             texres->ta= col[3];
01281             retval |= TEX_RGB;
01282         }
01283     }
01284     return retval;
01285 }
01286 
01287 /* this is called from the shader and texture nodes */
01288 int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex)
01289 {
01290     if(tex==NULL) {
01291         memset(texres, 0, sizeof(TexResult));
01292         return 0;
01293     }
01294 
01295     if(mtex)
01296         which_output= mtex->which_output;
01297     
01298     if(tex->type==TEX_IMAGE) {
01299         int rgbnor;
01300 
01301         if(mtex) {
01302             /* we have mtex, use it for 2d mapping images only */
01303             do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
01304             rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
01305 
01306             if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
01307                 ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
01308                 
01309                 /* don't linearize float buffers, assumed to be linear */
01310                 if(ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
01311                     srgb_to_linearrgb_v3_v3(&texres->tr, &texres->tr);
01312             }
01313         }
01314         else {
01315             /* we don't have mtex, do default flat 2d projection */
01316             MTex localmtex;
01317             float texvec_l[3], dxt_l[3], dyt_l[3];
01318             
01319             localmtex.mapping= MTEX_FLAT;
01320             localmtex.tex= tex;
01321             localmtex.object= NULL;
01322             localmtex.texco= TEXCO_ORCO;
01323             
01324             copy_v3_v3(texvec_l, texvec);
01325             if(dxt && dyt) {
01326                 copy_v3_v3(dxt_l, dxt);
01327                 copy_v3_v3(dyt_l, dyt);
01328             }
01329             else {
01330                 zero_v3(dxt_l);
01331                 zero_v3(dyt_l);
01332             }
01333             
01334             do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
01335             rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
01336         }
01337 
01338         return rgbnor;
01339     }
01340     else
01341         return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
01342 }
01343 
01344 /* this is called for surface shading */
01345 int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres)
01346 {
01347     Tex *tex= mtex->tex;
01348 
01349     if(tex->use_nodes && tex->nodetree) {
01350         /* stupid exception here .. but we have to pass shi and mtex to
01351            textures nodes for 2d mapping and color management for images */
01352         return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
01353             tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
01354     }
01355     else
01356         return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output);
01357 }
01358 
01359 /* Warning, if the texres's values are not declared zero, check the return value to be sure
01360  * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
01361 int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
01362 {
01363     return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL);
01364 }
01365 
01366 /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */
01367 int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres)
01368 {
01369     int use_nodes= tex->use_nodes, retval;
01370     
01371     tex->use_nodes= 0;
01372     retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL);
01373     tex->use_nodes= use_nodes;
01374     
01375     return retval;
01376 }
01377 
01378 
01379 /* ------------------------------------------------------------------------- */
01380 
01381 /* in = destination, tex = texture, out = previous color */
01382 /* fact = texture strength, facg = button strength value */
01383 void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype)
01384 {
01385     float facm, col;
01386     
01387     switch(blendtype) {
01388     case MTEX_BLEND:
01389         fact*= facg;
01390         facm= 1.0f-fact;
01391 
01392         in[0]= (fact*tex[0] + facm*out[0]);
01393         in[1]= (fact*tex[1] + facm*out[1]);
01394         in[2]= (fact*tex[2] + facm*out[2]);
01395         break;
01396         
01397     case MTEX_MUL:
01398         fact*= facg;
01399         facm= 1.0f-facg;
01400         in[0]= (facm+fact*tex[0])*out[0];
01401         in[1]= (facm+fact*tex[1])*out[1];
01402         in[2]= (facm+fact*tex[2])*out[2];
01403         break;
01404 
01405     case MTEX_SCREEN:
01406         fact*= facg;
01407         facm= 1.0f-facg;
01408         in[0]= 1.0f - (facm+fact*(1.0f-tex[0])) * (1.0f-out[0]);
01409         in[1]= 1.0f - (facm+fact*(1.0f-tex[1])) * (1.0f-out[1]);
01410         in[2]= 1.0f - (facm+fact*(1.0f-tex[2])) * (1.0f-out[2]);
01411         break;
01412 
01413     case MTEX_OVERLAY:
01414         fact*= facg;
01415         facm= 1.0f-facg;
01416         
01417         if(out[0] < 0.5f)
01418             in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
01419         else
01420             in[0] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[0])) * (1.0f - out[0]);
01421         if(out[1] < 0.5f)
01422             in[1] = out[1] * (facm + 2.0f*fact*tex[1]);
01423         else
01424             in[1] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[1])) * (1.0f - out[1]);
01425         if(out[2] < 0.5f)
01426             in[2] = out[2] * (facm + 2.0f*fact*tex[2]);
01427         else
01428             in[2] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[2])) * (1.0f - out[2]);
01429         break;
01430         
01431     case MTEX_SUB:
01432         fact= -fact;
01433     case MTEX_ADD:
01434         fact*= facg;
01435         in[0]= (fact*tex[0] + out[0]);
01436         in[1]= (fact*tex[1] + out[1]);
01437         in[2]= (fact*tex[2] + out[2]);
01438         break;
01439 
01440     case MTEX_DIV:
01441         fact*= facg;
01442         facm= 1.0f-fact;
01443         
01444         if(tex[0]!=0.0f)
01445             in[0]= facm*out[0] + fact*out[0]/tex[0];
01446         if(tex[1]!=0.0f)
01447             in[1]= facm*out[1] + fact*out[1]/tex[1];
01448         if(tex[2]!=0.0f)
01449             in[2]= facm*out[2] + fact*out[2]/tex[2];
01450 
01451         break;
01452 
01453     case MTEX_DIFF:
01454         fact*= facg;
01455         facm= 1.0f-fact;
01456         in[0]= facm*out[0] + fact*fabsf(tex[0]-out[0]);
01457         in[1]= facm*out[1] + fact*fabsf(tex[1]-out[1]);
01458         in[2]= facm*out[2] + fact*fabsf(tex[2]-out[2]);
01459         break;
01460 
01461     case MTEX_DARK:
01462         fact*= facg;
01463         facm= 1.0f-fact;
01464         
01465         col= tex[0]+((1-tex[0])*facm);
01466         if(col < out[0]) in[0]= col; else in[0]= out[0];
01467         col= tex[1]+((1-tex[1])*facm);
01468         if(col < out[1]) in[1]= col; else in[1]= out[1];
01469         col= tex[2]+((1-tex[2])*facm);
01470         if(col < out[2]) in[2]= col; else in[2]= out[2];
01471         break;
01472 
01473     case MTEX_LIGHT:
01474         fact*= facg;
01475         
01476         col= fact*tex[0];
01477         if(col > out[0]) in[0]= col; else in[0]= out[0];
01478         col= fact*tex[1];
01479         if(col > out[1]) in[1]= col; else in[1]= out[1];
01480         col= fact*tex[2];
01481         if(col > out[2]) in[2]= col; else in[2]= out[2];
01482         break;
01483         
01484     case MTEX_BLEND_HUE:
01485         fact*= facg;
01486         copy_v3_v3(in, out);
01487         ramp_blend(MA_RAMP_HUE, in, fact, tex);
01488         break;
01489     case MTEX_BLEND_SAT:
01490         fact*= facg;
01491         copy_v3_v3(in, out);
01492         ramp_blend(MA_RAMP_SAT, in, fact, tex);
01493         break;
01494     case MTEX_BLEND_VAL:
01495         fact*= facg;
01496         copy_v3_v3(in, out);
01497         ramp_blend(MA_RAMP_VAL, in, fact, tex);
01498         break;
01499     case MTEX_BLEND_COLOR:
01500         fact*= facg;
01501         copy_v3_v3(in, out);
01502         ramp_blend(MA_RAMP_COLOR, in, fact, tex);
01503         break;
01504     case MTEX_SOFT_LIGHT: 
01505         fact*= facg; 
01506         copy_v3_v3(in, out);
01507         ramp_blend(MA_RAMP_SOFT, in, fact, tex);
01508         break; 
01509     case MTEX_LIN_LIGHT: 
01510         fact*= facg; 
01511         copy_v3_v3(in, out);
01512         ramp_blend(MA_RAMP_LINEAR, in, fact, tex);
01513         break; 
01514     }
01515 }
01516 
01517 float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
01518 {
01519     float in=0.0, facm, col, scf;
01520     int flip= (facg < 0.0f);
01521 
01522     facg= fabsf(facg);
01523     
01524     fact*= facg;
01525     facm= 1.0f-fact;
01526     if(flip) SWAP(float, fact, facm);
01527 
01528     switch(blendtype) {
01529     case MTEX_BLEND:
01530         in= fact*tex + facm*out;
01531         break;
01532 
01533     case MTEX_MUL:
01534         facm= 1.0f-facg;
01535         in= (facm+fact*tex)*out;
01536         break;
01537 
01538     case MTEX_SCREEN:
01539         facm= 1.0f-facg;
01540         in= 1.0f-(facm+fact*(1.0f-tex))*(1.0f-out);
01541         break;
01542 
01543     case MTEX_OVERLAY:
01544         facm= 1.0f-facg;
01545         if(out < 0.5f)
01546             in = out * (facm + 2.0f*fact*tex);
01547         else
01548             in = 1.0f - (facm + 2.0f*fact*(1.0f - tex)) * (1.0f - out);
01549         break;
01550 
01551     case MTEX_SUB:
01552         fact= -fact;
01553     case MTEX_ADD:
01554         in= fact*tex + out;
01555         break;
01556 
01557     case MTEX_DIV:
01558         if(tex!=0.0f)
01559             in= facm*out + fact*out/tex;
01560         break;
01561 
01562     case MTEX_DIFF:
01563         in= facm*out + fact*fabsf(tex-out);
01564         break;
01565 
01566     case MTEX_DARK:
01567         col= fact*tex;
01568         if(col < out) in= col; else in= out;
01569         break;
01570 
01571     case MTEX_LIGHT:
01572         col= fact*tex;
01573         if(col > out) in= col; else in= out;
01574         break;
01575 
01576     case MTEX_SOFT_LIGHT: 
01577         scf=1.0f - (1.0f - tex) * (1.0f - out);
01578         in= facm*out + fact * ((1.0f - out) * tex * out) + (out * scf);
01579         break;       
01580 
01581     case MTEX_LIN_LIGHT: 
01582         if (tex > 0.5f)
01583             in = out + fact*(2.0f*(tex - 0.5f));
01584         else 
01585             in = out + fact*(2.0f*tex - 1.0f);
01586         break;
01587     }
01588     
01589     return in;
01590 }
01591 
01592 static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt)
01593 {
01594     // new: first swap coords, then map, then trans/scale
01595     if (tex->type == TEX_IMAGE) {
01596         // placement
01597         texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f;
01598         texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f;
01599         texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f;
01600 
01601         if (shi->osatex) {
01602             if (mtex->projx) {
01603                 dxt[0] = dx[mtex->projx - 1];
01604                 dyt[0] = dy[mtex->projx - 1];
01605             }
01606             else dxt[0] = dyt[0] = 0.f;
01607             if (mtex->projy) {
01608                 dxt[1] = dx[mtex->projy - 1];
01609                 dyt[1] = dy[mtex->projy - 1];
01610             }
01611             else dxt[1] = dyt[1] = 0.f;
01612             if (mtex->projz) {
01613                 dxt[2] = dx[mtex->projz - 1];
01614                 dyt[2] = dy[mtex->projz - 1];
01615             }
01616             else dxt[2] = dyt[2] = 0.f;
01617         }
01618         do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
01619 
01620         // translate and scale
01621         texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f;
01622         texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f;
01623         if (shi->osatex) {
01624             dxt[0] = mtex->size[0]*dxt[0];
01625             dxt[1] = mtex->size[1]*dxt[1];
01626             dyt[0] = mtex->size[0]*dyt[0];
01627             dyt[1] = mtex->size[1]*dyt[1];
01628         }
01629         
01630         /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */
01631         // TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too.
01632         // New texfilters solve mirroring differently so that it also works correctly when
01633         // textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping().
01634         // (since currently only done in osa mode, results will look incorrect without osa TODO) 
01635         if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) {
01636             if (tex->texfilter == TXF_BOX)
01637                 texvec[0] -= floorf(texvec[0]); // this line equivalent to old code, same below
01638             else if (texvec[0] < 0.f || texvec[0] > 1.f) {
01639                 const float tx = 0.5f*texvec[0];
01640                 texvec[0] = 2.f*(tx - floorf(tx));
01641                 if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0];
01642             }
01643         }
01644         if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) {
01645             if  (tex->texfilter == TXF_BOX)
01646                 texvec[1] -= floorf(texvec[1]);
01647             else if (texvec[1] < 0.f || texvec[1] > 1.f) {
01648                 const float ty = 0.5f*texvec[1];
01649                 texvec[1] = 2.f*(ty - floorf(ty));
01650                 if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1];
01651             }
01652         }
01653         
01654     }
01655     else {  // procedural
01656         // placement
01657         texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]);
01658         texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]);
01659         texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]);
01660 
01661         if (shi->osatex) {
01662             if (mtex->projx) {
01663                 dxt[0] = mtex->size[0]*dx[mtex->projx - 1];
01664                 dyt[0] = mtex->size[0]*dy[mtex->projx - 1];
01665             }
01666             else dxt[0] = dyt[0] = 0.f;
01667             if (mtex->projy) {
01668                 dxt[1] = mtex->size[1]*dx[mtex->projy - 1];
01669                 dyt[1] = mtex->size[1]*dy[mtex->projy - 1];
01670             }
01671             else dxt[1] = dyt[1] = 0.f;
01672             if (mtex->projz) {
01673                 dxt[2] = mtex->size[2]*dx[mtex->projz - 1];
01674                 dyt[2] = mtex->size[2]*dy[mtex->projz - 1];
01675             }
01676             else dxt[2]= dyt[2] = 0.f;
01677         }
01678     }
01679 }
01680 
01681 /* Bump code from 2.5 development cycle, has a number of bugs, but here for compatibility */
01682 
01683 typedef struct CompatibleBump {
01684     float nu[3], nv[3], nn[3];
01685     float dudnu, dudnv, dvdnu, dvdnv;
01686     int nunvdone;
01687 } CompatibleBump;
01688 
01689 static void compatible_bump_init(CompatibleBump *compat_bump)
01690 {
01691     memset(compat_bump, 0, sizeof(*compat_bump));
01692 
01693     compat_bump->dudnu = 1.0f;
01694     compat_bump->dvdnv = 1.0f;
01695 }
01696 
01697 static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, int i)
01698 {
01699     // uvmapping only, calculation of normal tangent u/v partial derivatives
01700     // (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
01701     //  nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
01702     // NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
01703     // NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know.
01704     if ((mtex->texflag & MTEX_COMPAT_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
01705         if(mtex->mapto & (MAP_NORM|MAP_WARP) && !((mtex->tex->type==TEX_IMAGE) && (mtex->tex->imaflag & TEX_NORMALMAP))) {
01706             MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
01707             int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
01708 
01709             vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
01710 
01711             // compute ortho basis around normal
01712             if(!compat_bump->nunvdone) {
01713                 // render normal is negated
01714                 compat_bump->nn[0] = -shi->vn[0];
01715                 compat_bump->nn[1] = -shi->vn[1];
01716                 compat_bump->nn[2] = -shi->vn[2];
01717                 ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
01718                 compat_bump->nunvdone= 1;
01719             }
01720 
01721             if (tf) {
01722                 float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
01723                 const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])};
01724                 const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
01725                 const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
01726                 const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
01727                 const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
01728                 const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
01729                 const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
01730                 const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
01731                 const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
01732                 const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
01733                 const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
01734                 const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
01735                 const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
01736                 float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
01737                 float uvd = du1*dv2 - dv1*du2;
01738 
01739                 if (uvd == 0.f) uvd = 1e-5f;
01740                 if (d == 0.f) d = 1e-5f;
01741                 d = uvd / d;
01742 
01743                 compat_bump->dudnu = (dpdv_a2*compat_bump->nu[a1] - dpdv_a1*compat_bump->nu[a2])*d;
01744                 compat_bump->dvdnu = (dpdu_a1*compat_bump->nu[a2] - dpdu_a2*compat_bump->nu[a1])*d;
01745                 compat_bump->dudnv = (dpdv_a2*compat_bump->nv[a1] - dpdv_a1*compat_bump->nv[a2])*d;
01746                 compat_bump->dvdnv = (dpdu_a1*compat_bump->nv[a2] - dpdu_a2*compat_bump->nv[a1])*d;
01747             }
01748         }
01749     }
01750 }
01751 
01752 static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt)
01753 {
01754     TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL};    // temp TexResult
01755     float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
01756     const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
01757     const float bf = -0.04f*Tnor*mtex->norfac;
01758     int rgbnor;
01759     // disable internal bump eval
01760     float* nvec = texres->nor;
01761     texres->nor = NULL;
01762     // du & dv estimates, constant value defaults
01763     du = dv = 0.01f;
01764 
01765     // compute ortho basis around normal
01766     if(!compat_bump->nunvdone) {
01767         // render normal is negated
01768         negate_v3_v3(compat_bump->nn, shi->vn);
01769         ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
01770         compat_bump->nunvdone= 1;
01771     }
01772 
01773     // two methods, either constant based on main image resolution,
01774     // (which also works without osa, though of course not always good (or even very bad) results),
01775     // or based on tex derivative max values (osa only). Not sure which is best...
01776 
01777     if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
01778         // in case we have no proper derivatives, fall back to
01779         // computing du/dv it based on image size
01780         ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
01781         if (ibuf) {
01782             du = 1.f/(float)ibuf->x;
01783             dv = 1.f/(float)ibuf->y;
01784         }
01785     }
01786     else if (shi->osatex) {
01787         // we have derivatives, can compute proper du/dv
01788         if (tex->type == TEX_IMAGE) {   // 2d image, use u & v max. of dx/dy 2d vecs
01789             const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])};
01790             const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])};
01791             du = MAX2(adx[0], ady[0]);
01792             dv = MAX2(adx[1], ady[1]);
01793         }
01794         else {  // 3d procedural, estimate from all dx/dy elems
01795             const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
01796             const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
01797             du = MAX3(adx[0], adx[1], adx[2]);
01798             dv = MAX3(ady[0], ady[1], ady[2]);
01799         }
01800     }
01801 
01802     // center, main return value
01803     texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
01804     rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
01805     cd = fromrgb ? (texres->tr + texres->tg + texres->tb)*0.33333333f : texres->tin;
01806 
01807     if (mtex->texco == TEXCO_UV) {
01808         // for the uv case, use the same value for both du/dv,
01809         // since individually scaling the normal derivatives makes them useless...
01810         du = MIN2(du, dv);
01811         idu = (du < 1e-5f) ? bf : (bf/du);
01812 
01813         // +u val
01814         tco[0] = co[0] + compat_bump->dudnu*du;
01815         tco[1] = co[1] + compat_bump->dvdnu*du;
01816         tco[2] = 0.f;
01817         texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
01818         multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
01819         ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
01820 
01821         // +v val
01822         tco[0] = co[0] + compat_bump->dudnv*du;
01823         tco[1] = co[1] + compat_bump->dvdnv*du;
01824         tco[2] = 0.f;
01825         texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
01826         multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
01827         vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
01828     }
01829     else {
01830         float tu[3], tv[3];
01831 
01832         copy_v3_v3(tu, compat_bump->nu);
01833         copy_v3_v3(tv, compat_bump->nv);
01834 
01835         idu = (du < 1e-5f) ? bf : (bf/du);
01836         idv = (dv < 1e-5f) ? bf : (bf/dv);
01837 
01838         if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
01839             mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu);
01840             mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv);
01841             normalize_v3(tu);
01842             normalize_v3(tv);
01843         }
01844         else if (mtex->texco == TEXCO_GLOB) {
01845             mul_mat3_m4_v3(R.viewinv, tu);
01846             mul_mat3_m4_v3(R.viewinv, tv);
01847         }
01848         else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
01849             mul_mat3_m4_v3(mtex->object->imat_ren, tu);
01850             mul_mat3_m4_v3(mtex->object->imat_ren, tv);
01851             normalize_v3(tu);
01852             normalize_v3(tv);
01853         }
01854 
01855         // +u val
01856         tco[0] = co[0] + tu[0]*du;
01857         tco[1] = co[1] + tu[1]*du;
01858         tco[2] = co[2] + tu[2]*du;
01859         texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
01860         multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
01861         ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
01862 
01863         // +v val
01864         tco[0] = co[0] + tv[0]*dv;
01865         tco[1] = co[1] + tv[1]*dv;
01866         tco[2] = co[2] + tv[2]*dv;
01867         texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
01868         multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
01869         vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
01870     }
01871 
01872     // bumped normal
01873     compat_bump->nu[0] += ud*compat_bump->nn[0];
01874     compat_bump->nu[1] += ud*compat_bump->nn[1];
01875     compat_bump->nu[2] += ud*compat_bump->nn[2];
01876     compat_bump->nv[0] += vd*compat_bump->nn[0];
01877     compat_bump->nv[1] += vd*compat_bump->nn[1];
01878     compat_bump->nv[2] += vd*compat_bump->nn[2];
01879     cross_v3_v3v3(nvec, compat_bump->nu, compat_bump->nv);
01880 
01881     nvec[0] = -nvec[0];
01882     nvec[1] = -nvec[1];
01883     nvec[2] = -nvec[2];
01884     texres->nor = nvec;
01885 
01886     rgbnor |= TEX_NOR;
01887     return rgbnor;
01888 }
01889 
01890 /* Improved bump code from later in 2.5 development cycle */
01891 
01892 typedef struct NTapBump {
01893     int init_done;
01894     int iPrevBumpSpace; // 0: uninitialized, 1: objectspace, 2: texturespace, 4: viewspace
01895     // bumpmapping
01896     float vNorg[3]; // backup copy of shi->vn
01897     float vNacc[3]; // original surface normal minus the surface gradient of every bump map which is encountered
01898     float vR1[3], vR2[3]; // cross products (sigma_y, original_normal), (original_normal, sigma_x)
01899     float sgn_det; // sign of the determinant of the matrix {sigma_x, sigma_y, original_normal}
01900     float fPrevMagnitude; // copy of previous magnitude, used for multiple bumps in different spaces
01901 } NTapBump;
01902 
01903 static void ntap_bump_init(NTapBump *ntap_bump)
01904 {
01905     memset(ntap_bump, 0, sizeof(*ntap_bump));
01906 }
01907 
01908 static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt)
01909 {
01910     TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL};    // temp TexResult
01911 
01912     const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
01913 
01914     // The negate on Hscale is done because the
01915     // normal in the renderer points inward which corresponds
01916     // to inverting the bump map. The normals are generated
01917     // this way in calc_vertexnormals(). Should this ever change
01918     // this negate must be removed.
01919     float Hscale = -Tnor*mtex->norfac;
01920 
01921     int dimx=512, dimy=512;
01922     const int imag_tspace_dimension_x = 1024;       // only used for texture space variant
01923     float aspect = 1.0f;
01924 
01925     // 2 channels for 2D texture and 3 for 3D textures.
01926     const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
01927     int c, rgbnor, iBumpSpace;
01928     float dHdx, dHdy;
01929     int found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
01930 
01931     // disable internal bump eval in sampler, save pointer
01932     float *nvec = texres->nor;
01933     texres->nor = NULL;
01934 
01935     if(found_deriv_map==0) {
01936         if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
01937             if(tex->ima)
01938                 Hscale *= 13.0f; // appears to be a sensible default value
01939         } else
01940             Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code
01941     }
01942 
01943     if( !ntap_bump->init_done ) {
01944         copy_v3_v3(ntap_bump->vNacc, shi->vn);
01945         copy_v3_v3(ntap_bump->vNorg, shi->vn);
01946         ntap_bump->fPrevMagnitude = 1.0f;
01947         ntap_bump->iPrevBumpSpace = 0;
01948         
01949         ntap_bump->init_done = 1;
01950     }
01951 
01952     // resolve image dimensions
01953     if(found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
01954         ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
01955         if (ibuf) {
01956             dimx = ibuf->x;
01957             dimy = ibuf->y;
01958             aspect = ((float) dimy) / dimx;
01959         }
01960     }
01961     
01962     if(found_deriv_map) {
01963         float dBdu, dBdv, auto_bump = 1.0f;
01964         float s = 1;        // negate this if flipped texture coordinate
01965         texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
01966         rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
01967 
01968         if(shi->obr->ob->derivedFinal)
01969         {
01970             auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
01971         }
01972         {
01973             float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1]));
01974             auto_bump /= MAX2(fVirtDim, FLT_EPSILON);
01975         }
01976         
01977         // this variant using a derivative map is described here
01978         // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
01979         dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1);
01980         dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1);
01981 
01982         dHdx = dBdu*dxt[0] + s * dBdv*dxt[1];
01983         dHdy = dBdu*dyt[0] + s * dBdv*dyt[1];
01984     }
01985     else if(!(mtex->texflag & MTEX_5TAP_BUMP)) {
01986         // compute height derivatives with respect to output image pixel coordinates x and y
01987         float STll[3], STlr[3], STul[3];
01988         float Hll, Hlr, Hul;
01989 
01990         texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
01991 
01992         for(c=0; c<nr_channels; c++) {
01993             // dx contains the derivatives (du/dx, dv/dx)
01994             // dy contains the derivatives (du/dy, dv/dy)
01995             STll[c] = texvec[c];
01996             STlr[c] = texvec[c]+dxt[c];
01997             STul[c] = texvec[c]+dyt[c];
01998         }
01999 
02000         // clear unused derivatives
02001         for(c=nr_channels; c<3; c++) {
02002             STll[c] = 0.0f;
02003             STlr[c] = 0.0f;
02004             STul[c] = 0.0f;
02005         }
02006 
02007         // use texres for the center sample, set rgbnor
02008         rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres);
02009         Hll = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin;
02010 
02011         // use ttexr for the other 2 taps
02012         multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr);
02013         Hlr = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02014 
02015         multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr);
02016         Hul = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02017 
02018         dHdx = Hscale*(Hlr - Hll);
02019         dHdy = Hscale*(Hul - Hll);
02020     }
02021     else {
02022         /* same as above, but doing 5 taps, increasing quality at cost of speed */
02023         float STc[3], STl[3], STr[3], STd[3], STu[3];
02024         float /* Hc, */ /* UNUSED */  Hl, Hr, Hd, Hu;
02025 
02026         texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
02027 
02028         for(c=0; c<nr_channels; c++) {
02029             STc[c] = texvec[c];
02030             STl[c] = texvec[c] - 0.5f*dxt[c];
02031             STr[c] = texvec[c] + 0.5f*dxt[c];
02032             STd[c] = texvec[c] - 0.5f*dyt[c];
02033             STu[c] = texvec[c] + 0.5f*dyt[c];
02034         }
02035 
02036         // clear unused derivatives
02037         for(c=nr_channels; c<3; c++) {
02038             STc[c] = 0.0f;
02039             STl[c] = 0.0f;
02040             STr[c] = 0.0f;
02041             STd[c] = 0.0f;
02042             STu[c] = 0.0f;
02043         }
02044 
02045         // use texres for the center sample, set rgbnor
02046         rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres);
02047         /* Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; */ /* UNUSED */
02048 
02049         // use ttexr for the other taps
02050         multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr);
02051         Hl = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02052         multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr);
02053         Hr = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02054         multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr);
02055         Hd = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02056         multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr);
02057         Hu = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin;
02058 
02059         dHdx = Hscale*(Hr - Hl);
02060         dHdy = Hscale*(Hu - Hd);
02061     }
02062 
02063     // restore pointer
02064     texres->nor = nvec;
02065 
02066     /* replaced newbump with code based on listing 1 and 2 of
02067         [Mik10] Mikkelsen M. S.: Bump Mapping Unparametrized Surfaces on the GPU.
02068         -> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */
02069 
02070     if( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
02071         iBumpSpace = 1;
02072     else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
02073         iBumpSpace = 2;
02074     else
02075         iBumpSpace = 4; // ViewSpace
02076     
02077     if( ntap_bump->iPrevBumpSpace != iBumpSpace ) {
02078         
02079         // initialize normal perturbation vectors
02080         int xyz;
02081         float fDet, abs_fDet, fMagnitude;
02082         // object2view and inverted matrix
02083         float obj2view[3][3], view2obj[3][3], tmp[4][4];
02084         // local copies of derivatives and normal
02085         float dPdx[3], dPdy[3], vN[3];
02086         copy_v3_v3(dPdx, shi->dxco);
02087         copy_v3_v3(dPdy, shi->dyco);
02088         copy_v3_v3(vN, ntap_bump->vNorg);
02089         
02090         if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
02091             // TODO: these calculations happen for every pixel!
02092             //  -> move to shi->obi
02093             mult_m4_m4m4(tmp, R.viewmat, shi->obr->ob->obmat);
02094             copy_m3_m4(obj2view, tmp); // use only upper left 3x3 matrix
02095             invert_m3_m3(view2obj, obj2view);
02096         
02097             // generate the surface derivatives in object space
02098             mul_m3_v3(view2obj, dPdx);
02099             mul_m3_v3( view2obj, dPdy );
02100             // generate the unit normal in object space
02101             mul_transposed_m3_v3( obj2view, vN );
02102             normalize_v3(vN);
02103         }
02104         
02105         cross_v3_v3v3(ntap_bump->vR1, dPdy, vN);
02106         cross_v3_v3v3(ntap_bump->vR2, vN, dPdx);
02107         fDet = dot_v3v3(dPdx, ntap_bump->vR1);
02108         ntap_bump->sgn_det = (fDet < 0)? -1.0f: 1.0f;
02109         abs_fDet = ntap_bump->sgn_det * fDet;
02110 
02111         if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
02112             if(tex->ima) {
02113                 // crazy hack solution that gives results similar to normal mapping - part 1
02114                 normalize_v3(ntap_bump->vR1);
02115                 normalize_v3(ntap_bump->vR2);
02116                 abs_fDet = 1.0f;
02117             }
02118         }
02119         
02120         fMagnitude = abs_fDet;
02121         if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
02122             // pre do transform of texres->nor by the inverse transposed of obj2view
02123             mul_transposed_m3_v3( view2obj, vN );
02124             mul_transposed_m3_v3( view2obj, ntap_bump->vR1 );
02125             mul_transposed_m3_v3( view2obj, ntap_bump->vR2 );
02126             
02127             fMagnitude *= len_v3(vN);
02128         }
02129         
02130         for(xyz=0; xyz<3; xyz++)
02131                 ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude;
02132         
02133         ntap_bump->fPrevMagnitude = fMagnitude;
02134         ntap_bump->iPrevBumpSpace = iBumpSpace;
02135     }
02136 
02137     if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
02138         if(tex->ima) {
02139             // crazy hack solution that gives results similar to normal mapping - part 2
02140             float vec[2];
02141             const float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
02142             
02143             vec[0] = imag_tspace_dimension_x*dxt[0];
02144             vec[1] = imag_tspace_dimension_y*dxt[1];
02145             dHdx *= 1.0f/len_v2(vec);
02146             vec[0] = imag_tspace_dimension_x*dyt[0];
02147             vec[1] = imag_tspace_dimension_y*dyt[1];
02148             dHdy *= 1.0f/len_v2(vec);
02149         }
02150     }
02151     
02152     // subtract the surface gradient from vNacc
02153     for(c=0; c<3; c++) {
02154         float vSurfGrad_compi = ntap_bump->sgn_det * (dHdx * ntap_bump->vR1[c] + dHdy * ntap_bump->vR2[c]);
02155         ntap_bump->vNacc[c] -= vSurfGrad_compi;
02156         texres->nor[c] = ntap_bump->vNacc[c]; // copy
02157     }
02158 
02159     rgbnor |= TEX_NOR;
02160     return rgbnor;
02161 }
02162 
02163 void do_material_tex(ShadeInput *shi, Render *re)
02164 {
02165     CompatibleBump compat_bump;
02166     NTapBump ntap_bump;
02167     MTex *mtex;
02168     Tex *tex;
02169     TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
02170     float *co = NULL, *dx = NULL, *dy = NULL;
02171     float fact, facm, factt, facmm, stencilTin=1.0;
02172     float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
02173     int tex_nr, rgbnor= 0, warpdone=0;
02174     int use_compat_bump = 0, use_ntap_bump = 0;
02175     int found_nmapping = 0, found_deriv_map = 0;
02176     int iFirstTimeNMap=1;
02177 
02178     compatible_bump_init(&compat_bump);
02179     ntap_bump_init(&ntap_bump);
02180 
02181     if (re->r.scemode & R_NO_TEX) return;
02182     /* here: test flag if there's a tex (todo) */
02183 
02184     for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
02185         
02186         /* separate tex switching */
02187         if(shi->mat->septex & (1<<tex_nr)) continue;
02188         
02189         if(shi->mat->mtex[tex_nr]) {
02190             mtex= shi->mat->mtex[tex_nr];
02191             
02192             tex= mtex->tex;
02193             if(tex==0) continue;
02194 
02195             found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
02196             use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP);
02197             use_ntap_bump= ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? 1 : 0;
02198 
02199             /* XXX texture node trees don't work for this yet */
02200             if(tex->nodetree && tex->use_nodes) {
02201                 use_compat_bump = 0;
02202                 use_ntap_bump = 0;
02203             }
02204             
02205             /* case displacement mapping */
02206             if(shi->osatex==0 && use_ntap_bump) {
02207                 use_ntap_bump = 0;
02208                 use_compat_bump = 1;
02209             }
02210             
02211             /* case ocean */
02212             if(tex->type == TEX_OCEAN) {
02213                 use_ntap_bump = 0;
02214                 use_compat_bump = 0;
02215             }
02216 
02217             /* which coords */
02218             if(mtex->texco==TEXCO_ORCO) {
02219                 if(mtex->texflag & MTEX_DUPLI_MAPTO) {
02220                     co= shi->duplilo; dx= dxt; dy= dyt;
02221                     dxt[0]= dxt[1]= dxt[2]= 0.0f;
02222                     dyt[0]= dyt[1]= dyt[2]= 0.0f;
02223                 }
02224                 else {
02225                     co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
02226                 }
02227             }
02228             else if(mtex->texco==TEXCO_STICKY) {
02229                 co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
02230             }
02231             else if(mtex->texco==TEXCO_OBJECT) {
02232                 Object *ob= mtex->object;
02233                 if(ob) {
02234                     co= tempvec;
02235                     dx= dxt;
02236                     dy= dyt;
02237                     copy_v3_v3(tempvec, shi->co);
02238                     if(mtex->texflag & MTEX_OB_DUPLI_ORIG)
02239                         if(shi->obi && shi->obi->duplitexmat)
02240                             mul_m4_v3(shi->obi->duplitexmat, tempvec);
02241                     mul_m4_v3(ob->imat_ren, tempvec);
02242                     if(shi->osatex) {
02243                         copy_v3_v3(dxt, shi->dxco);
02244                         copy_v3_v3(dyt, shi->dyco);
02245                         mul_mat3_m4_v3(ob->imat_ren, dxt);
02246                         mul_mat3_m4_v3(ob->imat_ren, dyt);
02247                     }
02248                 }
02249                 else {
02250                     /* if object doesn't exist, do not use orcos (not initialized) */
02251                     co= shi->co;
02252                     dx= shi->dxco; dy= shi->dyco;
02253                 }
02254             }
02255             else if(mtex->texco==TEXCO_REFL) {
02256                 calc_R_ref(shi);
02257                 co= shi->ref; dx= shi->dxref; dy= shi->dyref;
02258             }
02259             else if(mtex->texco==TEXCO_NORM) {
02260                 co= shi->orn; dx= shi->dxno; dy= shi->dyno;
02261             }
02262             else if(mtex->texco==TEXCO_TANGENT) {
02263                 co= shi->tang; dx= shi->dxno; dy= shi->dyno;
02264             }
02265             else if(mtex->texco==TEXCO_GLOB) {
02266                 co= shi->gl; dx= shi->dxgl; dy= shi->dygl;
02267             }
02268             else if(mtex->texco==TEXCO_UV) {
02269                 if(mtex->texflag & MTEX_DUPLI_MAPTO) {
02270                     co= shi->dupliuv; dx= dxt; dy= dyt;
02271                     dxt[0]= dxt[1]= dxt[2]= 0.0f;
02272                     dyt[0]= dyt[1]= dyt[2]= 0.0f;
02273                 }
02274                 else {
02275                     ShadeInputUV *suv= &shi->uv[shi->actuv];
02276                     int i = shi->actuv;
02277 
02278                     if(mtex->uvname[0] != 0) {
02279                         for(i = 0; i < shi->totuv; i++) {
02280                             if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
02281                                 suv= &shi->uv[i];
02282                                 break;
02283                             }
02284                         }
02285                     }
02286 
02287                     co= suv->uv;
02288                     dx= suv->dxuv;
02289                     dy= suv->dyuv; 
02290 
02291                     compatible_bump_uv_derivs(&compat_bump, shi, mtex, i);
02292                 }
02293             }
02294             else if(mtex->texco==TEXCO_WINDOW) {
02295                 co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
02296             }
02297             else if(mtex->texco==TEXCO_STRAND) {
02298                 co= tempvec; dx= dxt; dy= dyt;
02299                 co[0]= shi->strandco;
02300                 co[1]= co[2]= 0.0f;
02301                 dx[0]= shi->dxstrand;
02302                 dx[1]= dx[2]= 0.0f;
02303                 dy[0]= shi->dystrand;
02304                 dy[1]= dy[2]= 0.0f;
02305             }
02306             else if(mtex->texco==TEXCO_STRESS) {
02307                 co= tempvec; dx= dxt; dy= dyt;
02308                 co[0]= shi->stress;
02309                 co[1]= co[2]= 0.0f;
02310                 dx[0]= 0.0f;
02311                 dx[1]= dx[2]= 0.0f;
02312                 dy[0]= 0.0f;
02313                 dy[1]= dy[2]= 0.0f;
02314             }
02315             else continue;  // can happen when texco defines disappear and it renders old files
02316 
02317             /* the pointer defines if bumping happens */
02318             if(mtex->mapto & (MAP_NORM|MAP_WARP)) {
02319                 texres.nor= norvec;
02320                 norvec[0]= norvec[1]= norvec[2]= 0.0;
02321             }
02322             else texres.nor= NULL;
02323             
02324             if(warpdone) {
02325                 add_v3_v3v3(tempvec, co, warpvec);
02326                 co= tempvec;
02327             }
02328 
02329             /* XXX texture node trees don't work for this yet */
02330             if(texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
02331                 if(use_compat_bump) {
02332                     rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex,
02333                         &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
02334                 }
02335                 else if(use_ntap_bump) {
02336                     rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex,
02337                         &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
02338                 }
02339                 else {
02340                     texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
02341                     rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
02342                 }
02343             }
02344             else {
02345                 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
02346                 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
02347             }
02348 
02349             /* texture output */
02350 
02351             if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
02352                 texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02353                 rgbnor-= TEX_RGB;
02354             }
02355             if(mtex->texflag & MTEX_NEGATIVE) {
02356                 if(rgbnor & TEX_RGB) {
02357                     texres.tr= 1.0f-texres.tr;
02358                     texres.tg= 1.0f-texres.tg;
02359                     texres.tb= 1.0f-texres.tb;
02360                 }
02361                 texres.tin= 1.0f-texres.tin;
02362             }
02363             if(mtex->texflag & MTEX_STENCIL) {
02364                 if(rgbnor & TEX_RGB) {
02365                     fact= texres.ta;
02366                     texres.ta*= stencilTin;
02367                     stencilTin*= fact;
02368                 }
02369                 else {
02370                     fact= texres.tin;
02371                     texres.tin*= stencilTin;
02372                     stencilTin*= fact;
02373                 }
02374             }
02375             else {
02376                 Tnor*= stencilTin;
02377             }
02378             
02379             if(texres.nor) {
02380                 if((rgbnor & TEX_NOR)==0) {
02381                     /* make our own normal */
02382                     if(rgbnor & TEX_RGB) {
02383                         texres.nor[0]= texres.tr;
02384                         texres.nor[1]= texres.tg;
02385                         texres.nor[2]= texres.tb;
02386                     }
02387                     else {
02388                         float co_nor= 0.5*cos(texres.tin-0.5f);
02389                         float si= 0.5*sin(texres.tin-0.5f);
02390                         float f1, f2;
02391 
02392                         f1= shi->vn[0];
02393                         f2= shi->vn[1];
02394                         texres.nor[0]= f1*co_nor+f2*si;
02395                         f1= shi->vn[1];
02396                         f2= shi->vn[2];
02397                         texres.nor[1]= f1*co_nor+f2*si;
02398                         texres.nor[2]= f2*co_nor-f1*si;
02399                     }
02400                 }
02401                 // warping, local space
02402                 if(mtex->mapto & MAP_WARP) {
02403                     float *warpnor= texres.nor, warpnor_[3];
02404                     
02405                     if(use_ntap_bump) {
02406                         copy_v3_v3(warpnor_, texres.nor);
02407                         warpnor= warpnor_;
02408                         normalize_v3(warpnor_);
02409                     }
02410                     warpvec[0]= mtex->warpfac*warpnor[0];
02411                     warpvec[1]= mtex->warpfac*warpnor[1];
02412                     warpvec[2]= mtex->warpfac*warpnor[2];
02413                     warpdone= 1;
02414                 }
02415 #if 0               
02416                 if(mtex->texflag & MTEX_VIEWSPACE) {
02417                     // rotate to global coords
02418                     if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
02419                         if(shi->vlr && shi->obr && shi->obr->ob) {
02420                             float len= normalize_v3(texres.nor);
02421                             // can be optimized... (ton)
02422                             mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor);
02423                             mul_mat3_m4_v3(re->viewmat, texres.nor);
02424                             normalize_v3(texres.nor);
02425                             mul_v3_fl(texres.nor, len);
02426                         }
02427                     }
02428                 }
02429 #endif              
02430             }
02431 
02432             /* mapping */
02433             if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
02434                 float tcol[3];
02435                 
02436                 /* stencil maps on the texture control slider, not texture intensity value */
02437                 
02438                 tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb;
02439                 
02440                 if((rgbnor & TEX_RGB)==0) {
02441                     tcol[0]= mtex->r;
02442                     tcol[1]= mtex->g;
02443                     tcol[2]= mtex->b;
02444                 }
02445                 else if(mtex->mapto & MAP_ALPHA) {
02446                     texres.tin= stencilTin;
02447                 }
02448                 else texres.tin= texres.ta;
02449                 
02450                 /* inverse gamma correction */
02451                 if (tex->type==TEX_IMAGE) {
02452                     Image *ima = tex->ima;
02453                     ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
02454                     
02455                     /* don't linearize float buffers, assumed to be linear */
02456                     if (ibuf && !(ibuf->rect_float) && re->r.color_mgt_flag & R_COLOR_MANAGEMENT)
02457                         srgb_to_linearrgb_v3_v3(tcol, tcol);
02458                 }
02459                 
02460                 if(mtex->mapto & MAP_COL) {
02461                     float colfac= mtex->colfac*stencilTin;
02462                     texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
02463                 }
02464                 if(mtex->mapto & MAP_COLSPEC) {
02465                     float colspecfac= mtex->colspecfac*stencilTin;
02466                     texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype);
02467                 }
02468                 if(mtex->mapto & MAP_COLMIR) {
02469                     float mirrfac= mtex->mirrfac*stencilTin;
02470 
02471                     // exception for envmap only
02472                     if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
02473                         fact= texres.tin*mirrfac;
02474                         facm= 1.0f- fact;
02475                         shi->refcol[0]= fact + facm*shi->refcol[0];
02476                         shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
02477                         shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2];
02478                         shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
02479                     }
02480                     else {
02481                         texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype);
02482                     }
02483                 }
02484             }
02485             if( (mtex->mapto & MAP_NORM) ) {
02486                 if(texres.nor) {
02487                     float norfac= mtex->norfac;
02488                     
02489                     /* we need to code blending modes for normals too once.. now 1 exception hardcoded */
02490                     
02491                     if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
02492                         
02493                         found_nmapping = 1;
02494                         
02495                         /* qdn: for normalmaps, to invert the normalmap vector,
02496                            it is better to negate x & y instead of subtracting the vector as was done before */
02497                         if (norfac < 0.0f) {
02498                             texres.nor[0] = -texres.nor[0];
02499                             texres.nor[1] = -texres.nor[1];
02500                         }
02501                         fact = Tnor*fabsf(norfac);
02502                         if (fact>1.f) fact = 1.f;
02503                         facm = 1.f-fact;
02504                         if(mtex->normapspace == MTEX_NSPACE_TANGENT) {
02505                             /* qdn: tangent space */
02506                             float B[3], tv[3];
02507                             const float * no = iFirstTimeNMap!=0 ? shi->nmapnorm : shi->vn;
02508                             iFirstTimeNMap=0;
02509                             cross_v3_v3v3(B, no, shi->nmaptang);    /* bitangent */
02510                             mul_v3_fl(B, shi->nmaptang[3]);
02511                             /* transform norvec from tangent space to object surface in camera space */
02512                             tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*no[0];
02513                             tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*no[1];
02514                             tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*no[2];
02515                             shi->vn[0]= facm*no[0] + fact*tv[0];
02516                             shi->vn[1]= facm*no[1] + fact*tv[1];
02517                             shi->vn[2]= facm*no[2] + fact*tv[2];
02518                         }
02519                         else {
02520                             float nor[3];
02521 
02522                             copy_v3_v3(nor, texres.nor);
02523 
02524                             if(mtex->normapspace == MTEX_NSPACE_CAMERA);
02525                             else if(mtex->normapspace == MTEX_NSPACE_WORLD) {
02526                                 mul_mat3_m4_v3(re->viewmat, nor);
02527                             }
02528                             else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
02529                                 if(shi->obr && shi->obr->ob)
02530                                     mul_mat3_m4_v3(shi->obr->ob->obmat, nor);
02531                                 mul_mat3_m4_v3(re->viewmat, nor);
02532                             }
02533 
02534                             normalize_v3(nor);
02535 
02536                             /* qdn: worldspace */
02537                             shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
02538                             shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
02539                             shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
02540                         }
02541                     }
02542                     else {
02543                         /* XXX texture node trees don't work for this yet */
02544                         if (use_compat_bump || use_ntap_bump) {
02545                             shi->vn[0] = texres.nor[0];
02546                             shi->vn[1] = texres.nor[1];
02547                             shi->vn[2] = texres.nor[2];
02548                         }
02549                         else {
02550                             float nor[3], dot;
02551     
02552                             if(shi->mat->mode & MA_TANGENT_V) {
02553                                 shi->tang[0]+= Tnor*norfac*texres.nor[0];
02554                                 shi->tang[1]+= Tnor*norfac*texres.nor[1];
02555                                 shi->tang[2]+= Tnor*norfac*texres.nor[2];
02556                             }
02557     
02558                             /* prevent bump to become negative normal */
02559                             nor[0]= Tnor*norfac*texres.nor[0];
02560                             nor[1]= Tnor*norfac*texres.nor[1];
02561                             nor[2]= Tnor*norfac*texres.nor[2];
02562                             
02563                             dot= 0.5f + 0.5f * dot_v3v3(nor, shi->vn);
02564                             
02565                             shi->vn[0]+= dot*nor[0];
02566                             shi->vn[1]+= dot*nor[1];
02567                             shi->vn[2]+= dot*nor[2];
02568                         }
02569                     }
02570                     normalize_v3(shi->vn);
02571                     
02572                     /* this makes sure the bump is passed on to the next texture */
02573                     shi->orn[0]= -shi->vn[0];
02574                     shi->orn[1]= -shi->vn[1];
02575                     shi->orn[2]= -shi->vn[2];
02576                 }
02577             }
02578 
02579             if( mtex->mapto & MAP_DISPLACE ) {
02580                 /* Now that most textures offer both Nor and Intensity, allow  */
02581                 /* both to work, and let user select with slider.   */
02582                 if(texres.nor) {
02583                     float norfac= mtex->norfac;
02584 
02585                     shi->displace[0]+= 0.2f*Tnor*norfac*texres.nor[0];
02586                     shi->displace[1]+= 0.2f*Tnor*norfac*texres.nor[1];
02587                     shi->displace[2]+= 0.2f*Tnor*norfac*texres.nor[2];
02588                 }
02589                 
02590                 if(rgbnor & TEX_RGB) {
02591                     texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02592                 }
02593 
02594                 factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
02595 
02596                 if(mtex->blendtype==MTEX_BLEND) {
02597                     shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
02598                     shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1];
02599                     shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2];
02600                 }
02601                 else if(mtex->blendtype==MTEX_MUL) {
02602                     shi->displace[0]*= factt*shi->vn[0];
02603                     shi->displace[1]*= factt*shi->vn[1];
02604                     shi->displace[2]*= factt*shi->vn[2];
02605                 }
02606                 else { /* add or sub */
02607                     if(mtex->blendtype==MTEX_SUB) factt= -factt;
02608                     shi->displace[0]+= factt*shi->vn[0];
02609                     shi->displace[1]+= factt*shi->vn[1];
02610                     shi->displace[2]+= factt*shi->vn[2];
02611                 }
02612             }
02613 
02614             if(mtex->mapto & MAP_VARS) {
02615                 /* stencil maps on the texture control slider, not texture intensity value */
02616                 
02617                 if(rgbnor & TEX_RGB) {
02618                     if(texres.talpha) texres.tin= texres.ta;
02619                     else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02620                 }
02621 
02622                 if(mtex->mapto & MAP_REF) {
02623                     float difffac= mtex->difffac*stencilTin;
02624 
02625                     shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype);
02626                     if(shi->refl<0.0f) shi->refl= 0.0f;
02627                 }
02628                 if(mtex->mapto & MAP_SPEC) {
02629                     float specfac= mtex->specfac*stencilTin;
02630                     
02631                     shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype);
02632                     if(shi->spec<0.0f) shi->spec= 0.0f;
02633                 }
02634                 if(mtex->mapto & MAP_EMIT) {
02635                     float emitfac= mtex->emitfac*stencilTin;
02636 
02637                     shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype);
02638                     if(shi->emit<0.0f) shi->emit= 0.0f;
02639                 }
02640                 if(mtex->mapto & MAP_ALPHA) {
02641                     float alphafac= mtex->alphafac*stencilTin;
02642 
02643                     shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype);
02644                     if(shi->alpha<0.0f) shi->alpha= 0.0f;
02645                     else if(shi->alpha>1.0f) shi->alpha= 1.0f;
02646                 }
02647                 if(mtex->mapto & MAP_HAR) {
02648                     float har;  // have to map to 0-1
02649                     float hardfac= mtex->hardfac*stencilTin;
02650                     
02651                     har= ((float)shi->har)/128.0f;
02652                     har= 128.0f*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype);
02653                     
02654                     if(har<1.0f) shi->har= 1;
02655                     else if(har>511) shi->har= 511;
02656                     else shi->har= (int)har;
02657                 }
02658                 if(mtex->mapto & MAP_RAYMIRR) {
02659                     float raymirrfac= mtex->raymirrfac*stencilTin;
02660 
02661                     shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype);
02662                     if(shi->ray_mirror<0.0f) shi->ray_mirror= 0.0f;
02663                     else if(shi->ray_mirror>1.0f) shi->ray_mirror= 1.0f;
02664                 }
02665                 if(mtex->mapto & MAP_TRANSLU) {
02666                     float translfac= mtex->translfac*stencilTin;
02667 
02668                     shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype);
02669                     if(shi->translucency<0.0f) shi->translucency= 0.0f;
02670                     else if(shi->translucency>1.0f) shi->translucency= 1.0f;
02671                 }
02672                 if(mtex->mapto & MAP_AMB) {
02673                     float ambfac= mtex->ambfac*stencilTin;
02674 
02675                     shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype);
02676                     if(shi->amb<0.0f) shi->amb= 0.0f;
02677                     else if(shi->amb>1.0f) shi->amb= 1.0f;
02678                     
02679                     shi->ambr= shi->amb*re->wrld.ambr;
02680                     shi->ambg= shi->amb*re->wrld.ambg;
02681                     shi->ambb= shi->amb*re->wrld.ambb;
02682                 }
02683             }
02684         }
02685     }
02686     if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V)!=0) {
02687         const float fnegdot = -dot_v3v3(shi->vn, shi->tang);
02688         // apply Gram-Schmidt projection
02689         madd_v3_v3fl(shi->tang,  shi->vn, fnegdot);
02690         normalize_v3(shi->tang);
02691     }
02692 }
02693 
02694 
02695 void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float *col, float *val, Render *re)
02696 {
02697     MTex *mtex;
02698     Tex *tex;
02699     TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
02700     int tex_nr, rgbnor= 0;
02701     float co[3], texvec[3];
02702     float fact, stencilTin=1.0;
02703     
02704     if (re->r.scemode & R_NO_TEX) return;
02705     /* here: test flag if there's a tex (todo) */
02706     
02707     for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
02708         /* separate tex switching */
02709         if(shi->mat->septex & (1<<tex_nr)) continue;
02710         
02711         if(shi->mat->mtex[tex_nr]) {
02712             mtex= shi->mat->mtex[tex_nr];
02713             tex= mtex->tex;
02714             if(tex==0) continue;
02715             
02716             /* only process if this texture is mapped 
02717              * to one that we're interested in */
02718             if (!(mtex->mapto & mapto_flag)) continue;
02719             
02720             /* which coords */
02721             if(mtex->texco==TEXCO_OBJECT) { 
02722                 Object *ob= mtex->object;
02723                 if(ob) {                        
02724                     copy_v3_v3(co, xyz);
02725                     if(mtex->texflag & MTEX_OB_DUPLI_ORIG) {
02726                         if(shi->obi && shi->obi->duplitexmat)
02727                             mul_m4_v3(shi->obi->duplitexmat, co);                   
02728                     } 
02729                     mul_m4_v3(ob->imat_ren, co);
02730                 }
02731             }
02732             /* not really orco, but 'local' */
02733             else if(mtex->texco==TEXCO_ORCO) {
02734                 
02735                 if(mtex->texflag & MTEX_DUPLI_MAPTO) {
02736                     copy_v3_v3(co, shi->duplilo);
02737                 }
02738                 else {
02739                     Object *ob= shi->obi->ob;
02740                     copy_v3_v3(co, xyz);
02741                     mul_m4_v3(ob->imat_ren, co);
02742                 }
02743             }
02744             else if(mtex->texco==TEXCO_GLOB) {
02745                 copy_v3_v3(co, xyz);
02746                 mul_m4_v3(re->viewinv, co);
02747             }
02748             else continue;  // can happen when texco defines disappear and it renders old files
02749 
02750             texres.nor= NULL;
02751             
02752             if(tex->type==TEX_IMAGE) {
02753                 continue;   /* not supported yet */             
02754                 //do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
02755             }
02756             else {
02757                 /* placement */
02758                 if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
02759                 else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
02760 
02761                 if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
02762                 else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
02763 
02764                 if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
02765                 else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
02766             }
02767             
02768             rgbnor= multitex(tex, texvec, NULL, NULL, 0, &texres, 0, mtex->which_output);   /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
02769             
02770             /* texture output */
02771 
02772             if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
02773                 texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02774                 rgbnor-= TEX_RGB;
02775             }
02776             if(mtex->texflag & MTEX_NEGATIVE) {
02777                 if(rgbnor & TEX_RGB) {
02778                     texres.tr= 1.0f-texres.tr;
02779                     texres.tg= 1.0f-texres.tg;
02780                     texres.tb= 1.0f-texres.tb;
02781                 }
02782                 texres.tin= 1.0f-texres.tin;
02783             }
02784             if(mtex->texflag & MTEX_STENCIL) {
02785                 if(rgbnor & TEX_RGB) {
02786                     fact= texres.ta;
02787                     texres.ta*= stencilTin;
02788                     stencilTin*= fact;
02789                 }
02790                 else {
02791                     fact= texres.tin;
02792                     texres.tin*= stencilTin;
02793                     stencilTin*= fact;
02794                 }
02795             }
02796             
02797             
02798             if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
02799                 float tcol[3];
02800                 
02801                 /* stencil maps on the texture control slider, not texture intensity value */
02802                 
02803                 if((rgbnor & TEX_RGB)==0) {
02804                     tcol[0]= mtex->r;
02805                     tcol[1]= mtex->g;
02806                     tcol[2]= mtex->b;
02807                 } else {
02808                     tcol[0]=texres.tr;
02809                     tcol[1]=texres.tg;
02810                     tcol[2]=texres.tb;
02811                     if(texres.talpha)
02812                         texres.tin= texres.ta;
02813                 }
02814                 
02815                 /* used for emit */
02816                 if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
02817                     float colemitfac= mtex->colemitfac*stencilTin;
02818                     texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype);
02819                 }
02820                 
02821                 if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
02822                     float colreflfac= mtex->colreflfac*stencilTin;
02823                     texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype);
02824                 }
02825                 
02826                 if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
02827                     float coltransfac= mtex->coltransfac*stencilTin;
02828                     texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype);
02829                 }
02830             }
02831             
02832             if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) {
02833                 /* stencil maps on the texture control slider, not texture intensity value */
02834                 
02835                 /* convert RGB to intensity if intensity info isn't provided */
02836                 if (!(rgbnor & TEX_INT)) {
02837                     if (rgbnor & TEX_RGB) {
02838                         if(texres.talpha) texres.tin= texres.ta;
02839                         else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02840                     }
02841                 }
02842                 
02843                 if((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) {
02844                     float emitfac= mtex->emitfac*stencilTin;
02845 
02846                     *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype);
02847                     if(*val<0.0f) *val= 0.0f;
02848                 }
02849                 if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) {
02850                     float densfac= mtex->densfac*stencilTin;
02851 
02852                     *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype);
02853                     CLAMP(*val, 0.0f, 1.0f);
02854                 }
02855                 if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
02856                     float scatterfac= mtex->scatterfac*stencilTin;
02857                     
02858                     *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype);
02859                     CLAMP(*val, 0.0f, 1.0f);
02860                 }
02861                 if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) {
02862                     float reflfac= mtex->reflfac*stencilTin;
02863                     
02864                     *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype);
02865                     CLAMP(*val, 0.0f, 1.0f);
02866                 }
02867             }
02868         }
02869     }
02870 }
02871 
02872 
02873 /* ------------------------------------------------------------------------- */
02874 
02875 void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
02876 {
02877     MTex *mtex;
02878     TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
02879     float texvec[3], dxt[3], dyt[3], fact, facm, dx;
02880     int rgb, osatex;
02881 
02882     if (R.r.scemode & R_NO_TEX) return;
02883     
02884     mtex= har->mat->mtex[0];
02885     if(har->mat->septex & (1<<0)) return;
02886     if(mtex->tex==NULL) return;
02887     
02888     /* no normal mapping */
02889     texres.nor= NULL;
02890         
02891     texvec[0]= xn/har->rad;
02892     texvec[1]= yn/har->rad;
02893     texvec[2]= 0.0;
02894     
02895     osatex= (har->mat->texco & TEXCO_OSA);
02896 
02897     /* placement */
02898     if(mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]);
02899     else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
02900     
02901     if(mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]);
02902     else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
02903     
02904     if(mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]);
02905     else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
02906     
02907     if(osatex) {
02908     
02909         dx= 1.0f/har->rad;
02910     
02911         if(mtex->projx) {
02912             dxt[0]= mtex->size[0]*dx;
02913             dyt[0]= mtex->size[0]*dx;
02914         }
02915         else dxt[0]= dyt[0]= 0.0;
02916         
02917         if(mtex->projy) {
02918             dxt[1]= mtex->size[1]*dx;
02919             dyt[1]= mtex->size[1]*dx;
02920         }
02921         else dxt[1]= dyt[1]= 0.0;
02922         
02923         if(mtex->projz) {
02924             dxt[2]= 0.0;
02925             dyt[2]= 0.0;
02926         }
02927         else dxt[2]= dyt[2]= 0.0;
02928 
02929     }
02930 
02931     if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
02932     
02933     rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output);
02934 
02935     /* texture output */
02936     if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
02937         texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
02938         rgb= 0;
02939     }
02940     if(mtex->texflag & MTEX_NEGATIVE) {
02941         if(rgb) {
02942             texres.tr= 1.0f-texres.tr;
02943             texres.tg= 1.0f-texres.tg;
02944             texres.tb= 1.0f-texres.tb;
02945         }
02946         else texres.tin= 1.0f-texres.tin;
02947     }
02948 
02949     /* mapping */
02950     if(mtex->mapto & MAP_COL) {
02951         
02952         if(rgb==0) {
02953             texres.tr= mtex->r;
02954             texres.tg= mtex->g;
02955             texres.tb= mtex->b;
02956         }
02957         else if(mtex->mapto & MAP_ALPHA) {
02958             texres.tin= 1.0;
02959         }
02960         else texres.tin= texres.ta;
02961 
02962         /* inverse gamma correction */
02963         if (mtex->tex->type==TEX_IMAGE) {
02964             Image *ima = mtex->tex->ima;
02965             ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser);
02966             
02967             /* don't linearize float buffers, assumed to be linear */
02968             if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
02969                 srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
02970         }
02971 
02972         fact= texres.tin*mtex->colfac;
02973         facm= 1.0f-fact;
02974         
02975         if(mtex->blendtype==MTEX_MUL) {
02976             facm= 1.0f-mtex->colfac;
02977         }
02978         
02979         if(mtex->blendtype==MTEX_SUB) fact= -fact;
02980 
02981         if(mtex->blendtype==MTEX_BLEND) {
02982             col_r[0]= (fact*texres.tr + facm*har->r);
02983             col_r[1]= (fact*texres.tg + facm*har->g);
02984             col_r[2]= (fact*texres.tb + facm*har->b);
02985         }
02986         else if(mtex->blendtype==MTEX_MUL) {
02987             col_r[0]= (facm+fact*texres.tr)*har->r;
02988             col_r[1]= (facm+fact*texres.tg)*har->g;
02989             col_r[2]= (facm+fact*texres.tb)*har->b;
02990         }
02991         else {
02992             col_r[0]= (fact*texres.tr + har->r);
02993             col_r[1]= (fact*texres.tg + har->g);
02994             col_r[2]= (fact*texres.tb + har->b);
02995             
02996             CLAMP(col_r[0], 0.0f, 1.0f);
02997             CLAMP(col_r[1], 0.0f, 1.0f);
02998             CLAMP(col_r[2], 0.0f, 1.0f);
02999         }
03000     }
03001     if(mtex->mapto & MAP_ALPHA) {
03002         if(rgb) {
03003             if(texres.talpha) texres.tin= texres.ta;
03004             else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
03005         }
03006                 
03007         col_r[3]*= texres.tin;
03008     }
03009 }
03010 
03011 /* ------------------------------------------------------------------------- */
03012 
03013 /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
03014 void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread)
03015 {
03016     MTex *mtex;
03017     Tex *tex;
03018     TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
03019     float *co, fact, stencilTin=1.0;
03020     float tempvec[3], texvec[3], dxt[3], dyt[3];
03021     int tex_nr, rgb= 0;
03022     
03023     if (R.r.scemode & R_NO_TEX) return;
03024     /* todo: add flag to test if there's a tex */
03025     texres.nor= NULL;
03026     
03027     for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
03028         if(R.wrld.mtex[tex_nr]) {
03029             mtex= R.wrld.mtex[tex_nr];
03030             
03031             tex= mtex->tex;
03032             if(tex==0) continue;
03033             /* if(mtex->mapto==0) continue; */
03034             
03035             /* which coords */
03036             co= lo;
03037             
03038             /* dxt dyt just from 1 value */
03039             if(dxyview) {
03040                 dxt[0]= dxt[1]= dxt[2]= dxyview[0];
03041                 dyt[0]= dyt[1]= dyt[2]= dxyview[1];
03042             }
03043             else {
03044                 dxt[0]= dxt[1]= dxt[2]= 0.0;
03045                 dyt[0]= dyt[1]= dyt[2]= 0.0;
03046             }
03047             
03048             /* Grab the mapping settings for this texture */
03049             switch(mtex->texco) {
03050             case TEXCO_ANGMAP:
03051                 /* only works with texture being "real" */
03052                 /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less then -1.0 */
03053                 if(lo[0] || lo[1]) { /* check for zero case [#24807] */
03054                     fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrtf(lo[0]*lo[0] + lo[1]*lo[1]));
03055                     tempvec[0]= lo[0]*fact;
03056                     tempvec[1]= lo[1]*fact;
03057                     tempvec[2]= 0.0;
03058                 }
03059                 else {
03060                     /* this value has no angle, the vector is directly along the view.
03061                      * avoide divide by zero and use a dummy value. */
03062                     tempvec[0]= 1.0f;
03063                     tempvec[1]= 0.0;
03064                     tempvec[2]= 0.0;
03065                 }
03066                 co= tempvec;
03067                 break;
03068                 
03069             case TEXCO_H_SPHEREMAP:
03070             case TEXCO_H_TUBEMAP:
03071                 if(skyflag & WO_ZENUP) {
03072                     if(mtex->texco==TEXCO_H_TUBEMAP) map_to_tube( tempvec, tempvec+1,lo[0], lo[2], lo[1]);
03073                     else map_to_sphere( tempvec, tempvec+1,lo[0], lo[2], lo[1]);
03074                     /* tube/spheremap maps for outside view, not inside */
03075                     tempvec[0]= 1.0f-tempvec[0];
03076                     /* only top half */
03077                     tempvec[1]= 2.0f*tempvec[1]-1.0f;
03078                     tempvec[2]= 0.0;
03079                     /* and correction for do_2d_mapping */
03080                     tempvec[0]= 2.0f*tempvec[0]-1.0f;
03081                     tempvec[1]= 2.0f*tempvec[1]-1.0f;
03082                     co= tempvec;
03083                 }
03084                 else {
03085                     /* potentially dangerous... check with multitex! */
03086                     continue;
03087                 }
03088                 break;
03089             case TEXCO_EQUIRECTMAP:
03090                 tempvec[0]= atan2f(lo[0], lo[2]) / (float)M_PI;
03091                 tempvec[1]= 1.0f - 2.0f*saacos(lo[1]) / (float)M_PI;
03092                 tempvec[2]= 0.0f;
03093                 co= tempvec;
03094                 break;
03095             case TEXCO_OBJECT:
03096                 if(mtex->object) {
03097                     copy_v3_v3(tempvec, lo);
03098                     mul_m4_v3(mtex->object->imat_ren, tempvec);
03099                     co= tempvec;
03100                 }
03101                 break;
03102                 
03103             case TEXCO_GLOB:
03104                 if(rco) {
03105                     copy_v3_v3(tempvec, rco);
03106                     mul_m4_v3(R.viewinv, tempvec);
03107                     co= tempvec;
03108                 }
03109                 else
03110                     co= lo;
03111                 
03112 //              copy_v3_v3(shi->dxgl, shi->dxco);
03113 //              mul_m3_v3(R.imat, shi->dxco);
03114 //              copy_v3_v3(shi->dygl, shi->dyco);
03115 //              mul_m3_v3(R.imat, shi->dyco);
03116                 break;
03117             }
03118             
03119             /* placement */         
03120             if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
03121             else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
03122             
03123             if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
03124             else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
03125             
03126             if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
03127             else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
03128             
03129             /* texture */
03130             if(tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
03131         
03132             rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output);
03133             
03134             /* texture output */
03135             if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
03136                 texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
03137                 rgb= 0;
03138             }
03139             if(mtex->texflag & MTEX_NEGATIVE) {
03140                 if(rgb) {
03141                     texres.tr= 1.0f-texres.tr;
03142                     texres.tg= 1.0f-texres.tg;
03143                     texres.tb= 1.0f-texres.tb;
03144                 }
03145                 else texres.tin= 1.0f-texres.tin;
03146             }
03147             if(mtex->texflag & MTEX_STENCIL) {
03148                 if(rgb) {
03149                     fact= texres.ta;
03150                     texres.ta*= stencilTin;
03151                     stencilTin*= fact;
03152                 }
03153                 else {
03154                     fact= texres.tin;
03155                     texres.tin*= stencilTin;
03156                     stencilTin*= fact;
03157                 }
03158             }
03159             else {
03160                 if(rgb) texres.ta *= stencilTin;
03161                 else texres.tin*= stencilTin;
03162             }
03163             
03164             /* color mapping */
03165             if(mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) {
03166                 float tcol[3];
03167                 
03168                 if(rgb==0) {
03169                     texres.tr= mtex->r;
03170                     texres.tg= mtex->g;
03171                     texres.tb= mtex->b;
03172                 }
03173                 else texres.tin= texres.ta;
03174                 
03175                 tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb;
03176 
03177                 /* inverse gamma correction */
03178                 if (tex->type==TEX_IMAGE) {
03179                     Image *ima = tex->ima;
03180                     ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
03181                     
03182                     /* don't linearize float buffers, assumed to be linear */
03183                     if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
03184                         srgb_to_linearrgb_v3_v3(tcol, tcol);
03185                 }
03186 
03187                 if(mtex->mapto & WOMAP_HORIZ) {
03188                     texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype);
03189                 }
03190                 if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) {
03191                     float zenfac = 0.0f;
03192 
03193                     if(R.wrld.skytype & WO_SKYREAL) {
03194                         if((skyflag & WO_ZENUP)) {
03195                             if(mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac;
03196                         }
03197                         else if(mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac;
03198                     }
03199                     else {
03200                         if(mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac;
03201                         else if(mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac;
03202                     }
03203                     
03204                     if(zenfac != 0.0f)
03205                         texture_rgb_blend(zen, tcol, zen, texres.tin, zenfac, mtex->blendtype);
03206                 }
03207             }
03208             if(mtex->mapto & WOMAP_BLEND) {
03209                 if(rgb) texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
03210                 
03211                 *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype);
03212             }
03213         }
03214     }
03215 }
03216 
03217 /* ------------------------------------------------------------------------- */
03218 /* col_r supposed to be initialized with la->r,g,b */
03219 
03220 void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect)
03221 {
03222     Object *ob;
03223     MTex *mtex;
03224     Tex *tex;
03225     TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
03226     float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0;
03227     float texvec[3], dxt[3], dyt[3], tempvec[3];
03228     int i, tex_nr, rgb= 0;
03229     
03230     if (R.r.scemode & R_NO_TEX) return;
03231     tex_nr= 0;
03232     
03233     for(; tex_nr<MAX_MTEX; tex_nr++) {
03234         
03235         if(la->mtex[tex_nr]) {
03236             mtex= la->mtex[tex_nr];
03237             
03238             tex= mtex->tex;
03239             if(tex==NULL) continue;
03240             texres.nor= NULL;
03241             
03242             /* which coords */
03243             if(mtex->texco==TEXCO_OBJECT) {
03244                 ob= mtex->object;
03245                 if(ob) {
03246                     co= tempvec;
03247                     dx= dxt;
03248                     dy= dyt;
03249                     copy_v3_v3(tempvec, shi->co);
03250                     mul_m4_v3(ob->imat_ren, tempvec);
03251                     if(shi->osatex) {
03252                         copy_v3_v3(dxt, shi->dxco);
03253                         copy_v3_v3(dyt, shi->dyco);
03254                         mul_mat3_m4_v3(ob->imat_ren, dxt);
03255                         mul_mat3_m4_v3(ob->imat_ren, dyt);
03256                     }
03257                 }
03258                 else {
03259                     co= shi->co;
03260                     dx= shi->dxco; dy= shi->dyco;
03261                 }
03262             }
03263             else if(mtex->texco==TEXCO_GLOB) {
03264                 co= shi->gl; dx= shi->dxco; dy= shi->dyco;
03265                 copy_v3_v3(shi->gl, shi->co);
03266                 mul_m4_v3(R.viewinv, shi->gl);
03267             }
03268             else if(mtex->texco==TEXCO_VIEW) {
03269                 
03270                 copy_v3_v3(tempvec, lavec);
03271                 mul_m3_v3(la->imat, tempvec);
03272                 
03273                 if(la->type==LA_SPOT) {
03274                     tempvec[0]*= la->spottexfac;
03275                     tempvec[1]*= la->spottexfac;
03276                 /* project from 3d to 2d */
03277                     tempvec[0] /= -tempvec[2];
03278                     tempvec[1] /= -tempvec[2];
03279                 }
03280                 co= tempvec; 
03281                 
03282                 dx= dxt; dy= dyt;   
03283                 if(shi->osatex) {
03284                     copy_v3_v3(dxt, shi->dxlv);
03285                     copy_v3_v3(dyt, shi->dylv);
03286                     /* need some matrix conversion here? la->imat is a [3][3]  matrix!!! **/
03287                     mul_m3_v3(la->imat, dxt);
03288                     mul_m3_v3(la->imat, dyt);
03289                     
03290                     mul_v3_fl(dxt, la->spottexfac);
03291                     mul_v3_fl(dyt, la->spottexfac);
03292                 }
03293             }
03294             
03295             
03296             /* placement */
03297             if(mtex->projx && co) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
03298             else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
03299             
03300             if(mtex->projy && co) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
03301             else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
03302             
03303             if(mtex->projz && co) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
03304             else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
03305             
03306             if(shi->osatex) {
03307                 if (!dx) {
03308                     for(i=0;i<2;i++) { 
03309                         dxt[i] = dyt[i] = 0.0;
03310                     }
03311                 } else {
03312                     if(mtex->projx) {
03313                         dxt[0]= mtex->size[0]*dx[mtex->projx-1];
03314                         dyt[0]= mtex->size[0]*dy[mtex->projx-1];
03315                     } else {
03316                         dxt[0]= 0.0;
03317                         dyt[0]= 0.0;
03318                     }
03319                     if(mtex->projy) {
03320                         dxt[1]= mtex->size[1]*dx[mtex->projy-1];
03321                         dyt[1]= mtex->size[1]*dy[mtex->projy-1];
03322                     } else {
03323                         dxt[1]= 0.0;
03324                         dyt[1]= 0.0;
03325                     }
03326                     if(mtex->projz) {
03327                         dxt[2]= mtex->size[2]*dx[mtex->projz-1];
03328                         dyt[2]= mtex->size[2]*dy[mtex->projz-1];
03329                     } else {
03330                         dxt[2]= 0.0;
03331                         dyt[2]= 0.0;
03332                     }
03333                 }
03334             }
03335             
03336             /* texture */
03337             if(tex->type==TEX_IMAGE) {
03338                 do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
03339             }
03340             
03341             rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
03342 
03343             /* texture output */
03344             if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
03345                 texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
03346                 rgb= 0;
03347             }
03348             if(mtex->texflag & MTEX_NEGATIVE) {
03349                 if(rgb) {
03350                     texres.tr= 1.0f-texres.tr;
03351                     texres.tg= 1.0f-texres.tg;
03352                     texres.tb= 1.0f-texres.tb;
03353                 }
03354                 else texres.tin= 1.0f-texres.tin;
03355             }
03356             if(mtex->texflag & MTEX_STENCIL) {
03357                 if(rgb) {
03358                     fact= texres.ta;
03359                     texres.ta*= stencilTin;
03360                     stencilTin*= fact;
03361                 }
03362                 else {
03363                     fact= texres.tin;
03364                     texres.tin*= stencilTin;
03365                     stencilTin*= fact;
03366                 }
03367             }
03368             else {
03369                 if(rgb) texres.ta*= stencilTin;
03370                 else texres.tin*= stencilTin;
03371             }
03372             
03373             /* mapping */
03374             if(((mtex->mapto & LAMAP_COL) && (effect & LA_TEXTURE))||((mtex->mapto & LAMAP_SHAD) && (effect & LA_SHAD_TEX))) {
03375                 float col[3];
03376                 
03377                 if(rgb==0) {
03378                     texres.tr= mtex->r;
03379                     texres.tg= mtex->g;
03380                     texres.tb= mtex->b;
03381                 }
03382                 else if(mtex->mapto & MAP_ALPHA) {
03383                     texres.tin= stencilTin;
03384                 }
03385                 else texres.tin= texres.ta;
03386 
03387                 /* inverse gamma correction */
03388                 if (tex->type==TEX_IMAGE) {
03389                     Image *ima = tex->ima;
03390                     ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
03391                     
03392                     /* don't linearize float buffers, assumed to be linear */
03393                     if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
03394                         srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
03395                 }
03396 
03397                 /* lamp colors were premultiplied with this */
03398                 col[0]= texres.tr*la->energy;
03399                 col[1]= texres.tg*la->energy;
03400                 col[2]= texres.tb*la->energy;
03401                 
03402                 texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype);
03403             }
03404         }
03405     }
03406 }
03407 
03408 /* ------------------------------------------------------------------------- */
03409 
03410 int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread)
03411 {
03412     Tex *tex;
03413     TexResult texr;
03414     float dxt[3], dyt[3], texvec[3];
03415     int rgb;
03416     
03417     tex= mtex->tex;
03418     if(tex==NULL) return 0;
03419     texr.nor= NULL;
03420     
03421     /* placement */
03422     if(mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]);
03423     else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
03424     
03425     if(mtex->projy) texvec[1]= mtex->size[1]*(vec[mtex->projy-1]+mtex->ofs[1]);
03426     else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
03427     
03428     if(mtex->projz) texvec[2]= mtex->size[2]*(vec[mtex->projz-1]+mtex->ofs[2]);
03429     else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
03430     
03431     /* texture */
03432     if(tex->type==TEX_IMAGE) {
03433         do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
03434     }
03435     
03436     rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output);
03437     
03438     if(rgb) {
03439         texr.tin= (0.35f*texr.tr+0.45f*texr.tg+0.2f*texr.tb);
03440     }
03441     else {
03442         texr.tr= mtex->r;
03443         texr.tg= mtex->g;
03444         texr.tb= mtex->b;
03445     }
03446     
03447     *tin= texr.tin;
03448     *tr= texr.tr;
03449     *tg= texr.tg;
03450     *tb= texr.tb;
03451     *ta= texr.ta;
03452 
03453     return (rgb != 0);
03454 }
03455 
03456 
03457 /* ------------------------------------------------------------------------- */
03458 
03459 void render_realtime_texture(ShadeInput *shi, Image *ima)
03460 {
03461     TexResult texr;
03462     static Tex imatex[BLENDER_MAX_THREADS]; // threadsafe
03463     static int firsttime= 1;
03464     Tex *tex;
03465     float texvec[3], dx[2], dy[2];
03466     ShadeInputUV *suv= &shi->uv[shi->actuv];
03467     int a;
03468 
03469     if(R.r.scemode & R_NO_TEX) return;
03470 
03471     if(firsttime) {
03472         BLI_lock_thread(LOCK_IMAGE);
03473         if(firsttime) {
03474             for(a=0; a<BLENDER_MAX_THREADS; a++) {
03475                 memset(&imatex[a], 0, sizeof(Tex));
03476                 default_tex(&imatex[a]);
03477                 imatex[a].type= TEX_IMAGE;
03478             }
03479 
03480             firsttime= 0;
03481         }
03482         BLI_unlock_thread(LOCK_IMAGE);
03483     }
03484     
03485     tex= &imatex[shi->thread];
03486     tex->iuser.ok= ima->ok;
03487     
03488     texvec[0]= 0.5f+0.5f*suv->uv[0];
03489     texvec[1]= 0.5f+0.5f*suv->uv[1];
03490     texvec[2] = 0.0f;  // initalize it because imagewrap looks at it.
03491     if(shi->osatex) {
03492         dx[0]= 0.5f*suv->dxuv[0];
03493         dx[1]= 0.5f*suv->dxuv[1];
03494         dy[0]= 0.5f*suv->dyuv[0];
03495         dy[1]= 0.5f*suv->dyuv[1];
03496     }
03497     
03498     texr.nor= NULL;
03499     
03500     if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
03501     else imagewrap(tex, ima, NULL, texvec, &texr); 
03502 
03503     shi->vcol[0]*= texr.tr;
03504     shi->vcol[1]*= texr.tg;
03505     shi->vcol[2]*= texr.tb;
03506     shi->vcol[3]*= texr.ta;
03507 }
03508 
03509 /* A modified part of shadeinput.c -> shade_input_set_uv()
03510 *  Used for sampling UV mapped texture color */
03511 static void textured_face_generate_uv(float *uv, float *normal, float *hit, float *v1, float *v2, float *v3)
03512 {
03513 
03514     float detsh, t00, t10, t01, t11;
03515     int axis1, axis2;
03516 
03517     /* find most stable axis to project */
03518     axis_dominant_v3(&axis1, &axis2, normal);
03519 
03520     /* compute u,v and derivatives */
03521     t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
03522     t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
03523 
03524     detsh= 1.0f/(t00*t11-t10*t01);
03525     t00*= detsh; t01*=detsh; 
03526     t10*=detsh; t11*=detsh;
03527 
03528     uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10;
03529     uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01;
03530 
03531     /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
03532     CLAMP(uv[0], -2.0f, 1.0f);
03533     CLAMP(uv[1], -2.0f, 1.0f);
03534 }
03535 
03536 /* Generate an updated copy of material to use for color sampling. */
03537 Material *RE_init_sample_material(Material *orig_mat, Scene *scene)
03538 {
03539     Tex *tex = NULL;
03540     Material *mat;
03541     int tex_nr;
03542 
03543     if (!orig_mat) return NULL;
03544 
03545     /* copy material */
03546     mat = localize_material(orig_mat);
03547 
03548     /* update material anims */
03549     BKE_animsys_evaluate_animdata(scene, &mat->id, mat->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
03550 
03551     /* strip material copy from unsupported flags */
03552     for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
03553         if(mat->septex & (1<<tex_nr)) continue;
03554     
03555         if(mat->mtex[tex_nr]) {
03556             MTex *mtex = mat->mtex[tex_nr];
03557 
03558             /* only keep compatible texflags */
03559             mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX);
03560 
03561             /* depending of material type, strip non-compatible mapping modes */
03562             if (mat->material_type == MA_TYPE_SURFACE) {
03563                 if (!ELEM4(mtex->texco, TEXCO_ORCO, TEXCO_OBJECT, TEXCO_GLOB, TEXCO_UV)) {
03564                     /* ignore this texture */
03565                     mtex->texco = 0;
03566                     continue;
03567                 }
03568                 /* strip all mapto flags except color and alpha */
03569                 mtex->mapto = (mtex->mapto & MAP_COL) | (mtex->mapto & MAP_ALPHA);
03570             }
03571             else if (mat->material_type == MA_TYPE_VOLUME) {
03572                 if (!ELEM3(mtex->texco, TEXCO_OBJECT, TEXCO_ORCO, TEXCO_GLOB)) {
03573                     /* ignore */
03574                     mtex->texco = 0;
03575                     continue;
03576                 }
03577                 /* strip all mapto flags except color and alpha */
03578                 mtex->mapto = mtex->mapto & (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY);
03579             }
03580             
03581             /* if mapped to an object, calculate inverse matrices */
03582             if(mtex->texco==TEXCO_OBJECT) { 
03583                 Object *ob= mtex->object;
03584                 if(ob) {
03585                     invert_m4_m4(ob->imat, ob->obmat);
03586                     copy_m4_m4(ob->imat_ren, ob->imat);
03587                 }
03588             }
03589 
03590             /* copy texture */
03591             tex= mtex->tex = localize_texture(mtex->tex);
03592 
03593             /* update texture anims */
03594             BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
03595 
03596             /* update texture cache if required */
03597             if(tex->type==TEX_VOXELDATA) {
03598                 cache_voxeldata(tex, (int)scene->r.cfra);
03599             }
03600             if(tex->type==TEX_POINTDENSITY) {
03601                 /* set dummy values for render and do cache */
03602                 Render dummy_re = {0};
03603                 dummy_re.scene = scene;
03604                 unit_m4(dummy_re.viewinv);
03605                 unit_m4(dummy_re.viewmat);
03606                 unit_m4(dummy_re.winmat);
03607                 dummy_re.winx = dummy_re.winy = 128;
03608                 cache_pointdensity(&dummy_re, tex);
03609             }
03610 
03611             /* update image sequences and movies */
03612             if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
03613                 if(tex->iuser.flag & IMA_ANIM_ALWAYS)
03614                     BKE_image_user_calc_frame(&tex->iuser, (int)scene->r.cfra, 0);
03615             }
03616         }
03617     }
03618     return mat;
03619 }
03620 
03621 /* free all duplicate data allocated by RE_init_sample_material() */
03622 void RE_free_sample_material(Material *mat)
03623 {
03624     int tex_nr;
03625 
03626     /* free textures */
03627     for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
03628         if(mat->septex & (1<<tex_nr)) continue;
03629         if(mat->mtex[tex_nr]) {
03630             MTex *mtex= mat->mtex[tex_nr];
03631             free_texture(mtex->tex);
03632             MEM_freeN(mtex->tex);
03633             mtex->tex = NULL;
03634         }
03635     }
03636 
03637     free_material(mat);
03638     MEM_freeN(mat);
03639 }
03640 
03641 
03642 
03643 /*
03644 *   Get material diffuse color and alpha (including linked textures) in given coordinates
03645 *   
03646 *   color,alpha : input/output color values
03647 *   volume_co : sample coordinate in global space. used by volumetric materials
03648 *   surface_co : sample surface coordinate in global space. used by "surface" materials
03649 *   face_index : surface face index
03650 *   hit_quad : whether point is on second "half" of a quad
03651 *   orcoDm : orco state derived mesh
03652 */
03653 void RE_sample_material_color(Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], int face_index, short hit_quad, DerivedMesh *orcoDm, Object *ob)
03654 {
03655     MFace *mface;
03656     int v1, v2, v3;
03657     MVert *mvert;
03658     float uv[3], normal[3];
03659     ShadeInput shi = {0};
03660     Render re = {0};
03661 
03662     /* Get face data    */
03663     mvert = orcoDm->getVertArray(orcoDm);
03664     mface = orcoDm->getFaceArray(orcoDm);
03665 
03666     if (!mvert || !mface || !mat) return;
03667     v1=mface[face_index].v1, v2=mface[face_index].v2, v3=mface[face_index].v3;
03668     if (hit_quad) {v2=mface[face_index].v3; v3=mface[face_index].v4;}
03669     normal_tri_v3( normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
03670 
03671     /* generate shadeinput with data required */
03672     shi.mat = mat;
03673 
03674     /* fill shadeinput data depending on material type */
03675     if (mat->material_type == MA_TYPE_SURFACE) {
03676         /* global coordinates */
03677         copy_v3_v3(shi.gl, surface_co);
03678         /* object space coordinates */
03679         copy_v3_v3(shi.co, surface_co);
03680         mul_m4_v3(ob->imat, shi.co);
03681         /* orco coordinates */
03682         {
03683             float l;
03684             /* Get generated UV */
03685             textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co);
03686             l= 1.0f+uv[0]+uv[1];
03687 
03688             /* calculate generated coordinate */
03689             shi.lo[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0];
03690             shi.lo[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1];
03691             shi.lo[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2];
03692         }
03693         /* uv coordinates */
03694         {
03695             int i, layers = CustomData_number_of_layers(&orcoDm->faceData, CD_MTFACE);
03696             int layer_index = CustomData_get_layer_index(&orcoDm->faceData, CD_MTFACE);
03697 
03698             /* for every uv map set coords and name */
03699             for (i=0; i<layers; i++) {
03700                 if(layer_index >= 0) {
03701                     float *uv1, *uv2, *uv3;
03702                     float l;
03703                     CustomData *data = &orcoDm->faceData;
03704                     MTFace *tface = (MTFace*) data->layers[layer_index+i].data;
03705                     float uv[3];
03706                     /* point layer name from actual layer data */
03707                     shi.uv[i].name = data->layers[i].name;
03708                     /* Get generated coordinates to calculate UV from */
03709                     textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co);
03710                     /* Get UV mapping coordinate */
03711                     l= 1.0f+uv[0]+uv[1];
03712                         
03713                     uv1= tface[face_index].uv[0];
03714                     uv2= (hit_quad) ? tface[face_index].uv[2] : tface[face_index].uv[1];
03715                     uv3= (hit_quad) ? tface[face_index].uv[3] : tface[face_index].uv[2];
03716                                 
03717                     shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]);
03718                     shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]);
03719                     shi.uv[i].uv[2]= 0.0f;  /* texture.c assumes there are 3 coords */
03720                 }
03721             }
03722             /* active uv map */
03723             shi.actuv = CustomData_get_active_layer_index(&orcoDm->faceData,CD_MTFACE) - layer_index;
03724             shi.totuv = layers;
03725         }
03726 
03727         /* apply initial values from material */
03728         shi.r = mat->r;
03729         shi.g = mat->g;
03730         shi.b = mat->b;
03731         shi.alpha = mat->alpha;
03732 
03733         /* do texture */
03734         do_material_tex(&shi, &re);
03735 
03736         /* apply result */
03737         color[0] = shi.r;
03738         color[1] = shi.g;
03739         color[2] = shi.b;
03740         *alpha = shi.alpha;
03741     }
03742     else if (mat->material_type == MA_TYPE_VOLUME) {
03743         ObjectInstanceRen obi = {0};
03744         obi.ob = ob;
03745         shi.obi = &obi;
03746         unit_m4(re.viewinv);
03747         copy_v3_v3(color, mat->vol.reflection_col);
03748         *alpha = mat->vol.density;
03749 
03750         /* do texture */
03751         do_volume_tex(&shi, volume_co, (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY),
03752                       color, alpha, &re);
03753     }
03754 }
03755 
03756 /* eof */