diff options
Diffstat (limited to 'source/blender/blenkernel/intern/texture.c')
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 2320 |
1 files changed, 2320 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c new file mode 100644 index 00000000000..eed8a39d6ce --- /dev/null +++ b/source/blender/blenkernel/intern/texture.c @@ -0,0 +1,2320 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "MEM_guardedalloc.h" + +#include "PIL_dynlib.h" + +#include "MTC_matrixops.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "DNA_texture_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_image_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BKE_osa_types.h" +#include "BKE_plugin_types.h" + +#include "BKE_bad_level_calls.h" +#include "BKE_utildefines.h" + +#include "BKE_global.h" +#include "BKE_main.h" + +#include "BKE_library.h" +#include "BKE_image.h" +#include "BKE_texture.h" +#include "BKE_key.h" +#include "BKE_ipo.h" + + +/* These vars form the texture channel */ +float Tin, Tr, Tg, Tb, Ta, Txtra; +extern int Talpha; + + +/* ------------------------------------------------------------------------- */ + +/* Alle support voor plugin textures: */ +int test_dlerr(const char *name, const char *symbol) +{ + char *err; + + err= PIL_dynlib_get_error_as_string(NULL); + if(err) { + printf("var1: %s, var2: %s, var3: %s\n", name, symbol, err); + return 1; + } + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +void open_plugin_tex(PluginTex *pit) +{ + int (*version)(void); + + /* init all the happy variables */ + pit->doit= 0; + pit->pname= 0; + pit->stnames= 0; + pit->varstr= 0; + pit->result= 0; + pit->cfra= 0; + pit->version= 0; + + /* clear the error list */ + PIL_dynlib_get_error_as_string(NULL); + + /* no PIL_dynlib_close! multiple opened plugins... */ + /* if(pit->handle) PIL_dynlib_close(pit->handle); */ + /* pit->handle= 0; */ + + /* open the needed object */ + pit->handle= PIL_dynlib_open(pit->name); + if(test_dlerr(pit->name, pit->name)) return; + + if (pit->handle != 0) { + /* find the address of the version function */ + version= (int (*)(void)) PIL_dynlib_find_symbol(pit->handle, "plugin_tex_getversion"); + if (test_dlerr(pit->name, "plugin_tex_getversion")) return; + + if (version != 0) { + pit->version= version(); + if (pit->version==2 || pit->version==3) { + int (*info_func)(PluginInfo *); + PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info"); + + info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pit->handle, "plugin_getinfo"); + if (!test_dlerr(pit->name, "plugin_getinfo")) { + + info_func(info); + + pit->doit= (int(*)(void)) info->tex_doit; + pit->callback= (void(*)(unsigned short)) info->callback; + pit->stypes= info->stypes; + pit->vars= info->nvars; + pit->pname= info->name; + pit->stnames= info->snames; + pit->varstr= info->varstr; + pit->result= info->result; + pit->cfra= info->cfra; + if (info->init) info->init(); + } + MEM_freeN(info); + } else { + printf ("Plugin returned unrecognized version number\n"); + return; + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +PluginTex *add_plugin_tex(char *str) +{ + PluginTex *pit; + VarStruct *varstr; + int a; + + pit= MEM_callocN(sizeof(PluginTex), "plugintex"); + + strcpy(pit->name, str); + open_plugin_tex(pit); + + if(pit->doit==0) { + if(pit->handle==0) error("no plugin: %s", str); + else error("in plugin: %s", str); + MEM_freeN(pit); + return NULL; + } + + varstr= pit->varstr; + for(a=0; a<pit->vars; a++, varstr++) { + if( (varstr->type & FLO)==FLO) + pit->data[a]= varstr->def; + else if( (varstr->type & INT)==INT) + *((int *)(pit->data+a))= (int) varstr->def; + } + + return pit; +} + +/* ------------------------------------------------------------------------- */ + +void free_plugin_tex(PluginTex *pit) +{ + if(pit==0) return; + + /* geen PIL_dynlib_close: dezelfde plugin kan meerdere keren geopend zijn: 1 handle */ + MEM_freeN(pit); +} + +/* ****************** COLORBAND ******************* */ + +ColorBand *add_colorband() +{ + ColorBand *coba; + int a; + + coba= MEM_callocN( sizeof(ColorBand), "colorband"); + + coba->data[0].r= 0.0; + coba->data[0].g= 0.0; + coba->data[0].b= 0.0; + coba->data[0].a= 0.0; + coba->data[0].pos= 0.0; + + coba->data[1].r= 0.0; + coba->data[1].g= 1.0; + coba->data[1].b= 1.0; + coba->data[1].a= 1.0; + coba->data[1].pos= 1.0; + + for(a=2; a<MAXCOLORBAND; a++) { + coba->data[a].r= 0.5; + coba->data[a].g= 0.5; + coba->data[a].b= 0.5; + coba->data[a].a= 1.0; + coba->data[a].pos= 0.5; + } + + coba->tot= 2; + + return coba; +} + +/* ------------------------------------------------------------------------- */ + +int do_colorband(ColorBand *coba) +{ + CBData *cbd1, *cbd2, *cbd0, *cbd3; + float fac, mfac, t[4]; + int a; + + if(coba->tot==0) return 0; + Talpha= 1; + + cbd1= coba->data; + + if(Tin <= cbd1->pos) { /* helemaal links */ + Tr= cbd1->r; + Tg= cbd1->g; + Tb= cbd1->b; + Ta= cbd1->a; + } + else { + /* we zoeken de eerste pos > Tin */ + + for(a=0; a<coba->tot; a++, cbd1++) if(cbd1->pos >= Tin) break; + + if(a==coba->tot) { /* helemaal rechts */ + cbd1--; + Tr= cbd1->r; + Tg= cbd1->g; + Tb= cbd1->b; + Ta= cbd1->a; + } + else { + cbd2= cbd1-1; + fac= (Tin-cbd1->pos)/(cbd2->pos-cbd1->pos); + + if(coba->ipotype==2) { + /* ipo van r naar l: 3 2 1 0 */ + + if(a>=coba->tot-1) cbd0= cbd1; + else cbd0= cbd1+1; + if(a<2) cbd3= cbd2; + else cbd3= cbd2-1; + + set_four_ipo(fac, t, KEY_BSPLINE); + + Tr= t[3]*cbd3->r +t[2]*cbd2->r +t[1]*cbd1->r +t[0]*cbd0->r; + Tg= t[3]*cbd3->g +t[2]*cbd2->g +t[1]*cbd1->g +t[0]*cbd0->g; + Tb= t[3]*cbd3->b +t[2]*cbd2->b +t[1]*cbd1->b +t[0]*cbd0->b; + Ta= t[3]*cbd3->a +t[2]*cbd2->a +t[1]*cbd1->a +t[0]*cbd0->a; + CLAMP(Tr, 0.0, 1.0); + CLAMP(Tg, 0.0, 1.0); + CLAMP(Tb, 0.0, 1.0); + CLAMP(Ta, 0.0, 1.0); + } + else { + + if(coba->ipotype==1) { /* EASE */ + mfac= fac*fac; + fac= 3.0f*mfac-2.0f*mfac*fac; + } + mfac= 1.0f-fac; + + Tr= mfac*cbd1->r + fac*cbd2->r; + Tg= mfac*cbd1->g + fac*cbd2->g; + Tb= mfac*cbd1->b + fac*cbd2->b; + Ta= mfac*cbd1->a + fac*cbd2->a; + } + } + } + return 1; /* OK */ +} + +/* ******************* TEX ************************ */ + +void free_texture(Tex *tex) +{ + free_plugin_tex(tex->plugin); + if(tex->coba) MEM_freeN(tex->coba); + if(tex->env) RE_free_envmap(tex->env); +} + +/* ------------------------------------------------------------------------- */ + +void default_tex(Tex *tex) +{ + tex->stype= 0; + tex->imaflag= TEX_INTERPOL+TEX_MIPMAP; + tex->extend= TEX_REPEAT; + tex->cropxmin= tex->cropymin= 0.0; + tex->cropxmax= tex->cropymax= 1.0; + tex->xrepeat= tex->yrepeat= 1; + tex->fie_ima= 2; + tex->sfra= 1; + tex->frames= 0; + tex->offset= 0; + tex->noisesize= 0.25; + tex->noisedepth= 2; + tex->turbul= 5.0; + tex->bright= 1.0; + tex->contrast= tex->filtersize= 1.0; + tex->rfac= 1.0; + tex->gfac= 1.0; + tex->bfac= 1.0; + +} + +/* ------------------------------------------------------------------------- */ + +Tex *add_texture(char *name) +{ + Tex *tex; + + tex= alloc_libblock(&G.main->tex, ID_TE, name); + + default_tex(tex); + + return tex; +} + +/* ------------------------------------------------------------------------- */ + +void default_mtex(MTex *mtex) +{ + mtex->texco= TEXCO_ORCO; + mtex->mapto= MAP_COL; + mtex->object= 0; + mtex->projx= PROJ_X; + mtex->projy= PROJ_Y; + mtex->projz= PROJ_Z; + mtex->mapping= MTEX_FLAT; + mtex->ofs[0]= 0.0; + mtex->ofs[1]= 0.0; + mtex->ofs[2]= 0.0; + mtex->size[0]= 1.0; + mtex->size[1]= 1.0; + mtex->size[2]= 1.0; + mtex->tex= 0; + mtex->texflag= 0; + mtex->colormodel= 0; + mtex->r= 1.0; + mtex->g= 0.0; + mtex->b= 1.0; + mtex->k= 1.0; + mtex->def_var= 1.0; + mtex->blendtype= MTEX_BLEND; + mtex->colfac= 1.0; + mtex->norfac= 0.5; + mtex->varfac= 1.0; +} + + +/* ------------------------------------------------------------------------- */ + +MTex *add_mtex() +{ + MTex *mtex; + + mtex= MEM_callocN(sizeof(MTex), "add_mtex"); + + default_mtex(mtex); + + return mtex; +} + +/* ------------------------------------------------------------------------- */ + +Tex *copy_texture(Tex *tex) +{ + Tex *texn; + + texn= copy_libblock(tex); + if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima); + else texn->ima= 0; + + if(texn->plugin) { + texn->plugin= MEM_dupallocN(texn->plugin); + open_plugin_tex(texn->plugin); + } + + if(texn->coba) texn->coba= MEM_dupallocN(texn->coba); + if(texn->env) texn->env= RE_copy_envmap(texn->env); + + return texn; +} + +/* ------------------------------------------------------------------------- */ + +void make_local_texture(Tex *tex) +{ + Tex *texn; + Material *ma; + World *wrld; + Lamp *la; + int a, local=0, lib=0; + + /* - zijn er alleen lib users: niet doen + * - zijn er alleen locale users: flag zetten + * - mixed: copy + */ + + if(tex->id.lib==0) return; + + /* speciaal geval: ima altijd meteen lokaal */ + if(tex->ima) { + tex->ima->id.lib= 0; + tex->ima->id.flag= LIB_LOCAL; + new_id(0, (ID *)tex->ima, 0); + } + + if(tex->id.us==1) { + tex->id.lib= 0; + tex->id.flag= LIB_LOCAL; + new_id(0, (ID *)tex, 0); + + return; + } + + ma= G.main->mat.first; + while(ma) { + for(a=0; a<8; a++) { + if(ma->mtex[a] && ma->mtex[a]->tex==tex) { + if(ma->id.lib) lib= 1; + else local= 1; + } + } + ma= ma->id.next; + } + la= G.main->lamp.first; + while(la) { + for(a=0; a<8; a++) { + if(la->mtex[a] && la->mtex[a]->tex==tex) { + if(la->id.lib) lib= 1; + else local= 1; + } + } + la= la->id.next; + } + wrld= G.main->world.first; + while(wrld) { + for(a=0; a<8; a++) { + if(wrld->mtex[a] && wrld->mtex[a]->tex==tex) { + if(wrld->id.lib) lib= 1; + else local= 1; + } + } + wrld= wrld->id.next; + } + + if(local && lib==0) { + tex->id.lib= 0; + tex->id.flag= LIB_LOCAL; + new_id(0, (ID *)tex, 0); + } + else if(local && lib) { + texn= copy_texture(tex); + texn->id.us= 0; + + ma= G.main->mat.first; + while(ma) { + for(a=0; a<8; a++) { + if(ma->mtex[a] && ma->mtex[a]->tex==tex) { + if(ma->id.lib==0) { + ma->mtex[a]->tex= texn; + texn->id.us++; + tex->id.us--; + } + } + } + ma= ma->id.next; + } + la= G.main->lamp.first; + while(la) { + for(a=0; a<8; a++) { + if(la->mtex[a] && la->mtex[a]->tex==tex) { + if(la->id.lib==0) { + la->mtex[a]->tex= texn; + texn->id.us++; + tex->id.us--; + } + } + } + la= la->id.next; + } + wrld= G.main->world.first; + while(wrld) { + for(a=0; a<8; a++) { + if(wrld->mtex[a] && wrld->mtex[a]->tex==tex) { + if(wrld->id.lib==0) { + wrld->mtex[a]->tex= texn; + texn->id.us++; + tex->id.us--; + } + } + } + wrld= wrld->id.next; + } + + } +} + +/* ------------------------------------------------------------------------- */ + +void autotexname(Tex *tex) +{ +/* extern char texstr[15][8]; *//* buttons.c, already in bad lev calls*/ + Image *ima; + char di[FILE_MAXDIR], fi[FILE_MAXFILE]; + + if(tex) { + if(tex->type==TEX_IMAGE) { + ima= tex->ima; + if(ima) { + strcpy(di, ima->name); + BLI_splitdirstring(di, fi); + strcpy(di, "I."); + strcat(di, fi); + new_id(&G.main->tex, (ID *)tex, di); + } + else new_id(&G.main->tex, (ID *)tex, texstr[tex->type]); + } + else if(tex->type==TEX_PLUGIN && tex->plugin) new_id(&G.main->tex, (ID *)tex, tex->plugin->pname); + else new_id(&G.main->tex, (ID *)tex, texstr[tex->type]); + } +} + +/* ------------------------------------------------------------------------- */ + +void init_render_texture(Tex *tex) +{ + Image *ima; + int imanr; + unsigned short numlen; + char name[256], head[FILE_MAXFILE], tail[FILE_MAXFILE]; + + /* is also used as signal */ + tex->nor= 0; + + /* imap testen */ + if(tex->frames && tex->ima && tex->ima->name) { /* frames */ + strcpy(name, tex->ima->name); + + imanr= calcimanr(G.scene->r.cfra, tex); + + if(tex->imaflag & TEX_ANIM5) { + if(tex->ima->lastframe != imanr) { + if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf); + tex->ima->ibuf= 0; + tex->ima->lastframe= imanr; + } + } + else { + /* voor patch field-ima rendering */ + tex->ima->lastframe= imanr; + + BLI_stringdec(name, head, tail, &numlen); + BLI_stringenc(name, head, tail, numlen, imanr); + + ima= add_image(name); + + if(ima) { + ima->flag |= IMA_FROMANIM; + + if(tex->ima) tex->ima->id.us--; + tex->ima= ima; + + ima->ok= 1; + } + } + } + if(tex->imaflag & (TEX_ANTIALI+TEX_ANTISCALE)) { + if(tex->ima && tex->ima->lastquality<R.osa) { + if(tex->ima->ibuf) IMB_freeImBuf(tex->ima->ibuf); + tex->ima->ibuf= 0; + } + } + + if(tex->type==TEX_PLUGIN) { + if(tex->plugin && tex->plugin->doit) { + if(tex->plugin->cfra) { + *(tex->plugin->cfra)= frame_to_float(G.scene->r.cfra); + } + } + } + else if(tex->type==TEX_ENVMAP) { + /* just in case */ + tex->imaflag= TEX_INTERPOL | TEX_MIPMAP; + tex->extend= TEX_CLIP; + + if(tex->env) { + /* temporal solution: layer 21 is to indicate an anvmap object */ + tex->env->notlay |= (1<<20); + if(tex->env->object) tex->env->object->lay |= (1<<20); + + if(R.flag & R_RENDERING) { + if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env); + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +void init_render_textures() +{ + Tex *tex; + + tex= G.main->tex.first; + while(tex) { + if(tex->id.us) init_render_texture(tex); + tex= tex->id.next; + } + + free_unused_animimages(); +} + +/* ------------------------------------------------------------------------- */ + +void end_render_texture(Tex *tex) +{ + + +} + +/* ------------------------------------------------------------------------- */ + +void end_render_textures() +{ + Tex *tex; + + tex= G.main->tex.first; + while(tex) { + if(tex->id.us) end_render_texture(tex); + tex= tex->id.next; + } + +} + + +/* ************************** */ + +int clouds(Tex *tex, float *texvec) +{ + float (*turbfunc)(float, float, float, float, int); + + if(tex->noisetype==TEX_NOISESOFT) turbfunc= BLI_turbulence; + else turbfunc= BLI_turbulence1; + + Tin= turbfunc(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth); + + if(tex->stype==1) { + + Tr= Tin; + Tg= turbfunc(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth); + + Tb= turbfunc(tex->noisesize,texvec[1],texvec[2],texvec[0], tex->noisedepth); + + BRICONRGB; + Ta= 1.0; + + return 1; + } + + BRICON; + + if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int blend(Tex *tex, float *texvec) +{ + float x, y, t; + + if(tex->flag & TEX_FLIPBLEND) { + x= texvec[1]; + y= texvec[0]; + } + else { + x= texvec[0]; + y= texvec[1]; + } + + if(tex->stype==0) { /* lin */ + Tin= (1.0+x)/2.0; + } + else if(tex->stype==1) { /* quad */ + Tin= (1.0+x)/2.0; + if(Tin<0.0) Tin= 0.0; + else Tin*= Tin; + } + else if(tex->stype==2) { /* ease */ + Tin= (1.0+x)/2.0; + if(Tin<=.0) Tin= 0.0; + else if(Tin>=1.0) Tin= 1.0; + else { + t= Tin*Tin; + Tin= (3.0*t-2.0*t*Tin); + } + } + else if(tex->stype==3) { /* diag */ + Tin= (2.0+x+y)/4.0; + } + else { /* sphere */ + Tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]); + if(Tin<0.0) Tin= 0.0; + if(tex->stype==5) Tin*= Tin; /* halo */ + } + + BRICON; + if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int wood(Tex *tex, float *texvec) +{ + float (*noisefunc)(float, float, float, float); + + if(tex->noisetype==TEX_NOISESOFT) noisefunc= BLI_hnoise; + else noisefunc= BLI_hnoisep; + + + if(tex->stype==0) { + Tin= 0.5+0.5*sin( (texvec[0]+texvec[1]+texvec[2])*10.0 ); + } + else if(tex->stype==1) { + Tin= 0.5+0.5*sin( sqrt(texvec[0]*texvec[0]+texvec[1]*texvec[1]+texvec[2]*texvec[2])*20.0 ); + } + else if(tex->stype==2) { + Tin= noisefunc(tex->noisesize, texvec[0], texvec[1], texvec[2]); + Tin= 0.5+ 0.5*sin(tex->turbul*Tin+(texvec[0]+texvec[1]+texvec[2])*10.0); + } + else if(tex->stype==3) { + Tin= noisefunc(tex->noisesize, texvec[0], texvec[1], texvec[2]); + Tin= 0.5+ 0.5*sin(tex->turbul*Tin+(sqrt(texvec[0]*texvec[0]+texvec[1]*texvec[1]+texvec[2]*texvec[2]))*20.0); + } + + + BRICON; + if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int marble(Tex *tex, float *texvec) +{ + float n; + float (*turbfunc)(float, float, float, float, int); + + if(tex->noisetype==TEX_NOISESOFT) turbfunc= BLI_turbulence; + else turbfunc= BLI_turbulence1; + + n= 5.0*(texvec[0]+texvec[1]+texvec[2]); + + Tin = 0.5+0.5*sin(n+tex->turbul*turbfunc(tex->noisesize, texvec[0],texvec[1],texvec[2], tex->noisedepth)); + + switch (tex->stype) { + case 1: + Tin= sqrt(Tin); + break; + case 2: + Tin= sqrt(Tin); + Tin= sqrt(Tin); + break; + } + + BRICON; + if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int magic(Tex *tex, float *texvec) +{ + float x, y, z, turb=1.0; + int n; + + n= tex->noisedepth; + turb= tex->turbul/5.0; + + x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0 ); + y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0 ); + z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0 ); + if(n>0) { + x*= turb; + y*= turb; + z*= turb; + y= -cos(x-y+z); + y*= turb; + if(n>1) { + x= cos(x-y-z); + x*= turb; + if(n>2) { + z= sin(-x-y-z); + z*= turb; + if(n>3) { + x= -cos(-x+y-z); + x*= turb; + if(n>4) { + y= -sin(-x+y+z); + y*= turb; + if(n>5) { + y= -cos(-x+y+z); + y*= turb; + if(n>6) { + x= cos(x+y+z); + x*= turb; + if(n>7) { + z= sin(x+y-z); + z*= turb; + if(n>8) { + x= -cos(-x-y+z); + x*= turb; + if(n>9) { + y= -sin(x-y+z); + y*= turb; + } + } + } + } + } + } + } + } + } + } + + if(turb!=0.0) { + turb*= 2.0; + x/= turb; + y/= turb; + z/= turb; + } + Tr= 0.5-x; + Tg= 0.5-y; + Tb= 0.5-z; + + BRICONRGB; + Ta= 1.0; + + return 1; +} + +/* ------------------------------------------------------------------------- */ + +int stucci(Tex *tex, float *texvec) +{ + float b2, vec[3]; + float ofs; + float (*noisefunc)(float, float, float, float); + + if(tex->nor == NULL) return 0; + + if(tex->noisetype==TEX_NOISESOFT) noisefunc= BLI_hnoise; + else noisefunc= BLI_hnoisep; + + ofs= tex->turbul/200.0; + + b2= noisefunc(tex->noisesize, texvec[0], texvec[1], texvec[2]); + if(tex->stype) ofs*=(b2*b2); + vec[0]= b2-noisefunc(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2]); + vec[1]= b2-noisefunc(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2]); + vec[2]= b2-noisefunc(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs); + + if(tex->stype==1) { + tex->nor[0]= vec[0]; + tex->nor[1]= vec[1]; + tex->nor[2]= vec[2]; + } + else { + tex->nor[0]= -vec[0]; + tex->nor[1]= -vec[1]; + tex->nor[2]= -vec[2]; + } + + return 2; +} + +/* ------------------------------------------------------------------------- */ + +int texnoise(Tex *tex) +{ + float div=3.0; + int val, ran, loop; + + ran= BLI_rand(); + val= (ran & 3); + + loop= tex->noisedepth; + while(loop--) { + ran= (ran>>2); + val*= (ran & 3); + div*= 3.0; + } + + Tin= ((float)val)/div;; + + BRICON; + if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt) +{ + PluginTex *pit; + int rgbnor=0; + + Tin= 0.0; + + pit= tex->plugin; + if(pit && pit->doit) { + VECCOPY(pit->result+5, R.vn); + + if(R.osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, dxt, dyt); + else rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, 0, 0); + + Tin= pit->result[0]; + + if(rgbnor & TEX_NOR) { + if(tex->nor) { + VECCOPY(tex->nor, pit->result+5); + } + } + + if(rgbnor & TEX_RGB) { + Tr= pit->result[1]; + Tg= pit->result[2]; + Tb= pit->result[3]; + Ta= pit->result[4]; + + BRICONRGB; + } + + BRICON; + if(tex->flag & TEX_COLORBAND) rgbnor |= do_colorband(tex->coba); + } + + return rgbnor; +} + +/* *************** PROJEKTIES ******************* */ + +void tubemap(float x, float y, float z, float *adr1, float *adr2) +{ + float len; + + *adr2 = (z + 1.0) / 2.0; + + len= sqrt(x*x+y*y); + if(len>0) { + *adr1 = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0; + } +} + +/* ------------------------------------------------------------------------- */ + +void spheremap(float x, float y, float z, float *adr1, float *adr2) +{ + float len; + + len= sqrt(x*x+y*y+z*z); + if(len>0.0) { + + if(x==0.0 && y==0.0) *adr1= 0.0; /* anders domain error */ + else *adr1 = (1.0 - atan2(x,y)/M_PI )/2.0; + + z/=len; + *adr2 = 1.0- saacos(z)/M_PI; + } +} + +/* ------------------------------------------------------------------------- */ + +static int cubemap_glob(MTex *mtex, float x, float y, float z, float *adr1, float *adr2) +{ + float x1, y1, z1, nor[3]; + int ret; + + VECCOPY(nor, R.vn); + MTC_Mat4Mul3Vecfl(R.viewinv, nor); + + x1= fabs(nor[0]); + y1= fabs(nor[1]); + z1= fabs(nor[2]); + + if(z1>=x1 && z1>=y1) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (y + 1.0) / 2.0; + ret= 0; + } + else if(y1>=x1 && y1>=z1) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 1; + } + else { + *adr1 = (y + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 2; + } + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int cubemap(MTex *mtex, float x, float y, float z, float *adr1, float *adr2) +{ + int proj[4], ret= 0; + + if(R.vlr && R.vlr->mface) { + int index; + /* the mtex->proj{xyz} have type char. maybe this should be wider? */ + /* casting to int ensures that the index type is right. */ + index = (int) mtex->projx; + proj[index]= ME_PROJXY; + + index = (int) mtex->projy; + proj[index]= ME_PROJXZ; + + index = (int) mtex->projz; + proj[index]= ME_PROJYZ; + + if(R.vlr->mface->puno & proj[1]) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (y + 1.0) / 2.0; + } + else if(R.vlr->mface->puno & proj[2]) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 1; + } + else { + *adr1 = (y + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 2; + } + } else + return cubemap_glob(mtex, x, y, z, adr1, adr2); + + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int cubemap_ob(MTex *mtex, float x, float y, float z, float *adr1, float *adr2) +{ + float x1, y1, z1, nor[3]; + int ret; + + VECCOPY(nor, R.vn); + if(mtex->object) MTC_Mat4Mul3Vecfl(mtex->object->imat, nor); + + x1= fabs(nor[0]); + y1= fabs(nor[1]); + z1= fabs(nor[2]); + + if(z1>=x1 && z1>=y1) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (y + 1.0) / 2.0; + ret= 0; + } + else if(y1>=x1 && y1>=z1) { + *adr1 = (x + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 1; + } + else { + *adr1 = (y + 1.0) / 2.0; + *adr2 = (z + 1.0) / 2.0; + ret= 2; + } + return ret; +} + +/* ------------------------------------------------------------------------- */ + +void do_2d_mapping(MTex *mtex, float *t, float *dxt, float *dyt) +{ + Tex *tex; + float fx, fy, fac1, area[8]; + int ok, proj, areaflag= 0, wrap; + + wrap= mtex->mapping; + tex= mtex->tex; + + if(R.osa==0) { + + if(wrap==MTEX_FLAT) { + fx = (t[0] + 1.0) / 2.0; + fy = (t[1] + 1.0) / 2.0; + } + else if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy); + else if(wrap==MTEX_SPHERE) spheremap(t[0], t[1], t[2], &fx, &fy); + else { + if(mtex->texco==TEXCO_OBJECT) cubemap_ob(mtex, t[0], t[1], t[2], &fx, &fy); + else if(mtex->texco==TEXCO_GLOB) cubemap_glob(mtex, t[0], t[1], t[2], &fx, &fy); + else cubemap(mtex, t[0], t[1], t[2], &fx, &fy); + } + + /* repeat */ + if(tex->xrepeat>1) { + fx *= tex->xrepeat; + if(fx>1.0) fx -= (int)(fx); + else if(fx<0.0) fx+= 1-(int)(fx); + } + if(tex->yrepeat>1) { + fy *= tex->yrepeat; + if(fy>1.0) fy -= (int)(fy); + else if(fy<0.0) fy+= 1-(int)(fy); + } + + /* crop */ + if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { + fac1= tex->cropxmax - tex->cropxmin; + fx= tex->cropxmin+ fx*fac1; + } + if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { + fac1= tex->cropymax - tex->cropymin; + fy= tex->cropymin+ fy*fac1; + } + + t[0]= fx; + t[1]= fy; + } + else { + + if(wrap==MTEX_FLAT) { + fx= (t[0] + 1.0) / 2.0; + fy= (t[1] + 1.0) / 2.0; + dxt[0]/= 2.0; + dxt[1]/= 2.0; + dyt[0]/= 2.0; + dyt[1]/= 2.0; + } + else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) { + /* uitzondering: de naad achter (y<0.0) */ + ok= 1; + if(t[1]<=0.0) { + fx= t[0]+dxt[0]; + fy= t[0]+dyt[0]; + if(fx>=0.0 && fy>=0.0 && t[0]>=0.0); + else if(fx<=0.0 && fy<=0.0 && t[0]<=0.0); + else ok= 0; + } + if(ok) { + if(wrap==MTEX_TUBE) { + tubemap(t[0], t[1], t[2], area, area+1); + tubemap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3); + tubemap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5); + } + else { + spheremap(t[0], t[1], t[2],area,area+1); + spheremap(t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2], area+2, area+3); + spheremap(t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2], area+4, area+5); + } + areaflag= 1; + } + else { + if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy); + else spheremap(t[0], t[1], t[2], &fx, &fy); + dxt[0]/= 2.0; + dxt[1]/= 2.0; + dyt[0]/= 2.0; + dyt[1]/= 2.0; + } + } + else { + + if(mtex->texco==TEXCO_OBJECT) proj = cubemap_ob(mtex, t[0], t[1], t[2], &fx, &fy); + else if (mtex->texco==TEXCO_GLOB) proj = cubemap_glob(mtex, t[0], t[1], t[2], &fx, &fy); + else proj = cubemap(mtex, t[0], t[1], t[2], &fx, &fy); + + if(proj==1) { + dxt[1]= dxt[2]; + dyt[1]= dyt[2]; + } + else if(proj==2) { + dxt[0]= dxt[1]; + dyt[0]= dyt[1]; + dxt[1]= dxt[2]; + dyt[1]= dyt[2]; + } + dxt[0]/= 2.0; + dxt[1]/= 2.0; + dyt[0]/= 2.0; + dyt[1]/= 2.0; + } + + /* als area dan dxt[] en dyt[] opnieuw berekenen */ + if(areaflag) { + fx= area[0]; + fy= area[1]; + dxt[0]= area[2]-fx; + dxt[1]= area[3]-fy; + dyt[0]= area[4]-fx; + dyt[1]= area[5]-fy; + } + + /* repeat */ + if(tex->xrepeat>1) { + fx *= tex->xrepeat; + dxt[0]*= tex->xrepeat; + dyt[0]*= tex->xrepeat; + if(fx>1.0) fx -= (int)(fx); + else if(fx<0.0) fx+= 1-(int)(fx); + } + if(tex->yrepeat>1) { + fy *= tex->yrepeat; + dxt[1]*= tex->yrepeat; + dyt[1]*= tex->yrepeat; + if(fy>1.0) fy -= (int)(fy); + else if(fy<0.0) fy+= 1-(int)(fy); + } + + /* crop */ + if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { + fac1= tex->cropxmax - tex->cropxmin; + fx= tex->cropxmin+ fx*fac1; + dxt[0]*= fac1; + dyt[0]*= fac1; + } + if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { + fac1= tex->cropymax - tex->cropymin; + fy= tex->cropymin+ fy*fac1; + dxt[1]*= fac1; + dyt[1]*= fac1; + } + + t[0]= fx; + t[1]= fy; + + } +} + + +/* ************************************** */ + +int multitex(Tex *tex, float *texvec, float *dxt, float *dyt) +{ + + + switch(tex->type) { + + case 0: + Tin= 0.0; + return 0; + case TEX_CLOUDS: + return clouds(tex, texvec); + case TEX_WOOD: + return wood(tex, texvec); + case TEX_MARBLE: + return marble(tex, texvec); + case TEX_MAGIC: + return magic(tex, texvec); + case TEX_BLEND: + return blend(tex, texvec); + case TEX_STUCCI: + Tin= 0.0; + return stucci(tex, texvec); + case TEX_NOISE: + return texnoise(tex); + case TEX_IMAGE: + if(R.osatex) return imagewraposa(tex, texvec, dxt, dyt); + else return imagewrap(tex, texvec); + break; + case TEX_PLUGIN: + return plugintex(tex, texvec, dxt, dyt); + break; + case TEX_ENVMAP: + return RE_envmaptex(tex, texvec, dxt, dyt); + break; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +void do_material_tex() +{ + Object *ob; + Material *mat_col, *mat_colspec, *mat_colmir, *mat_ref; + Material *mat_spec, *mat_har, *mat_emit, *mat_alpha; + MTex *mtex; + Tex *tex; + float *co = NULL, *dx = NULL, *dy = NULL, fact, + facm, factt, facmm, facmul = 0.0, stencilTin=1.0; + float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3]; + int tex_nr, rgbnor= 0; + + /* hier flag testen of er wel tex is */ + + mat_col=mat_colspec=mat_colmir=mat_ref=mat_spec=mat_har=mat_emit=mat_alpha= R.mat; + + tex_nr= 0; + if(R.mat->septex) tex_nr= R.mat->texact; + + for(; tex_nr<8; tex_nr++) { + if(R.mat->mtex[tex_nr]) { + mtex= R.mat->mtex[tex_nr]; + + tex= mtex->tex; + if(tex==0) continue; + + /* welke coords */ + if(mtex->texco==TEXCO_ORCO) { + co= R.lo; dx= O.dxlo; dy= O.dylo; + } + else if(mtex->texco==TEXCO_STICKY) { + co= R.sticky; dx= O.dxsticky; dy= O.dysticky; + } + else if(mtex->texco==TEXCO_OBJECT) { + ob= mtex->object; + if(ob) { + co= tempvec; + dx= dxt; + dy= dyt; + VECCOPY(tempvec, R.co); + MTC_Mat4MulVecfl(ob->imat, tempvec); + if(R.osatex) { + VECCOPY(dxt, O.dxco); + VECCOPY(dyt, O.dyco); + MTC_Mat4Mul3Vecfl(ob->imat, dxt); + MTC_Mat4Mul3Vecfl(ob->imat, dyt); + } + } + else { + /* als object niet bestaat geen orco's gebruiken (zijn niet geinitialiseerd */ + co= R.co; + dx= O.dxco; dy= O.dyco; + } + } + else if(mtex->texco==TEXCO_REFL) { + co= R.ref; dx= O.dxref; dy= O.dyref; + } + else if(mtex->texco==TEXCO_NORM) { + co= R.orn; dx= O.dxno; dy= O.dyno; + } + else if(mtex->texco==TEXCO_GLOB) { + co= R.gl; dx= O.dxco; dy= O.dyco; + } + else if(mtex->texco==TEXCO_UV) { + co= R.uv; dx= O.dxuv; dy= O.dyuv; + } + else if(mtex->texco==TEXCO_WINDOW) { + co= R.winco; dx= O.dxwin; dy= O.dywin; + } + + /* de pointer defines if bumping happens */ + if(mtex->mapto & MAP_NORM) { + tex->nor= norvec; + norvec[0]= norvec[1]= norvec[2]= 0.0; + } + else tex->nor= 0; + + if(tex->type==TEX_IMAGE) { + + /* nieuw: eerst coords verwisselen, dan map, dan trans/scale */ + + /* placement */ + if(mtex->projx) texvec[0]= co[mtex->projx-1]; + else texvec[0]= 0.0; + if(mtex->projy) texvec[1]= co[mtex->projy-1]; + else texvec[1]= 0.0; + if(mtex->projz) texvec[2]= co[mtex->projz-1]; + else texvec[2]= 0.0; + + if(R.osatex) { + + if(mtex->projx) { + dxt[0]= dx[mtex->projx-1]; + dyt[0]= dy[mtex->projx-1]; + } + else dxt[0]= 0.0; + if(mtex->projy) { + dxt[1]= dx[mtex->projy-1]; + dyt[1]= dy[mtex->projy-1]; + } + else dxt[1]= 0.0; + if(mtex->projx) { + dxt[2]= dx[mtex->projz-1]; + dyt[2]= dy[mtex->projz-1]; + } + else dxt[2]= 0.0; + } + + do_2d_mapping(mtex, texvec, dxt, dyt); + + /* translate en scale */ + texvec[0]= mtex->size[0]*(texvec[0]-0.5) +mtex->ofs[0]+0.5; + texvec[1]= mtex->size[1]*(texvec[1]-0.5) +mtex->ofs[1]+0.5; + if(R.osatex) { + dxt[0]= mtex->size[0]*dxt[0]; + dxt[1]= mtex->size[1]*dxt[1]; + dyt[0]= mtex->size[0]*dyt[0]; + dyt[1]= mtex->size[1]*dyt[1]; + } + } + else { + + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + + if(R.osatex) { + if(mtex->projx) { + dxt[0]= mtex->size[0]*dx[mtex->projx-1]; + dyt[0]= mtex->size[0]*dy[mtex->projx-1]; + } + else dxt[0]= 0.0; + if(mtex->projy) { + dxt[1]= mtex->size[1]*dx[mtex->projy-1]; + dyt[1]= mtex->size[1]*dy[mtex->projy-1]; + } + else dxt[1]= 0.0; + if(mtex->projx) { + dxt[2]= mtex->size[2]*dx[mtex->projz-1]; + dyt[2]= mtex->size[2]*dy[mtex->projz-1]; + } + else dxt[2]= 0.0; + } + } + + rgbnor= multitex(tex, texvec, dxt, dyt); + + /* texture output */ + + if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { + Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + rgbnor-= 1; + } + if(mtex->texflag & MTEX_NEGATIVE) { + if(rgbnor & TEX_RGB) { + Tr= 1.0-Tr; + Tg= 1.0-Tg; + Tb= 1.0-Tb; + } + Tin= 1.0-Tin; + } + if(mtex->texflag & MTEX_STENCIL) { + if(rgbnor & TEX_RGB) { + fact= Ta; + Ta*= stencilTin; + stencilTin*= fact; + } + else { + fact= Tin; + Tin*= stencilTin; + stencilTin*= fact; + } + } + else { + if(rgbnor & TEX_RGB) Ta*= stencilTin; + else Tin*= stencilTin; + } + + if(tex->nor && (rgbnor & TEX_NOR)==0) { + /* make our own normal */ + if(rgbnor & TEX_RGB) { + tex->nor[0]= Tr; + tex->nor[1]= Tg; + tex->nor[2]= Tb; + } + else { + float co= 0.5*cos(Tin-0.5); + float si= 0.5*sin(Tin-0.5); + float f1, f2; + + f1= R.vn[0]; + f2= R.vn[1]; + tex->nor[0]= f1*co+f2*si; + tex->nor[1]= f2*co-f1*si; + f1= R.vn[1]; + f2= R.vn[2]; + tex->nor[1]= f1*co+f2*si; + tex->nor[2]= f2*co-f1*si; + } + } + + + /* mapping */ + if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { + + if((rgbnor & TEX_RGB)==0) { + Tr= mtex->r; + Tg= mtex->g; + Tb= mtex->b; + } + else if(mtex->mapto & MAP_ALPHA) { + if(mtex->texflag & MTEX_ALPHAMIX) Tin= Ta; + else Tin= stencilTin; + } + else Tin= Ta; + + fact= Tin*mtex->colfac; + facm= 1.0-fact; + if(mtex->blendtype==MTEX_MUL) facm= 1.0-mtex->colfac; + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + if(mtex->mapto & MAP_COL) { + if(mtex->blendtype==MTEX_BLEND) { + R.matren->r= (fact*Tr + facm*mat_col->r); + R.matren->g= (fact*Tg + facm*mat_col->g); + R.matren->b= (fact*Tb + facm*mat_col->b); + } + else if(mtex->blendtype==MTEX_MUL) { + R.matren->r= (facm+fact*Tr)*mat_col->r; + R.matren->g= (facm+fact*Tg)*mat_col->g; + R.matren->b= (facm+fact*Tb)*mat_col->b; + } + else { + R.matren->r= (fact*Tr + mat_col->r); + R.matren->g= (fact*Tg + mat_col->g); + R.matren->b= (fact*Tb + mat_col->b); + } + mat_col= R.matren; + } + if(mtex->mapto & MAP_COLSPEC) { + if(mtex->blendtype==MTEX_BLEND) { + R.matren->specr= (fact*Tr + facm*mat_colspec->specr); + R.matren->specg= (fact*Tg + facm*mat_colspec->specg); + R.matren->specb= (fact*Tb + facm*mat_colspec->specb); + } + else if(mtex->blendtype==MTEX_MUL) { + R.matren->specr= (facm+fact*Tr)*mat_colspec->specr; + R.matren->specg= (facm+fact*Tg)*mat_colspec->specg; + R.matren->specb= (facm+fact*Tb)*mat_colspec->specb; + } + else { + R.matren->specr= (fact*Tr + mat_colspec->specr); + R.matren->specg= (fact*Tg + mat_colspec->specg); + R.matren->specb= (fact*Tb + mat_colspec->specb); + } + mat_colspec= R.matren; + } + if(mtex->mapto & MAP_COLMIR) { + if(mtex->blendtype==MTEX_BLEND) { + R.refcol[0]= fact + facm*R.refcol[0]; + + R.refcol[1]= fact*Tr + facm*R.refcol[1]; + R.refcol[2]= fact*Tg + facm*R.refcol[2]; + R.refcol[3]= fact*Tb + facm*R.refcol[3]; + } + else if(mtex->blendtype==MTEX_MUL) { + R.matren->mirr= (facm+fact*Tr)*mat_colmir->mirr; + R.matren->mirg= (facm+fact*Tg)*mat_colmir->mirg; + R.matren->mirb= (facm+fact*Tb)*mat_colmir->mirb; + } + else { + R.matren->mirr= (fact*Tr + mat_colmir->mirr); + R.matren->mirg= (fact*Tg + mat_colmir->mirg); + R.matren->mirb= (fact*Tb + mat_colmir->mirb); + } + mat_colmir= R.matren; + } + } + if( (mtex->mapto & MAP_NORM) ) { + if(tex->nor) { + + if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; + else tex->norfac= mtex->norfac; + + R.vn[0]+= tex->norfac*tex->nor[0]; + R.vn[1]+= tex->norfac*tex->nor[1]; + R.vn[2]+= tex->norfac*tex->nor[2]; + + Normalise(R.vn); + + /* hierdoor wordt de bump aan de volgende texture doorgegeven */ + R.orn[0]= R.vn[0]; + R.orn[1]= -R.vn[1]; + R.orn[2]= R.vn[2]; + + /* reflection vector */ + RE_calc_R_ref(); + } + } + + if(mtex->mapto & MAP_VARS) { + if(rgbnor & TEX_RGB) { + if(Talpha) Tin= Ta; + else Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + } + + fact= Tin*mtex->varfac; + facm= 1.0-fact; + if(mtex->blendtype==MTEX_MUL) facmul= 1.0-mtex->varfac; + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + if(mtex->mapto & MAP_REF) { + if(mtex->maptoneg & MAP_REF) {factt= facm; facmm= fact;} + else {factt= fact; facmm= facm;} + + if(mtex->blendtype==MTEX_BLEND) + R.matren->ref= factt*mtex->def_var+ facmm*mat_ref->ref; + else if(mtex->blendtype==MTEX_MUL) + R.matren->ref= (facmul+factt)*mat_ref->ref; + else { + R.matren->ref= factt+mat_ref->ref; + if(R.matren->ref<0.0) R.matren->ref= 0.0; + } + mat_ref= R.matren; + } + if(mtex->mapto & MAP_SPEC) { + if(mtex->maptoneg & MAP_SPEC) {factt= facm; facmm= fact;} + else {factt= fact; facmm= facm;} + + if(mtex->blendtype==MTEX_BLEND) + R.matren->spec= factt*mtex->def_var+ facmm*mat_spec->spec; + else if(mtex->blendtype==MTEX_MUL) + R.matren->spec= (facmul+factt)*mat_spec->spec; + else { + R.matren->spec= factt+mat_spec->spec; + if(R.matren->spec<0.0) R.matren->spec= 0.0; + } + mat_spec= R.matren; + } + if(mtex->mapto & MAP_EMIT) { + if(mtex->maptoneg & MAP_EMIT) {factt= facm; facmm= fact;} + else {factt= fact; facmm= facm;} + + if(mtex->blendtype==MTEX_BLEND) + R.matren->emit= factt*mtex->def_var+ facmm*mat_emit->emit; + else if(mtex->blendtype==MTEX_MUL) + R.matren->emit= (facmul+factt)*mat_emit->emit; + else { + R.matren->emit= factt+mat_emit->emit; + if(R.matren->emit<0.0) R.matren->emit= 0.0; + } + mat_emit= R.matren; + } + if(mtex->mapto & MAP_ALPHA) { + if(mtex->maptoneg & MAP_ALPHA) {factt= facm; facmm= fact;} + else {factt= fact; facmm= facm;} + + if(mtex->blendtype==MTEX_BLEND) + R.matren->alpha= factt*mtex->def_var+ facmm*mat_alpha->alpha; + else if(mtex->blendtype==MTEX_MUL) + R.matren->alpha= (facmul+factt)*mat_alpha->alpha; + else { + R.matren->alpha= factt+mat_alpha->alpha; + if(R.matren->alpha<0.0) R.matren->alpha= 0.0; + else if(R.matren->alpha>1.0) R.matren->alpha= 1.0; + } + mat_alpha= R.matren; + } + if(mtex->mapto & MAP_HAR) { + if(mtex->maptoneg & MAP_HAR) {factt= facm; facmm= fact;} + else {factt= fact; facmm= facm;} + + if(mtex->blendtype==MTEX_BLEND) { + R.matren->har= 128.0*factt*mtex->def_var+ facmm*mat_har->har; + } else if(mtex->blendtype==MTEX_MUL) { + R.matren->har= (facmul+factt)*mat_har->har; + } else { + R.matren->har= 128.0*factt+mat_har->har; + if(R.matren->har<1) R.matren->har= 1; + } + mat_har= R.matren; + } + } + } + + if(R.mat->septex) break; + } +} + +/* ------------------------------------------------------------------------- */ + +void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) +{ + MTex *mtex; + float texvec[3], dxt[3], dyt[3], fact, facm, dx; + int rgb; + + mtex= har->mat->mtex[0]; + if(mtex->tex==0) return; + /* no normal mapping */ + mtex->tex->nor= 0; + + texvec[0]= xn/har->rad; + texvec[1]= yn/har->rad; + texvec[2]= 0.0; + + R.osatex= (har->mat->texco & TEXCO_OSA); + + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + + if(R.osatex) { + + dx= 1.0/har->rad; + + if(mtex->projx) { + dxt[0]= mtex->size[0]*dx; + dyt[0]= mtex->size[0]*dx; + } + else dxt[0]= 0.0; + if(mtex->projy) { + dxt[1]= mtex->size[1]*dx; + dyt[1]= mtex->size[1]*dx; + } + else dxt[1]= 0.0; + if(mtex->projz) { + dxt[2]= 0.0; + dyt[2]= 0.0; + } + else dxt[2]= 0.0; + + } + + + if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, dxt, dyt); + + rgb= multitex(mtex->tex, texvec, dxt, dyt); + + /* texture uitgang */ + if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { + Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + rgb= 0; + } + if(mtex->texflag & MTEX_NEGATIVE) { + if(rgb) { + Tr= 1.0-Tr; + Tg= 1.0-Tg; + Tb= 1.0-Tb; + } + else Tin= 1.0-Tin; + } + + /* mapping */ + if(mtex->mapto & MAP_COL) { + + if(rgb==0) { + Tr= mtex->r; + Tg= mtex->g; + Tb= mtex->b; + } + else if(mtex->mapto & MAP_ALPHA) { + if(mtex->texflag & MTEX_ALPHAMIX) Tin= Ta; + else Tin= 1.0; + } + else Tin= Ta; + + fact= Tin*mtex->colfac; + facm= 1.0-fact; + + if(mtex->blendtype==MTEX_MUL) { + facm= 1.0-mtex->colfac; + } + else fact*= 256; + + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + if(mtex->blendtype==MTEX_BLEND) { + colf[0]= (fact*Tr + facm*har->r); + colf[1]= (fact*Tg + facm*har->g); + colf[2]= (fact*Tb + facm*har->b); + } + else if(mtex->blendtype==MTEX_MUL) { + colf[0]= (facm+fact*Tr)*har->r; + colf[1]= (facm+fact*Tg)*har->g; + colf[2]= (facm+fact*Tb)*har->b; + } + else { + colf[0]= (fact*Tr + har->r); + colf[1]= (fact*Tg + har->g); + colf[2]= (fact*Tb + har->b); + + CLAMP(colf[0], 0.0, 1.0); + CLAMP(colf[1], 0.0, 1.0); + CLAMP(colf[2], 0.0, 1.0); + } + } + if(mtex->mapto & MAP_ALPHA) { + if(rgb) { + if(Talpha) Tin= Ta; + else Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + } + + colf[3]*= Tin; + } + + R.osatex= 0; +} + +/* ------------------------------------------------------------------------- */ + +void do_sky_tex() +{ + World *wrld_hor, *wrld_zen; + MTex *mtex; + float *co, fact, facm, factt, facmm, facmul = 0.0, stencilTin=1.0; + float tempvec[3], texvec[3], dxt[3], dyt[3]; + int tex_nr, rgb= 0, ok; + + + /* hier flag testen of er wel tex is */ + + wrld_hor= wrld_zen= G.scene->world; + + /* The 6 here is rather arbitrary, it seems. */ + for(tex_nr=0; tex_nr<6; tex_nr++) { + if(R.wrld.mtex[tex_nr]) { + mtex= R.wrld.mtex[tex_nr]; + + if(mtex->tex==0) continue; + /* if(mtex->mapto==0) continue; */ + + /* welke coords */ + co= R.lo; + + /* Grab the mapping settings for this texture */ + if(mtex->texco==TEXCO_OBJECT) { + Object *ob= mtex->object; + if(ob) { + VECCOPY(tempvec, R.lo); + MTC_Mat4MulVecfl(ob->imat, tempvec); + co= tempvec; + } + } + + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + + /* texture */ + if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, dxt, dyt); + + rgb= multitex(mtex->tex, texvec, dxt, dyt); + + /* texture uitgang */ + if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { + Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + rgb= 0; + } + if(mtex->texflag & MTEX_NEGATIVE) { + if(rgb) { + Tr= 1.0-Tr; + Tg= 1.0-Tg; + Tb= 1.0-Tb; + } + else Tin= 1.0-Tin; + } + if(mtex->texflag & MTEX_STENCIL) { + if(rgb) { + + } + else { + fact= Tin; + Tin*= stencilTin; + stencilTin*= fact; + } + } + else { + if(rgb) ; + else Tin*= stencilTin; + } + + /* colour mapping */ + if(mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) { + + if(rgb==0) { + Tr= mtex->r; + Tg= mtex->g; + Tb= mtex->b; + } + else Tin= 1.0; + + fact= Tin*mtex->colfac; + facm= 1.0-fact; + if(mtex->blendtype==MTEX_MUL) facm= 1.0-mtex->colfac; + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + if(mtex->mapto & WOMAP_HORIZ) { + if(mtex->blendtype==MTEX_BLEND) { + R.wrld.horr= (fact*Tr + facm*wrld_hor->horr); + R.wrld.horg= (fact*Tg + facm*wrld_hor->horg); + R.wrld.horb= (fact*Tb + facm*wrld_hor->horb); + } + else if(mtex->blendtype==MTEX_MUL) { + R.wrld.horr= (facm+fact*Tr)*wrld_hor->horr; + R.wrld.horg= (facm+fact*Tg)*wrld_hor->horg; + R.wrld.horb= (facm+fact*Tb)*wrld_hor->horb; + } + else { + R.wrld.horr= (fact*Tr + wrld_hor->horr); + R.wrld.horg= (fact*Tg + wrld_hor->horg); + R.wrld.horb= (fact*Tb + wrld_hor->horb); + } + wrld_hor= &R.wrld; + } + if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) { + ok= 0; + if(R.wrld.skytype & WO_SKYREAL) { + if((R.wrld.skytype & WO_ZENUP)) { + if(mtex->mapto & WOMAP_ZENUP) ok= 1; + } + else if(mtex->mapto & WOMAP_ZENDOWN) ok= 1; + } + else ok= 1; + + if(ok) { + + if(mtex->blendtype==MTEX_BLEND) { + R.wrld.zenr= (fact*Tr + facm*wrld_zen->zenr); + R.wrld.zeng= (fact*Tg + facm*wrld_zen->zeng); + R.wrld.zenb= (fact*Tb + facm*wrld_zen->zenb); + } + else if(mtex->blendtype==MTEX_MUL) { + R.wrld.zenr= (facm+fact*Tr)*wrld_zen->zenr; + R.wrld.zeng= (facm+fact*Tg)*wrld_zen->zeng; + R.wrld.zenb= (facm+fact*Tb)*wrld_zen->zenb; + } + else { + R.wrld.zenr= (fact*Tr + wrld_zen->zenr); + R.wrld.zeng= (fact*Tg + wrld_zen->zeng); + R.wrld.zenb= (fact*Tb + wrld_zen->zenb); + } + wrld_zen= &R.wrld; + } + else { + /* anders blijft zenRGB hangen */ + R.wrld.zenr= wrld_zen->zenr; + R.wrld.zeng= wrld_zen->zeng; + R.wrld.zenb= wrld_zen->zenb; + } + } + } + if(mtex->mapto & WOMAP_BLEND) { + if(rgb) Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + + fact= Tin*mtex->varfac; + facm= 1.0-fact; + if(mtex->blendtype==MTEX_MUL) facmul= 1.0-mtex->varfac; + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + factt= fact; facmm= facm; + + if(mtex->blendtype==MTEX_BLEND) + R.inprz= factt*mtex->def_var+ facmm*R.inprz; + else if(mtex->blendtype==MTEX_MUL) + R.inprz= (facmul+factt)*R.inprz; + else { + R.inprz= factt+R.inprz; + } + } + } + } +} + +/* ------------------------------------------------------------------------- */ +/* explicit lampren stuff should be factored out! or rather, the + texturing stuff might need to go...*/ +void do_lamp_tex(LampRen *la, float *lavec) +{ + Object *ob; + LampRen *la_col; + MTex *mtex; + Tex *tex; + float *co = NULL, *dx = NULL, *dy = NULL, fact, facm, stencilTin=1.0; + float texvec[3], dxt[3], dyt[3], tempvec[3]; + int tex_nr, rgb= 0; + + /* hier flag testen of er wel tex is */ + + la_col= la->org; + + tex_nr= 0; + + for(; tex_nr<6; tex_nr++) { + + if(la->mtex[tex_nr]) { + mtex= la->mtex[tex_nr]; + + tex= mtex->tex; + if(tex==0) continue; + + /* welke coords */ + if(mtex->texco==TEXCO_OBJECT) { + ob= mtex->object; + if(ob) { + co= tempvec; + dx= dxt; + dy= dyt; + VECCOPY(tempvec, R.co); + MTC_Mat4MulVecfl(ob->imat, tempvec); + if(R.osatex) { + VECCOPY(dxt, O.dxco); + VECCOPY(dyt, O.dyco); + MTC_Mat4Mul3Vecfl(ob->imat, dxt); + MTC_Mat4Mul3Vecfl(ob->imat, dyt); + } + } + else { + co= R.co; + dx= O.dxco; dy= O.dyco; + } + } + else if(mtex->texco==TEXCO_GLOB) { + co= R.gl; dx= O.dxco; dy= O.dyco; + VECCOPY(R.gl, R.co); + MTC_Mat4MulVecfl(R.viewinv, R.gl); + } + else if(mtex->texco==TEXCO_VIEW) { + + VECCOPY(tempvec, lavec); + MTC_Mat3MulVecfl(la->imat, tempvec); + + tempvec[0]*= la->spottexfac; + tempvec[1]*= la->spottexfac; + co= tempvec; + + dx= dxt; dy= dyt; + if(R.osatex) { + VECCOPY(dxt, O.dxlv); + VECCOPY(dyt, O.dylv); + /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ + MTC_Mat3MulVecfl(la->imat, dxt); + MTC_Mat3MulVecfl(la->imat, dyt); + + VecMulf(dxt, la->spottexfac); + VecMulf(dyt, la->spottexfac); + } + } + + + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + + if(R.osatex) { + if(mtex->projx) { + dxt[0]= mtex->size[0]*dx[mtex->projx-1]; + dyt[0]= mtex->size[0]*dy[mtex->projx-1]; + } + else dxt[0]= 0.0; + if(mtex->projy) { + dxt[1]= mtex->size[1]*dx[mtex->projy-1]; + dyt[1]= mtex->size[1]*dy[mtex->projy-1]; + } + else dxt[1]= 0.0; + if(mtex->projx) { + dxt[2]= mtex->size[2]*dx[mtex->projz-1]; + dyt[2]= mtex->size[2]*dy[mtex->projz-1]; + } + else dxt[2]= 0.0; + } + + /* texture */ + if(tex->type==TEX_IMAGE) { + do_2d_mapping(mtex, texvec, dxt, dyt); + + if(mtex->mapto & MAP_NORM) { + /* de pointer bepaalt of er gebumpt wordt */ + tex->nor= R.vn; + if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; + else tex->norfac= mtex->norfac; + } + else tex->nor= 0; + } + + rgb= multitex(tex, texvec, dxt, dyt); + + + + /* texture uitgang */ + if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { + Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + rgb= 0; + } + if(mtex->texflag & MTEX_NEGATIVE) { + if(rgb) { + Tr= 1.0-Tr; + Tg= 1.0-Tg; + Tb= 1.0-Tb; + } + else Tin= 1.0-Tin; + } + if(mtex->texflag & MTEX_STENCIL) { + if(rgb) { + fact= Ta; + Ta*= stencilTin; + stencilTin*= fact; + } + else { + fact= Tin; + Tin*= stencilTin; + stencilTin*= fact; + } + } + else { + if(rgb) Ta*= stencilTin; + else Tin*= stencilTin; + } + + /* mapping */ + if(mtex->mapto & LAMAP_COL) { + + if(rgb==0) { + Tr= mtex->r; + Tg= mtex->g; + Tb= mtex->b; + } + else if(mtex->mapto & MAP_ALPHA) { + if(mtex->texflag & MTEX_ALPHAMIX) Tin= Ta; + else Tin= stencilTin; + } + else Tin= Ta; + + Tr*= la->energy; + Tg*= la->energy; + Tb*= la->energy; + + fact= Tin*mtex->colfac; + facm= 1.0-fact; + if(mtex->blendtype==MTEX_MUL) facm= 1.0-mtex->colfac; + if(mtex->blendtype==MTEX_SUB) fact= -fact; + + if(mtex->blendtype==MTEX_BLEND) { + la->r= (fact*Tr + facm*la_col->r); + la->g= (fact*Tg + facm*la_col->g); + la->b= (fact*Tb + facm*la_col->b); + } + else if(mtex->blendtype==MTEX_MUL) { + la->r= (facm+fact*Tr)*la_col->r; + la->g= (facm+fact*Tg)*la_col->g; + la->b= (facm+fact*Tb)*la_col->b; + } + else { + la->r= (fact*Tr + la_col->r); + la->g= (fact*Tg + la_col->g); + la->b= (fact*Tb + la_col->b); + } + la_col= la; /* Is it just me or is this a useless statement? */ + } + + } + } +} + +/* ------------------------------------------------------------------------- */ + +void externtex(MTex *mtex, float *vec) +{ + Tex *tex; + float dxt[3], dyt[3], texvec[3]; + int rgb; + + tex= mtex->tex; + if(tex==0) return; + + R.osatex= 0; + R.vlr= 0; + + /* placement */ + if(mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]); + else texvec[0]= mtex->size[0]*(mtex->ofs[0]); + + if(mtex->projy) texvec[1]= mtex->size[1]*(vec[mtex->projy-1]+mtex->ofs[1]); + else texvec[1]= mtex->size[1]*(mtex->ofs[1]); + + if(mtex->projz) texvec[2]= mtex->size[2]*(vec[mtex->projz-1]+mtex->ofs[2]); + else texvec[2]= mtex->size[2]*(mtex->ofs[2]); + + /* texture */ + if(tex->type==TEX_IMAGE) { + do_2d_mapping(mtex, texvec, dxt, dyt); + + if(mtex->mapto & MAP_NORM) { + /* de pointer bepaalt of er gebumpt wordt */ + tex->nor= R.vn; + if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; + else tex->norfac= mtex->norfac; + } + else tex->nor= 0; + } + + rgb= multitex(tex, texvec, dxt, dyt); + if(rgb) { + Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + } + else { + Tr= mtex->r; + Tg= mtex->g; + Tb= mtex->b; + } +} + +/* ------------------------------------------------------------------------- */ + +void externtexcol(MTex *mtex, float *orco, char *col) +{ + int temp; + float b1; + + if(mtex->tex==0) return; + + externtex(mtex, orco); + + b1= 1.0-Tin; + + temp= 255*(Tin*Tr)+b1*col[0]; + if(temp>255) col[0]= 255; else col[0]= temp; + temp= 255*(Tin*Tg)+b1*col[1]; + if(temp>255) col[1]= 255; else col[1]= temp; + temp= 255*(Tin*Tb)+b1*col[2]; + if(temp>255) col[2]= 255; else col[2]= temp; + +} + +/* ------------------------------------------------------------------------- */ + +void render_realtime_texture() +{ + static Tex tex; + static int firsttime= 1; + float texvec[2], dx[2], dy[2]; + + if(firsttime) { + default_tex(&tex); + tex.type= TEX_IMAGE; + firsttime= 0; + } + + tex.ima = R.vlr->tface->tpage; + if(tex.ima) { + + texvec[0]= 0.5+0.5*R.uv[0]; + texvec[1]= 0.5+0.5*R.uv[1]; + if(R.osatex) { + dx[0]= 0.5*O.dxuv[0]; + dx[1]= 0.5*O.dxuv[1]; + dy[0]= 0.5*O.dyuv[0]; + dy[1]= 0.5*O.dyuv[1]; + } + + if(R.osatex) imagewraposa(&tex, texvec, dx, dy); + else imagewrap(&tex, texvec); + + R.vcol[0]*= Tr; + R.vcol[1]*= Tg; + R.vcol[2]*= Tb; + } + + +} + +/* eof */ |