include/shapes.h
branchpyrit
changeset 78 9569e9f35374
child 79 062b1c4143f7
equal deleted inserted replaced
77:dbe8438d5dca 78:9569e9f35374
       
     1 /*
       
     2  * shapes.h: shape classes
       
     3  *
       
     4  * This file is part of Pyrit Ray Tracer.
       
     5  *
       
     6  * Copyright 2006, 2007, 2008  Radek Brich
       
     7  *
       
     8  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     9  * of this software and associated documentation files (the "Software"), to deal
       
    10  * in the Software without restriction, including without limitation the rights
       
    11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    12  * copies of the Software, and to permit persons to whom the Software is
       
    13  * furnished to do so, subject to the following conditions:
       
    14  *
       
    15  * The above copyright notice and this permission notice shall be included in
       
    16  * all copies or substantial portions of the Software.
       
    17  *
       
    18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    24  * THE SOFTWARE.
       
    25  */
       
    26 
       
    27 #ifndef SHAPES_H
       
    28 #define SHAPES_H
       
    29 
       
    30 #include "common.h"
       
    31 #include "scene.h"
       
    32 
       
    33 /*
       
    34 triangle intersection alghoritm
       
    35 options are:
       
    36 TRI_PLUCKER
       
    37 TRI_BARI
       
    38 TRI_BARI_PRE
       
    39 */
       
    40 #if !defined(TRI_PLUCKER) && !defined(TRI_BARI) && !defined(TRI_BARI_PRE)
       
    41 #	define TRI_BARI_PRE
       
    42 #endif
       
    43 
       
    44 /**
       
    45  * shape
       
    46  */
       
    47 class Shape
       
    48 {
       
    49 public:
       
    50 	Material *material;
       
    51 	Shape() {};
       
    52 	virtual ~Shape() {};
       
    53 
       
    54 	// first intersection point
       
    55 	virtual bool intersect(const Ray &ray, Float &dist) const = 0;
       
    56 
       
    57 	// all intersections (only for CSG)
       
    58 	virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const = 0;
       
    59 
       
    60 	// intersection with AABB
       
    61 	virtual bool intersect_bbox(const BBox &bbox) const = 0;
       
    62 
       
    63 	// normal at point P
       
    64 	virtual const Vector3 normal(const Vector3 &P) const = 0;
       
    65 
       
    66 	virtual BBox get_bbox() const = 0;
       
    67 
       
    68 	virtual ostream & dump(ostream &st) const = 0;
       
    69 };
       
    70 
       
    71 /**
       
    72  * list of shapes
       
    73  */
       
    74 typedef vector<Shape*> ShapeList;
       
    75 
       
    76 /**
       
    77  * sphere shape
       
    78  */
       
    79 class Sphere: public Shape
       
    80 {
       
    81 	Vector3 center;
       
    82 	Float radius;
       
    83 
       
    84 	Float sqr_radius;
       
    85 	Float inv_radius;
       
    86 public:
       
    87 	Sphere(const Vector3 &acenter, const Float aradius, Material *amaterial):
       
    88 		center(acenter), radius(aradius),
       
    89 		sqr_radius(aradius*aradius), inv_radius(1.0f/aradius)
       
    90 		{ material = amaterial; }
       
    91 	bool intersect(const Ray &ray, Float &dist) const;
       
    92 	bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const;
       
    93 	bool intersect_bbox(const BBox &bbox) const;
       
    94 	const Vector3 normal(const Vector3 &P) const { return (P - center) * inv_radius; };
       
    95 	BBox get_bbox() const;
       
    96 	const Vector3 getCenter() const { return center; };
       
    97 	const Float getRadius() const { return radius; };
       
    98 	ostream & dump(ostream &st) const;
       
    99 };
       
   100 
       
   101 /**
       
   102  * box shape
       
   103  */
       
   104 class Box: public Shape
       
   105 {
       
   106 	Vector3 L;
       
   107 	Vector3 H;
       
   108 public:
       
   109 	Box(const Vector3 &aL, const Vector3 &aH, Material *amaterial): L(aL), H(aH)
       
   110 	{
       
   111 		for (int i = 0; i < 3; i++)
       
   112 			if (L.cell[i] > H.cell[i])
       
   113 				swap(L.cell[i], H.cell[i]);
       
   114 		material = amaterial;
       
   115 	};
       
   116 	bool intersect(const Ray &ray, Float &dist) const;
       
   117 	bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const { return false; };
       
   118 	bool intersect_bbox(const BBox &bbox) const;
       
   119 	const Vector3 normal(const Vector3 &P) const;
       
   120 	BBox get_bbox() const { return BBox(L, H); };
       
   121 	const Vector3 getL() const { return L; };
       
   122 	const Vector3 getH() const { return H; };
       
   123 	ostream & dump(ostream &st) const;
       
   124 };
       
   125 
       
   126 /**
       
   127  * triangle vertex
       
   128  */
       
   129 class Vertex
       
   130 {
       
   131 public:
       
   132 	Vector3 P;
       
   133 	Vertex(const Vector3 &aP): P(aP) {};
       
   134 	virtual ostream & dump(ostream &st) const;
       
   135 };
       
   136 
       
   137 /**
       
   138  * triangle vertex with normal
       
   139  */
       
   140 class NormalVertex: public Vertex
       
   141 {
       
   142 public:
       
   143 	Vector3 N;
       
   144 	NormalVertex(const NormalVertex *v): Vertex(v->P), N(v->N) {};
       
   145 	NormalVertex(const Vector3 &aP): Vertex(aP) {};
       
   146 	NormalVertex(const Vector3 &aP, const Vector3 &aN): Vertex(aP), N(aN) {};
       
   147 	const Vector3 &getNormal() { return N; };
       
   148 	void setNormal(const Vector3 &aN) { N = aN; };
       
   149 	ostream & dump(ostream &st) const;
       
   150 };
       
   151 
       
   152 /**
       
   153  * triangle shape
       
   154  */
       
   155 class Triangle: public Shape
       
   156 {
       
   157 #ifdef TRI_BARI_PRE
       
   158 	Float nu, nv, nd;
       
   159 	int k; // dominant axis
       
   160 	Float bnu, bnv;
       
   161 	Float cnu, cnv;
       
   162 #endif
       
   163 #ifdef TRI_BARI
       
   164 	int k; // dominant axis
       
   165 #endif
       
   166 #ifdef TRI_PLUCKER
       
   167 	Float pla[6], plb[6], plc[6];
       
   168 #endif
       
   169 	Vector3 N;
       
   170 	const Vector3 smooth_normal(const Vector3 &P) const
       
   171 	{
       
   172 #ifdef TRI_BARI_PRE
       
   173 		const Vector3 &NA = static_cast<NormalVertex*>(A)->N;
       
   174 		const Vector3 &NB = static_cast<NormalVertex*>(B)->N;
       
   175 		const Vector3 &NC = static_cast<NormalVertex*>(C)->N;
       
   176 		static const int modulo3[5] = {0,1,2,0,1};
       
   177 		register const int ku = modulo3[k+1];
       
   178 		register const int kv = modulo3[k+2];
       
   179 		const Float pu = P[ku] - A->P[ku];
       
   180 		const Float pv = P[kv] - A->P[kv];
       
   181 		const Float u = pv * bnu + pu * bnv;
       
   182 		const Float v = pu * cnv + pv * cnu;
       
   183 		Vector3 n = NA + u * (NB - NA) + v * (NC - NA);
       
   184 		n.normalize();
       
   185 		return n;
       
   186 #else
       
   187 		return N; // not implemented for other algorithms
       
   188 #endif
       
   189 	};
       
   190 public:
       
   191 	Vertex *A, *B, *C;
       
   192 
       
   193 	Triangle() {};
       
   194 	Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial);
       
   195 	bool intersect(const Ray &ray, Float &dist) const;
       
   196 	bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const {return false;};
       
   197 	bool intersect_bbox(const BBox &bbox) const;
       
   198 	const Vector3 normal(const Vector3 &P) const { return (material->smooth ? smooth_normal(P) : N); };
       
   199 	const Vector3 getNormal() const { return N; };
       
   200 	BBox get_bbox() const;
       
   201 	ostream & dump(ostream &st) const;
       
   202 };
       
   203 
       
   204 template <class T> class Array
       
   205 {
       
   206 	T *array;
       
   207 public:
       
   208 	Array(int n) { array = new T[n]; };
       
   209 	~Array() { delete[] array; };
       
   210 	const T &operator[](int i) const { return array[i]; };
       
   211 };
       
   212 
       
   213 typedef Array<Vertex> VertexArray;
       
   214 typedef Array<NormalVertex> NormalVertexArray;
       
   215 typedef Array<Triangle> TriangleArray;
       
   216 
       
   217 #endif