Updated to compile:
- KdTree+Octree: max_depth changed to static const (this should be configured at compile time)
- wget tool replaced by curl, which is now more widespread
- added CMakeLists (to eventually replace SCons)
- various fixes
/** * @file scene.h * @brief Classes for objects in scene (other than shapes). * * This file is part of Pyrit Ray Tracer. * * Copyright 2006, 2007, 2008 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 "common.h"#include "sampler.h"#include "vector.h"#include "quaternion.h"/** * A ray */class Ray{public: Vector o; ///< Origin Vector dir; ///< Normalized direction Ray(): o(), dir() {}; Ray(const Vector &ao, const Vector &adir): o(ao), dir(adir) {};};#ifndef NO_SIMD/** * Packet of four rays for SIMD accelerated packet tracing. */class RayPacket{public: VectorPacket o; ///< Packet of four origins VectorPacket dir; ///< Directions VectorPacket invdir; ///< Inverted directions (1/dir) RayPacket(): o(), dir() {}; RayPacket(const VectorPacket &ao, const VectorPacket &adir): o(ao), dir(adir), invdir(mOne/adir) {}; /** Index operator: get ray 'i' */ Ray operator[](int i) const { return Ray( Vector(o.x[i], o.y[i], o.z[i]), Vector(dir.x[i], dir.y[i], dir.z[i])); };};#endif/** * Standard ray tracing camera */class Camera{ Vector eye, p, u, v; Float F;public: Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2*tan(PI/8)) {}; /** Position + p,u,v constructor */ Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): eye(C), p(ap), u(au), v(av), F(2*tan(PI/8)) {}; /** Look-at constructor */ Camera(const Vector &from, const Vector &lookat, const Vector &up): eye(from), F(2*tan(PI/8)) { p = lookat - from; u = cross(up, p); p.normalize(); u.normalize(); v = cross(p, u); };#ifndef NO_SIMD void *operator new(size_t size) { return _mm_malloc(size, 16); }; void operator delete(void *p) { _mm_free(p); };#endif const Vector &getEye() const { return eye; }; const Vector &getp() const { return p; }; const Vector &getu() const { return u; }; const Vector &getv() const { return v; }; const Float &getF() const { return F; }; void setEye(const Vector &aeye) { eye = aeye; }; void setp(const Vector &ap) { p = ap; }; void setu(const Vector &au) { u = au; }; void setv(const Vector &av) { v = av; }; /** set "screen plane" size * @param[in] F height of the screen plane */ void setF(const Float &aF) { F = aF; }; /** set camera's angle of view (in radians) */ void setAngle(const Float angle) { F = 2*tan(angle/2); }; /** rotate camera using a quaternion */ void rotate(const Quaternion &q); /** translate the camera in its direction * @param[in] fw size of forward step * @param[in] left size of left step * @param[in] up size of up step */ void move(const Float fw, const Float left, const Float up); /** make the ray from screen sample according the camera's parameters */ const Ray makeRay(const Sample &samp) const { Vector dir = normalize(p - (u*samp.x + v*samp.y)*F); return Ray(eye, dir); }; /** same as makeRay but for ray packet */#ifndef NO_SIMD void makeRayPacket(const Sample *samples, RayPacket &rays) const { mfloat4 m1x,m1y,m1z; mfloat4 m2x,m2y,m2z; mfloat4 m; // m1(xyz) = u * samples[i].x m1x = mshuffle(u.mf4, u.mf4, mShuffle0); // u.x m1y = mshuffle(u.mf4, u.mf4, mShuffle1); // u.y m1z = mshuffle(u.mf4, u.mf4, mShuffle2); // u.z m = mset(samples[3].x, samples[2].x, samples[1].x, samples[0].x); m1x = mmul(m1x, m); m1y = mmul(m1y, m); m1z = mmul(m1z, m); // m2(xyz) = v * samples[i].y m2x = mshuffle(v.mf4, v.mf4, mShuffle0); // v.x m2y = mshuffle(v.mf4, v.mf4, mShuffle1); // v.y m2z = mshuffle(v.mf4, v.mf4, mShuffle2); // v.z m = mset(samples[3].y, samples[2].y, samples[1].y, samples[0].y); m2x = mmul(m2x, m); m2y = mmul(m2y, m); m2z = mmul(m2z, m); // m1(xyz) = (m1 + m2) = (u*samples[i].x + v*samples[i].y) m1x = madd(m1x, m2x); m1y = madd(m1y, m2y); m1z = madd(m1z, m2z); // m1(xyz) = m1*F = (u*samples[i].x + v*samples[i].y)*F m = mset1(F); m1x = mmul(m1x, m); m1y = mmul(m1y, m); m1z = mmul(m1z, m); // m1(xyz) = p - m1 = p - (u*samples[i].x + v*samples[i].y)*F = dir m2x = mshuffle(p.mf4, p.mf4, mShuffle0); // p.x m2y = mshuffle(p.mf4, p.mf4, mShuffle1); // p.y m2z = mshuffle(p.mf4, p.mf4, mShuffle2); // p.z rays.dir.mx = msub(m2x, m1x); rays.dir.my = msub(m2y, m1y); rays.dir.mz = msub(m2z, m1z); // copy origin rays.o.mx = mshuffle(eye.mf4, eye.mf4, mShuffle0); // eye.x rays.o.my = mshuffle(eye.mf4, eye.mf4, mShuffle1); // eye.y rays.o.mz = mshuffle(eye.mf4, eye.mf4, mShuffle2); // eye.z rays.dir.normalize(); rays.invdir = mOne / rays.dir; };#endif};/** * light object */class Light{public: Vector pos; Colour colour; int cast_shadows; Light(): pos(Vector(0,0,0)), colour(Colour(1,1,1)), cast_shadows(true) {}; Light(const Vector &position, const Colour &acolour): pos(position), colour(acolour), cast_shadows(true) {}; /** allow shadows from this light */ void castShadows(int cast) { cast_shadows = cast; };};/** * axis-aligned bounding box */class BBox{public: Vector L; Vector H; BBox(): L(), H() {}; BBox(const Vector &aL, const Vector &aH): L(aL), H(aH) {}; Float w() const { return H.x-L.x; }; Float h() const { return H.y-L.y; }; Float d() const { return H.z-L.z; }; /** * intersect ray with the bounding box * @param[in] ray the ray * @param[out] a distance of first intersection * @param[out] b distance of second intersection * @return true if ray intersects bbox */ bool intersect(const Ray &ray, Float &a, Float &b) const; /** same as intersect() but for ray packets */#ifndef NO_SIMD mfloat4 intersect_packet(const RayPacket &rays, mfloat4 &a, mfloat4 &b) const;#endif};#endif