--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/scene.h Mon Dec 03 01:49:23 2007 +0100
@@ -0,0 +1,205 @@
+/*
+ * C++ RayTracer
+ * file: scene.h
+ *
+ * Radek Brich, 2006
+ */
+
+#ifndef SCENE_H
+#define SCENE_H
+
+#include <vector>
+
+#include "noise.h"
+
+#include "vector.h"
+
+using namespace std;
+
+class Ray
+{
+public:
+ Vector3 o, dir;
+ Ray(const Vector3 &ao, const Vector3 &adir):
+ o(ao), dir(adir) {};
+};
+
+class Quaternion
+{
+public:
+ Float a,b,c,d;
+ Quaternion(): a(0), b(0), c(0), d(0) {};
+ Quaternion(const Float aa, const Float ab, const Float ac, const Float ad):
+ a(aa), b(ab), c(ac), d(ad) {};
+ Quaternion(const Vector3& v): a(1), b(v.x), c(v.y), d(v.z) {};
+
+ Vector3 toVector() { return Vector3(b/a, c/a, d/a); };
+
+ Quaternion normalize()
+ {
+ Float f = 1.0f / sqrtf(a * a + b * b + c * c + d * d);
+ a *= f;
+ b *= f;
+ c *= f;
+ d *= f;
+ return *this;
+ };
+ friend Quaternion operator*(const Quaternion &q1, const Quaternion &q2)
+ {
+ return Quaternion(
+ q1.a*q2.a - q1.b*q2.b - q1.c*q2.c - q1.d*q2.d,
+ q1.a*q2.b + q1.b*q2.a + q1.c*q2.d - q1.d*q2.c,
+ q1.a*q2.c + q1.c*q2.a + q1.d*q2.b - q1.b*q2.d,
+ q1.a*q2.d + q1.d*q2.a + q1.b*q2.c - q1.c*q2.b);
+ };
+ friend Quaternion conjugate(const Quaternion &q)
+ {
+ return Quaternion(q.a, -q.b, -q.c, -q.d);
+ }
+};
+
+class Camera
+{
+public:
+ Vector3 eye, p, u, v;
+ Float f;
+
+ Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), f(3.14/4.0) {};
+ Camera(const Vector3 &C, const Vector3 &ap, const Vector3 &au, const Vector3 &av):
+ eye(C), p(ap), u(au), v(av), f(3.14/4.0) {};
+ void setEye(const Vector3 &aeye) { eye = aeye; };
+ void setFocalLength(const Float af) { f = af; };
+ void rotate(const Quaternion &q);
+ void move(const Float fw, const Float left, const Float up);
+};
+
+/* 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);
+};
+
+class Light
+{
+public:
+ Vector3 pos;
+ Colour colour;
+ bool cast_shadows;
+
+ Light(const Vector3 &position, const Colour &acolour):
+ pos(position), colour(acolour), cast_shadows(true) {};
+ void castShadows(bool cast) { cast_shadows = cast; };
+};
+
+class Texture
+{
+public:
+ Colour colour;
+ 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*colour.r, value*colour.g, value*colour.b);
+ };
+};
+
+class Material
+{
+public:
+ Float ambient, diffuse, specular, shininess; // Phong constants
+ Float reflection; // how much reflectife is the surface
+ Float refraction; // refraction index
+ Float transmitivity;
+ Texture texture;
+
+ Material(const Colour &acolour) {
+ texture.colour = acolour;
+ ambient = 0.1;
+ diffuse = 0.5;
+ specular = 0.1;
+ shininess = 0.5;
+ reflection = 0.5;
+ }
+};
+
+class Shape
+{
+public:
+ Material *material;
+ Shape() {};
+ virtual ~Shape() {};
+
+ // first intersection point
+ virtual bool intersect(const Ray &ray, Float &dist) = 0;
+
+ // all intersections (only for CSG)
+ virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) = 0;
+
+ // normal at point P
+ virtual Vector3 normal(Vector3 &P) = 0;
+
+ virtual BBox get_bbox() = 0;
+};
+
+class Sphere: public Shape
+{
+ Float sqr_radius;
+ Float inv_radius;
+public:
+ Vector3 center;
+ Float radius;
+
+ Sphere(const Vector3 &acenter, const Float aradius, Material *amaterial):
+ sqr_radius(aradius*aradius), inv_radius(1.0f/aradius),
+ center(acenter), radius(aradius) { material = amaterial; }
+ bool intersect(const Ray &ray, Float &dist);
+ bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts);
+ Vector3 normal(Vector3 &P) { return (P - center) * inv_radius; };
+ BBox get_bbox();
+};
+
+class Box: public Shape
+{
+ Vector3 L;
+ Vector3 H;
+public:
+ Box(const Vector3 &aL, const Vector3 &aH, Material *amaterial): L(aL), H(aH)
+ {
+ for (int i = 0; i < 3; i++)
+ if (L.cell[i] > H.cell[i])
+ swap(L.cell[i], H.cell[i]);
+ material = amaterial;
+ };
+ bool intersect(const Ray &ray, Float &dist);
+ bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) {return false;};
+ Vector3 normal(Vector3 &P);
+ BBox get_bbox() { return BBox(L, H); };
+};
+
+class Triangle: public Shape
+{
+ int k; // dominant axis
+ Float nu, nv, nd;
+ Float bnu, bnv;
+ Float cnu, cnv;
+public:
+ Vector3 A, B, C, N;
+
+ Triangle(const Vector3 &aA, const Vector3 &aB, const Vector3 &aC, Material *amaterial);
+ bool intersect(const Ray &ray, Float &dist);
+ bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) {return false;};
+ Vector3 normal(Vector3 &) { return N; };
+ BBox get_bbox();
+};
+
+#endif