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