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