diff -r 9569e9f35374 -r 062b1c4143f7 include/material.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/material.h Wed Apr 23 14:39:33 2008 +0200 @@ -0,0 +1,296 @@ +/* + * material.h: material and texture classes + * + * This file is part of Pyrit Ray Tracer. + * + * Copyright 2006, 2007, 2008 Radek Brich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MATERIAL_H +#define MATERIAL_H + +#include "common.h" +#include "vector.h" +#include "noise.h" + +/** + * perlin noise + */ +Float perlin(Float x, Float y, Float z); + +/** + * general texture + */ +class Texture +{ +public: + virtual ~Texture() {}; + virtual Colour evaluate(const Vector3 &point) = 0; +}; + +/** + * general colour map + */ +class ColourMap +{ +public: + virtual Colour map(const Float &val) = 0; +}; + +/** + * linear colour map + * maps value lineary between two colours + */ +class LinearColourMap: public ColourMap +{ + Colour col,cdiff; +public: + LinearColourMap(const Colour &clow, const Colour &chigh): + col(clow), cdiff(chigh-clow) {}; + Colour map(const Float &val) { return col + cdiff*val; }; +}; + +/** + * bound colour map + * initialize with two arrays, bounds and colours, of same size + * bounds must contain numbers between 0 and 1 in rising order, + * last number should be larger than max 'val' + * colours are mapped to slices between bounds (with zero being + * implicit bottom bound) + */ +class BoundColourMap: public ColourMap +{ + Float *bounds; + Colour *colours; +public: + BoundColourMap(Float *abounds, Colour *acolours): + bounds(abounds), colours(acolours) {}; + Colour map(const Float &val) + { + Float *b = bounds; + Colour *c = colours; + while (val > *b) + { + b++; + c++; + } + return *c; + }; +}; + +/** + * general texture mapping + */ +class TextureMap +{ +protected: + Vector3 center; + Float invsize; +public: + TextureMap(const Vector3 &acenter, const Float &size): + center(acenter), invsize(1./size) {}; + virtual void map(const Vector3 &point, Float &u, Float &v) = 0; +}; + +/** + * planar mapping + */ +class PlanarMap: public TextureMap +{ +public: + PlanarMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = p.x*invsize; + v = p.y*invsize; + }; +}; + +/** + * cubic mapping + */ +class CubicMap: public TextureMap +{ +public: + CubicMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + if (fabs(p.x) > fabs(p.y)) + { + if (fabs(p.x) > fabs(p.z)) + { + if (p.x < 0) + u = -p.y; + else + u = p.y; + v = p.z; + } + else + { + if (p.z < 0) + u = -p.x; + else + u = p.x; + v = p.y; + } + } + else + { + if (fabs(p.y) > fabs(p.z)) + { + if (p.y < 0) + u = -p.x; + else + u = p.x; + v = p.z; + } + else + { + if (p.z < 0) + u = -p.x; + else + u = p.x; + v = p.y; + } + } + u = u*invsize; + v = v*invsize; + }; +}; + +/** + * cylindrical mapping + */ +class CylinderMap: public TextureMap +{ +public: + CylinderMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = ( M_PI + atan2(p.z, p.x) ) * invsize; + v = p.y * invsize; + }; +}; + +/** + * spherical mapping + */ +class SphereMap: public TextureMap +{ +public: + SphereMap(const Vector3 &acenter, const Float &size): + TextureMap(acenter, size) {}; + void map(const Vector3 &point, Float &u, Float &v) + { + const Vector3 p = point - center; + u = ( M_PI + atan2(p.z, p.x) ) * invsize; + v = acos(p.y / p.mag()) * invsize; + }; +}; + +/** + * general 2D texture + */ +class Texture2D: public Texture +{ +protected: + TextureMap *map; +public: + Texture2D(TextureMap *amap): map(amap) {}; +}; + +/** + * 2D checkers texture + */ +class CheckersTexture: public Texture2D +{ + ColourMap *colourmap; +public: + CheckersTexture(TextureMap *tmap, ColourMap *cmap): + Texture2D(tmap), colourmap(cmap) {}; + Colour evaluate(const Vector3 &point) + { + Float u,v, val; + map->map(point, u,v); + val = 0.5*(round(u - floor(u)) + round(v - floor(v))); + return colourmap->map(val); + }; +}; + +/** + * 3D perlin cloud texture + */ +class CloudTexture: public Texture +{ + Float detail; + ColourMap *colourmap; +public: + CloudTexture(const Float &adetail, ColourMap *cmap): + detail(adetail), colourmap(cmap) {}; + Colour evaluate(const Vector3 &point) + { + Float sum = 0.0; + for (int i = 1; i < detail; i++) + sum += fabs(perlin(point.x*i, point.y*i, point.z*i))/i; + //Float value = sinf(point.x + sum)/2 + 0.5; + return colourmap->map(sum); + }; +}; + +/** + * material + */ +class Material +{ +public: + Colour colour; + Texture *texture; + Float ambient, diffuse, specular, shininess; // Phong constants + Float reflectivity; // how much reflective is the surface + Float transmissivity, refract_index; // part of light which can be refracted; index of refraction + bool smooth; // triangle smoothing + + Material(const Colour &acolour): colour(acolour), texture(NULL), smooth(false) + { + ambient = 0.2; + diffuse = 0.8; + specular = 0.2; + shininess = 0.5; + reflectivity = 0.2; + transmissivity = 0.0; + refract_index = 1.3; + } + + void setPhong(const Float amb, const Float dif, const Float spec, const Float shin) + { ambient = amb; diffuse = dif; specular = spec; shininess = shin; }; + void setReflectivity(const Float refl) { reflectivity = refl; }; + void setTransmissivity(const Float trans, const Float rindex) + { transmissivity = trans; refract_index = rindex; }; + void setSmooth(bool sm) { smooth = sm; }; +}; + +#endif