/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 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 ***** */ /* texture.c MIX MODEL * * maart 95 * */ #include "blender.h" #include "render.h" #include "plugin.h" float Tin, Tr, Tg, Tb, Ta, Txtra; extern int Talpha; /* Alle support voor plugin textures: */ void test_dlerr(PluginTex *pit) { char *err; err= dlerror(); if(err) { PRINT2(s, s, pit->name, err); } } void open_plugin_tex(PluginTex *pit) { void (*fptr)(); /* if(pit->handle) dlclose(pit->handle); */ /* pit->handle= 0; */ /* voor zekerheid: (hier wordt op getest) */ pit->doit= 0; pit->pname= 0; pit->stnames= 0; /* open the needed object */ pit->handle = dlopen(pit->name, RTLD_LAZY); if(pit->handle==0) return; /* find address of functions and data objects */ pit->doit = dlsym(pit->handle, "plugin_tex_doit"); test_dlerr(pit); fptr= dlsym(pit->handle, "plugin_tex_getinfo"); test_dlerr(pit); fptr( &pit->stypes, &pit->vars); pit->pname= (char *)dlsym(pit->handle, "_name"); test_dlerr(pit); pit->stnames= (char *)dlsym(pit->handle, "_stnames"); test_dlerr(pit); pit->varstr= (void *)dlsym(pit->handle, "_varstr"); test_dlerr(pit); pit->result= (float *)dlsym(pit->handle, "_result"); test_dlerr(pit); /* fptr= dlsym(pit->handle, "init"); */ /* if(fptr) fptr(); */ /* PRINT4(s, x, x, x, pit->pname, pit->handle, pit->doit, pit->result); */ } PluginTex *add_plugin_tex(char *str) { void *handle; void (*fptr)(); PluginTex *pit; VarStruct *varstr; int a; pit= callocN(sizeof(PluginTex), "plugintex"); strcpy(pit->name, str); open_plugin_tex(pit); if(pit->doit==0) { if(pit->handle==0) errorstr("no plugin:", str, 0); else errorstr("in plugin:", str, 0); freeN(pit); return; } /* default waardes */ varstr= pit->varstr; for(a=0; avars; 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; else if( (varstr->type & LON)==LON) *((int *)(pit->data+a))= (int) varstr->def; } return pit; } void free_plugin_tex(PluginTex *pit) { if(pit==0) return; /* geen dlclose: dezelfde plugin kan meerdere keren geopend zijn: 1 handle */ freeN(pit); } /* ****************** COLORBAND ******************* */ ColorBand *add_colorband() { ColorBand *coba; int a; coba= 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; adata[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; atot; 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.0*mfac-2.0*mfac*fac; } mfac= 1.0-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) freeN(tex->coba); } 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= callocN(sizeof(MTex), "add_mtex"); default_mtex(mtex); return mtex; } Tex *copy_texture(Tex *tex) { Tex *texn; int a; texn= copy_libblock(tex); if(texn->type==TEX_IMAGE) id_us_plus(texn->ima); else texn->ima= 0; if(texn->plugin) { texn->plugin= dupallocN(texn->plugin); open_plugin_tex(texn->plugin); } if(texn->coba) texn->coba= dupallocN(texn->coba); 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, tex->ima, 0); } if(tex->id.us==1) { tex->id.lib= 0; tex->id.flag= LIB_LOCAL; new_id(0, 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, 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 */ Image *ima; char di[80], fi[80]; if(tex) { if(tex->type==TEX_IMAGE) { ima= tex->ima; if(ima) { strcpy(di, ima->name); splitdirstring(di, fi); strcpy(di, "I."); strcat(di, fi); new_id(&G.main->tex, tex, di); } else new_id(&G.main->tex, tex, texstr[tex->type]); } else if(tex->type==TEX_PLUGIN && tex->plugin) new_id(&G.main->tex, tex, tex->plugin->pname); else new_id(&G.main->tex, tex, texstr[tex->type]); } } void init_render_texture(Tex *tex) { Image *ima; float *fp; int imanr; ushort numlen; char name[256], head[120], tail[120]; /* imap testen */ if(tex->frames && tex->ima && tex->ima->name) { /* frames */ strcpy(name, tex->ima->name); imanr= calcimanr(CFRA, tex); if(tex->imaflag & TEX_ANIM5) { if(tex->ima->lastframe != imanr) { if(tex->ima->ibuf) freeImBuf(tex->ima->ibuf); tex->ima->ibuf= 0; tex->ima->lastframe= imanr; } } else { /* voor patch field-ima rendering */ tex->ima->lastframe= imanr; stringdec(name, head, tail, &numlen); 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->lastqualityima->ibuf) freeImBuf(tex->ima->ibuf); tex->ima->ibuf= 0; } } if(tex->type==TEX_PLUGIN) { if(tex->plugin && tex->plugin->doit) { fp= dlsym(tex->plugin->handle, "cfra"); if(fp) { *fp= frame_to_float(CFRA); } } } /* niet net: eigenlijk met xtra var... */ if(tex->filtersize>1.0) { tex->filtersize= 1.0 + (tex->filtersize-1.0)*((float)G.scene->r.size)/100.0; } } 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) { /* niet net: eigenlijk met xtra var... */ if(tex->filtersize>1.0) { tex->filtersize= 1.0 + (tex->filtersize -1.0)/(((float)G.scene->r.size)/100.0); } } 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= turbulence; else turbfunc= 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-fsqrt(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= hnoise; else noisefunc= hnoisep; if(tex->stype==0) { Tin= 0.5+0.5*fsin( (texvec[0]+texvec[1]+texvec[2])*10.0 ); } else if(tex->stype==1) { Tin= 0.5+0.5*fsin( fsqrt(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*fsin(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*fsin(tex->turbul*Tin+(fsqrt(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, turb; float (*turbfunc)(float, float, float, float, int); if(tex->noisetype==TEX_NOISESOFT) turbfunc= turbulence; else turbfunc= turbulence1; n= 5.0*(texvec[0]+texvec[1]+texvec[2]); Tin = 0.5+0.5*fsin(n+tex->turbul*turbfunc(tex->noisesize, texvec[0],texvec[1],texvec[2], tex->noisedepth)); switch (tex->stype) { case 1: Tin= fsqrt(Tin); break; case 2: Tin= fsqrt(Tin); Tin= fsqrt(Tin); break; } BRICON; if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); return 0; } int magic(Tex *tex, float *texvec) { float tt, x, y, z, turb=1.0; int n; n= tex->noisedepth; turb= tex->turbul/5.0; x= fsin( ( texvec[0]+texvec[1]+texvec[2])*5.0 ); y= fcos( (-texvec[0]+texvec[1]-texvec[2])*5.0 ); z= -fcos( (-texvec[0]-texvec[1]+texvec[2])*5.0 ); if(n>0) { x*= turb; y*= turb; z*= turb; y= -fcos(x-y+z); y*= turb; if(n>1) { x= fcos(x-y-z); x*= turb; if(n>2) { z= fsin(-x-y-z); z*= turb; if(n>3) { x= -fcos(-x+y-z); x*= turb; if(n>4) { y= -fsin(-x+y+z); y*= turb; if(n>5) { y= -fcos(-x+y+z); y*= turb; if(n>6) { x= fcos(x+y+z); x*= turb; if(n>7) { z= fsin(x+y-z); z*= turb; if(n>8) { x= -fcos(-x-y+z); x*= turb; if(n>9) { y= -fsin(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->noisetype==TEX_NOISESOFT) noisefunc= hnoise; else noisefunc= 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) { R.vn[0]+= vec[0]; R.vn[1]+= vec[1]; R.vn[2]+= vec[2]; } else { R.vn[0]-= vec[0]; R.vn[1]-= vec[1]; R.vn[2]-= vec[2]; } Normalise(R.vn); return 0; } int texnoise(Tex *tex) { float div=3.0; long val, ran, loop; ran= random(); 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 rgb; pit= tex->plugin; if(pit && pit->doit) { VECCOPY(pit->result+5, R.vn); if(R.osatex) rgb= pit->doit(tex->stype, pit->data, texvec, dxt, dyt); else rgb= pit->doit(tex->stype, pit->data, texvec, 0, 0); Tin= pit->result[0]; if(rgb & 2) { VECCOPY(R.vn, pit->result+5); } if(rgb & 1) { Tr= pit->result[1]; Tg= pit->result[2]; Tb= pit->result[3]; Ta= pit->result[4]; BRICONRGB; } if(rgb==0) { BRICON; if(tex->flag & TEX_COLORBAND) return do_colorband(tex->coba); } } return (rgb & 1); } /* *************** PROJEKTIES ******************* */ void tubemap(x, y, z, adr1, adr2) float x, y, z, *adr1, *adr2; { float len; *adr2 = (z + 1.0) / 2.0; len= fsqrt(x*x+y*y); if(len>0) { *adr1 = (1.0 - (fatan2(x/len,y/len) / M_PI)) / 2.0; } } void spheremap(x, y, z, adr1, adr2) float x, y, z, *adr1, *adr2; { float len; len= fsqrt(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 - fatan2(x,y)/M_PI )/2.0; z/=len; *adr2 = 1.0- facos(z)/M_PI; } } 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) { proj[mtex->projx]= ME_PROJXY; proj[mtex->projy]= ME_PROJXZ; proj[mtex->projz]= 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 { *adr1 = (x + 1.0) / 2.0; *adr2 = (y + 1.0) / 2.0; } return ret; } 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) 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; } 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); 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; } 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 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: 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; } } 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, *dx, *dy, fact, facm, factt, facmm, facmul, 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 */ 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); Mat4MulVecfl(ob->imat, tempvec); if(R.osatex) { VECCOPY(dxt, O.dxco); VECCOPY(dyt, O.dyco); Mat4Mul3Vecfl(ob->imat, dxt); 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; } /* VECCOPY(texvec, co); */ 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); 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; /* 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; } } 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 & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { 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; 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.matren->mirr= (fact*Tr + facm*mat_colmir->mirr); R.matren->mirg= (fact*Tg + facm*mat_colmir->mirg); R.matren->mirb= (fact*Tb + facm*mat_colmir->mirb); } 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) || tex->type==TEX_STUCCI ) { /* 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]; } if(mtex->mapto & MAP_VARS) { if(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(mtex->mapto & MAP_XTRA) { if(mtex->maptoneg & MAP_XTRA) {factt= facm; facmm= fact;} else {factt= fact; facmm= facm;} if(mtex->blendtype==MTEX_BLEND) { Txtra= factt*mtex->def_var + facmm; } else Txtra= 0.0; } } } 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, facmul, facmm, factt; int rgb; mtex= har->mat->mtex[0]; if(mtex->tex==0) return; 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, stencilTin=1.0; float 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; 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; /* 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; } /* 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; } } } } } void do_lamp_tex(LampRen *la, float *lavec) { Object *ob; LampRen *la_col; MTex *mtex; Tex *tex; float *co, *dx, *dy, fact, facm, factt, facmm, facmul, 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); Mat4MulVecfl(ob->imat, tempvec); if(R.osatex) { VECCOPY(dxt, O.dxco); VECCOPY(dyt, O.dyco); Mat4Mul3Vecfl(ob->imat, dxt); 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); Mat4MulVecfl(R.viewinv, R.gl); } else if(mtex->texco==TEXCO_VIEW) { VECCOPY(tempvec, lavec); 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); Mat4Mul3Vecfl(la->imat, dxt); Mat4Mul3Vecfl(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; } } } } 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; /* 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; }