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