material and texture classes moved to material.(cc,h)
2D texture mappings from textures.cc polished and moved to material.h
add ColourMap class and subclasses to make textures more flexible
two example textures: CheckersTexture and CloudTexture (using Perlin noise)
--- a/TODO	Wed Apr 23 10:38:33 2008 +0200
+++ b/TODO	Wed Apr 23 14:39:33 2008 +0200
@@ -4,7 +4,7 @@
 
 Future Plans
 ============
- * textures (3D procedural, pixmaps)
+ * pixmap textures
  * generalization: Camera "shader" (ray generator), surface shader and maybe light & background shaders
  * namespace
  * Python binding for all classes
--- a/ccdemos/textures.cc	Wed Apr 23 10:38:33 2008 +0200
+++ b/ccdemos/textures.cc	Wed Apr 23 14:39:33 2008 +0200
@@ -9,137 +9,6 @@
 
 Float lx, ly, lz, cf;
 
-
-/*class CloudTexture: public Texture
-{
-	Vector3 centre;
-public:
-	Colour evaluate(Vector3 point)
-	{
-		Float sum = 0.0;
-		for (int i = 1; i < 5; i++)
-			sum += fabsf(perlin(point.x*i, point.y*i, point.z*i))/i;
-		Float value = sinf(point.x + sum)/2 + 0.5;
-		return Colour(value, value*0.5, value*0.5);
-	};
-};*/
-
-void texture2D(Float u, Float v, Float &r, Float &g, Float &b)
-{
-	// checkers
-	r = fabs((int)(u*4.2)%2 + (int)(v*4.2)%2 - 1);
-	g=r; b=r;
-}
-
-class PlanarMapTexture: public Texture
-{
-	Vector3 centre;
-public:
-	PlanarMapTexture(Vector3 acentre): centre(acentre) {};
-	Colour evaluate(Vector3 point)
-	{
-		point = point - centre;
-		Float u = 1000+point.x;
-		Float v = 1000+point.y;
-		Float r,g,b;
-		texture2D(u,v, r,g,b);
-		return Colour(r, g, b);
-	};
-};
-
-class CubicMapTexture: public Texture
-{
-	Vector3 centre;
-public:
-	CubicMapTexture(Vector3 acentre): centre(acentre) {};
-	Colour evaluate(Vector3 point)
-	{
-		point = point - centre;
-		Float u,v;
-		if (fabs(point.x) > fabs(point.y))
-		{
-			if (fabs(point.x) > fabs(point.z))
-			{
-				if (point.x < 0)
-					u = -point.y;
-				else
-					u = point.y;
-				v = point.z;
-			}
-			else
-			{
-				if (point.z < 0)
-					u = -point.x;
-				else
-					u = point.x;
-				v = point.y;
-			}
-		}
-		else
-		{
-			if (fabs(point.y) > fabs(point.z))
-			{
-				if (point.y < 0)
-					u = -point.x;
-				else
-					u = point.x;
-				v = point.z;
-			}
-			else
-			{
-				if (point.z < 0)
-					u = -point.x;
-				else
-					u = point.x;
-				v = point.y;
-			}
-		}
-		u += 1000;
-		v += 1000;
-		Float r,g,b;
-		texture2D(u,v, r,g,b);
-		return Colour(r, g, b);
-	};
-};
-
-class CylinderMapTexture: public Texture
-{
-	Vector3 centre;
-public:
-	CylinderMapTexture(Vector3 acentre): centre(acentre) {};
-	Colour evaluate(Vector3 point)
-	{
-		point = point - centre;
-
-		Float u,v;
-		v = 1000+point.y;
-		u = M_PI + atan2(point.z, point.x);
-
-		Float r,g,b;
-		texture2D(u,v, r,g,b);
-		return Colour(r, g, b);
-	};
-};
-
-class SphereMapTexture: public Texture
-{
-	Vector3 centre;
-public:
-	SphereMapTexture(Vector3 acentre): centre(acentre) {};
-	Colour evaluate(Vector3 point)
-	{
-		point = point - centre;
-
-		Float u,v;
-		v = acos(point.y / point.mag());
-		u = M_PI + atan2(point.z, point.x);
-
-		Float r,g,b;
-		texture2D(u,v, r,g,b);
-		return Colour(r, g, b);
-	};
-};
-
 void update_callback()
 {
 	if (lx != 0.0)
@@ -196,7 +65,7 @@
 	light.castShadows(false);
 
 	Material mat0a(Colour(0.7, 0.7, 0.7));
-	mat0a. setReflectivity(0.0);
+	mat0a.setReflectivity(0.0);
 	Box box(Vector3(-12.0, -1.2, -20.0), Vector3(12.0, -1.0, 0.0), &mat0a);
 	rt.addShape(&box);
 
@@ -205,45 +74,49 @@
 	Box box2(Vector3(-12.0, -1.2, -10.0), Vector3(12.0, 10.0, -10.2), &mat0b);
 	rt.addShape(&box2);
 
+	Float bounds[] = {0.3, 0.6, 1.1};
+	Colour colours[] = {Colour(0,0,0), Colour(1,1,1), Colour(0,0,0)};
+	BoundColourMap cmap(bounds, colours);
+
 	// spheres
 	Material mat1(Colour(1.0, 1.0, 1.0));
-	mat1.texture = new PlanarMapTexture(Vector3(-4.5, 2.0, -7.0));
+	mat1.texture = new CheckersTexture(new PlanarMap(Vector3(-4.5, 2.0, -7.0), 0.48), &cmap);
 	Sphere sphere1(Vector3(-4.5, 2.0, -7.0), 1.0, &mat1);
 	rt.addShape(&sphere1);
 
 	Material mat2(Colour(1.0, 1.0, 1.0));
-	mat2.texture = new CubicMapTexture(Vector3(-1.5, 2.0, -7.0));
+	mat2.texture = new CheckersTexture(new CubicMap(Vector3(-1.5, 2.0, -7.0), 0.48), &cmap);
 	Sphere sphere2(Vector3(-1.5, 2.0, -7.0), 1.0, &mat2);
 	rt.addShape(&sphere2);
 
 	Material mat3(Colour(1.0, 1.0, 1.0));
-	mat3.texture = new CylinderMapTexture(Vector3(1.5, 2.0, -7.0));
+	mat3.texture = new CheckersTexture(new CylinderMap(Vector3(1.5, 2.0, -7.0), 0.48), &cmap);
 	Sphere sphere3(Vector3(1.5, 2.0, -7.0), 1.0, &mat3);
 	rt.addShape(&sphere3);
 
 	Material mat4(Colour(1.0, 1.0, 1.0));
-	mat4.texture = new SphereMapTexture(Vector3(4.5, 2.0, -7.0));
+	mat4.texture = new CheckersTexture(new SphereMap(Vector3(4.5, 2.0, -7.0), 0.48), &cmap);
 	Sphere sphere4(Vector3(4.5, 2.0, -7.0), 1.0, &mat4);
 	rt.addShape(&sphere4);
 
 	// cubes
 	Material mat5(Colour(1.0, 1.0, 1.0));
-	mat5.texture = new PlanarMapTexture(Vector3(-4.5, 0.0, -7.0));
+	mat5.texture = new CheckersTexture(new PlanarMap(Vector3(-4.5, 0.0, -7.0), 0.48), &cmap);
 	Box cube1(Vector3(-4.5, 0.0, -7.0)-1.0, Vector3(-4.5, 0.0, -7.0)+1.0, &mat5);
 	rt.addShape(&cube1);
 
 	Material mat6(Colour(1.0, 1.0, 1.0));
-	mat6.texture = new CubicMapTexture(Vector3(-1.5, 0.0, -7.0));
+	mat6.texture = new CheckersTexture(new CubicMap(Vector3(-1.5, 0.0, -7.0), 0.48), &cmap);
 	Box cube2(Vector3(-1.5, 0.0, -7.0)-1.0, Vector3(-1.5, 0.0, -7.0)+1.0, &mat6);
 	rt.addShape(&cube2);
 
 	Material mat7(Colour(1.0, 1.0, 1.0));
-	mat7.texture = new CylinderMapTexture(Vector3(1.5, 0.0, -7.0));
+	mat7.texture = new CheckersTexture(new CylinderMap(Vector3(1.5, 0.0, -7.0), 0.48), &cmap);
 	Box cube3(Vector3(1.5, 0.0, -7.0)-1.0, Vector3(1.5, 0.0, -7.0)+1.0, &mat7);
 	rt.addShape(&cube3);
 
 	Material mat8(Colour(1.0, 1.0, 1.0));
-	mat8.texture = new SphereMapTexture(Vector3(4.5, 0.0, -7.0));
+	mat8.texture = new CheckersTexture(new SphereMap(Vector3(4.5, 0.0, -7.0), 0.48), &cmap);
 	Box cube4(Vector3(4.5, 0.0, -7.0)-1.0, Vector3(4.5, 0.0, -7.0)+1.0, &mat8);
 	rt.addShape(&cube4);
 
--- /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
--- a/include/noise.h	Wed Apr 23 10:38:33 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * noise.h: noise generators
- *
- * This file is part of Pyrit Ray Tracer.
- *
- * Copyright 2006  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 NOISE_H
-#define NOISE_H
-
-#include "common.h"
-
-/**
- * Perlin noise generator
- */
-Float perlin(Float x, Float y, Float z);
-
-#endif
--- a/include/scene.h	Wed Apr 23 10:38:33 2008 +0200
+++ b/include/scene.h	Wed Apr 23 14:39:33 2008 +0200
@@ -81,22 +81,6 @@
 };
 
 /**
- * axis-aligned bounding box
- */
-class BBox
-{
-public:
-	Vector3 L;
-	Vector3 H;
-	BBox(): L(), H() {};
-	BBox(const Vector3 aL, const Vector3 aH): L(aL), H(aH) {};
-	Float w() { return H.x-L.x; };
-	Float h() { return H.y-L.y; };
-	Float d() { return H.z-L.z; };
-	bool intersect(const Ray &ray, Float &a, Float &b);
-};
-
-/**
  * light object
  */
 class Light
@@ -114,45 +98,19 @@
 };
 
 /**
- * texture
+ * axis-aligned bounding box
  */
-class Texture
-{
-public:
-	virtual ~Texture() {};
-	virtual Colour evaluate(Vector3 point) = 0;
-};
-
-/**
- * material
- */
-class Material
+class BBox
 {
 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; };
+	Vector3 L;
+	Vector3 H;
+	BBox(): L(), H() {};
+	BBox(const Vector3 aL, const Vector3 aH): L(aL), H(aH) {};
+	Float w() { return H.x-L.x; };
+	Float h() { return H.y-L.y; };
+	Float d() { return H.z-L.z; };
+	bool intersect(const Ray &ray, Float &a, Float &b);
 };
 
 #endif
--- a/include/shapes.h	Wed Apr 23 10:38:33 2008 +0200
+++ b/include/shapes.h	Wed Apr 23 14:39:33 2008 +0200
@@ -29,6 +29,7 @@
 
 #include "common.h"
 #include "scene.h"
+#include "material.h"
 
 /*
 triangle intersection alghoritm
--- a/src/SConscript	Wed Apr 23 10:38:33 2008 +0200
+++ b/src/SConscript	Wed Apr 23 14:39:33 2008 +0200
@@ -17,7 +17,7 @@
 
 sources = [
 	'raytracer.cc', 'scene.cc', 'shapes.cc', 'sampler.cc',
-	'container.cc', 'kdtree.cc', 'octree.cc', 'noise.cc',
+	'container.cc', 'kdtree.cc', 'octree.cc', 'material.cc',
 	'serialize.cc']
 
 objs = []
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/material.cc	Wed Apr 23 14:39:33 2008 +0200
@@ -0,0 +1,108 @@
+/*
+ * material.cc: material and texture classes
+ *
+ * This file is part of Pyrit Ray Tracer.
+ *
+ * Copyright 2006, 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.
+ */
+
+#include <math.h>
+
+#include "material.h"
+
+/**
+ * Perlin noise
+ * Based on JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE by KEN PERLIN (COPYRIGHT 2002)
+ */
+
+Float fade(Float t)
+{
+	return t * t * t * (t * (t * 6 - 15) + 10);
+}
+
+Float lerp(Float t, Float a, Float b)
+{
+	return a + t * (b - a);
+}
+
+Float grad(unsigned char hash, Float x, Float y, Float z)
+{
+	unsigned char h = hash & 15;            // CONVERT LO 4 BITS OF HASH CODE
+	Float	u = h<8 ? x : y,                 // INTO 12 GRADIENT DIRECTIONS.
+			v = h<4 ? y : h==12||h==14 ? x : z;
+	return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
+}
+
+const unsigned char p[512] =
+{
+	151,160,137,91,90,15,
+	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
+	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
+	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
+	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
+	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
+	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
+	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
+	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
+	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
+	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
+	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
+	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
+
+	151,160,137,91,90,15,
+	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
+	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
+	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
+	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
+	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
+	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
+	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
+	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
+	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
+	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
+	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
+	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
+};
+
+
+Float perlin(Float x, Float y, Float z)
+{
+	int	X = (int)floor(x) & 255,
+		Y = (int)floor(y) & 255,
+		Z = (int)floor(z) & 255;
+	x -= floor(x);
+	y -= floor(y);
+	z -= floor(z);
+	Float	u = fade(x),
+			v = fade(y),
+			w = fade(z);
+	int	A = p[X  ]+Y, AA = p[A]+Z, AB = p[A+1]+Z,
+		B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z;
+
+	return	lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),
+									grad(p[BA  ], x-1, y  , z   )),
+							lerp(u, grad(p[AB  ], x  , y-1, z   ),
+									grad(p[BB  ], x-1, y-1, z   ))),
+					lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),
+									grad(p[BA+1], x-1, y  , z-1 )),
+							lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
+									grad(p[BB+1], x-1, y-1, z-1 ))));
+}
--- a/src/noise.cc	Wed Apr 23 10:38:33 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * noise.cc: noise generators
- *
- * This file is part of Pyrit Ray Tracer.
- *
- * Copyright 2006, 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.
- */
-
-#include <math.h>
-
-#include "noise.h"
-
-/*
-Perlin noise
-Based on JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE by KEN PERLIN (COPYRIGHT 2002)
-*/
-
-Float fade(Float t)
-{
-	return t * t * t * (t * (t * 6 - 15) + 10);
-}
-
-Float lerp(Float t, Float a, Float b)
-{
-	return a + t * (b - a);
-}
-
-Float grad(unsigned char hash, Float x, Float y, Float z)
-{
-	unsigned char h = hash & 15;            // CONVERT LO 4 BITS OF HASH CODE
-	Float	u = h<8 ? x : y,                 // INTO 12 GRADIENT DIRECTIONS.
-			v = h<4 ? y : h==12||h==14 ? x : z;
-	return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
-}
-
-const unsigned char p[512] =
-{
-	151,160,137,91,90,15,
-	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
-	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
-	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
-	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
-	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
-	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
-	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
-	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
-	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
-	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
-	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
-	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
-
-	151,160,137,91,90,15,
-	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
-	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
-	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
-	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
-	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
-	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
-	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
-	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
-	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
-	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
-	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
-	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
-};
-
-
-Float perlin(Float x, Float y, Float z)
-{
-	int	X = (int)floor(x) & 255,
-		Y = (int)floor(y) & 255,
-		Z = (int)floor(z) & 255;
-	x -= floor(x);
-	y -= floor(y);
-	z -= floor(z);
-	Float	u = fade(x),
-			v = fade(y),
-			w = fade(z);
-	int	A = p[X  ]+Y, AA = p[A]+Z, AB = p[A+1]+Z,
-		B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z;
-
-	return	lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),
-									grad(p[BA  ], x-1, y  , z   )),
-							lerp(u, grad(p[AB  ], x  , y-1, z   ),
-									grad(p[BB  ], x-1, y-1, z   ))),
-					lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),
-									grad(p[BA+1], x-1, y  , z-1 )),
-							lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
-									grad(p[BB+1], x-1, y-1, z-1 ))));
-}