Doxygen
new Sampler object
replacing rendering algorithm with more flexible one -- this breaks most of demos and disables threads and (over-/sub-)sampling functionality, need a rewrote
/* * scene.h: classes for objects in scene * * This file is part of Pyrit Ray Tracer. * * Copyright 2006, 2007 Radek Brich * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#ifndef SCENE_H#define SCENE_H#include <vector>#include <typeinfo>#include "noise.h"#include "vector.h"#include "quaternion.h"/*triangle intersection alghoritmchooses are:TRI_PLUCKERTRI_BARITRI_BARI_PRE*/#if !defined(TRI_PLUCKER) && !defined(TRI_BARI) && !defined(TRI_BARI_PRE)# define TRI_BARI_PRE#endifusing namespace std;class Ray{public: Vector3 o, dir; Ray(const Vector3 &ao, const Vector3 &adir): o(ao), dir(adir) {};};/** * sample */class Sample{public: Float x,y;};/** * A abstract sampler. * It generates screen samples in coordinates between [-1..1] for height * and [-w/h..w/h] for width. It works in phases: initSampleSet returns * number of samples for each phase, then samples can be generated using * nextSample method. The resulting colour of each sample should be returned * via saveSample method. The sampler should save the results to given buffer * and decide if other phase is needed. When the picture is complete, * initSampleSet returns zero and picture can be read from buffer. */class Sampler{public: Float *buffer; int w,h; Sampler(Float *abuffer, int &aw, int &ah): buffer(abuffer), w(aw), h(ah) {}; void resetBuffer(Float *abuffer, int &aw, int &ah) { buffer = abuffer; w = aw; h = ah; }; virtual void init() = 0; virtual int initSampleSet() = 0; virtual Sample *nextSample(Sample *prev) = 0; virtual void saveSample(Sample *samp, Colour &col) = 0;};/** * default sample */class DefaultSample: public Sample{ friend class DefaultSampler; int sx,sy;};/** * Default sampler. */class DefaultSampler: public Sampler{ int phase;public: DefaultSampler(Float *abuffer, int &aw, int &ah): Sampler(abuffer, aw, ah), phase(-1) {}; void init() { phase = 0; }; int initSampleSet(); Sample *nextSample(Sample *prev); void saveSample(Sample *samp, Colour &col);};/** * a camera */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); Ray makeRay(Sample *samp);};/** * 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);};/** * light object */class Light{public: Vector3 pos; Colour colour; bool cast_shadows; Light(): pos(Vector3(0,0,0)), colour(Colour(1,1,1)), cast_shadows(true) {}; Light(const Vector3 &position, const Colour &acolour): pos(position), colour(acolour), cast_shadows(true) {}; void castShadows(bool cast) { cast_shadows = cast; };};/** * texture */class Texture{public: virtual Colour evaluate(Vector3 point) = 0;};/** * material */class Material{public: Colour colour; Float ambient, diffuse, specular, shininess; // Phong constants Float reflectivity; // how much reflective is the surface Float transmissivity, refract_index; // part of light which can be refracted; index of refraction Texture *texture; Material(const Colour &acolour): colour(acolour), texture(NULL) { ambient = 0.2; diffuse = 0.8; specular = 0.2; shininess = 0.5; reflectivity = 0.2; transmissivity = 0.0; refract_index = 1.3; } void setPhong(const Float amb, const Float dif, const Float spec, const Float shin) { ambient = amb; diffuse = dif; specular = spec; shininess = shin; }; void setReflectivity(const Float refl) { reflectivity = refl; }; void setTransmissivity(const Float trans, const Float rindex) { transmissivity = trans; refract_index = rindex; };};/** * shape */class Shape{public: Material *material; Shape() {}; virtual ~Shape() {}; // first intersection point virtual bool intersect(const Ray &ray, Float &dist) const = 0; // all intersections (only for CSG) virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const = 0; // intersection with AABB virtual bool intersect_bbox(const BBox &bbox) const = 0; // normal at point P virtual const Vector3 normal(const Vector3 &P) const = 0; virtual BBox get_bbox() const = 0;};/** * list of shapes */class ShapeList: public vector<Shape*>{};/** * sphere shape */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) const; bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const; bool intersect_bbox(const BBox &bbox) const; const Vector3 normal(const Vector3 &P) const { return (P - center) * inv_radius; }; BBox get_bbox() const;};/** * box shape */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) const; bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const { return false; }; bool intersect_bbox(const BBox &bbox) const; const Vector3 normal(const Vector3 &P) const; BBox get_bbox() const { return BBox(L, H); };};/** * triangle vertex */class Vertex{public: Vector3 P; Vertex(const Vector3 &aP): P(aP) {};};/** * triangle vertex with normal */class NormalVertex: public Vertex{public: Vector3 N; NormalVertex(const Vector3 &aP): Vertex(aP) {}; NormalVertex(const Vector3 &aP, const Vector3 &aN): Vertex(aP), N(aN) {}; const Vector3 &getNormal() { return N; }; void setNormal(const Vector3 &aN) { N = aN; };};/** * triangle shape */class Triangle: public Shape{#ifdef TRI_BARI_PRE Float nu, nv, nd; int k; // dominant axis Float bnu, bnv; Float cnu, cnv;#endif#ifdef TRI_BARI int k; // dominant axis#endif#ifdef TRI_PLUCKER Float pla[6], plb[6], plc[6];#endif Vector3 N; bool smooth; const Vector3 smooth_normal(const Vector3 &P) const {#ifdef TRI_BARI_PRE const Vector3 &NA = static_cast<NormalVertex*>(A)->N; const Vector3 &NB = static_cast<NormalVertex*>(B)->N; const Vector3 &NC = static_cast<NormalVertex*>(C)->N; static const int modulo3[5] = {0,1,2,0,1}; register const int ku = modulo3[k+1]; register const int kv = modulo3[k+2]; const Float pu = P[ku] - A->P[ku]; const Float pv = P[kv] - A->P[kv]; const Float u = pv * bnu + pu * bnv; const Float v = pu * cnv + pv * cnu; Vector3 n = NA + u * (NB - NA) + v * (NC - NA); n.normalize(); return n;#else return N; // not implemented for other algorithms#endif };public: Vertex *A, *B, *C; Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial); bool intersect(const Ray &ray, Float &dist) const; bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const {return false;}; bool intersect_bbox(const BBox &bbox) const; const Vector3 normal(const Vector3 &P) const { return (smooth ? smooth_normal(P) : N); }; const Vector3 getNormal() const { return N; }; void setSmooth() { smooth = true; };//(typeid(*A) == typeid(*B) == typeid(*C) == typeid(NormalVertex)); }; void setFlat() { smooth = false; }; bool getSmooth() const { return smooth; }; BBox get_bbox() const;};#endif