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