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