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