replace Plane with axis-aligned Box (because infinite Plane is not usable with kd-tree)
fix memory leak in KdTree::nearest_intersection
rename BBox::R to BBox::H
new file: common.h (Eps and Inf constants)
/* * 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 a, dir; Ray(const Vector3 &aa, const Vector3 &adir): a(aa), dir(adir) {};};/* 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; int shadows; Light(const Vector3 &position, const Colour &acolour): pos(position), colour(acolour), shadows(1) {}; void castshadows(bool ashadows) { shadows = ashadows; };};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 = 1.0; shininess = 20.0; 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