home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gondwana.ecr.mu.oz.au/pub/
/
Graphics.tar
/
Graphics
/
atomart.tar.gz
/
atomart.tar
/
texture.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-28
|
4KB
|
251 lines
#include <stdio.h>
#include <math.h>
#include "atomart.h"
#include "macro.h"
#include "gram.h"
extern float randtable[];
extern float noise();
extern void Vnoise();
extern attr *astackp;
static noise_inited = 0;
/*
* turbulence
*
* Accumulate a 3D noise function over octaves octaves, scaling
* each by 1 / f
*/
float
turbulence(pos, octaves)
vector *pos;
int octaves;
{
float scale, t, f;
vector p;
int i;
scale = f = 1.0;
t = 0.0;
for (i = 0; i < octaves; i++) {
p.x = pos->x * f;
p.y = pos->y * f;
p.z = pos->z * f;
t += fabs(noise(&p) * scale);
f *= 2;
scale *= 0.5;
}
return(t);
}
/*
* marble
*
* Does marble texture.
*/
void
marble(o, txt, l, n, pcol, type)
object *o;
texture *txt;
vector *l, *n;
pixel *pcol;
int type;
{
float x;
vector loc, tmp;
totexture(txt, loc, *l);
x = txt->var[0] * loc.x + txt->var[1] * turbulence(&loc, txt->octaves);
x = 0.5 * (1.0 + sin(x));
x = pow((double)x, (double)txt->var[2]);
texturec(txt, pcol, &loc, n, type, x);
}
/*
* wood
*
* Does wood texture.
*/
void
wood(o, txt, l, n, pcol, type)
object *o;
texture *txt;
vector *l, *n;
pixel *pcol;
int type;
{
float x;
vector loc, tmp;
totexture(txt, loc, *l);
x = sqrt(loc.x * loc.x + loc.y * loc.y);
x *= txt->var[0];
x += txt->var[1] * turbulence(&loc, txt->octaves);
x = 0.5 * (1.0 + sin(x));
x = pow((double)x, (double)txt->var[2]);
texturec(txt, pcol, &loc, n, type, x);
}
/*
* bumpy
*
* Does a bumpy texture.
*/
void
bumpy(o, txt, l, n, pcol, type)
object *o;
texture *txt;
vector *l, *n;
pixel *pcol;
int type;
{
vector amp, loc, tmp;
totexture(txt, loc, *l);
Vnoise(&loc, &);
n->x += amp.x * txt->var[0];
n->y += amp.y * txt->var[1];
n->z += amp.z * txt->var[2];
normalise(*n);
}
/*
* texturec
*
* compute the color for a textured surface.
*/
texturec(txt, pcol, l, n, type, x)
texture *txt;
pixel *pcol;
vector *l, *n;
int type;
float x;
{
int i;
if (txt->map == (char *)NULL) {
/*
* It's a variation of the base color.
*/
if (x < 0.0)
x = 0.0;
if (x > 1.0)
x = 1.0;
pcol->r = (1.0 - x) * pcol->r + x * txt->blendcolour.r;
pcol->g = (1.0 - x) * pcol->g + x * txt->blendcolour.g;
pcol->b = (1.0 - x) * pcol->b + x * txt->blendcolour.b;
} else {
i = fabs(x) * txt->pixw;
if (i < 0)
i = 0;
if (i > txt->pixw)
i = txt->pixw;
i *= 3;
pcol->r = (unsigned char)txt->map[i] / 255.0;
pcol->g = (unsigned char)txt->map[i + 1] / 255.0;
pcol->b = (unsigned char)txt->map[i + 2] / 255.0;
}
}
/*
* textureinit
*
* initialise the function pointers and fields for a texture pattern.
*/
tlist *
textureinit(name, d)
char *name;
details *d;
{
tlist *tl;
char buf[128];
details *ld;
if (!noise_inited) {
init_noise();
noise_inited = 1;
}
tl = (tlist *)smalloc(sizeof(tlist));
tl->txt.refset = FALSE;
if (strcmp(name, "marble") == 0)
tl->txtcol = marble;
else if (strcmp(name, "wood") == 0)
tl->txtcol = wood;
else if (strcmp(name, "bumpy") == 0)
tl->txtcol = bumpy;
else if (strcmp(name, "tile") == 0) /* different for each object */
tl->txtcol = (void (*)())NULL;
else {
sprintf(buf, "atomart: unknown procedural texture %s.\n", name);
fatal(buf);
}
tl->txt.map = (char *)NULL;
tl->txt.octaves = 6;
cp3x3(tl->txt.mat, astackp->m);
tl->txt.trans.x = astackp->m[3][0];
tl->txt.trans.y = astackp->m[3][1];
tl->txt.trans.z = astackp->m[3][2];
tl->txt.scales = astackp->scales;
tl->txt.scalew = 1.0;
tl->txt.scaleh = 1.0;
while (d != (details *)NULL) {
switch (d->type) {
case MAP:
readascmap(&tl->txt, d->u.s);
break;
case RANGE:
tl->txt.octaves = d->u.f;
break;
case BLENDCOLOR:
tl->txt.blendcolour.r = d->u.v.x;
tl->txt.blendcolour.g = d->u.v.y;
tl->txt.blendcolour.b = d->u.v.z;
break;
case SCALEFACTORS:
tl->txt.var[0] = d->u.v.x;
tl->txt.var[1] = d->u.v.y;
tl->txt.var[2] = d->u.v.z;
break;
case VORTFILE:
tileinit(&tl->txt, d->u.s, 1.0, 1.0);
break;
case SIZE:
tl->txt.scalew /= d->u.v.x;
tl->txt.scaleh /= d->u.v.y;
break;
default:
warning("atomart: illegal field in procedural texture ignored.\n");
}
ld = d;
d = d->nxt;
free(ld);
}
return(tl);
}