include/material.h
branchpyrit
changeset 79 062b1c4143f7
child 80 907929fa9b59
equal deleted inserted replaced
78:9569e9f35374 79:062b1c4143f7
       
     1 /*
       
     2  * material.h: material and texture classes
       
     3  *
       
     4  * This file is part of Pyrit Ray Tracer.
       
     5  *
       
     6  * Copyright 2006, 2007, 2008  Radek Brich
       
     7  *
       
     8  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     9  * of this software and associated documentation files (the "Software"), to deal
       
    10  * in the Software without restriction, including without limitation the rights
       
    11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    12  * copies of the Software, and to permit persons to whom the Software is
       
    13  * furnished to do so, subject to the following conditions:
       
    14  *
       
    15  * The above copyright notice and this permission notice shall be included in
       
    16  * all copies or substantial portions of the Software.
       
    17  *
       
    18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    24  * THE SOFTWARE.
       
    25  */
       
    26 
       
    27 #ifndef MATERIAL_H
       
    28 #define MATERIAL_H
       
    29 
       
    30 #include "common.h"
       
    31 #include "vector.h"
       
    32 #include "noise.h"
       
    33 
       
    34 /**
       
    35  * perlin noise
       
    36  */
       
    37 Float perlin(Float x, Float y, Float z);
       
    38 
       
    39 /**
       
    40  * general texture
       
    41  */
       
    42 class Texture
       
    43 {
       
    44 public:
       
    45 	virtual ~Texture() {};
       
    46 	virtual Colour evaluate(const Vector3 &point) = 0;
       
    47 };
       
    48 
       
    49 /**
       
    50  * general colour map
       
    51  */
       
    52 class ColourMap
       
    53 {
       
    54 public:
       
    55 	virtual Colour map(const Float &val) = 0;
       
    56 };
       
    57 
       
    58 /**
       
    59  * linear colour map
       
    60  * maps value lineary between two colours
       
    61  */
       
    62 class LinearColourMap: public ColourMap
       
    63 {
       
    64 	Colour col,cdiff;
       
    65 public:
       
    66 	LinearColourMap(const Colour &clow, const Colour &chigh):
       
    67 		col(clow), cdiff(chigh-clow) {};
       
    68 	Colour map(const Float &val) { return col + cdiff*val; };
       
    69 };
       
    70 
       
    71 /**
       
    72  * bound colour map
       
    73  * initialize with two arrays, bounds and colours, of same size
       
    74  * bounds must contain numbers between 0 and 1 in rising order,
       
    75  * last number should be larger than max 'val'
       
    76  * colours are mapped to slices between bounds (with zero being
       
    77  * implicit bottom bound)
       
    78  */
       
    79 class BoundColourMap: public ColourMap
       
    80 {
       
    81 	Float *bounds;
       
    82 	Colour *colours;
       
    83 public:
       
    84 	BoundColourMap(Float *abounds, Colour *acolours):
       
    85 		bounds(abounds), colours(acolours) {};
       
    86 	Colour map(const Float &val)
       
    87 	{
       
    88 		Float *b = bounds;
       
    89 		Colour *c = colours;
       
    90 		while (val > *b)
       
    91 		{
       
    92 			b++;
       
    93 			c++;
       
    94 		}
       
    95 		return *c;
       
    96 	};
       
    97 };
       
    98 
       
    99 /**
       
   100  * general texture mapping
       
   101  */
       
   102 class TextureMap
       
   103 {
       
   104 protected:
       
   105 	Vector3 center;
       
   106 	Float invsize;
       
   107 public:
       
   108 	TextureMap(const Vector3 &acenter, const Float &size):
       
   109 		center(acenter), invsize(1./size) {};
       
   110 	virtual void map(const Vector3 &point, Float &u, Float &v) = 0;
       
   111 };
       
   112 
       
   113 /**
       
   114  * planar mapping
       
   115  */
       
   116 class PlanarMap: public TextureMap
       
   117 {
       
   118 public:
       
   119 	PlanarMap(const Vector3 &acenter, const Float &size):
       
   120 		TextureMap(acenter, size) {};
       
   121 	void map(const Vector3 &point, Float &u, Float &v)
       
   122 	{
       
   123 		const Vector3 p = point - center;
       
   124 		u = p.x*invsize;
       
   125 		v = p.y*invsize;
       
   126 	};
       
   127 };
       
   128 
       
   129 /**
       
   130  * cubic mapping
       
   131  */
       
   132 class CubicMap: public TextureMap
       
   133 {
       
   134 public:
       
   135 	CubicMap(const Vector3 &acenter, const Float &size):
       
   136 		TextureMap(acenter, size) {};
       
   137 	void map(const Vector3 &point, Float &u, Float &v)
       
   138 	{
       
   139 		const Vector3 p = point - center;
       
   140 		if (fabs(p.x) > fabs(p.y))
       
   141 		{
       
   142 			if (fabs(p.x) > fabs(p.z))
       
   143 			{
       
   144 				if (p.x < 0)
       
   145 					u = -p.y;
       
   146 				else
       
   147 					u = p.y;
       
   148 				v = p.z;
       
   149 			}
       
   150 			else
       
   151 			{
       
   152 				if (p.z < 0)
       
   153 					u = -p.x;
       
   154 				else
       
   155 					u = p.x;
       
   156 				v = p.y;
       
   157 			}
       
   158 		}
       
   159 		else
       
   160 		{
       
   161 			if (fabs(p.y) > fabs(p.z))
       
   162 			{
       
   163 				if (p.y < 0)
       
   164 					u = -p.x;
       
   165 				else
       
   166 					u = p.x;
       
   167 				v = p.z;
       
   168 			}
       
   169 			else
       
   170 			{
       
   171 				if (p.z < 0)
       
   172 					u = -p.x;
       
   173 				else
       
   174 					u = p.x;
       
   175 				v = p.y;
       
   176 			}
       
   177 		}
       
   178 		u = u*invsize;
       
   179 		v = v*invsize;
       
   180 	};
       
   181 };
       
   182 
       
   183 /**
       
   184  * cylindrical mapping
       
   185  */
       
   186 class CylinderMap: public TextureMap
       
   187 {
       
   188 public:
       
   189 	CylinderMap(const Vector3 &acenter, const Float &size):
       
   190 		TextureMap(acenter, size) {};
       
   191 	void map(const Vector3 &point, Float &u, Float &v)
       
   192 	{
       
   193 		const Vector3 p = point - center;
       
   194 		u = ( M_PI + atan2(p.z, p.x) ) * invsize;
       
   195 		v = p.y * invsize;
       
   196 	};
       
   197 };
       
   198 
       
   199 /**
       
   200  * spherical mapping
       
   201  */
       
   202 class SphereMap: public TextureMap
       
   203 {
       
   204 public:
       
   205 	SphereMap(const Vector3 &acenter, const Float &size):
       
   206 		TextureMap(acenter, size) {};
       
   207 	void map(const Vector3 &point, Float &u, Float &v)
       
   208 	{
       
   209 		const Vector3 p = point - center;
       
   210 		u = ( M_PI + atan2(p.z, p.x) ) * invsize;
       
   211 		v = acos(p.y / p.mag()) * invsize;
       
   212 	};
       
   213 };
       
   214 
       
   215 /**
       
   216  * general 2D texture
       
   217  */
       
   218 class Texture2D: public Texture
       
   219 {
       
   220 protected:
       
   221 	TextureMap *map;
       
   222 public:
       
   223 	Texture2D(TextureMap *amap): map(amap) {};
       
   224 };
       
   225 
       
   226 /**
       
   227  * 2D checkers texture
       
   228  */
       
   229 class CheckersTexture: public Texture2D
       
   230 {
       
   231 	ColourMap *colourmap;
       
   232 public:
       
   233 	CheckersTexture(TextureMap *tmap, ColourMap *cmap):
       
   234 		Texture2D(tmap), colourmap(cmap) {};
       
   235 	Colour evaluate(const Vector3 &point)
       
   236 	{
       
   237 		Float u,v, val;
       
   238 		map->map(point, u,v);
       
   239 		val = 0.5*(round(u - floor(u)) + round(v - floor(v)));
       
   240 		return colourmap->map(val);
       
   241 	};
       
   242 };
       
   243 
       
   244 /**
       
   245  * 3D perlin cloud texture
       
   246  */
       
   247 class CloudTexture: public Texture
       
   248 {
       
   249 	Float detail;
       
   250 	ColourMap *colourmap;
       
   251 public:
       
   252 	CloudTexture(const Float &adetail, ColourMap *cmap):
       
   253 		detail(adetail), colourmap(cmap) {};
       
   254 	Colour evaluate(const Vector3 &point)
       
   255 	{
       
   256 		Float sum = 0.0;
       
   257 		for (int i = 1; i < detail; i++)
       
   258 			sum += fabs(perlin(point.x*i, point.y*i, point.z*i))/i;
       
   259 		//Float value = sinf(point.x + sum)/2 + 0.5;
       
   260 		return colourmap->map(sum);
       
   261 	};
       
   262 };
       
   263 
       
   264 /**
       
   265  * material
       
   266  */
       
   267 class Material
       
   268 {
       
   269 public:
       
   270 	Colour colour;
       
   271 	Texture *texture;
       
   272 	Float ambient, diffuse, specular, shininess; // Phong constants
       
   273 	Float reflectivity; // how much reflective is the surface
       
   274 	Float transmissivity, refract_index; // part of light which can be refracted; index of refraction
       
   275 	bool smooth; // triangle smoothing
       
   276 
       
   277 	Material(const Colour &acolour): colour(acolour), texture(NULL), smooth(false)
       
   278 	{
       
   279 		ambient = 0.2;
       
   280 		diffuse = 0.8;
       
   281 		specular = 0.2;
       
   282 		shininess = 0.5;
       
   283 		reflectivity = 0.2;
       
   284 		transmissivity = 0.0;
       
   285 		refract_index = 1.3;
       
   286 	}
       
   287 
       
   288 	void setPhong(const Float amb, const Float dif, const Float spec, const Float shin)
       
   289 		{ ambient = amb; diffuse = dif; specular = spec; shininess = shin; };
       
   290 	void setReflectivity(const Float refl) { reflectivity = refl; };
       
   291 	void setTransmissivity(const Float trans, const Float rindex)
       
   292 		{ transmissivity = trans; refract_index = rindex; };
       
   293 	void setSmooth(bool sm) { smooth = sm; };
       
   294 };
       
   295 
       
   296 #endif