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