diff -r 79b516a3803d -r 76b7bd51d64a include/scene.h --- /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 + +#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 &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 &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 &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 &allts) {return false;}; + Vector3 normal(Vector3 &) { return N; }; + BBox get_bbox(); +}; + +#endif