74 }; |
74 }; |
75 }; |
75 }; |
76 #endif |
76 #endif |
77 |
77 |
78 /** |
78 /** |
79 * General camera |
79 * Standard ray tracing camera |
80 */ |
80 */ |
81 class Camera |
81 class Camera |
82 { |
82 { |
83 Vector eye, p, u, v; |
83 Vector eye, p, u, v; |
84 Float F; |
84 Float F; |
85 public: |
85 public: |
86 Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2*tan(PI/8)) {}; |
86 Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2*tan(PI/8)) {}; |
|
87 |
|
88 /** Position + p,u,v constructor */ |
87 Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): |
89 Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): |
88 eye(C), p(ap), u(au), v(av), F(2*tan(PI/8)) {}; |
90 eye(C), p(ap), u(au), v(av), F(2*tan(PI/8)) {}; |
|
91 |
|
92 /** Look-at constructor */ |
89 Camera(const Vector &from, const Vector &lookat, const Vector &up): |
93 Camera(const Vector &from, const Vector &lookat, const Vector &up): |
90 eye(from), F(2*tan(PI/8)) |
94 eye(from), F(2*tan(PI/8)) |
91 { |
95 { |
92 p = lookat - from; u = cross(up, p); |
96 p = lookat - from; u = cross(up, p); |
93 p.normalize(); u.normalize(); |
97 p.normalize(); u.normalize(); |
102 const Vector &getEye() const { return eye; }; |
106 const Vector &getEye() const { return eye; }; |
103 const Vector &getp() const { return p; }; |
107 const Vector &getp() const { return p; }; |
104 const Vector &getu() const { return u; }; |
108 const Vector &getu() const { return u; }; |
105 const Vector &getv() const { return v; }; |
109 const Vector &getv() const { return v; }; |
106 const Float &getF() const { return F; }; |
110 const Float &getF() const { return F; }; |
|
111 |
107 void setEye(const Vector &aeye) { eye = aeye; }; |
112 void setEye(const Vector &aeye) { eye = aeye; }; |
108 void setp(const Vector &ap) { p = ap; }; |
113 void setp(const Vector &ap) { p = ap; }; |
109 void setu(const Vector &au) { u = au; }; |
114 void setu(const Vector &au) { u = au; }; |
110 void setv(const Vector &av) { v = av; }; |
115 void setv(const Vector &av) { v = av; }; |
|
116 |
|
117 /** set "screen plane" size |
|
118 * @param[in] F height of the screen plane */ |
111 void setF(const Float &aF) { F = aF; }; |
119 void setF(const Float &aF) { F = aF; }; |
|
120 |
|
121 /** set camera's angle of view (in radians) */ |
112 void setAngle(const Float angle) { F = 2*tan(angle/2); }; |
122 void setAngle(const Float angle) { F = 2*tan(angle/2); }; |
|
123 |
|
124 /** rotate camera using a quaternion */ |
113 void rotate(const Quaternion &q); |
125 void rotate(const Quaternion &q); |
|
126 |
|
127 /** translate the camera in its direction |
|
128 * @param[in] fw size of forward step |
|
129 * @param[in] left size of left step |
|
130 * @param[in] up size of up step |
|
131 */ |
114 void move(const Float fw, const Float left, const Float up); |
132 void move(const Float fw, const Float left, const Float up); |
115 |
133 |
|
134 /** make the ray from screen sample according the camera's parameters */ |
116 const Ray makeRay(const Sample &samp) const |
135 const Ray makeRay(const Sample &samp) const |
117 { |
136 { |
118 Vector dir = normalize(p - (u*samp.x + v*samp.y)*F); |
137 Vector dir = normalize(p - (u*samp.x + v*samp.y)*F); |
119 return Ray(eye, dir); |
138 return Ray(eye, dir); |
120 }; |
139 }; |
121 |
140 |
|
141 /** same as makeRay but for ray packet */ |
122 #ifndef NO_SIMD |
142 #ifndef NO_SIMD |
123 void makeRayPacket(const Sample *samples, RayPacket &rays) const |
143 void makeRayPacket(const Sample *samples, RayPacket &rays) const |
124 { |
144 { |
125 mfloat4 m1x,m1y,m1z; |
145 mfloat4 m1x,m1y,m1z; |
126 mfloat4 m2x,m2y,m2z; |
146 mfloat4 m2x,m2y,m2z; |
186 |
206 |
187 Light(): |
207 Light(): |
188 pos(Vector(0,0,0)), colour(Colour(1,1,1)), cast_shadows(true) {}; |
208 pos(Vector(0,0,0)), colour(Colour(1,1,1)), cast_shadows(true) {}; |
189 Light(const Vector &position, const Colour &acolour): |
209 Light(const Vector &position, const Colour &acolour): |
190 pos(position), colour(acolour), cast_shadows(true) {}; |
210 pos(position), colour(acolour), cast_shadows(true) {}; |
|
211 |
|
212 /** allow shadows from this light */ |
191 void castShadows(int cast) { cast_shadows = cast; }; |
213 void castShadows(int cast) { cast_shadows = cast; }; |
192 }; |
214 }; |
193 |
215 |
194 /** |
216 /** |
195 * axis-aligned bounding box |
217 * axis-aligned bounding box |
204 BBox(const Vector &aL, const Vector &aH): L(aL), H(aH) {}; |
226 BBox(const Vector &aL, const Vector &aH): L(aL), H(aH) {}; |
205 |
227 |
206 Float w() const { return H.x-L.x; }; |
228 Float w() const { return H.x-L.x; }; |
207 Float h() const { return H.y-L.y; }; |
229 Float h() const { return H.y-L.y; }; |
208 Float d() const { return H.z-L.z; }; |
230 Float d() const { return H.z-L.z; }; |
|
231 |
|
232 /** |
|
233 * intersect ray with the bounding box |
|
234 * @param[in] ray the ray |
|
235 * @param[out] a distance of first intersection |
|
236 * @param[out] b distance of second intersection |
|
237 * @return true if ray intersects bbox |
|
238 */ |
209 bool intersect(const Ray &ray, Float &a, Float &b) const; |
239 bool intersect(const Ray &ray, Float &a, Float &b) const; |
|
240 |
|
241 /** same as intersect() but for ray packets */ |
210 #ifndef NO_SIMD |
242 #ifndef NO_SIMD |
211 mfloat4 intersect_packet(const RayPacket &rays, mfloat4 &a, mfloat4 &b) const; |
243 mfloat4 intersect_packet(const RayPacket &rays, mfloat4 &a, mfloat4 &b) const; |
212 #endif |
244 #endif |
213 }; |
245 }; |
214 |
246 |