svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20937:21899
[blender.git] / source / blender / render / intern / source / texture.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): 2004-2006, Blender Foundation, full recode
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include "MTC_matrixops.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37 #include "BLI_rand.h"
38
39 #include "DNA_texture_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_lamp_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_material_types.h"
45 #include "DNA_image_types.h"
46 #include "DNA_node_types.h"
47
48 #include "IMB_imbuf_types.h"
49 #include "IMB_imbuf.h"
50
51 #include "BKE_colortools.h"
52 #include "BKE_image.h"
53 #include "BKE_node.h"
54 #include "BKE_plugin_types.h"
55 #include "BKE_utildefines.h"
56
57 #include "BKE_global.h"
58 #include "BKE_main.h"
59 #include "BKE_material.h"
60
61 #include "BKE_library.h"
62 #include "BKE_image.h"
63 #include "BKE_texture.h"
64 #include "BKE_key.h"
65 #include "BKE_ipo.h"
66
67 #include "envmap.h"
68 #include "renderpipeline.h"
69 #include "render_types.h"
70 #include "rendercore.h"
71 #include "shading.h"
72 #include "texture.h"
73
74 #include "renderdatabase.h" /* needed for UV */
75
76 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
77 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
78 /* only to be used here in this file, it's for speed */
79 extern struct Render R;
80 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
81
82
83
84
85 void init_render_texture(Render *re, Tex *tex)
86 {
87         int cfra= re->scene->r.cfra;
88         
89         if(re) cfra= re->r.cfra;
90         
91         /* imap test */
92         if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
93                 BKE_image_user_calc_imanr(&tex->iuser, cfra, re?re->flag & R_SEC_FIELD:0);
94         }
95         
96         if(tex->type==TEX_PLUGIN) {
97                 if(tex->plugin && tex->plugin->doit) {
98                         if(tex->plugin->cfra) {
99                                 *(tex->plugin->cfra)= (float)cfra; //frame_to_float(re->scene, cfra); // XXX old animsys - timing stuff to be fixed 
100                         }
101                 }
102         }
103         else if(tex->type==TEX_ENVMAP) {
104                 /* just in case */
105                 tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP;
106                 tex->extend= TEX_CLIP;
107                 
108                 if(tex->env) {
109                         if(tex->env->type==ENV_PLANE)
110                                 tex->extend= TEX_EXTEND;
111                         
112                         /* only free envmap when rendermode was set to render envmaps, for previewrender */
113                         if(G.rendering && re) {
114                                 if (re->r.mode & R_ENVMAP)
115                                         if(tex->env->stype==ENV_ANIM) 
116                                                 BKE_free_envmapdata(tex->env);
117                         }
118                 }
119         }
120         
121         if(tex->nodetree && tex->use_nodes) {
122                 ntreeBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
123         }
124 }
125
126 /* ------------------------------------------------------------------------- */
127
128 void init_render_textures(Render *re)
129 {
130         Tex *tex;
131         
132         tex= G.main->tex.first;
133         while(tex) {
134                 if(tex->id.us) init_render_texture(re, tex);
135                 tex= tex->id.next;
136         }
137 }
138
139 void end_render_texture(Tex *tex)
140 {
141         if(tex && tex->use_nodes && tex->nodetree)
142                 ntreeEndExecTree(tex->nodetree);
143 }
144
145 void end_render_textures(void)
146 {
147         Tex *tex;
148         for(tex= G.main->tex.first; tex; tex= tex->id.next)
149                 if(tex->id.us)
150                         end_render_texture(tex);
151 }
152
153 /* ------------------------------------------------------------------------- */
154
155
156 /* this allows colorbanded textures to control normals as well */
157 static void tex_normal_derivate(Tex *tex, TexResult *texres)
158 {
159         if (tex->flag & TEX_COLORBAND) {
160                 float col[4];
161                 if (do_colorband(tex->coba, texres->tin, col)) {
162                         float fac0, fac1, fac2, fac3;
163                         
164                         fac0= (col[0]+col[1]+col[2]);
165                         do_colorband(tex->coba, texres->nor[0], col);
166                         fac1= (col[0]+col[1]+col[2]);
167                         do_colorband(tex->coba, texres->nor[1], col);
168                         fac2= (col[0]+col[1]+col[2]);
169                         do_colorband(tex->coba, texres->nor[2], col);
170                         fac3= (col[0]+col[1]+col[2]);
171                         
172                         texres->nor[0]= 0.3333*(fac0 - fac1);
173                         texres->nor[1]= 0.3333*(fac0 - fac2);
174                         texres->nor[2]= 0.3333*(fac0 - fac3);
175                         
176                         return;
177                 }
178         }
179         texres->nor[0]= texres->tin - texres->nor[0];
180         texres->nor[1]= texres->tin - texres->nor[1];
181         texres->nor[2]= texres->tin - texres->nor[2];
182 }
183
184
185
186 static int blend(Tex *tex, float *texvec, TexResult *texres)
187 {
188         float x, y, t;
189
190         if(tex->flag & TEX_FLIPBLEND) {
191                 x= texvec[1];
192                 y= texvec[0];
193         }
194         else {
195                 x= texvec[0];
196                 y= texvec[1];
197         }
198
199         if(tex->stype==TEX_LIN) {       /* lin */
200                 texres->tin= (1.0+x)/2.0;
201         }
202         else if(tex->stype==TEX_QUAD) { /* quad */
203                 texres->tin= (1.0+x)/2.0;
204                 if(texres->tin<0.0) texres->tin= 0.0;
205                 else texres->tin*= texres->tin;
206         }
207         else if(tex->stype==TEX_EASE) { /* ease */
208                 texres->tin= (1.0+x)/2.0;
209                 if(texres->tin<=.0) texres->tin= 0.0;
210                 else if(texres->tin>=1.0) texres->tin= 1.0;
211                 else {
212                         t= texres->tin*texres->tin;
213                         texres->tin= (3.0*t-2.0*t*texres->tin);
214                 }
215         }
216         else if(tex->stype==TEX_DIAG) { /* diag */
217                 texres->tin= (2.0+x+y)/4.0;
218         }
219         else if(tex->stype==TEX_RAD) { /* radial */
220                 texres->tin= (atan2(y,x) / (2*M_PI) + 0.5);
221         }
222         else {  /* sphere TEX_SPHERE */
223                 texres->tin= 1.0-sqrt(x*x+      y*y+texvec[2]*texvec[2]);
224                 if(texres->tin<0.0) texres->tin= 0.0;
225                 if(tex->stype==TEX_HALO) texres->tin*= texres->tin;  /* halo */
226         }
227
228         BRICONT;
229
230         return TEX_INT;
231 }
232
233 /* ------------------------------------------------------------------------- */
234 /* ************************************************************************* */
235
236 /* newnoise: all noisebased types now have different noisebases to choose from */
237
238 static int clouds(Tex *tex, float *texvec, TexResult *texres)
239 {
240         int rv = TEX_INT;
241         
242         texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
243
244         if (texres->nor!=NULL) {
245                 // calculate bumpnormal
246                 texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
247                 texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
248                 texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth,  (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
249                 
250                 tex_normal_derivate(tex, texres);
251                 rv |= TEX_NOR;
252         }
253
254         if (tex->stype==TEX_COLOR) {
255                 // in this case, int. value should really be computed from color,
256                 // and bumpnormal from that, would be too slow, looks ok as is
257                 texres->tr = texres->tin;
258                 texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
259                 texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
260                 BRICONTRGB;
261                 texres->ta = 1.0;
262                 return (rv | TEX_RGB);
263         }
264
265         BRICONT;
266
267         return rv;
268
269 }
270
271 /* creates a sine wave */
272 static float tex_sin(float a)
273 {
274         a = 0.5 + 0.5*sin(a);
275                 
276         return a;
277 }
278
279 /* creates a saw wave */
280 static float tex_saw(float a)
281 {
282         const float b = 2*M_PI;
283         
284         int n = (int)(a / b);
285         a -= n*b;
286         if (a < 0) a += b;
287         return a / b;
288 }
289
290 /* creates a triangle wave */
291 static float tex_tri(float a)
292 {
293         const float b = 2*M_PI;
294         const float rmax = 1.0;
295         
296         a = rmax - 2.0*fabs(floor((a*(1.0/b))+0.5) - (a*(1.0/b)));
297         
298         return a;
299 }
300
301 /* computes basic wood intensity value at x,y,z */
302 static float wood_int(Tex *tex, float x, float y, float z)
303 {
304         float wi=0;                                             
305         short wf = tex->noisebasis2;    /* wave form:   TEX_SIN=0,  TEX_SAW=1,  TEX_TRI=2                                                */
306         short wt = tex->stype;                  /* wood type:   TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3 */
307
308         float (*waveform[3])(float);    /* create array of pointers to waveform functions */
309         waveform[0] = tex_sin;                  /* assign address of tex_sin() function to pointer array */
310         waveform[1] = tex_saw;
311         waveform[2] = tex_tri;
312         
313         if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */
314                 
315         if (wt==TEX_BAND) {
316                 wi = waveform[wf]((x + y + z)*10.0);
317         }
318         else if (wt==TEX_RING) {
319                 wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0);
320         }
321         else if (wt==TEX_BANDNOISE) {
322                 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
323                 wi = waveform[wf]((x + y + z)*10.0 + wi);
324         }
325         else if (wt==TEX_RINGNOISE) {
326                 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
327                 wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0 + wi);
328         }
329         
330         return wi;
331 }
332
333 static int wood(Tex *tex, float *texvec, TexResult *texres)
334 {
335         int rv=TEX_INT;
336
337         texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
338         if (texres->nor!=NULL) {
339                 /* calculate bumpnormal */
340                 texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
341                 texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
342                 texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
343                 
344                 tex_normal_derivate(tex, texres);
345                 rv |= TEX_NOR;
346         }
347
348         BRICONT;
349
350         return rv;
351 }
352
353 /* computes basic marble intensity at x,y,z */
354 static float marble_int(Tex *tex, float x, float y, float z)
355 {
356         float n, mi;
357         short wf = tex->noisebasis2;    /* wave form:   TEX_SIN=0,  TEX_SAW=1,  TEX_TRI=2                                               */
358         short mt = tex->stype;                  /* marble type: TEX_SOFT=0,     TEX_SHARP=1,TEX_SHAPER=2                                        */
359         
360         float (*waveform[3])(float);    /* create array of pointers to waveform functions */
361         waveform[0] = tex_sin;                  /* assign address of tex_sin() function to pointer array */
362         waveform[1] = tex_saw;
363         waveform[2] = tex_tri;
364         
365         if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */
366         
367         n = 5.0 * (x + y + z);
368         
369         mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT),  tex->noisebasis);
370
371         if (mt>=TEX_SOFT) {  /* TEX_SOFT always true */
372                 mi = waveform[wf](mi);
373                 if (mt==TEX_SHARP) {
374                         mi = sqrt(mi);
375                 } 
376                 else if (mt==TEX_SHARPER) {
377                         mi = sqrt(sqrt(mi));
378                 }
379         }
380
381         return mi;
382 }
383
384 static int marble(Tex *tex, float *texvec, TexResult *texres)
385 {
386         int rv=TEX_INT;
387
388         texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
389
390         if (texres->nor!=NULL) {
391                 /* calculate bumpnormal */
392                 texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
393                 texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
394                 texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
395                 
396                 tex_normal_derivate(tex, texres);
397                 
398                 rv |= TEX_NOR;
399         }
400
401         BRICONT;
402
403         return rv;
404 }
405
406 /* ------------------------------------------------------------------------- */
407
408 static int magic(Tex *tex, float *texvec, TexResult *texres)
409 {
410         float x, y, z, turb=1.0;
411         int n;
412
413         n= tex->noisedepth;
414         turb= tex->turbul/5.0;
415
416         x=  sin( ( texvec[0]+texvec[1]+texvec[2])*5.0 );
417         y=  cos( (-texvec[0]+texvec[1]-texvec[2])*5.0 );
418         z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0 );
419         if(n>0) {
420                 x*= turb;
421                 y*= turb;
422                 z*= turb;
423                 y= -cos(x-y+z);
424                 y*= turb;
425                 if(n>1) {
426                         x= cos(x-y-z);
427                         x*= turb;
428                         if(n>2) {
429                                 z= sin(-x-y-z);
430                                 z*= turb;
431                                 if(n>3) {
432                                         x= -cos(-x+y-z);
433                                         x*= turb;
434                                         if(n>4) {
435                                                 y= -sin(-x+y+z);
436                                                 y*= turb;
437                                                 if(n>5) {
438                                                         y= -cos(-x+y+z);
439                                                         y*= turb;
440                                                         if(n>6) {
441                                                                 x= cos(x+y+z);
442                                                                 x*= turb;
443                                                                 if(n>7) {
444                                                                         z= sin(x+y-z);
445                                                                         z*= turb;
446                                                                         if(n>8) {
447                                                                                 x= -cos(-x-y+z);
448                                                                                 x*= turb;
449                                                                                 if(n>9) {
450                                                                                         y= -sin(x-y+z);
451                                                                                         y*= turb;
452                                                                                 }
453                                                                         }
454                                                                 }
455                                                         }
456                                                 }
457                                         }
458                                 }
459                         }
460                 }
461         }
462
463         if(turb!=0.0) {
464                 turb*= 2.0;
465                 x/= turb; 
466                 y/= turb; 
467                 z/= turb;
468         }
469         texres->tr= 0.5-x;
470         texres->tg= 0.5-y;
471         texres->tb= 0.5-z;
472
473         texres->tin= 0.3333*(texres->tr+texres->tg+texres->tb);
474         
475         BRICONTRGB;
476         texres->ta= 1.0;
477         
478         return TEX_RGB;
479 }
480
481 /* ------------------------------------------------------------------------- */
482
483 /* newnoise: stucci also modified to use different noisebasis */
484 static int stucci(Tex *tex, float *texvec, TexResult *texres)
485 {
486         float nor[3], b2, ofs;
487         int retval= TEX_INT;
488         
489         b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
490         
491         ofs= tex->turbul/200.0;
492
493         if(tex->stype) ofs*=(b2*b2);
494         nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
495         nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);     
496         nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
497
498         texres->tin= nor[2];
499         
500         if(texres->nor) { 
501                 
502                 VECCOPY(texres->nor, nor);
503                 tex_normal_derivate(tex, texres);
504                 
505                 if(tex->stype==TEX_WALLOUT) {
506                         texres->nor[0]= -texres->nor[0];
507                         texres->nor[1]= -texres->nor[1];
508                         texres->nor[2]= -texres->nor[2];
509                 }
510                 
511                 retval |= TEX_NOR;
512         }
513         
514         if(tex->stype==TEX_WALLOUT) 
515                 texres->tin= 1.0f-texres->tin;
516         
517         if(texres->tin<0.0f)
518                 texres->tin= 0.0f;
519         
520         return retval;
521 }
522
523 /* ------------------------------------------------------------------------- */
524 /* newnoise: musgrave terrain noise types */
525
526 static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres)
527 {
528         int rv = TEX_INT;
529         float (*mgravefunc)(float, float, float, float, float, float, int);
530
531         if (tex->stype==TEX_MFRACTAL)
532                 mgravefunc = mg_MultiFractal;
533         else
534                 mgravefunc = mg_fBm;
535
536         texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
537
538         if (texres->nor!=NULL) {
539                 float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
540                 
541                 /* calculate bumpnormal */
542                 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);
543                 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);
544                 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);
545                 
546                 tex_normal_derivate(tex, texres);
547                 rv |= TEX_NOR;
548         }
549
550         BRICONT;
551
552         return rv;
553
554 }
555
556 static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres)
557 {
558         int rv = TEX_INT;
559         float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
560
561         if (tex->stype==TEX_RIDGEDMF)
562                 mgravefunc = mg_RidgedMultiFractal;
563         else
564                 mgravefunc = mg_HybridMultiFractal;
565
566         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);
567
568         if (texres->nor!=NULL) {
569                 float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
570                 
571                 /* calculate bumpnormal */
572                 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);
573                 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);
574                 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);
575                 
576                 tex_normal_derivate(tex, texres);
577                 rv |= TEX_NOR;
578         }
579
580         BRICONT;
581
582         return rv;
583
584 }
585
586
587 static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres)
588 {
589         int rv = TEX_INT;
590
591         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);
592
593         if (texres->nor!=NULL) {
594                 float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
595                 
596                 /* calculate bumpnormal */
597                 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);
598                 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);
599                 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);
600                 
601                 tex_normal_derivate(tex, texres);
602                 rv |= TEX_NOR;
603         }
604
605         BRICONT;
606
607         return rv;
608
609 }
610
611
612 static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres)
613 {
614         int rv = TEX_INT;
615
616         texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
617
618         if (texres->nor!=NULL) {
619                 float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
620                 
621                 /* calculate bumpnormal */
622                 texres->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
623                 texres->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
624                 texres->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2);
625
626                 tex_normal_derivate(tex, texres);
627                 rv |= TEX_NOR;
628         }
629
630         BRICONT;
631
632
633         return rv;
634
635 }
636
637
638 /* ------------------------------------------------------------------------- */
639 /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */
640
641 static float voronoiTex(Tex *tex, float *texvec, TexResult *texres)
642 {
643         int rv = TEX_INT;
644         float da[4], pa[12];    /* distance and point coordinate arrays of 4 nearest neighbours */
645         float aw1 = fabs(tex->vn_w1);
646         float aw2 = fabs(tex->vn_w2);
647         float aw3 = fabs(tex->vn_w3);
648         float aw4 = fabs(tex->vn_w4);
649         float sc = (aw1 + aw2 + aw3 + aw4);
650         if (sc!=0.f) sc =  tex->ns_outscale/sc;
651
652         voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
653         texres->tin = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
654
655         if (tex->vn_coltype) {
656                 float ca[3];    /* cell color */
657                 cellNoiseV(pa[0], pa[1], pa[2], ca);
658                 texres->tr = aw1*ca[0];
659                 texres->tg = aw1*ca[1];
660                 texres->tb = aw1*ca[2];
661                 cellNoiseV(pa[3], pa[4], pa[5], ca);
662                 texres->tr += aw2*ca[0];
663                 texres->tg += aw2*ca[1];
664                 texres->tb += aw2*ca[2];
665                 cellNoiseV(pa[6], pa[7], pa[8], ca);
666                 texres->tr += aw3*ca[0];
667                 texres->tg += aw3*ca[1];
668                 texres->tb += aw3*ca[2];
669                 cellNoiseV(pa[9], pa[10], pa[11], ca);
670                 texres->tr += aw4*ca[0];
671                 texres->tg += aw4*ca[1];
672                 texres->tb += aw4*ca[2];
673                 if (tex->vn_coltype>=2) {
674                         float t1 = (da[1]-da[0])*10;
675                         if (t1>1) t1=1;
676                         if (tex->vn_coltype==3) t1*=texres->tin; else t1*=sc;
677                         texres->tr *= t1;
678                         texres->tg *= t1;
679                         texres->tb *= t1;
680                 }
681                 else {
682                         texres->tr *= sc;
683                         texres->tg *= sc;
684                         texres->tb *= sc;
685                 }
686         }
687
688         if (texres->nor!=NULL) {
689                 float offs= tex->nabla/tex->noisesize;  // also scaling of texvec
690
691                 /* calculate bumpnormal */
692                 voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
693                 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]);
694                 voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp,  tex->vn_distm);
695                 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]);
696                 voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp,  tex->vn_distm);
697                 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]);
698                 
699                 tex_normal_derivate(tex, texres);
700                 rv |= TEX_NOR;
701         }
702
703         if (tex->vn_coltype) {
704                 BRICONTRGB;
705                 texres->ta = 1.0;
706                 return (rv | TEX_RGB);
707         }
708         
709         BRICONT;
710
711         return rv;
712
713 }
714
715 /* ------------------------------------------------------------------------- */
716
717 static int evalnodes(Tex *tex, float *texvec, TexResult *texres, short thread, short which_output)
718 {
719         short rv = TEX_INT;
720         bNodeTree *nodes = tex->nodetree;
721         
722         ntreeTexExecTree(nodes, texres, texvec, 0, thread, tex, which_output, R.r.cfra);
723         
724         if(texres->nor) rv |= TEX_NOR;
725         rv |= TEX_RGB;
726         return rv;
727 }
728
729 /* ------------------------------------------------------------------------- */
730
731 static int texnoise(Tex *tex, TexResult *texres)
732 {
733         float div=3.0;
734         int val, ran, loop;
735         
736         ran= BLI_rand();
737         val= (ran & 3);
738         
739         loop= tex->noisedepth;
740         while(loop--) {
741                 ran= (ran>>2);
742                 val*= (ran & 3);
743                 div*= 3.0;
744         }
745         
746         texres->tin= ((float)val)/div;;
747
748         BRICONT;
749         return TEX_INT;
750 }
751
752 /* ------------------------------------------------------------------------- */
753
754 static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
755 {
756         PluginTex *pit;
757         int rgbnor=0;
758         float result[ 8 ];
759
760         texres->tin= 0.0;
761
762         pit= tex->plugin;
763         if(pit && pit->doit) {
764                 if(texres->nor) {
765                         if (pit->version < 6) {
766                                 VECCOPY(pit->result+5, texres->nor);
767                         } else {
768                                 VECCOPY(result+5, texres->nor);
769                         }
770                 }
771                 if (pit->version < 6) {
772                         if(osatex) rgbnor= ((TexDoitold)pit->doit)(tex->stype, 
773                                 pit->data, texvec, dxt, dyt);
774                         else rgbnor= ((TexDoitold)pit->doit)(tex->stype, 
775                                 pit->data, texvec, 0, 0);
776                 } else {
777                         if(osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, 
778                                 pit->data, texvec, dxt, dyt, result);
779                         else rgbnor= ((TexDoit)pit->doit)(tex->stype, 
780                                 pit->data, texvec, 0, 0, result);
781                 }
782
783                 if (pit->version < 6) {
784                         texres->tin = pit->result[0];
785                 } else {
786                         texres->tin = result[0];
787                 }
788
789                 if(rgbnor & TEX_NOR) {
790                         if(texres->nor) {
791                                 if (pit->version < 6) {
792                                         VECCOPY(texres->nor, pit->result+5);
793                                 } else {
794                                         VECCOPY(texres->nor, result+5);
795                                 }
796                         }
797                 }
798                 
799                 if(rgbnor & TEX_RGB) {
800                         if (pit->version < 6) {
801                                 texres->tr = pit->result[1];
802                                 texres->tg = pit->result[2];
803                                 texres->tb = pit->result[3];
804                                 texres->ta = pit->result[4];
805                         } else {
806                                 texres->tr = result[1];
807                                 texres->tg = result[2];
808                                 texres->tb = result[3];
809                                 texres->ta = result[4];
810                         }
811
812                         BRICONTRGB;
813                 }
814                 
815                 BRICONT;
816         }
817
818         return rgbnor;
819 }
820
821
822 static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float *adr2)
823 {
824         float x1, y1, z1, nor[3];
825         int ret;
826         
827         if(n==NULL) {
828                 nor[0]= x; nor[1]= y; nor[2]= z;        // use local render coord
829         }
830         else {
831                 VECCOPY(nor, n);
832         }
833         MTC_Mat4Mul3Vecfl(R.viewinv, nor);
834
835         x1= fabs(nor[0]);
836         y1= fabs(nor[1]);
837         z1= fabs(nor[2]);
838         
839         if(z1>=x1 && z1>=y1) {
840                 *adr1 = (x + 1.0) / 2.0;
841                 *adr2 = (y + 1.0) / 2.0;
842                 ret= 0;
843         }
844         else if(y1>=x1 && y1>=z1) {
845                 *adr1 = (x + 1.0) / 2.0;
846                 *adr2 = (z + 1.0) / 2.0;
847                 ret= 1;
848         }
849         else {
850                 *adr1 = (y + 1.0) / 2.0;
851                 *adr2 = (z + 1.0) / 2.0;
852                 ret= 2;         
853         }
854         return ret;
855 }
856
857 /* ------------------------------------------------------------------------- */
858
859 /* mtex argument only for projection switches */
860 static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z, float *adr1, float *adr2)
861 {
862         int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
863         
864         if(vlr) {
865                 int index;
866                 
867                 /* Mesh vertices have such flags, for others we calculate it once based on orco */
868                 if((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) {
869                         /* test for v1, vlr can be faked for baking */
870                         if(vlr->v1 && vlr->v1->orco) {
871                                 float nor[3];
872                                 CalcNormFloat(vlr->v1->orco, vlr->v2->orco, vlr->v3->orco, nor);
873                                 
874                                 if( fabs(nor[0])<fabs(nor[2]) && fabs(nor[1])<fabs(nor[2]) ) vlr->puno |= ME_PROJXY;
875                                 else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
876                                 else vlr->puno |= ME_PROJYZ;
877                         }
878                         else return cubemap_glob(n, x, y, z, adr1, adr2);
879                 }
880                 
881                 if(mtex) {
882                         /* the mtex->proj{xyz} have type char. maybe this should be wider? */
883                         /* casting to int ensures that the index type is right.            */
884                         index = (int) mtex->projx;
885                         proj[index]= ME_PROJXY;
886
887                         index = (int) mtex->projy;
888                         proj[index]= ME_PROJXZ;
889
890                         index = (int) mtex->projz;
891                         proj[index]= ME_PROJYZ;
892                 }
893                 
894                 if(vlr->puno & proj[1]) {
895                         *adr1 = (x + 1.0) / 2.0;
896                         *adr2 = (y + 1.0) / 2.0;        
897                 }
898                 else if(vlr->puno & proj[2]) {
899                         *adr1 = (x + 1.0) / 2.0;
900                         *adr2 = (z + 1.0) / 2.0;
901                         ret= 1;
902                 }
903                 else {
904                         *adr1 = (y + 1.0) / 2.0;
905                         *adr2 = (z + 1.0) / 2.0;
906                         ret= 2;
907                 }               
908         } 
909         else {
910                 return cubemap_glob(n, x, y, z, adr1, adr2);
911         }
912         
913         return ret;
914 }
915
916 /* ------------------------------------------------------------------------- */
917
918 static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *adr1, float *adr2)
919 {
920         float x1, y1, z1, nor[3];
921         int ret;
922         
923         if(n==NULL) return 0;
924         
925         VECCOPY(nor, n);
926         if(ob) MTC_Mat4Mul3Vecfl(ob->imat, nor);
927         
928         x1= fabs(nor[0]);
929         y1= fabs(nor[1]);
930         z1= fabs(nor[2]);
931         
932         if(z1>=x1 && z1>=y1) {
933                 *adr1 = (x + 1.0) / 2.0;
934                 *adr2 = (y + 1.0) / 2.0;
935                 ret= 0;
936         }
937         else if(y1>=x1 && y1>=z1) {
938                 *adr1 = (x + 1.0) / 2.0;
939                 *adr2 = (z + 1.0) / 2.0;
940                 ret= 1;
941         }
942         else {
943                 *adr1 = (y + 1.0) / 2.0;
944                 *adr2 = (z + 1.0) / 2.0;
945                 ret= 2;         
946         }
947         return ret;
948 }
949
950 /* ------------------------------------------------------------------------- */
951
952 static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *dxt, float *dyt)
953 {
954         Tex *tex;
955         Object *ob= NULL;
956         float fx, fy, fac1, area[8];
957         int ok, proj, areaflag= 0, wrap, texco;
958         
959         /* mtex variables localized, only cubemap doesn't cooperate yet... */
960         wrap= mtex->mapping;
961         tex= mtex->tex;
962         ob= mtex->object;
963         texco= mtex->texco;
964
965         if(R.osa==0) {
966                 
967                 if(wrap==MTEX_FLAT) {
968                         fx = (t[0] + 1.0) / 2.0;
969                         fy = (t[1] + 1.0) / 2.0;
970                 }
971                 else if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
972                 else if(wrap==MTEX_SPHERE) spheremap(t[0], t[1], t[2], &fx, &fy);
973                 else {
974                         if(texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
975                         else if(texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
976                         else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
977                 }
978                 
979                 /* repeat */
980                 if(tex->extend==TEX_REPEAT) {
981                         if(tex->xrepeat>1) {
982                                 float origf= fx *= tex->xrepeat;
983                                 
984                                 if(fx>1.0) fx -= (int)(fx);
985                                 else if(fx<0.0) fx+= 1-(int)(fx);
986                                 
987                                 if(tex->flag & TEX_REPEAT_XMIR) {
988                                         int orig= (int)floor(origf);
989                                         if(orig & 1)
990                                                 fx= 1.0-fx;
991                                 }
992                         }
993                         if(tex->yrepeat>1) {
994                                 float origf= fy *= tex->yrepeat;
995                                 
996                                 if(fy>1.0) fy -= (int)(fy);
997                                 else if(fy<0.0) fy+= 1-(int)(fy);
998                                 
999                                 if(tex->flag & TEX_REPEAT_YMIR) {
1000                                         int orig= (int)floor(origf);
1001                                         if(orig & 1) 
1002                                                 fy= 1.0-fy;
1003                                 }
1004                         }
1005                 }
1006                 /* crop */
1007                 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) {
1008                         fac1= tex->cropxmax - tex->cropxmin;
1009                         fx= tex->cropxmin+ fx*fac1;
1010                 }
1011                 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) {
1012                         fac1= tex->cropymax - tex->cropymin;
1013                         fy= tex->cropymin+ fy*fac1;
1014                 }
1015
1016                 t[0]= fx;
1017                 t[1]= fy;
1018         }
1019         else {
1020                 
1021                 if(wrap==MTEX_FLAT) {
1022                         fx= (t[0] + 1.0) / 2.0;
1023                         fy= (t[1] + 1.0) / 2.0;
1024                         dxt[0]/= 2.0; 
1025                         dxt[1]/= 2.0;
1026                         dxt[2]/= 2.0;
1027                         dyt[0]/= 2.0; 
1028                         dyt[1]/= 2.0;
1029                         dyt[2]/= 2.0;
1030                 }
1031                 else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) {
1032                         /* exception: the seam behind (y<0.0) */
1033                         ok= 1;
1034                         if(t[1]<=0.0) {
1035                                 fx= t[0]+dxt[0];
1036                                 fy= t[0]+dyt[0];
1037                                 if(fx>=0.0 && fy>=0.0 && t[0]>=0.0);
1038                                 else if(fx<=0.0 && fy<=0.0 && t[0]<=0.0);
1039                                 else ok= 0;
1040                         }
1041                         if(ok) {
1042                                 if(wrap==MTEX_TUBE) {
1043                                         tubemap(t[0], t[1], t[2], area, area+1);
1044                                         tubemap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3);
1045                                         tubemap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5);
1046                                 }
1047                                 else { 
1048                                         spheremap(t[0], t[1], t[2],area,area+1);
1049                                         spheremap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3);
1050                                         spheremap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5);
1051                                 }
1052                                 areaflag= 1;
1053                         }
1054                         else {
1055                                 if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
1056                                 else spheremap(t[0], t[1], t[2], &fx, &fy);
1057                                 dxt[0]/= 2.0; 
1058                                 dxt[1]/= 2.0;
1059                                 dyt[0]/= 2.0; 
1060                                 dyt[1]/= 2.0;
1061                         }
1062                 }
1063                 else {
1064
1065                         if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
1066                         else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
1067                         else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
1068
1069                         if(proj==1) {
1070                                 SWAP(float, dxt[1], dxt[2]);
1071                                 SWAP(float, dyt[1], dyt[2]);
1072                         }
1073                         else if(proj==2) {
1074                                 float f1= dxt[0], f2= dyt[0];
1075                                 dxt[0]= dxt[1];
1076                                 dyt[0]= dyt[1];
1077                                 dxt[1]= dxt[2];
1078                                 dyt[1]= dyt[2];
1079                                 dxt[2]= f1;
1080                                 dyt[2]= f2;
1081                         }
1082
1083                         dxt[0] *= 0.5f;
1084                         dxt[1] *= 0.5f;
1085                         dxt[2] *= 0.5f;
1086
1087                         dyt[0] *= 0.5f;
1088                         dyt[1] *= 0.5f;
1089                         dyt[2] *= 0.5f;
1090
1091                 }
1092                 
1093                 /* if area, then reacalculate dxt[] and dyt[] */
1094                 if(areaflag) {
1095                         fx= area[0]; 
1096                         fy= area[1];
1097                         dxt[0]= area[2]-fx;
1098                         dxt[1]= area[3]-fy;
1099                         dyt[0]= area[4]-fx;
1100                         dyt[1]= area[5]-fy;
1101                 }
1102                 
1103                 /* repeat */
1104                 if(tex->extend==TEX_REPEAT) {
1105                         float max= 1.0f;
1106                         if(tex->xrepeat>1) {
1107                                 float origf= fx *= tex->xrepeat;
1108                                 
1109                                 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
1110                                 if (tex->texfilter == TXF_BOX) {
1111                                         if(fx>1.0f) fx -= (int)(fx);
1112                                         else if(fx<0.0f) fx+= 1-(int)(fx);
1113                                 
1114                                         if(tex->flag & TEX_REPEAT_XMIR) {
1115                                                 int orig= (int)floor(origf);
1116                                                 if(orig & 1) 
1117                                                         fx= 1.0f-fx;
1118                                         }
1119                                 }
1120                                 
1121                                 max= tex->xrepeat;
1122                                 
1123                                 dxt[0]*= tex->xrepeat;
1124                                 dyt[0]*= tex->xrepeat;
1125                         }
1126                         if(tex->yrepeat>1) {
1127                                 float origf= fy *= tex->yrepeat;
1128                                 
1129                                 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
1130                                 if (tex->texfilter == TXF_BOX) {
1131                                         if(fy>1.0f) fy -= (int)(fy);
1132                                         else if(fy<0.0f) fy+= 1-(int)(fy);
1133                                 
1134                                         if(tex->flag & TEX_REPEAT_YMIR) {
1135                                                 int orig= (int)floor(origf);
1136                                                 if(orig & 1) 
1137                                                         fy= 1.0f-fy;
1138                                         }
1139                                 }
1140                                 
1141                                 if(max<tex->yrepeat)
1142                                         max= tex->yrepeat;
1143
1144                                 dxt[1]*= tex->yrepeat;
1145                                 dyt[1]*= tex->yrepeat;
1146                         }
1147                         if(max!=1.0f) {
1148                                 dxt[2]*= max;
1149                                 dyt[2]*= max;
1150                         }
1151                         
1152                 }
1153                 /* crop */
1154                 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) {
1155                         fac1= tex->cropxmax - tex->cropxmin;
1156                         fx= tex->cropxmin+ fx*fac1;
1157                         dxt[0]*= fac1;
1158                         dyt[0]*= fac1;
1159                 }
1160                 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) {
1161                         fac1= tex->cropymax - tex->cropymin;
1162                         fy= tex->cropymin+ fy*fac1;
1163                         dxt[1]*= fac1;
1164                         dyt[1]*= fac1;
1165                 }
1166                 
1167                 t[0]= fx;
1168                 t[1]= fy;
1169
1170         }
1171 }
1172
1173 /* ************************************** */
1174
1175 static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
1176 {
1177         float tmpvec[3];
1178         int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
1179
1180         texres->talpha= 0;      /* is set when image texture returns alpha (considered premul) */
1181         
1182         if(tex->use_nodes && tex->nodetree) {
1183                 retval = evalnodes(tex, texvec, texres, thread, which_output);
1184         }
1185         else
1186         switch(tex->type) {
1187         
1188         case 0:
1189                 texres->tin= 0.0f;
1190                 return 0;
1191         case TEX_CLOUDS:
1192                 retval= clouds(tex, texvec, texres);
1193                 break;
1194         case TEX_WOOD:
1195                 retval= wood(tex, texvec, texres); 
1196                 break;
1197         case TEX_MARBLE:
1198                 retval= marble(tex, texvec, texres); 
1199                 break;
1200         case TEX_MAGIC:
1201                 retval= magic(tex, texvec, texres); 
1202                 break;
1203         case TEX_BLEND:
1204                 retval= blend(tex, texvec, texres);
1205                 break;
1206         case TEX_STUCCI:
1207                 retval= stucci(tex, texvec, texres); 
1208                 break;
1209         case TEX_NOISE:
1210                 retval= texnoise(tex, texres); 
1211                 break;
1212         case TEX_IMAGE:
1213                 if(osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres);
1214                 else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); 
1215                 tag_image_time(tex->ima); /* tag image as having being used */
1216                 break;
1217         case TEX_PLUGIN:
1218                 retval= plugintex(tex, texvec, dxt, dyt, osatex, texres);
1219                 break;
1220         case TEX_ENVMAP:
1221                 retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres);
1222                 break;
1223         case TEX_MUSGRAVE:
1224                 /* newnoise: musgrave types */
1225                 
1226                 /* ton: added this, for Blender convention reason. 
1227                  * artificer: added the use of tmpvec to avoid scaling texvec
1228                  */
1229                 VECCOPY(tmpvec, texvec);
1230                 VecMulf(tmpvec, 1.0/tex->noisesize);
1231                 
1232                 switch(tex->stype) {
1233                 case TEX_MFRACTAL:
1234                 case TEX_FBM:
1235                         retval= mg_mFractalOrfBmTex(tex, tmpvec, texres);
1236                         break;
1237                 case TEX_RIDGEDMF:
1238                 case TEX_HYBRIDMF:
1239                         retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres);
1240                         break;
1241                 case TEX_HTERRAIN:
1242                         retval= mg_HTerrainTex(tex, tmpvec, texres);
1243                         break;
1244                 }
1245                 break;
1246         /* newnoise: voronoi type */
1247         case TEX_VORONOI:
1248                 /* ton: added this, for Blender convention reason.
1249                  * artificer: added the use of tmpvec to avoid scaling texvec
1250                  */
1251                 VECCOPY(tmpvec, texvec);
1252                 VecMulf(tmpvec, 1.0/tex->noisesize);
1253                 
1254                 retval= voronoiTex(tex, tmpvec, texres);
1255                 break;
1256         case TEX_DISTNOISE:
1257                 /* ton: added this, for Blender convention reason.
1258                  * artificer: added the use of tmpvec to avoid scaling texvec
1259                  */
1260                 VECCOPY(tmpvec, texvec);
1261                 VecMulf(tmpvec, 1.0/tex->noisesize);
1262                 
1263                 retval= mg_distNoiseTex(tex, tmpvec, texres);
1264                 break;
1265         }
1266
1267         if (tex->flag & TEX_COLORBAND) {
1268                 float col[4];
1269                 if (do_colorband(tex->coba, texres->tin, col)) {
1270                         texres->talpha= 1;
1271                         texres->tr= col[0];
1272                         texres->tg= col[1];
1273                         texres->tb= col[2];
1274                         texres->ta= col[3];
1275                         retval |= 1;
1276                 }
1277         }
1278         return retval;
1279 }
1280
1281 /* Warning, if the texres's values are not declared zero, check the return value to be sure
1282  * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
1283 int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
1284 {
1285         return multitex_thread(tex, texvec, dxt, dyt, osatex, texres, 0, 0);
1286 }
1287
1288 int multitex_thread(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
1289 {
1290         if(tex==NULL) {
1291                 memset(texres, 0, sizeof(TexResult));
1292                 return 0;
1293         }
1294         
1295         /* Image requires 2d mapping conversion */
1296         if(tex->type==TEX_IMAGE) {
1297                 MTex mtex;
1298                 float texvec_l[3], dxt_l[3], dyt_l[3];
1299                 
1300                 mtex.mapping= MTEX_FLAT;
1301                 mtex.tex= tex;
1302                 mtex.object= NULL;
1303                 mtex.texco= TEXCO_ORCO;
1304                 
1305                 VECCOPY(texvec_l, texvec);
1306                 if(dxt && dyt) {
1307                         VECCOPY(dxt_l, dxt);
1308                         VECCOPY(dyt_l, dyt);
1309                 }
1310                 else {
1311                         dxt_l[0]= dxt_l[1]= dxt_l[2]= 0.0f;
1312                         dyt_l[0]= dyt_l[1]= dyt_l[2]= 0.0f;
1313                 }
1314                 
1315                 do_2d_mapping(&mtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
1316
1317                 return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
1318         }
1319         else
1320                 return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
1321 }
1322
1323 /* ------------------------------------------------------------------------- */
1324
1325 /* in = destination, tex = texture, out = previous color */
1326 /* fact = texture strength, facg = button strength value */
1327 void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype)
1328 {
1329         float facm, col;
1330         
1331         switch(blendtype) {
1332         case MTEX_BLEND:
1333                 fact*= facg;
1334                 facm= 1.0-fact;
1335
1336                 in[0]= (fact*tex[0] + facm*out[0]);
1337                 in[1]= (fact*tex[1] + facm*out[1]);
1338                 in[2]= (fact*tex[2] + facm*out[2]);
1339                 break;
1340                 
1341         case MTEX_MUL:
1342                 fact*= facg;
1343                 facm= 1.0-facg;
1344                 in[0]= (facm+fact*tex[0])*out[0];
1345                 in[1]= (facm+fact*tex[1])*out[1];
1346                 in[2]= (facm+fact*tex[2])*out[2];
1347                 break;
1348
1349         case MTEX_SCREEN:
1350                 fact*= facg;
1351                 facm= 1.0-facg;
1352                 in[0]= 1.0 - (facm+fact*(1.0-tex[0])) * (1.0-out[0]);
1353                 in[1]= 1.0 - (facm+fact*(1.0-tex[1])) * (1.0-out[1]);
1354                 in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]);
1355                 break;
1356
1357         case MTEX_OVERLAY:
1358                 fact*= facg;
1359                 facm= 1.0-facg;
1360                 
1361                 if(out[0] < 0.5f)
1362                         in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
1363                 else
1364                         in[0] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[0])) * (1.0 - out[0]);
1365                 if(out[1] < 0.5f)
1366                         in[1] = out[1] * (facm + 2.0f*fact*tex[1]);
1367                 else
1368                         in[1] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[1])) * (1.0 - out[1]);
1369                 if(out[2] < 0.5f)
1370                         in[2] = out[2] * (facm + 2.0f*fact*tex[2]);
1371                 else
1372                         in[2] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[2])) * (1.0 - out[2]);
1373                 break;
1374                 
1375         case MTEX_SUB:
1376                 fact= -fact;
1377         case MTEX_ADD:
1378                 fact*= facg;
1379                 in[0]= (fact*tex[0] + out[0]);
1380                 in[1]= (fact*tex[1] + out[1]);
1381                 in[2]= (fact*tex[2] + out[2]);
1382                 break;
1383
1384         case MTEX_DIV:
1385                 fact*= facg;
1386                 facm= 1.0-fact;
1387                 
1388                 if(tex[0]!=0.0)
1389                         in[0]= facm*out[0] + fact*out[0]/tex[0];
1390                 if(tex[1]!=0.0)
1391                         in[1]= facm*out[1] + fact*out[1]/tex[1];
1392                 if(tex[2]!=0.0)
1393                         in[2]= facm*out[2] + fact*out[2]/tex[2];
1394
1395                 break;
1396
1397         case MTEX_DIFF:
1398                 fact*= facg;
1399                 facm= 1.0-fact;
1400                 in[0]= facm*out[0] + fact*fabs(tex[0]-out[0]);
1401                 in[1]= facm*out[1] + fact*fabs(tex[1]-out[1]);
1402                 in[2]= facm*out[2] + fact*fabs(tex[2]-out[2]);
1403                 break;
1404
1405         case MTEX_DARK:
1406                 fact*= facg;
1407                 facm= 1.0-fact;
1408                 
1409                 col= fact*tex[0];
1410                 if(col < out[0]) in[0]= col; else in[0]= out[0];
1411                 col= fact*tex[1];
1412                 if(col < out[1]) in[1]= col; else in[1]= out[1];
1413                 col= fact*tex[2];
1414                 if(col < out[2]) in[2]= col; else in[2]= out[2];
1415                 break;
1416
1417         case MTEX_LIGHT:
1418                 fact*= facg;
1419                 facm= 1.0-fact;
1420                 
1421                 col= fact*tex[0];
1422                 if(col > out[0]) in[0]= col; else in[0]= out[0];
1423                 col= fact*tex[1];
1424                 if(col > out[1]) in[1]= col; else in[1]= out[1];
1425                 col= fact*tex[2];
1426                 if(col > out[2]) in[2]= col; else in[2]= out[2];
1427                 break;
1428                 
1429         case MTEX_BLEND_HUE:
1430                 fact*= facg;
1431                 VECCOPY(in, out);
1432                 ramp_blend(MA_RAMP_HUE, in, in+1, in+2, fact, tex);
1433                 break;
1434         case MTEX_BLEND_SAT:
1435                 fact*= facg;
1436                 VECCOPY(in, out);
1437                 ramp_blend(MA_RAMP_SAT, in, in+1, in+2, fact, tex);
1438                 break;
1439         case MTEX_BLEND_VAL:
1440                 fact*= facg;
1441                 VECCOPY(in, out);
1442                 ramp_blend(MA_RAMP_VAL, in, in+1, in+2, fact, tex);
1443                 break;
1444         case MTEX_BLEND_COLOR:
1445                 fact*= facg;
1446                 VECCOPY(in, out);
1447                 ramp_blend(MA_RAMP_COLOR, in, in+1, in+2, fact, tex);
1448                 break;
1449         }
1450 }
1451
1452 float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip)
1453 {
1454         float in=0.0, facm, col;
1455         
1456         fact*= facg;
1457         facm= 1.0-fact;
1458         if(flip) SWAP(float, fact, facm);
1459
1460         switch(blendtype) {
1461         case MTEX_BLEND:
1462                 in= fact*tex + facm*out;
1463                 break;
1464
1465         case MTEX_MUL:
1466                 facm= 1.0-facg;
1467                 in= (facm+fact*tex)*out;
1468                 break;
1469
1470         case MTEX_SCREEN:
1471                 facm= 1.0-facg;
1472                 in= 1.0-(facm+fact*(1.0-tex))*(1.0-out);
1473                 break;
1474
1475         case MTEX_SUB:
1476                 fact= -fact;
1477         case MTEX_ADD:
1478                 in= fact*tex + out;
1479                 break;
1480
1481         case MTEX_DIV:
1482                 if(tex!=0.0)
1483                         in= facm*out + fact*out/tex;
1484                 break;
1485
1486         case MTEX_DIFF:
1487                 in= facm*out + fact*fabs(tex-out);
1488                 break;
1489
1490         case MTEX_DARK:
1491                 col= fact*tex;
1492                 if(col < out) in= col; else in= out;
1493                 break;
1494
1495         case MTEX_LIGHT:
1496                 col= fact*tex;
1497                 if(col > out) in= col; else in= out;
1498                 break;
1499         }
1500         
1501         return in;
1502 }
1503
1504 static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt)
1505 {
1506         // new: first swap coords, then map, then trans/scale
1507         if (tex->type == TEX_IMAGE) {
1508                 // placement
1509                 texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f;
1510                 texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f;
1511                 texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f;
1512
1513                 if (shi->osatex) {
1514                         if (mtex->projx) {
1515                                 dxt[0] = dx[mtex->projx - 1];
1516                                 dyt[0] = dy[mtex->projx - 1];
1517                         }
1518                         else dxt[0] = dyt[0] = 0.f;
1519                         if (mtex->projy) {
1520                                 dxt[1] = dx[mtex->projy - 1];
1521                                 dyt[1] = dy[mtex->projy - 1];
1522                         }
1523                         else dxt[1] = dyt[1] = 0.f;
1524                         if (mtex->projz) {
1525                                 dxt[2] = dx[mtex->projz - 1];
1526                                 dyt[2] = dy[mtex->projz - 1];
1527                         }
1528                         else dxt[2] = dyt[2] = 0.f;
1529                 }
1530                 do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
1531
1532                 // translate and scale
1533                 texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f;
1534                 texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f;
1535                 if (shi->osatex) {
1536                         dxt[0] = mtex->size[0]*dxt[0];
1537                         dxt[1] = mtex->size[1]*dxt[1];
1538                         dyt[0] = mtex->size[0]*dyt[0];
1539                         dyt[1] = mtex->size[1]*dyt[1];
1540                 }
1541                 
1542                 /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */
1543                 // TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too.
1544                 // New texfilters solve mirroring differently so that it also works correctly when
1545                 // textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping().
1546                 // (since currently only done in osa mode, results will look incorrect without osa TODO) 
1547                 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) {
1548                         if (tex->texfilter == TXF_BOX)
1549                                 texvec[0] -= floorf(texvec[0]); // this line equivalent to old code, same below
1550                         else if (texvec[0] < 0.f || texvec[0] > 1.f) {
1551                                 const float tx = 0.5f*texvec[0];
1552                                 texvec[0] = 2.f*(tx - floorf(tx));
1553                                 if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0];
1554                         }
1555                 }
1556                 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) {
1557                         if  (tex->texfilter == TXF_BOX)
1558                                 texvec[1] -= floorf(texvec[1]);
1559                         else if (texvec[1] < 0.f || texvec[1] > 1.f) {
1560                                 const float ty = 0.5f*texvec[1];
1561                                 texvec[1] = 2.f*(ty - floorf(ty));
1562                                 if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1];
1563                         }
1564                 }
1565                 
1566         }
1567         else {  // procedural
1568                 // placement
1569                 texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]);
1570                 texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]);
1571                 texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]);
1572
1573                 if (shi->osatex) {
1574                         if (mtex->projx) {
1575                                 dxt[0] = mtex->size[0]*dx[mtex->projx - 1];
1576                                 dyt[0] = mtex->size[0]*dy[mtex->projx - 1];
1577                         }
1578                         else dxt[0] = 0.f;
1579                         if (mtex->projy) {
1580                                 dxt[1] = mtex->size[1]*dx[mtex->projy - 1];
1581                                 dyt[1] = mtex->size[1]*dy[mtex->projy - 1];
1582                         }
1583                         else dxt[1] = 0.f;
1584                         if (mtex->projz) {
1585                                 dxt[2] = mtex->size[2]*dx[mtex->projz - 1];
1586                                 dyt[2] = mtex->size[2]*dy[mtex->projz - 1];
1587                         }
1588                         else dxt[2]= 0.f;
1589                 }
1590         }
1591 }
1592
1593 void do_material_tex(ShadeInput *shi)
1594 {
1595         MTex *mtex;
1596         Tex *tex;
1597         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
1598         float *co = NULL, *dx = NULL, *dy = NULL;
1599         float fact, facm, factt, facmm, stencilTin=1.0;
1600         float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
1601         int tex_nr, rgbnor= 0, warpdone=0;
1602         float nu[3], nv[3], nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
1603         int nunvdone= 0;
1604
1605         if (R.r.scemode & R_NO_TEX) return;
1606         /* here: test flag if there's a tex (todo) */
1607
1608         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
1609                 
1610                 /* separate tex switching */
1611                 if(shi->mat->septex & (1<<tex_nr)) continue;
1612                 
1613                 if(shi->mat->mtex[tex_nr]) {
1614                         mtex= shi->mat->mtex[tex_nr];
1615                         
1616                         tex= mtex->tex;
1617                         if(tex==0) continue;
1618
1619                         /* which coords */
1620                         if(mtex->texco==TEXCO_ORCO) {
1621                                 if(mtex->texflag & MTEX_DUPLI_MAPTO) {
1622                                         co= shi->duplilo; dx= dxt; dy= dyt;
1623                                         dxt[0]= dxt[1]= dxt[2]= 0.0f;
1624                                         dyt[0]= dyt[1]= dyt[2]= 0.0f;
1625                                 }
1626                                 else {
1627                                         co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
1628                                 }
1629                         }
1630                         else if(mtex->texco==TEXCO_STICKY) {
1631                                 co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
1632                         }
1633                         else if(mtex->texco==TEXCO_OBJECT) {
1634                                 Object *ob= mtex->object;
1635                                 if(ob) {
1636                                         co= tempvec;
1637                                         dx= dxt;
1638                                         dy= dyt;
1639                                         VECCOPY(tempvec, shi->co);
1640                                         if(mtex->texflag & MTEX_OB_DUPLI_ORIG)
1641                                                 if(shi->obi && shi->obi->duplitexmat)
1642                                                         MTC_Mat4MulVecfl(shi->obi->duplitexmat, tempvec);
1643                                         MTC_Mat4MulVecfl(ob->imat, tempvec);
1644                                         if(shi->osatex) {
1645                                                 VECCOPY(dxt, shi->dxco);
1646                                                 VECCOPY(dyt, shi->dyco);
1647                                                 MTC_Mat4Mul3Vecfl(ob->imat, dxt);
1648                                                 MTC_Mat4Mul3Vecfl(ob->imat, dyt);
1649                                         }
1650                                 }
1651                                 else {
1652                                         /* if object doesn't exist, do not use orcos (not initialized) */
1653                                         co= shi->co;
1654                                         dx= shi->dxco; dy= shi->dyco;
1655                                 }
1656                         }
1657                         else if(mtex->texco==TEXCO_REFL) {
1658                                 co= shi->ref; dx= shi->dxref; dy= shi->dyref;
1659                         }
1660                         else if(mtex->texco==TEXCO_NORM) {
1661                                 co= shi->orn; dx= shi->dxno; dy= shi->dyno;
1662                         }
1663                         else if(mtex->texco==TEXCO_TANGENT) {
1664                                 co= shi->tang; dx= shi->dxno; dy= shi->dyno;
1665                         }
1666                         else if(mtex->texco==TEXCO_GLOB) {
1667                                 co= shi->gl; dx= shi->dxco; dy= shi->dyco;
1668                         }
1669                         else if(mtex->texco==TEXCO_UV) {
1670                                 if(mtex->texflag & MTEX_DUPLI_MAPTO) {
1671                                         co= shi->dupliuv; dx= dxt; dy= dyt;
1672                                         dxt[0]= dxt[1]= dxt[2]= 0.0f;
1673                                         dyt[0]= dyt[1]= dyt[2]= 0.0f;
1674                                 }
1675                                 else {
1676                                         ShadeInputUV *suv= &shi->uv[shi->actuv];
1677                                         int i = shi->actuv;
1678
1679                                         if(mtex->uvname[0] != 0) {
1680                                                 for(i = 0; i < shi->totuv; i++) {
1681                                                         if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
1682                                                                 suv= &shi->uv[i];
1683                                                                 break;
1684                                                         }
1685                                                 }
1686                                         }
1687
1688                                         co= suv->uv;
1689                                         dx= suv->dxuv;
1690                                         dy= suv->dyuv; 
1691
1692                                         // uvmapping only, calculation of normal tangent u/v partial derivatives
1693                                         // (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
1694                                         //  nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
1695                                         // NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
1696                                         if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob) {
1697                                                 if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
1698                                                         MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
1699                                                         int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
1700
1701                                                         vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
1702
1703                                                         if (tf) {
1704                                                                 float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
1705                                                                 const float an[3] = {fabsf(nn[0]), fabsf(nn[1]), fabsf(nn[2])};
1706                                                                 const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
1707                                                                 const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
1708                                                                 const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
1709                                                                 const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
1710                                                                 const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
1711                                                                 const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
1712                                                                 const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
1713                                                                 const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
1714                                                                 const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
1715                                                                 const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
1716                                                                 const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
1717                                                                 const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
1718                                                                 float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
1719                                                                 float uvd = du1*dv2 - dv1*du2;
1720
1721                                                                 if (uvd == 0.f) uvd = 1e-5f;
1722                                                                 if (d == 0.f) d = 1e-5f;
1723                                                                 d = uvd / d;
1724
1725                                                                 dudnu = (dpdv_a2*nu[a1] - dpdv_a1*nu[a2])*d;
1726                                                                 dvdnu = (dpdu_a1*nu[a2] - dpdu_a2*nu[a1])*d;
1727                                                                 dudnv = (dpdv_a2*nv[a1] - dpdv_a1*nv[a2])*d;
1728                                                                 dvdnv = (dpdu_a1*nv[a2] - dpdu_a2*nv[a1])*d;
1729                                                         }
1730                                                 }
1731                                         }
1732                                 }
1733                         }
1734                         else if(mtex->texco==TEXCO_WINDOW) {
1735                                 co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
1736                         }
1737                         else if(mtex->texco==TEXCO_STRAND) {
1738                                 co= tempvec; dx= dxt; dy= dyt;
1739                                 co[0]= shi->strandco;
1740                                 co[1]= co[2]= 0.0f;
1741                                 dx[0]= shi->dxstrand;
1742                                 dx[1]= dx[2]= 0.0f;
1743                                 dy[0]= shi->dystrand;
1744                                 dy[1]= dy[2]= 0.0f;
1745                         }
1746                         else if(mtex->texco==TEXCO_STRESS) {
1747                                 co= tempvec; dx= dxt; dy= dyt;
1748                                 co[0]= shi->stress;
1749                                 co[1]= co[2]= 0.0f;
1750                                 dx[0]= 0.0f;
1751                                 dx[1]= dx[2]= 0.0f;
1752                                 dy[0]= 0.0f;
1753                                 dy[1]= dy[2]= 0.0f;
1754                         }
1755                         else continue;  // can happen when texco defines disappear and it renders old files
1756
1757                         /* the pointer defines if bumping happens */
1758                         if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
1759                                 texres.nor= norvec;
1760                                 norvec[0]= norvec[1]= norvec[2]= 0.0;
1761                         }
1762                         else texres.nor= NULL;
1763                         
1764                         if(warpdone) {
1765                                 VECADD(tempvec, co, warpvec);
1766                                 co= tempvec;
1767                         }
1768
1769                         if(mtex->texflag & MTEX_NEW_BUMP) {
1770                                 // compute ortho basis around normal
1771                                 if(!nunvdone) {
1772                                         // render normal is negated
1773                                         nn[0] = -shi->vn[0];
1774                                         nn[1] = -shi->vn[1];
1775                                         nn[2] = -shi->vn[2];
1776                                         VecOrthoBasisf(nn, nu, nv);
1777                                         nunvdone= 1;
1778                                 }
1779
1780                                 if(texres.nor) {
1781                                         TexResult ttexr = {0, 0, 0, 0, 0, texres.talpha, NULL}; // temp TexResult
1782                                         float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
1783                                         const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
1784                                         const float bf = 0.04f*Tnor*((mtex->maptoneg & MAP_NORM) ? -mtex->norfac : mtex->norfac);
1785                                         // disable internal bump eval
1786                                         float* nvec = texres.nor;
1787                                         texres.nor = NULL;
1788                                         // du & dv estimates, constant value defaults
1789                                         du = dv = 0.01f;
1790
1791                                         // two methods, either constant based on main image resolution,
1792                                         // (which also works without osa, though of course not always good (or even very bad) results),
1793                                         // or based on tex derivative max values (osa only). Not sure which is best...
1794
1795                                         if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
1796                                                 // in case we have no proper derivatives, fall back to
1797                                                 // computing du/dv it based on image size
1798                                                 ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
1799                                                 if (ibuf) {
1800                                                         du = 1.f/(float)ibuf->x;
1801                                                         dv = 1.f/(float)ibuf->y;
1802                                                 }
1803                                         }
1804                                         else if (shi->osatex) {
1805                                                 // we have derivatives, can compute proper du/dv
1806                                                 if (tex->type == TEX_IMAGE) {   // 2d image, use u & v max. of dx/dy 2d vecs
1807                                                         const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])};
1808                                                         const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])};
1809                                                         du = MAX2(adx[0], ady[0]);
1810                                                         dv = MAX2(adx[1], ady[1]);
1811                                                 }
1812                                                 else {  // 3d procedural, estimate from all dx/dy elems
1813                                                         const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
1814                                                         const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
1815                                                         du = MAX3(adx[0], adx[1], adx[2]);
1816                                                         dv = MAX3(ady[1], ady[1], ady[2]);
1817                                                 }
1818                                         }
1819
1820                                         // center, main return value
1821                                         texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1822                                         rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
1823                                         cd = fromrgb ? (texres.tr + texres.tg + texres.tb)*0.33333333f : texres.tin;
1824
1825                                         if (mtex->texco == TEXCO_UV) {
1826                                                 // for the uv case, use the same value for both du/dv,
1827                                                 // since individually scaling the normal derivatives makes them useless...
1828                                                 du = MIN2(du, dv);
1829                                                 idu = (du < 1e-6f) ? bf : (bf/du);
1830
1831                                                 // +u val
1832                                                 tco[0] = co[0] + dudnu*du;
1833                                                 tco[1] = co[1] + dvdnu*du;
1834                                                 tco[2] = 0.f;
1835                                                 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1836                                                 multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
1837                                                 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1838
1839                                                 // +v val
1840                                                 tco[0] = co[0] + dudnv*du;
1841                                                 tco[1] = co[1] + dvdnv*du;
1842                                                 tco[2] = 0.f;
1843                                                 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1844                                                 multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
1845                                                 vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1846                                         }
1847                                         else {
1848                                                 float tu[3] = {nu[0], nu[1], nu[2]}, tv[3] = {nv[0], nv[1], nv[2]};
1849
1850                                                 idu = (du < 1e-6f) ? bf : (bf/du);
1851                                                 idv = (dv < 1e-6f) ? bf : (bf/dv);
1852
1853                                                 if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
1854                                                         Mat4Mul3Vecfl(shi->obr->ob->imat, tu);
1855                                                         Mat4Mul3Vecfl(shi->obr->ob->imat, tv);
1856                                                         Normalize(tu);
1857                                                         Normalize(tv);
1858                                                 }
1859                                                 else if (mtex->texco == TEXCO_GLOB) {
1860                                                         Mat4Mul3Vecfl(R.viewinv, tu);
1861                                                         Mat4Mul3Vecfl(R.viewinv, tv);
1862                                                 }
1863                                                 else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
1864                                                         Mat4Mul3Vecfl(mtex->object->imat, tu);
1865                                                         Mat4Mul3Vecfl(mtex->object->imat, tv);
1866                                                         Normalize(tu);
1867                                                         Normalize(tv);
1868                                                 }
1869
1870                                                 // +u val
1871                                                 tco[0] = co[0] + tu[0]*du;
1872                                                 tco[1] = co[1] + tu[1]*du;
1873                                                 tco[2] = co[2] + tu[2]*du;
1874                                                 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1875                                                 multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
1876                                                 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1877
1878                                                 // +v val
1879                                                 tco[0] = co[0] + tv[0]*dv;
1880                                                 tco[1] = co[1] + tv[1]*dv;
1881                                                 tco[2] = co[2] + tv[2]*dv;
1882                                                 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1883                                                 multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
1884                                                 vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1885                                         }
1886
1887                                         // bumped normal
1888                                         nu[0] += ud*nn[0];
1889                                         nu[1] += ud*nn[1];
1890                                         nu[2] += ud*nn[2];
1891                                         nv[0] += vd*nn[0];
1892                                         nv[1] += vd*nn[1];
1893                                         nv[2] += vd*nn[2];
1894                                         Crossf(nvec, nu, nv);
1895
1896                                         nvec[0] = -nvec[0];
1897                                         nvec[1] = -nvec[1];
1898                                         nvec[2] = -nvec[2];
1899                                         texres.nor = nvec;
1900                                         rgbnor |= TEX_NOR;
1901                                 }
1902                                 else {
1903                                         texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1904                                         rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
1905                                 }
1906                         }
1907                         else {
1908                                 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1909                                 rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
1910                         }
1911
1912                         /* texture output */
1913
1914                         if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1915                                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
1916                                 rgbnor-= TEX_RGB;
1917                         }
1918                         if(mtex->texflag & MTEX_NEGATIVE) {
1919                                 if(rgbnor & TEX_RGB) {
1920                                         texres.tr= 1.0-texres.tr;
1921                                         texres.tg= 1.0-texres.tg;
1922                                         texres.tb= 1.0-texres.tb;
1923                                 }
1924                                 texres.tin= 1.0-texres.tin;
1925                         }
1926                         if(mtex->texflag & MTEX_STENCIL) {
1927                                 if(rgbnor & TEX_RGB) {
1928                                         fact= texres.ta;
1929                                         texres.ta*= stencilTin;
1930                                         stencilTin*= fact;
1931                                 }
1932                                 else {
1933                                         fact= texres.tin;
1934                                         texres.tin*= stencilTin;
1935                                         stencilTin*= fact;
1936                                 }
1937                         }
1938                         else {
1939                                 Tnor*= stencilTin;
1940                         }
1941                         
1942                         if(texres.nor) {
1943                                 if((rgbnor & TEX_NOR)==0) {
1944                                         /* make our own normal */
1945                                         if(rgbnor & TEX_RGB) {
1946                                                 texres.nor[0]= texres.tr;
1947                                                 texres.nor[1]= texres.tg;
1948                                                 texres.nor[2]= texres.tb;
1949                                         }
1950                                         else {
1951                                                 float co_nor= 0.5*cos(texres.tin-0.5);
1952                                                 float si= 0.5*sin(texres.tin-0.5);
1953                                                 float f1, f2;
1954
1955                                                 f1= shi->vn[0];
1956                                                 f2= shi->vn[1];
1957                                                 texres.nor[0]= f1*co_nor+f2*si;
1958                                                 texres.nor[1]= f2*co_nor-f1*si;
1959                                                 f1= shi->vn[1];
1960                                                 f2= shi->vn[2];
1961                                                 texres.nor[1]= f1*co_nor+f2*si;
1962                                                 texres.nor[2]= f2*co_nor-f1*si;
1963                                         }
1964                                 }
1965                                 // warping, local space
1966                                 if(mtex->mapto & MAP_WARP) {
1967                                         warpvec[0]= mtex->warpfac*texres.nor[0];
1968                                         warpvec[1]= mtex->warpfac*texres.nor[1];
1969                                         warpvec[2]= mtex->warpfac*texres.nor[2];
1970                                         warpdone= 1;
1971                                 }
1972 #if 0                           
1973                                 if(mtex->texflag & MTEX_VIEWSPACE) {
1974                                         // rotate to global coords
1975                                         if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
1976                                                 if(shi->vlr && shi->obr && shi->obr->ob) {
1977                                                         float len= Normalize(texres.nor);
1978                                                         // can be optimized... (ton)
1979                                                         Mat4Mul3Vecfl(shi->obr->ob->obmat, texres.nor);
1980                                                         Mat4Mul3Vecfl(R.viewmat, texres.nor);
1981                                                         Normalize(texres.nor);
1982                                                         VecMulf(texres.nor, len);
1983                                                 }
1984                                         }
1985                                 }
1986 #endif                          
1987                         }
1988
1989                         /* mapping */
1990                         if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
1991                                 float tcol[3], colfac;
1992                                 
1993                                 /* stencil maps on the texture control slider, not texture intensity value */
1994                                 colfac= mtex->colfac*stencilTin;
1995                                 
1996                                 tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb;
1997                                 
1998                                 if((rgbnor & TEX_RGB)==0) {
1999                                         tcol[0]= mtex->r;
2000                                         tcol[1]= mtex->g;
2001                                         tcol[2]= mtex->b;
2002                                 }
2003                                 else if(mtex->mapto & MAP_ALPHA) {
2004                                         texres.tin= stencilTin;
2005                                 }
2006                                 else texres.tin= texres.ta;
2007                                 
2008                                 /* inverse gamma correction */
2009                                 if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
2010                                         color_manage_linearize(tcol, tcol);
2011                                 }
2012                                 
2013                                 if(mtex->mapto & MAP_COL) {
2014                                         texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
2015                                 }
2016                                 if(mtex->mapto & MAP_COLSPEC) {
2017                                         texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colfac, mtex->blendtype);
2018                                 }
2019                                 if(mtex->mapto & MAP_COLMIR) {
2020                                         // exception for envmap only
2021                                         if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
2022                                                 fact= texres.tin*colfac;
2023                                                 facm= 1.0- fact;
2024                                                 shi->refcol[0]= fact + facm*shi->refcol[0];
2025                                                 shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
2026                                                 shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2];
2027                                                 shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
2028                                         }
2029                                         else {
2030                                                 texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, colfac, mtex->blendtype);
2031                                         }
2032                                 }
2033                         }
2034                         if( (mtex->mapto & MAP_NORM) ) {
2035                                 if(texres.nor) {
2036                                         if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
2037                                         else tex->norfac= mtex->norfac;
2038                                         
2039                                         /* we need to code blending modes for normals too once.. now 1 exception hardcoded */
2040                                         
2041                                         if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
2042                                                 /* qdn: for normalmaps, to invert the normalmap vector,
2043                                                    it is better to negate x & y instead of subtracting the vector as was done before */
2044                                                 tex->norfac = mtex->norfac;
2045                                                 if (mtex->maptoneg & MAP_NORM) {
2046                                                         texres.nor[0] = -texres.nor[0];
2047                                                         texres.nor[1] = -texres.nor[1];
2048                                                 }
2049                                                 fact = Tnor*tex->norfac;
2050                                                 if (fact>1.f) fact = 1.f;
2051                                                 facm = 1.f-fact;
2052                                                 if(mtex->normapspace == MTEX_NSPACE_TANGENT) {
2053                                                         /* qdn: tangent space */
2054                                                         float B[3], tv[3];
2055                                                         Crossf(B, shi->vn, shi->nmaptang);      /* bitangent */
2056                                                         /* transform norvec from tangent space to object surface in camera space */
2057                                                         tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*shi->vn[0];
2058                                                         tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*shi->vn[1];
2059                                                         tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*shi->vn[2];
2060                                                         shi->vn[0]= facm*shi->vn[0] + fact*tv[0];
2061                                                         shi->vn[1]= facm*shi->vn[1] + fact*tv[1];
2062                                                         shi->vn[2]= facm*shi->vn[2] + fact*tv[2];
2063                                                 }
2064                                                 else {
2065                                                         float nor[3];
2066
2067                                                         VECCOPY(nor, texres.nor);
2068
2069                                                         if(mtex->normapspace == MTEX_NSPACE_CAMERA);
2070                                                         else if(mtex->normapspace == MTEX_NSPACE_WORLD) {
2071                                                                 Mat4Mul3Vecfl(R.viewmat, nor);
2072                                                         }
2073                                                         else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
2074                                                                 if(shi->obr && shi->obr->ob)
2075                                                                         Mat4Mul3Vecfl(shi->obr->ob->obmat, nor);
2076                                                                 Mat4Mul3Vecfl(R.viewmat, nor);
2077                                                         }
2078
2079                                                         Normalize(nor);
2080
2081                                                         /* qdn: worldspace */
2082                                                         shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
2083                                                         shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
2084                                                         shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
2085                                                 }
2086                                         }
2087                                         else {
2088                                                 if (mtex->texflag & MTEX_NEW_BUMP) {
2089                                                         shi->vn[0] = texres.nor[0];
2090                                                         shi->vn[1] = texres.nor[1];
2091                                                         shi->vn[2] = texres.nor[2];
2092                                                 }
2093                                                 else {
2094                                                         float nor[3], dot;
2095         
2096                                                         if(shi->mat->mode & MA_TANGENT_V) {
2097                                                                 shi->tang[0]+= Tnor*tex->norfac*texres.nor[0];
2098                                                                 shi->tang[1]+= Tnor*tex->norfac*texres.nor[1];
2099                                                                 shi->tang[2]+= Tnor*tex->norfac*texres.nor[2];
2100                                                         }
2101         
2102                                                         /* prevent bump to become negative normal */
2103                                                         nor[0]= Tnor*tex->norfac*texres.nor[0];
2104                                                         nor[1]= Tnor*tex->norfac*texres.nor[1];
2105                                                         nor[2]= Tnor*tex->norfac*texres.nor[2];
2106                                                         
2107                                                         dot= 0.5f + 0.5f*INPR(nor, shi->vn);
2108                                                         
2109                                                         shi->vn[0]+= dot*nor[0];
2110                                                         shi->vn[1]+= dot*nor[1];
2111                                                         shi->vn[2]+= dot*nor[2];
2112                                                 }
2113                                         }
2114                                         Normalize(shi->vn);
2115                                         
2116                                         /* this makes sure the bump is passed on to the next texture */
2117                                         shi->orn[0]= -shi->vn[0];
2118                                         shi->orn[1]= -shi->vn[1];
2119                                         shi->orn[2]= -shi->vn[2];
2120                                         
2121                                         /* reflection vector */
2122                                         calc_R_ref(shi);
2123                                 }
2124                         }
2125
2126                         if( mtex->mapto & MAP_DISPLACE ) {
2127                                 /* Now that most textures offer both Nor and Intensity, allow  */
2128                                 /* both to work, and let user select with slider.   */
2129                                 if(texres.nor) {
2130                                         if(mtex->maptoneg & MAP_DISPLACE) tex->norfac= -mtex->norfac;
2131                                         else tex->norfac= mtex->norfac;
2132
2133                                         shi->displace[0]+= 0.2f*Tnor*tex->norfac*texres.nor[0];
2134                                         shi->displace[1]+= 0.2f*Tnor*tex->norfac*texres.nor[1];
2135                                         shi->displace[2]+= 0.2f*Tnor*tex->norfac*texres.nor[2];
2136                                 }
2137                                 
2138                                 if(rgbnor & TEX_RGB) {
2139                                         if(texres.talpha) texres.tin= texres.ta;
2140                                         else texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb);
2141                                 }
2142
2143                                 if(mtex->maptoneg & MAP_DISPLACE) {
2144                                         factt= (texres.tin-0.5f)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
2145                                 }
2146                                 else {
2147                                         factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
2148                                 }
2149
2150                                 if(mtex->blendtype==MTEX_BLEND) {
2151                                         shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
2152                                         shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1];
2153                                         shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2];
2154                                 }
2155                                 else if(mtex->blendtype==MTEX_MUL) {
2156                                         shi->displace[0]*= factt*shi->vn[0];
2157                                         shi->displace[1]*= factt*shi->vn[1];
2158                                         shi->displace[2]*= factt*shi->vn[2];
2159                                 }
2160                                 else { /* add or sub */
2161                                         if(mtex->blendtype==MTEX_SUB) factt= -factt;
2162                                         else factt= factt;
2163                                         shi->displace[0]+= factt*shi->vn[0];
2164                                         shi->displace[1]+= factt*shi->vn[1];
2165                                         shi->displace[2]+= factt*shi->vn[2];
2166                                 }
2167                         }
2168
2169                         if(mtex->mapto & MAP_VARS) {
2170                                 /* stencil maps on the texture control slider, not texture intensity value */
2171                                 float varfac= mtex->varfac*stencilTin;
2172                                 
2173                                 if(rgbnor & TEX_RGB) {
2174                                         if(texres.talpha) texres.tin= texres.ta;
2175                                         else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2176                                 }
2177
2178                                 if(mtex->mapto & MAP_REF) {
2179                                         int flip= mtex->maptoneg & MAP_REF;
2180
2181                                         shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, varfac, mtex->blendtype, flip);
2182                                         if(shi->refl<0.0) shi->refl= 0.0;
2183                                 }
2184                                 if(mtex->mapto & MAP_SPEC) {
2185                                         int flip= mtex->maptoneg & MAP_SPEC;
2186                                         
2187                                         shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, varfac, mtex->blendtype, flip);
2188                                         if(shi->spec<0.0) shi->spec= 0.0;
2189                                 }
2190                                 if(mtex->mapto & MAP_EMIT) {
2191                                         int flip= mtex->maptoneg & MAP_EMIT;
2192
2193                                         shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, varfac, mtex->blendtype, flip);
2194                                         if(shi->emit<0.0) shi->emit= 0.0;
2195                                 }
2196                                 if(mtex->mapto & MAP_ALPHA) {
2197                                         int flip= mtex->maptoneg & MAP_ALPHA;
2198
2199                                         shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, varfac, mtex->blendtype, flip);
2200                                         if(shi->alpha<0.0) shi->alpha= 0.0;
2201                                         else if(shi->alpha>1.0) shi->alpha= 1.0;
2202                                 }
2203                                 if(mtex->mapto & MAP_HAR) {
2204                                         int flip= mtex->maptoneg & MAP_HAR;
2205                                         float har;  // have to map to 0-1
2206                                         
2207                                         har= ((float)shi->har)/128.0;
2208                                         har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, varfac, mtex->blendtype, flip);
2209                                         
2210                                         if(har<1.0) shi->har= 1; 
2211                                         else if(har>511.0) shi->har= 511;
2212                                         else shi->har= (int)har;
2213                                 }
2214                                 if(mtex->mapto & MAP_RAYMIRR) {
2215                                         int flip= mtex->maptoneg & MAP_RAYMIRR;
2216
2217                                         shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, varfac, mtex->blendtype, flip);
2218                                         if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0;
2219                                         else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0;
2220                                 }
2221                                 if(mtex->mapto & MAP_TRANSLU) {
2222                                         int flip= mtex->maptoneg & MAP_TRANSLU;
2223
2224                                         shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, varfac, mtex->blendtype, flip);
2225                                         if(shi->translucency<0.0) shi->translucency= 0.0;
2226                                         else if(shi->translucency>1.0) shi->translucency= 1.0;
2227                                 }
2228                                 if(mtex->mapto & MAP_LAYER) {
2229                                         int flip= mtex->maptoneg & MAP_LAYER;
2230                                         
2231                                         shi->layerfac= texture_value_blend(mtex->def_var, shi->layerfac, texres.tin, varfac, mtex->blendtype, flip);
2232                                         if(shi->layerfac<0.0) shi->layerfac= 0.0;
2233                                         else if(shi->layerfac>1.0) shi->layerfac= 1.0;
2234                                 }
2235                                 if(mtex->mapto & MAP_AMB) {
2236                                         int flip= mtex->maptoneg & MAP_AMB;
2237
2238                                         shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, varfac, mtex->blendtype, flip);
2239                                         if(shi->amb<0.0) shi->amb= 0.0;
2240                                         else if(shi->amb>1.0) shi->amb= 1.0;
2241                                         
2242                                         shi->ambr= shi->amb*R.wrld.ambr;
2243                                         shi->ambg= shi->amb*R.wrld.ambg;
2244                                         shi->ambb= shi->amb*R.wrld.ambb;
2245                                 }
2246                         }
2247                 }
2248         }
2249 }
2250
2251 /* ------------------------------------------------------------------------- */
2252
2253 void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
2254 {
2255         MTex *mtex;
2256         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2257         float texvec[3], dxt[3], dyt[3], fact, facm, dx;
2258         int rgb, osatex;
2259
2260         if (R.r.scemode & R_NO_TEX) return;
2261         
2262         mtex= har->mat->mtex[0];
2263         if(mtex->tex==NULL) return;
2264         
2265         /* no normal mapping */
2266         texres.nor= NULL;
2267                 
2268         texvec[0]= xn/har->rad;
2269         texvec[1]= yn/har->rad;
2270         texvec[2]= 0.0;
2271         
2272         osatex= (har->mat->texco & TEXCO_OSA);
2273
2274         /* placement */
2275         if(mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]);
2276         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
2277         
2278         if(mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]);
2279         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
2280         
2281         if(mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]);
2282         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
2283         
2284         if(osatex) {
2285         
2286                 dx= 1.0/har->rad;
2287         
2288                 if(mtex->projx) {
2289                         dxt[0]= mtex->size[0]*dx;
2290                         dyt[0]= mtex->size[0]*dx;
2291                 }
2292                 else dxt[0]= dyt[0]= 0.0;
2293                 
2294                 if(mtex->projy) {
2295                         dxt[1]= mtex->size[1]*dx;
2296                         dyt[1]= mtex->size[1]*dx;
2297                 }
2298                 else dxt[1]= dyt[1]= 0.0;
2299                 
2300                 if(mtex->projz) {
2301                         dxt[2]= 0.0;
2302                         dyt[2]= 0.0;
2303                 }
2304                 else dxt[2]= dyt[2]= 0.0;
2305
2306         }
2307
2308         if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
2309         
2310         rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output);
2311
2312         /* texture output */
2313         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
2314                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2315                 rgb= 0;
2316         }
2317         if(mtex->texflag & MTEX_NEGATIVE) {
2318                 if(rgb) {
2319                         texres.tr= 1.0-texres.tr;
2320                         texres.tg= 1.0-texres.tg;
2321                         texres.tb= 1.0-texres.tb;
2322                 }
2323                 else texres.tin= 1.0-texres.tin;
2324         }
2325
2326         /* mapping */
2327         if(mtex->mapto & MAP_COL) {
2328                 
2329                 if(rgb==0) {
2330                         texres.tr= mtex->r;
2331                         texres.tg= mtex->g;
2332                         texres.tb= mtex->b;
2333                 }
2334                 else if(mtex->mapto & MAP_ALPHA) {
2335                         texres.tin= 1.0;
2336                 }
2337                 else texres.tin= texres.ta;
2338
2339                 /* inverse gamma correction */
2340                 if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
2341                         color_manage_linearize(&texres.tr, &texres.tr);
2342                 }
2343
2344                 fact= texres.tin*mtex->colfac;
2345                 facm= 1.0-fact;
2346                 
2347                 if(mtex->blendtype==MTEX_MUL) {
2348                         facm= 1.0-mtex->colfac;
2349                 }
2350                 
2351                 if(mtex->blendtype==MTEX_SUB) fact= -fact;
2352
2353                 if(mtex->blendtype==MTEX_BLEND) {
2354                         colf[0]= (fact*texres.tr + facm*har->r);
2355                         colf[1]= (fact*texres.tg + facm*har->g);
2356                         colf[2]= (fact*texres.tb + facm*har->b);
2357                 }
2358                 else if(mtex->blendtype==MTEX_MUL) {
2359                         colf[0]= (facm+fact*texres.tr)*har->r;
2360                         colf[1]= (facm+fact*texres.tg)*har->g;
2361                         colf[2]= (facm+fact*texres.tb)*har->b;
2362                 }
2363                 else {
2364                         colf[0]= (fact*texres.tr + har->r);
2365                         colf[1]= (fact*texres.tg + har->g);
2366                         colf[2]= (fact*texres.tb + har->b);
2367                         
2368                         CLAMP(colf[0], 0.0, 1.0);
2369                         CLAMP(colf[1], 0.0, 1.0);
2370                         CLAMP(colf[2], 0.0, 1.0);
2371                 }
2372         }
2373         if(mtex->mapto & MAP_ALPHA) {
2374                 if(rgb) {
2375                         if(texres.talpha) texres.tin= texres.ta;
2376                         else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2377                 }
2378                                 
2379                 colf[3]*= texres.tin;
2380         }
2381 }
2382
2383 /* ------------------------------------------------------------------------- */
2384
2385 /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
2386 void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread)
2387 {
2388         MTex *mtex;
2389         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2390         float *co, fact, stencilTin=1.0;
2391         float tempvec[3], texvec[3], dxt[3], dyt[3];
2392         int tex_nr, rgb= 0, ok;
2393         
2394         if (R.r.scemode & R_NO_TEX) return;
2395         /* todo: add flag to test if there's a tex */
2396         texres.nor= NULL;
2397         
2398         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
2399                 if(R.wrld.mtex[tex_nr]) {
2400                         mtex= R.wrld.mtex[tex_nr];
2401                         
2402                         if(mtex->tex==0) continue;
2403                         /* if(mtex->mapto==0) continue; */
2404                         
2405                         /* which coords */
2406                         co= lo;
2407                         
2408                         /* dxt dyt just from 1 value */
2409                         if(dxyview) {
2410                                 dxt[0]= dxt[1]= dxt[2]= dxyview[0];
2411                                 dyt[0]= dyt[1]= dyt[2]= dxyview[1];
2412                         }
2413                         else {
2414                                 dxt[0]= dxt[1]= dxt[2]= 0.0;
2415                                 dyt[0]= dyt[1]= dyt[2]= 0.0;
2416                         }
2417                         
2418                         /* Grab the mapping settings for this texture */
2419                         switch(mtex->texco) {
2420                         case TEXCO_ANGMAP:
2421                                 /* only works with texture being "real" */
2422                                 fact= (1.0/M_PI)*acos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); 
2423                                 tempvec[0]= lo[0]*fact;
2424                                 tempvec[1]= lo[1]*fact;
2425                                 tempvec[2]= 0.0;
2426                                 co= tempvec;
2427                                 break;
2428                                 
2429                         case TEXCO_H_SPHEREMAP:
2430                         case TEXCO_H_TUBEMAP:
2431                                 if(skyflag & WO_ZENUP) {
2432                                         if(mtex->texco==TEXCO_H_TUBEMAP) tubemap(lo[0], lo[2], lo[1], tempvec, tempvec+1);
2433                                         else spheremap(lo[0], lo[2], lo[1], tempvec, tempvec+1);
2434                                         /* tube/spheremap maps for outside view, not inside */
2435                                         tempvec[0]= 1.0-tempvec[0];
2436                                         /* only top half */
2437                                         tempvec[1]= 2.0*tempvec[1]-1.0;
2438                                         tempvec[2]= 0.0;
2439                                         /* and correction for do_2d_mapping */
2440                                         tempvec[0]= 2.0*tempvec[0]-1.0;
2441                                         tempvec[1]= 2.0*tempvec[1]-1.0;
2442                                         co= tempvec;
2443                                 }
2444                                 else {
2445                                         /* potentially dangerous... check with multitex! */
2446                                         continue;
2447                                 }
2448                                 break;
2449                         case TEXCO_OBJECT:
2450                                 if(mtex->object) {
2451                                         VECCOPY(tempvec, lo);
2452                                         MTC_Mat4MulVecfl(mtex->object->imat, tempvec);
2453                                         co= tempvec;
2454                                 }
2455                                 break;
2456                                 
2457                         case TEXCO_GLOB:
2458                                 if(rco) {
2459                                         VECCOPY(tempvec, rco);
2460                                         MTC_Mat4MulVecfl(R.viewinv, tempvec);
2461                                         co= tempvec;
2462                                 }
2463                                 else
2464                                         co= lo;
2465                                 
2466 //                              VECCOPY(shi->dxgl, shi->dxco);
2467 //                              MTC_Mat3MulVecfl(R.imat, shi->dxco);
2468 //                              VECCOPY(shi->dygl, shi->dyco);
2469 //                              MTC_Mat3MulVecfl(R.imat, shi->dyco);
2470                                 break;
2471                         }
2472                         
2473                         /* placement */                 
2474                         if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
2475                         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
2476                         
2477                         if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
2478                         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
2479                         
2480                         if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
2481                         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
2482                         
2483                         /* texture */
2484                         if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
2485                 
2486                         rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output);
2487                         
2488                         /* texture output */
2489                         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
2490                                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2491                                 rgb= 0;
2492                         }
2493                         if(mtex->texflag & MTEX_NEGATIVE) {
2494                                 if(rgb) {
2495                                         texres.tr= 1.0-texres.tr;
2496                                         texres.tg= 1.0-texres.tg;
2497                                         texres.tb= 1.0-texres.tb;
2498                                 }
2499                                 else texres.tin= 1.0-texres.tin;
2500                         }
2501                         if(mtex->texflag & MTEX_STENCIL) {
2502                                 if(rgb) {
2503                                         fact= texres.ta;
2504                                         texres.ta*= stencilTin;
2505                                         stencilTin*= fact;
2506                                 }
2507                                 else {
2508                                         fact= texres.tin;
2509                                         texres.tin*= stencilTin;
2510                                         stencilTin*= fact;
2511                                 }
2512                         }
2513                         else {
2514                                 if(rgb) texres.ta *= stencilTin;
2515                                 else texres.tin*= stencilTin;
2516                         }
2517                         
2518                         /* color mapping */
2519                         if(mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) {
2520                                 float tcol[3];
2521                                 
2522                                 if(rgb==0) {
2523                                         texres.tr= mtex->r;
2524                                         texres.tg= mtex->g;
2525                                         texres.tb= mtex->b;
2526                                 }
2527                                 else texres.tin= texres.ta;
2528                                 
2529                                 tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb;
2530
2531                                 /* inverse gamma correction */
2532                                 if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
2533                                         color_manage_linearize(tcol, tcol);
2534                                 }
2535
2536                                 if(mtex->mapto & WOMAP_HORIZ) {
2537                                         texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype);
2538                                 }
2539                                 if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) {
2540                                         ok= 0;
2541                                         if(R.wrld.skytype & WO_SKYREAL) {
2542                                                 if((skyflag & WO_ZENUP)) {
2543                                                         if(mtex->mapto & WOMAP_ZENUP) ok= 1;
2544                                                 }
2545                                                 else if(mtex->mapto & WOMAP_ZENDOWN) ok= 1;
2546                                         }
2547                                         else ok= 1;
2548                                         
2549                                         if(ok) {
2550                                                 texture_rgb_blend(zen, tcol, zen, texres.tin, mtex->colfac, mtex->blendtype);
2551                                         }
2552                                 }
2553                         }
2554                         if(mtex->mapto & WOMAP_BLEND) {
2555                                 if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2556                                 
2557                                 *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->varfac, mtex->blendtype, 0);
2558                         }
2559                 }
2560         }
2561 }
2562
2563 /* ------------------------------------------------------------------------- */
2564 /* colf supposed to be initialized with la->r,g,b */
2565
2566 void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int effect)
2567 {
2568         Object *ob;
2569         MTex *mtex;
2570         Tex *tex;
2571         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2572         float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0;
2573         float texvec[3], dxt[3], dyt[3], tempvec[3];
2574         int i, tex_nr, rgb= 0;
2575         
2576         if (R.r.scemode & R_NO_TEX) return;
2577         tex_nr= 0;
2578         
2579         for(; tex_nr<MAX_MTEX; tex_nr++) {
2580                 
2581                 if(la->mtex[tex_nr]) {
2582                         mtex= la->mtex[tex_nr];
2583                         
2584                         tex= mtex->tex;
2585                         if(tex==NULL) continue;
2586                         texres.nor= NULL;
2587                         
2588                         /* which coords */
2589                         if(mtex->texco==TEXCO_OBJECT) {
2590                                 ob= mtex->object;
2591                                 if(ob) {
2592                                         co= tempvec;
2593                                         dx= dxt;
2594                                         dy= dyt;
2595                                         VECCOPY(tempvec, shi->co);
2596                                         MTC_Mat4MulVecfl(ob->imat, tempvec);
2597                                         if(shi->osatex) {
2598                                                 VECCOPY(dxt, shi->dxco);
2599                                                 VECCOPY(dyt, shi->dyco);
2600                                                 MTC_Mat4Mul3Vecfl(ob->imat, dxt);
2601                                                 MTC_Mat4Mul3Vecfl(ob->imat, dyt);
2602                                         }
2603                                 }
2604                                 else {
2605                                         co= shi->co;
2606                                         dx= shi->dxco; dy= shi->dyco;
2607                                 }
2608                         }
2609                         else if(mtex->texco==TEXCO_GLOB) {
2610                                 co= shi->gl; dx= shi->dxco; dy= shi->dyco;
2611                                 VECCOPY(shi->gl, shi->co);
2612                                 MTC_Mat4MulVecfl(R.viewinv, shi->gl);
2613                         }
2614                         else if(mtex->texco==TEXCO_VIEW) {
2615                                 
2616                                 VECCOPY(tempvec, lavec);
2617                                 MTC_Mat3MulVecfl(la->imat, tempvec);
2618                                 
2619                                 if(la->type==LA_SPOT) {
2620                                         tempvec[0]*= la->spottexfac;
2621                                         tempvec[1]*= la->spottexfac;
2622                                 }
2623                                 co= tempvec; 
2624                                 
2625                                 dx= dxt; dy= dyt;       
2626                                 if(shi->osatex) {
2627                                         VECCOPY(dxt, shi->dxlv);
2628                                         VECCOPY(dyt, shi->dylv);
2629                                         /* need some matrix conversion here? la->imat is a [3][3]  matrix!!! **/
2630                                         MTC_Mat3MulVecfl(la->imat, dxt);
2631                                         MTC_Mat3MulVecfl(la->imat, dyt);
2632                                         
2633                                         VecMulf(dxt, la->spottexfac);
2634                                         VecMulf(dyt, la->spottexfac);
2635                                 }
2636                         }
2637                         
2638                         
2639                         /* placement */
2640                         if(mtex->projx && co) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
2641                         else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
2642                         
2643                         if(mtex->projy && co) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
2644                         else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
2645                         
2646                         if(mtex->projz && co) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
2647                         else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
2648                         
2649                         if(shi->osatex) {
2650                                 if (!dx) {
2651                                         for(i=0;i<2;i++) { 
2652                                                 dxt[i] = dyt[i] = 0.0;
2653                                         }
2654                                 } else {
2655                                         if(mtex->projx) {
2656                                                 dxt[0]= mtex->size[0]*dx[mtex->projx-1];
2657                                                 dyt[0]= mtex->size[0]*dy[mtex->projx-1];
2658                                         } else {
2659                                                 dxt[0]= 0.0;
2660                                                 dyt[0]= 0.0;
2661                                         }
2662                                         if(mtex->projy) {
2663                                                 dxt[1]= mtex->size[1]*dx[mtex->projy-1];
2664                                                 dyt[1]= mtex->size[1]*dy[mtex->projy-1];
2665                                         } else {
2666                                                 dxt[1]= 0.0;
2667                                                 dyt[1]= 0.0;
2668                                         }
2669                                         if(mtex->projz) {
2670                                                 dxt[2]= mtex->size[2]*dx[mtex->projz-1];
2671                                                 dyt[2]= mtex->size[2]*dy[mtex->projz-1];
2672                                         } else {
2673                                                 dxt[2]= 0.0;
2674                                                 dyt[2]= 0.0;
2675                                         }
2676                                 }
2677                         }
2678                         
2679                         /* texture */
2680                         if(tex->type==TEX_IMAGE) {
2681                                 do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
2682                         }
2683                         
2684                         rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
2685
2686                         /* texture output */
2687                         if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
2688                                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2689                                 rgb= 0;
2690                         }
2691                         if(mtex->texflag & MTEX_NEGATIVE) {
2692                                 if(rgb) {
2693                                         texres.tr= 1.0-texres.tr;
2694