2321 lines
52 KiB
C
2321 lines
52 KiB
C
/**
|
|
* $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 */
|