diff -r dbe8438d5dca -r 9569e9f35374 include/shapes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/shapes.h Wed Apr 23 10:38:33 2008 +0200 @@ -0,0 +1,217 @@ +/* + * shapes.h: shape classes + * + * 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 SHAPES_H +#define SHAPES_H + +#include "common.h" +#include "scene.h" + +/* +triangle intersection alghoritm +options are: +TRI_PLUCKER +TRI_BARI +TRI_BARI_PRE +*/ +#if !defined(TRI_PLUCKER) && !defined(TRI_BARI) && !defined(TRI_BARI_PRE) +# define TRI_BARI_PRE +#endif + +/** + * 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 &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; + + virtual ostream & dump(ostream &st) const = 0; +}; + +/** + * list of shapes + */ +typedef vector ShapeList; + +/** + * sphere shape + */ +class Sphere: public Shape +{ + Vector3 center; + Float radius; + + Float sqr_radius; + Float inv_radius; +public: + Sphere(const Vector3 &acenter, const Float aradius, Material *amaterial): + center(acenter), radius(aradius), + sqr_radius(aradius*aradius), inv_radius(1.0f/aradius) + { material = amaterial; } + bool intersect(const Ray &ray, Float &dist) const; + bool intersect_all(const Ray &ray, Float dist, vector &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; + const Vector3 getCenter() const { return center; }; + const Float getRadius() const { return radius; }; + ostream & dump(ostream &st) 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 &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); }; + const Vector3 getL() const { return L; }; + const Vector3 getH() const { return H; }; + ostream & dump(ostream &st) const; +}; + +/** + * triangle vertex + */ +class Vertex +{ +public: + Vector3 P; + Vertex(const Vector3 &aP): P(aP) {}; + virtual ostream & dump(ostream &st) const; +}; + +/** + * triangle vertex with normal + */ +class NormalVertex: public Vertex +{ +public: + Vector3 N; + NormalVertex(const NormalVertex *v): Vertex(v->P), N(v->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; }; + ostream & dump(ostream &st) const; +}; + +/** + * 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; + const Vector3 smooth_normal(const Vector3 &P) const + { +#ifdef TRI_BARI_PRE + const Vector3 &NA = static_cast(A)->N; + const Vector3 &NB = static_cast(B)->N; + const Vector3 &NC = static_cast(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() {}; + 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 &allts) const {return false;}; + bool intersect_bbox(const BBox &bbox) const; + const Vector3 normal(const Vector3 &P) const { return (material->smooth ? smooth_normal(P) : N); }; + const Vector3 getNormal() const { return N; }; + BBox get_bbox() const; + ostream & dump(ostream &st) const; +}; + +template class Array +{ + T *array; +public: + Array(int n) { array = new T[n]; }; + ~Array() { delete[] array; }; + const T &operator[](int i) const { return array[i]; }; +}; + +typedef Array VertexArray; +typedef Array NormalVertexArray; +typedef Array TriangleArray; + +#endif