1 /* |
|
2 * C++ RayTracer |
|
3 * file: scene.h |
|
4 * |
|
5 * Radek Brich, 2006 |
|
6 */ |
|
7 |
|
8 #ifndef SCENE_H |
|
9 #define SCENE_H |
|
10 |
|
11 #include <vector> |
|
12 |
|
13 #include "noise.h" |
|
14 |
|
15 #include "vector.h" |
|
16 |
|
17 using namespace std; |
|
18 |
|
19 class Ray |
|
20 { |
|
21 public: |
|
22 Vector3 o, dir; |
|
23 Ray(const Vector3 &ao, const Vector3 &adir): |
|
24 o(ao), dir(adir) {}; |
|
25 }; |
|
26 |
|
27 class Quaternion |
|
28 { |
|
29 public: |
|
30 float a,b,c,d; |
|
31 Quaternion(): a(0), b(0), c(0), d(0) {}; |
|
32 Quaternion(const float aa, const float ab, const float ac, const float ad): |
|
33 a(aa), b(ab), c(ac), d(ad) {}; |
|
34 Quaternion(const Vector3& v): a(1), b(v.x), c(v.y), d(v.z) {}; |
|
35 |
|
36 Vector3 toVector() { return Vector3(b/a, c/a, d/a); }; |
|
37 |
|
38 Quaternion normalize() |
|
39 { |
|
40 float f = 1.0f / sqrtf(a * a + b * b + c * c + d * d); |
|
41 a *= f; |
|
42 b *= f; |
|
43 c *= f; |
|
44 d *= f; |
|
45 return *this; |
|
46 }; |
|
47 friend Quaternion operator*(const Quaternion &q1, const Quaternion &q2) |
|
48 { |
|
49 return Quaternion( |
|
50 q1.a*q2.a - q1.b*q2.b - q1.c*q2.c - q1.d*q2.d, |
|
51 q1.a*q2.b + q1.b*q2.a + q1.c*q2.d - q1.d*q2.c, |
|
52 q1.a*q2.c + q1.c*q2.a + q1.d*q2.b - q1.b*q2.d, |
|
53 q1.a*q2.d + q1.d*q2.a + q1.b*q2.c - q1.c*q2.b); |
|
54 }; |
|
55 friend Quaternion conjugate(const Quaternion &q) |
|
56 { |
|
57 return Quaternion(q.a, -q.b, -q.c, -q.d); |
|
58 } |
|
59 }; |
|
60 |
|
61 class Camera |
|
62 { |
|
63 public: |
|
64 Vector3 eye, p, u, v; |
|
65 float f; |
|
66 |
|
67 Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), f(3.14/4.0) {}; |
|
68 Camera(const Vector3 &C, const Vector3 &ap, const Vector3 &au, const Vector3 &av): |
|
69 eye(C), p(ap), u(au), v(av), f(3.14/4.0) {}; |
|
70 void setEye(const Vector3 &aeye) { eye = aeye; }; |
|
71 void setFocalLength(const float af) { f = af; }; |
|
72 void rotate(const Quaternion &q); |
|
73 void move(const float fw, const float left, const float up); |
|
74 }; |
|
75 |
|
76 /* axis-aligned bounding box */ |
|
77 class BBox |
|
78 { |
|
79 public: |
|
80 Vector3 L; |
|
81 Vector3 H; |
|
82 BBox(): L(), H() {}; |
|
83 BBox(const Vector3 aL, const Vector3 aH): L(aL), H(aH) {}; |
|
84 float w() { return H.x-L.x; }; |
|
85 float h() { return H.y-L.y; }; |
|
86 float d() { return H.z-L.z; }; |
|
87 bool intersect(const Ray &ray, float &a, float &b); |
|
88 }; |
|
89 |
|
90 class Light |
|
91 { |
|
92 public: |
|
93 Vector3 pos; |
|
94 Colour colour; |
|
95 bool cast_shadows; |
|
96 |
|
97 Light(const Vector3 &position, const Colour &acolour): |
|
98 pos(position), colour(acolour), cast_shadows(true) {}; |
|
99 void castShadows(bool cast) { cast_shadows = cast; }; |
|
100 }; |
|
101 |
|
102 class Texture |
|
103 { |
|
104 public: |
|
105 Colour colour; |
|
106 Colour evaluate(Vector3 point) |
|
107 { |
|
108 float sum = 0.0; |
|
109 for (int i = 1; i < 5; i++) |
|
110 sum += fabsf(perlin(point.x*i, point.y*i, point.z*i))/i; |
|
111 float value = sinf(point.x + sum)/2 + 0.5; |
|
112 return Colour(value*colour.r, value*colour.g, value*colour.b); |
|
113 }; |
|
114 }; |
|
115 |
|
116 class Material |
|
117 { |
|
118 public: |
|
119 float ambient, diffuse, specular, shininess; // Phong constants |
|
120 float reflection; // how much reflectife is the surface |
|
121 float refraction; // refraction index |
|
122 float transmitivity; |
|
123 Texture texture; |
|
124 |
|
125 Material(const Colour &acolour) { |
|
126 texture.colour = acolour; |
|
127 ambient = 0.1; |
|
128 diffuse = 0.5; |
|
129 specular = 0.1; |
|
130 shininess = 0.5; |
|
131 reflection = 0.5; |
|
132 } |
|
133 }; |
|
134 |
|
135 class Shape |
|
136 { |
|
137 public: |
|
138 Material *material; |
|
139 Shape() {}; |
|
140 virtual ~Shape() {}; |
|
141 |
|
142 // first intersection point |
|
143 virtual bool intersect(const Ray &ray, float &dist) = 0; |
|
144 |
|
145 // all intersections (only for CSG) |
|
146 virtual bool intersect_all(const Ray &ray, float dist, vector<float> &allts) = 0; |
|
147 |
|
148 // normal at point P |
|
149 virtual Vector3 normal(Vector3 &P) = 0; |
|
150 |
|
151 virtual BBox get_bbox() = 0; |
|
152 }; |
|
153 |
|
154 class Sphere: public Shape |
|
155 { |
|
156 float sqr_radius; |
|
157 float inv_radius; |
|
158 public: |
|
159 Vector3 center; |
|
160 float radius; |
|
161 |
|
162 Sphere(const Vector3 &acenter, const float aradius, Material *amaterial): |
|
163 sqr_radius(aradius*aradius), inv_radius(1.0f/aradius), |
|
164 center(acenter), radius(aradius) { material = amaterial; } |
|
165 bool intersect(const Ray &ray, float &dist); |
|
166 bool intersect_all(const Ray &ray, float dist, vector<float> &allts); |
|
167 Vector3 normal(Vector3 &P) { return (P - center) * inv_radius; }; |
|
168 BBox get_bbox(); |
|
169 }; |
|
170 |
|
171 class Box: public Shape |
|
172 { |
|
173 Vector3 L; |
|
174 Vector3 H; |
|
175 public: |
|
176 Box(const Vector3 &aL, const Vector3 &aH, Material *amaterial): L(aL), H(aH) |
|
177 { |
|
178 for (int i = 0; i < 3; i++) |
|
179 if (L.cell[i] > H.cell[i]) |
|
180 swap(L.cell[i], H.cell[i]); |
|
181 material = amaterial; |
|
182 }; |
|
183 bool intersect(const Ray &ray, float &dist); |
|
184 bool intersect_all(const Ray &ray, float dist, vector<float> &allts) {return false;}; |
|
185 Vector3 normal(Vector3 &P); |
|
186 BBox get_bbox() { return BBox(L, H); }; |
|
187 }; |
|
188 |
|
189 class Triangle: public Shape |
|
190 { |
|
191 int k; // dominant axis |
|
192 float nu, nv, nd; |
|
193 float bnu, bnv; |
|
194 float cnu, cnv; |
|
195 public: |
|
196 Vector3 A, B, C, N; |
|
197 |
|
198 Triangle(const Vector3 &aA, const Vector3 &aB, const Vector3 &aC, Material *amaterial); |
|
199 bool intersect(const Ray &ray, float &dist); |
|
200 bool intersect_all(const Ray &ray, float dist, vector<float> &allts) {return false;}; |
|
201 Vector3 normal(Vector3 &) { return N; }; |
|
202 BBox get_bbox(); |
|
203 }; |
|
204 |
|
205 #endif |
|