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