fixed Box::Extend(Vec3f&)
[MicroTrace.git] / Scene.cxx
1 #include <sstream>
2 #include <fstream>
3
4
5 #include "Scene.hxx"
6 #include "PerspectiveCamera.hxx"
7 #include "EyeLightShader.hxx"
8 #include "Triangle.hxx"
9
10 Scene::Scene()
11 : m_camera(new PerspectiveCamera(Vec3f(0,0,8),
12 Vec3f(0,0,-1),
13 Vec3f(0,1,0),
14 60,
15 640,
16 480)
17 ),
18 m_bgColor(Vec3f(0,0,0)),
19 m_shader(0),
20 m_scene_box(Box())
21 {
22 }
23
24 Scene::~Scene()
25 {
26 delete m_camera;
27 if(m_shader != 0)
28 delete m_shader;
29
30 for(unsigned int i = 0; i < m_primitives.size(); ++i)
31 {
32 delete m_primitives[i];
33 }
34 m_primitives.clear();
35 }
36
37 Scene::Scene(const Scene& s)
38 {
39 operator=(s);
40 }
41
42 Scene&
43 Scene::operator=(const Scene& s)
44 {
45 return *this;
46 }
47
48 void
49 Scene::Add(Primitive* p)
50 {
51 m_primitives.push_back(p);
52 }
53
54 void
55 Scene::Add(Light* l)
56 {
57 m_lights.push_back(l);
58 }
59
60 bool
61 Scene::Intersect(Ray& ray)
62 {
63 bool intersect = false;
64
65 for(unsigned int i = 0; i < m_primitives.size(); ++i)
66 {
67 intersect |= m_primitives[i]->Intersect(ray);
68 }
69
70 return intersect;
71 }
72
73 bool
74 Scene::Occluded(Ray& ray)
75 {
76 return this->Intersect(ray);
77 }
78
79 Vec3f
80 Scene::RayTrace(Ray& ray)
81 {
82 bool intersect = this->Intersect(ray);
83 return (intersect) ? ray.hit()->shader()->Shade(ray) : m_bgColor;
84 }
85
86 const Camera*
87 Scene::camera() const
88 {
89 return m_camera;
90 }
91
92 std::vector<Light*>
93 Scene::lights() const
94 {
95 return m_lights;
96 }
97
98 void
99 Scene::setCamera(const Camera* camera)
100 {
101 if(m_camera != 0)
102 delete m_camera;
103 m_camera = const_cast<Camera*>(camera);
104 }
105
106 void
107 Scene::ParseOBJ(const std::string& file, float scale)
108 {
109 std::cerr << "(Scene): Parsing OBJ file : " << file << std::endl;
110
111 // clear old buffers
112 m_vertices.clear();
113 m_faces.clear();
114
115 // for the moment, we will attach a white eyelight shader to each object
116 // in the future, you will extend your parser to also read in material definitiions
117 if(m_shader == 0) // not yet defined
118 m_shader = new EyeLightShader(this, Vec3f(1.0,1.0,1.0));
119
120
121 // now open file
122 std::fstream in;
123 in.open(file.c_str(), std::ios::in);
124 if(in.bad() || in.fail())
125 {
126 std::cerr << "(Scene): Could not open file " << file << std::endl;
127 return;
128 }
129
130 // read lines
131 std::string line;
132 while(!in.eof())
133 {
134 std::getline(in, line);
135 this->parseOBJLine(line);
136 }
137
138 // finished parsing file -> close fileStream
139 in.close();
140
141 // build triangle list from parsed vertices
142 this->buildTriangleList(scale);
143
144 std::cerr << "(Scene): Finished parsing." << std::endl;
145 }
146
147
148 void
149 Scene::parseOBJLine(const std::string& line)
150 {
151 std::istringstream iss(line);
152 std::string key;
153 iss >> key;
154 if (key == "v")
155 {
156 // parse vertex //
157 this->parseVertex(iss);
158 }
159 else if (key == "f")
160 {
161 // parse face //
162 this->parseFace(iss);
163 }
164 }
165
166 void
167 Scene::parseVertex(std::istringstream& iss)
168 {
169 Vec3f v;
170 iss >> v[0] >> v[1] >> v[2];
171
172 m_vertices.push_back(v);
173 m_centroid += v;
174 }
175
176 void
177 Scene::parseFace(std::istringstream& iss)
178 {
179 Vec3f f;
180 iss >> f[0] >> f[1] >> f[2];
181 m_faces.push_back(f);
182 }
183
184 void
185 Scene::buildTriangleList(float fac)
186 {
187 for(unsigned int f = 0; f < m_faces.size(); ++f)
188 {
189 // stores indices of triangle into vertex list
190 // remember: indices start at 1!!
191 Vec3f face_idx = m_faces[f];
192 this->Add(new Triangle(m_vertices[ face_idx[0]-1 ] * fac,
193 m_vertices[ face_idx[1]-1 ] * fac,
194 m_vertices[ face_idx[2]-1 ] * fac,
195 m_shader));
196
197 }
198 m_centroid /= static_cast<float>(m_vertices.size());
199 std::cerr << "(Scene): Model centroid = " << m_centroid * fac << std::endl;
200 }
201
202 void
203 Scene::CalcBounds()
204 {
205 for(unsigned int i = 0; i < m_primitives.size(); ++i)
206 {
207 m_scene_box.Extend(m_primitives[i]->CalcBounds());
208 }
209 }
210
211 const Box&
212 Scene::GetSceneBox() const
213 {
214 return m_scene_box;
215 }
This page took 0.053049 seconds and 5 git commands to generate.