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