packetize Phong shader
new scons config options:
simd=(yes|no) - allow/suppress explicit SSE
force_flags=(yes|no) - force use of specified flags instead of autodetected
profile=(yes|no) - enable gcc's profiling (-pg option)
check for pthread.h header, don't try to build without it
add fourth Vector3 component for better memory aligning
rename Vector3 to Vector
partialy SSE-ize Vector class (only fully vertical operations)
build static lib and python module in distinctive directories
to avoid collision of library file names on some platforms
/* * scene.h: classes for objects in scene * * 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"/** * ray */class Ray{public: Vector o, dir; Ray(): o(), dir() {}; Ray(const Vector &ao, const Vector &adir): o(ao), dir(adir) {};};#ifndef NO_SSE/** * packet of 4 rays */class RayPacket{public: VectorPacket o, dir; RayPacket(): o(), dir() {}; RayPacket(const VectorPacket &ao, const VectorPacket &adir): o(ao), dir(adir) {}; // index operator - get a ray 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/** * a camera */class Camera{public: Vector eye, p, u, v; Float F; Camera(): eye(0,0,10), p(0,0,-1), u(-1,0,0), v(0,1,0), F(2.*tan(M_PI/8.)) {}; Camera(const Vector &C, const Vector &ap, const Vector &au, const Vector &av): eye(C), p(ap), u(au), v(av), F(2.*tan(M_PI/8.)) {}; Camera(const Vector &from, const Vector &lookat, const Vector &up): eye(from), F(2.*tan(M_PI/8.)) { p = lookat - from; u = cross(up, p); p.normalize(); u.normalize(); v = cross(p, u); }; void setEye(const Vector &aeye) { eye = aeye; }; void setAngle(const Float angle) { F = 2.*tan(angle/2.); }; void rotate(const Quaternion &q); void move(const Float fw, const Float left, const Float up); Ray makeRay(Sample &samp) { Vector dir = p - (u*samp.x + v*samp.y)*F; dir.normalize(); return Ray(eye, dir); };#ifndef NO_SSE void makeRayPacket(Sample *samples, RayPacket &rays) { __m128 m1x,m1y,m1z; __m128 m2x,m2y,m2z; __m128 m; // m1(xyz) = u * samples[i].x m1x = _mm_set_ps1(u.x); m1y = _mm_set_ps1(u.y); m1z = _mm_set_ps1(u.z); m = _mm_set_ps(samples[3].x, samples[2].x, samples[1].x, samples[0].x); m1x = _mm_mul_ps(m1x, m); m1y = _mm_mul_ps(m1y, m); m1z = _mm_mul_ps(m1z, m); // m2(xyz) = v * samples[i].y m2x = _mm_set_ps1(v.x); m2y = _mm_set_ps1(v.y); m2z = _mm_set_ps1(v.z); m = _mm_set_ps(samples[3].y, samples[2].y, samples[1].y, samples[0].y); m2x = _mm_mul_ps(m2x, m); m2y = _mm_mul_ps(m2y, m); m2z = _mm_mul_ps(m2z, m); // m1(xyz) = (m1 + m2) = (u*samples[i].x + v*samples[i].y) m1x = _mm_add_ps(m1x, m2x); m1y = _mm_add_ps(m1y, m2y); m1z = _mm_add_ps(m1z, m2z); // m1(xyz) = m1*F = (u*samples[i].x + v*samples[i].y)*F m = _mm_set_ps1(F); m1x = _mm_mul_ps(m1x, m); m1y = _mm_mul_ps(m1y, m); m1z = _mm_mul_ps(m1z, m); // m1(xyz) = p - m1 = p - (u*samples[i].x + v*samples[i].y)*F = dir m2x = _mm_set_ps1(p.x); m2y = _mm_set_ps1(p.y); m2z = _mm_set_ps1(p.z); rays.dir.mx = _mm_sub_ps(m2x, m1x); rays.dir.my = _mm_sub_ps(m2y, m1y); rays.dir.mz = _mm_sub_ps(m2z, m1z); // copy origin rays.o.mx = _mm_set_ps1(eye.x); rays.o.my = _mm_set_ps1(eye.y); rays.o.mz = _mm_set_ps1(eye.z); rays.dir.normalize(); };#endif};/** * light object */class Light{public: Vector pos; Colour colour; bool 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) {}; void castShadows(bool 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() { 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);#ifndef NO_SSE __m128 intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b);#endif};#endif