1 #ifndef SCENE_HXX
  2 #define SCENE_HXX
  3 
  4 #include <vector>
  5 #include "defines.h"
  6 
  7 #include "Primitive.hxx"
  8 #include "PerspectiveCamera.hxx"
  9 #include "Light.hxx"
 10 
 11 #include "Sphere.hxx"
 12 #include "InfinitePlane.hxx"
 13 #include "Quadric.hxx"
 14 #include "Triangle.hxx"
 15 
 16 #include "SmoothTriangle.hxx"
 17 #include "TexturedSmoothTriangle.hxx"
 18 
 19 #include "Shader.hxx"
 20 #include "MaterialFactory.hxx"
 21 #include "SceneMaterialDescription.hxx"
 22 
 23 #include "BVH.h"
 24 
 25 class Scene
 26 {
 27 public:
 28 	Vec3f bgColor;                  // Background color
 29 
 30 	vector<Primitive*> primitive;   // Primitives
 31 	vector<Light*>     lights;      // Lights
 32 
 33 	Camera *camera; 
 34 
 35 	BVH* bvhTree;
 36 	Box boundingBox;
 37 
 38 	bool m_useBVH;
 39 
 40 	Scene(bool aUseBVH)
 41 		: bgColor(Vec3f(0,0,0))
 42 	{
 43 		m_useBVH = aUseBVH;
 44 		camera = NULL;
 45 	};
 46 
 47 	virtual ~Scene() 
 48 	{};
 49 
 50 #define DECL_FACTORY_FUNC \
 51 	virtual Primitive* createPrimitive( \
 52 		const int face, \
 53 		const Vec3f &v1, const Vec3f &v2, const Vec3f &v3, \
 54 		const Vec3f &vn1, const Vec3f &vn2, const Vec3f &vn3, \
 55 		const Vec3f &vt1, const Vec3f &vt2, const Vec3f &vt3 \
 56 		)
 57 
 58 	struct PrimitiveFactory
 59 	{
 60 		MaterialFactory *mFactory;
 61 
 62 		DECL_FACTORY_FUNC = 0;
 63 
 64 		PrimitiveFactory()
 65 		{
 66 			mFactory = NULL;
 67 		};
 68 
 69 		virtual ~PrimitiveFactory(){};
 70 	};
 71 
 72 	struct TriangleFactory : public PrimitiveFactory
 73 	{
 74 		Shader *shader;
 75 		PhotonDistributor *photon_distributor;
 76 
 77 		DECL_FACTORY_FUNC { return new Triangle(v1, v2, v3, (mFactory) ? mFactory->GetShader(face) : shader, (mFactory) ? mFactory->GetPhotonDistributor(face) : photon_distributor); }
 78 		virtual ~TriangleFactory(){};
 79 	};
 80 
 81 	struct SmoothTriangleFactory : public PrimitiveFactory
 82 	{
 83 		Shader *shader;
 84 		PhotonDistributor *photon_distributor;
 85 
 86 		DECL_FACTORY_FUNC { return new SmoothTriangle(v1, v2, v3, vn1, vn2, vn3, (mFactory) ? mFactory->GetShader(face) : shader, (mFactory) ? mFactory->GetPhotonDistributor(face) : photon_distributor); }
 87 		virtual ~SmoothTriangleFactory(){};
 88 	};
 89 
 90 	struct TexturedSmoothTriangleFactory : public PrimitiveFactory
 91 	{
 92 		Shader *shader;
 93 		PhotonDistributor *photon_distributor;
 94 
 95 		DECL_FACTORY_FUNC { return new TexturedSmoothTriangle(v1, v2, v3, vn1, vn2, vn3, vt1, vt2, vt3, (mFactory) ? mFactory->GetShader(face) : shader, (mFactory) ? mFactory->GetPhotonDistributor(face) : photon_distributor); }
 96 		virtual ~TexturedSmoothTriangleFactory(){};
 97 	};
 98 
 99 	// Parses an object and moves it to point offset (optionally)
100 	void ParseOBJ(char *fileName, PrimitiveFactory *aFactory, Vec3f offset = Vec3f(0,0,0));
101 
102 	// Add a new primitive
103 	void Add(Primitive *prim)
104 	{
105         	primitive.push_back(prim);
106         };
107 
108 	// Add a new light source
109         void Add(Light *light)
110         {
111         	lights.push_back(light);
112         };
113 
114 	// Intersect all contained objects
115 	virtual bool Intersect(Ray &ray)
116 	{
117 		if(m_useBVH)
118 		{
119 			return bvhTree->Intersect(ray);
120 		}
121 		else
122 		{
123 			bool hit = false;
124 
125 			for (unsigned int i = 0; i < primitive.size(); ++i)
126 				hit |= primitive[i]->Intersect(ray);
127 
128 			return hit;
129 		}
130 	};
131 
132 	// Find occluder
133 	bool Occluded(Ray &ray, Vec3f &color)
134 	{
135 		if(m_useBVH)
136 		{
137 			return bvhTree->Occluded(ray, color);
138 		}
139 		else
140 		{
141 			for (unsigned int i = 0; i < primitive.size(); ++i)
142 				if (primitive[i]->Occluded(ray))
143 				{
144 					if (ray.hit->shader->material->transparency <= 0.0)
145 						return true;
146 					else if (ray.t > Epsilon)
147 					{
148 						Vec3f newcolor = color;;
149 						Ray   newray;
150 
151 						newray.org = ray.org + ray.t * ray.dir;
152 						newray.dir = ray.dir;
153 
154 						if (!Occluded(newray, newcolor))
155 						{
156 							color = ray.hit->shader->material->color;
157 							color = color + ray.hit->shader->material->transparency * (newcolor - color);
158 						}
159 					}
160 				}
161 
162 			return false;
163 		}
164 	};
165 
166 	virtual Vec3f GetNormal(Ray &ray)
167 	{
168 		std::cerr << "Scene::GetNormal is not defined!" << std::endl;
169 		return Vec3f(0,0,0); // Dummy !
170 	};
171 
172 	Box CalcBounds()
173 	{
174 		boundingBox.Clear();
175 
176 		for (int i = 0; i < static_cast<int>(primitive.size()); ++i) 
177 		{
178 			Box box = primitive[i]->CalcBounds();
179 			boundingBox.Extend(box);
180 		}
181 
182 		return boundingBox;
183 	}
184 
185 	void BuildAccelStructure()
186 	{
187 		if(m_useBVH)
188 		{
189 			boundingBox = CalcBounds();
190 			bvhTree = new BVH(boundingBox, primitive);
191 
192 			cout << "Bounds are : " << boundingBox.min << " " << boundingBox.max << endl;
193 		}
194 	}
195 
196 	// Trace the given ray, shade it and return the color of the shaded ray
197 	Vec3f RayTrace(Ray &ray)
198 	{
199 		static int maxReflections = MAXREFLECTIONS;
200 
201 		Vec3f result;
202 
203 		// Only shoot another ray if the maximum recursion depth is not exceeded
204 		if (maxReflections >= 0 && Intersect(ray))
205 		{
206 			--maxReflections; 
207 			result = ray.hit->shader->Shade(ray); // Shade the primitive
208 			++maxReflections; 
209 
210 			return result;
211 		}
212 		else
213 			return bgColor;                       // Ray missed geometric primitives
214 	};
215 
216 	void PhotonTrace(TravellingPhoton &photon, vector<Photon*> &list)
217 	{
218 		static int maxReflections = MAXREFLECTIONS;
219 
220 		// Only shoot another photon if the maximum recursion depth is not exceeded
221 		if (maxReflections >= 0 && Intersect(photon))
222 		{
223 			--maxReflections; 
224 			photon.hit->photon_distributor->Distribute(photon, list);
225 			++maxReflections; 
226 		}
227 	};
228 };
229 
230 #endif


syntax highlighted by Code2HTML, v. 0.9.1