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