include/shapes.h
branchpyrit
changeset 78 9569e9f35374
child 79 062b1c4143f7
--- /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<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;
+
+	virtual ostream & dump(ostream &st) const = 0;
+};
+
+/**
+ * list of shapes
+ */
+typedef vector<Shape*> 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<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;
+	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<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); };
+	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<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() {};
+	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 (material->smooth ? smooth_normal(P) : N); };
+	const Vector3 getNormal() const { return N; };
+	BBox get_bbox() const;
+	ostream & dump(ostream &st) const;
+};
+
+template <class T> 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<Vertex> VertexArray;
+typedef Array<NormalVertex> NormalVertexArray;
+typedef Array<Triangle> TriangleArray;
+
+#endif