1 #ifndef PROCEDURALWOOD_HXX
  2 #define PROCEDURALWOOD_HXX
  3 
  4 #include "Procedural.hxx"
  5 #include "Noise.hxx"
  6 
  7 // Our first real procedural: Combined texturing and bumpmapping of a wooden structure.
  8 // Is used to create Woodentiles afterwards.
  9 class ProceduralWood : public Procedural
 10 {
 11 private:
 12 	Noise *noise;
 13 
 14 	Vec3f TrunkLocation,  // Origin of rings
 15 	      GrainDir;       // Vector through middles of rings
 16 	float RingWidth,      // Distance from one ring to another
 17 	      Weight,         // Intensity of bump mapping
 18 	      Chaos;          // Distortion weight
 19 	Vec3f LightColor,     // Light color in shading
 20 	      DarkColor;      // Dark  color in shading
 21 
 22 	float Wood(Vec3f position, float disturbation, float widthfactor, bool &falling, Vec3f &distance)
 23 	{
 24 		// Perform a Cylinder intersection
 25 		distance  = TrunkLocation - position;
 26 
 27 		distance       -= Dot(distance, GrainDir) * GrainDir;
 28 
 29 		// Calculate the radius the 'Position' point is on and disturb it,
 30 		// thus creating concentrical randomized circles
 31 		float Radius    = Length(distance) / RingWidth + Chaos * (disturbation - 0.5);
 32 
 33 		// Calculate the grey level
 34 		Radius -= floor(Radius);
 35 
 36 		float value;
 37 
 38 		if (Radius <= 0.7)
 39 		{
 40 			value   = Radius * 10.0f / 7.0f;
 41 			falling = false;
 42 		}
 43 		else
 44 		{
 45 			value   = (1 - Radius) * 10.0f / 3.0f;
 46 			falling = true;
 47 		}
 48 
 49 		// Disturb the value itself again to vary the width of the rings
 50 		// (applied weighted with widthfactor)
 51 		value = MAX(MIN(value + widthfactor * (disturbation - 0.5f), 1.0f), 0.0f);
 52 
 53 		return value;
 54 	}
 55 
 56 	Vec3f ToColor(float value)
 57 	{
 58 		return value * (LightColor - DarkColor) + DarkColor;
 59 	}
 60 
 61 public:
 62 	ProceduralWood(bool useTexture,     bool useBumpMap,
 63 	               Vec3f TrunkLocation, Vec3f GrainDir, float RingWidth, float Weight, float Chaos = 1.0,
 64 	               Vec3f LightColor = Vec3f(0.55,0.30,0.15), Vec3f DarkColor = Vec3f(0.75,0.45,0.20))
 65 		: Procedural(useTexture, useBumpMap, true, true),
 66 		  TrunkLocation(TrunkLocation), GrainDir(GrainDir), RingWidth(RingWidth), Weight(Weight), Chaos(Chaos),
 67 		  LightColor(LightColor), DarkColor(DarkColor)
 68 	{
 69 		Normalize(GrainDir);
 70 
 71 		noise = new Noise(Vec3f(64));
 72 	};
 73 
 74 	virtual ~ProceduralWood()
 75 	{
 76 		delete noise;
 77 	};
 78 
 79 	virtual Vec3f GetColor (Vec3f coordinate)
 80 	{
 81 		// These additional parameters are not needed for shading, but below for bumpmapping
 82 		bool  falling;
 83 		Vec3f distance;
 84 
 85 		return ToColor(Wood(coordinate, noise->Turbulence(coordinate, 0.01f), 0.3f, falling, distance));
 86 	};
 87 
 88 	virtual void BumpMap(Vec3f &normal, Vec3f coordinate)
 89 	{
 90 		bool  falling;
 91 		Vec3f distance;
 92 
 93 		float modification = Weight * sin(M_PI * Wood(coordinate, noise->Turbulence(coordinate, 0.01f), 0.3f, falling, distance)) * (-falling);
 94 
 95 		Normalize(distance);
 96 
 97 		normal = distance * modification + normal;
 98 		Normalize(normal);
 99 	};
100 };
101 
102 #endif


syntax highlighted by Code2HTML, v. 0.9.1