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