include/scene.h
branchpyrit
changeset 28 ffe83ca074f3
parent 25 b8232edee786
child 31 b4e09433934a
--- a/include/scene.h	Fri Dec 07 16:39:42 2007 +0100
+++ b/include/scene.h	Sat Dec 08 12:37:45 2007 +0100
@@ -9,6 +9,7 @@
 #define SCENE_H
 
 #include <vector>
+#include <typeinfo>
 
 #include "noise.h"
 #include "vector.h"
@@ -156,7 +157,7 @@
 	virtual bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const = 0;
 
 	// normal at point P
-	virtual Vector3 normal(Vector3 &P) const = 0;
+	virtual const Vector3 normal(const Vector3 &P) const = 0;
 
 	virtual BBox get_bbox() const = 0;
 };
@@ -178,7 +179,7 @@
 		center(acenter), radius(aradius) { material = amaterial; }
 	bool intersect(const Ray &ray, Float &dist) const;
 	bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const;
-	Vector3 normal(Vector3 &P) const { return (P - center) * inv_radius; };
+	const Vector3 normal(const Vector3 &P) const { return (P - center) * inv_radius; };
 	BBox get_bbox() const;
 };
 
@@ -196,10 +197,28 @@
 	};
 	bool intersect(const Ray &ray, Float &dist) const;
 	bool intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const { return false; };
-	Vector3 normal(Vector3 &P) const;
+	const Vector3 normal(const Vector3 &P) const;
 	BBox get_bbox() const { return BBox(L, H); };
 };
 
+class Vertex
+{
+public:
+	Vector3 P;
+	Vertex(const Vector3 &aP): P(aP) {};
+};
+
+class NormalVertex: public Vertex
+{
+public:
+	Vector3 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; };
+};
+
+
 class Triangle: public Shape
 {
 #ifdef TRI_BARI_PRE
@@ -214,13 +233,39 @@
 #ifdef TRI_PLUCKER
 	Float pla[6], plb[6], plc[6];
 #endif
+	Vector3 N;
+	bool smooth;
+	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:
-	Vector3 A, B, C, N;
+	Vertex *A, *B, *C;
 
-	Triangle(const Vector3 &aA, const Vector3 &aB, const Vector3 &aC, Material *amaterial);
+	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;};
-	Vector3 normal(Vector3 &) const { return N; };
+	const Vector3 normal(const Vector3 &P) const { return (smooth ? smooth_normal(P) : N); };
+	const Vector3 getNormal() const { return N; };
+	void setSmooth() { smooth = true; };//(typeid(*A) == typeid(*B) == typeid(*C) == typeid(NormalVertex)); };
+	void setFlat() { smooth = false; };
+	bool getSmooth() const { return smooth; };
 	BBox get_bbox() const;
 };