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