fixed Box::Extend(Vec3f&)
[MicroTrace.git] / Scene.cxx
index 69ea9ed..3085410 100644 (file)
--- a/Scene.cxx
+++ b/Scene.cxx
@@ -1,21 +1,37 @@
+#include <sstream>
+#include <fstream>
+
+
 #include "Scene.hxx"
 #include "PerspectiveCamera.hxx"
+#include "EyeLightShader.hxx"
+#include "Triangle.hxx"
 
 Scene::Scene()
-  : m_camera(new PerspectiveCamera(Vec3f(0,0,8), 
-                                  Vec3f(0,0,-1), 
-                                  Vec3f(0,1,0), 
-                                  50, 
-                                  640, 
+  : m_camera(new PerspectiveCamera(Vec3f(0,0,8),
+                                  Vec3f(0,0,-1),
+                                  Vec3f(0,1,0),
+                                  60,
+                                  640,
                                   480)
             ),
-    m_bgColor(Vec3f(0,0,0))
+    m_bgColor(Vec3f(0,0,0)),
+    m_shader(0),
+    m_scene_box(Box())
 {
 }
 
 Scene::~Scene()
 {
   delete m_camera;
+  if(m_shader != 0)
+    delete m_shader;
+
+  for(unsigned int i = 0; i < m_primitives.size(); ++i)
+    {
+      delete m_primitives[i];
+    }
+  m_primitives.clear();
 }
 
 Scene::Scene(const Scene& s)
@@ -29,38 +45,171 @@ Scene::operator=(const Scene& s)
   return *this;
 }
 
-void 
+void
 Scene::Add(Primitive* p)
 {
   m_primitives.push_back(p);
 }
 
+void
+Scene::Add(Light* l)
+{
+  m_lights.push_back(l);
+}
 
 bool
 Scene::Intersect(Ray& ray)
 {
-  bool hit = false;
-  for( std::vector<Primitive*>::iterator i = m_primitives.begin();
-    i != m_primitives.end(); i++ ) {
-    hit |= (*i)->Intersect(ray);
-  }
-  return hit;
+  bool intersect = false;
+
+  for(unsigned int i = 0; i < m_primitives.size(); ++i)
+    {
+      intersect |= m_primitives[i]->Intersect(ray);
+    }
+
+  return intersect;
 }
 
 bool
 Scene::Occluded(Ray& ray)
 {
-  return false;
+  return this->Intersect(ray);
 }
 
 Vec3f
 Scene::RayTrace(Ray& ray)
 {
-  return (Intersect(ray)) ? Vec3f(255,255,255) : Vec3f(0,0,0);
+  bool intersect = this->Intersect(ray);
+  return (intersect) ? ray.hit()->shader()->Shade(ray) : m_bgColor;
 }
 
-const Camera* 
+const Camera*
 Scene::camera() const
 {
   return m_camera;
 }
+
+std::vector<Light*>
+Scene::lights() const
+{
+  return m_lights;
+}
+
+void
+Scene::setCamera(const Camera* camera)
+{
+  if(m_camera != 0)
+    delete m_camera;
+  m_camera = const_cast<Camera*>(camera);
+}
+
+void
+Scene::ParseOBJ(const std::string& file, float scale)
+{
+  std::cerr << "(Scene): Parsing OBJ file : " << file << std::endl;
+
+  // clear old buffers
+  m_vertices.clear();
+  m_faces.clear();
+
+  // for the moment, we will attach a white eyelight shader to each object
+  // in the future, you will extend your parser to also read in material definitiions
+  if(m_shader == 0) // not yet defined
+    m_shader = new EyeLightShader(this, Vec3f(1.0,1.0,1.0));
+
+
+  // now open file
+  std::fstream in;
+  in.open(file.c_str(), std::ios::in);
+  if(in.bad() || in.fail())
+    {
+      std::cerr << "(Scene): Could not open file " << file << std::endl;
+      return;
+    }
+
+  // read lines
+  std::string line;
+  while(!in.eof())
+    {
+      std::getline(in, line);
+      this->parseOBJLine(line);
+    }
+
+  // finished parsing file -> close fileStream
+  in.close();
+
+  // build triangle list from parsed vertices
+  this->buildTriangleList(scale);
+
+  std::cerr << "(Scene): Finished parsing." << std::endl;
+}
+
+
+void
+Scene::parseOBJLine(const std::string& line)
+{
+  std::istringstream iss(line);
+  std::string key;
+  iss >> key;
+  if (key == "v")
+    {
+      // parse vertex //
+      this->parseVertex(iss);
+    }
+  else if (key == "f")
+    {
+      // parse face //
+      this->parseFace(iss);
+    }
+}
+
+void
+Scene::parseVertex(std::istringstream& iss)
+{
+  Vec3f v;
+  iss >> v[0] >> v[1] >> v[2];
+
+  m_vertices.push_back(v);
+  m_centroid += v;
+}
+
+void
+Scene::parseFace(std::istringstream& iss)
+{
+  Vec3f f;
+  iss >> f[0] >> f[1] >> f[2];
+  m_faces.push_back(f);
+}
+
+void
+Scene::buildTriangleList(float fac)
+{
+  for(unsigned int f = 0; f < m_faces.size(); ++f)
+    {
+      // stores indices of triangle into vertex list
+      // remember: indices start at 1!!
+      Vec3f face_idx = m_faces[f];
+      this->Add(new Triangle(m_vertices[ face_idx[0]-1 ] * fac,
+                            m_vertices[ face_idx[1]-1 ] * fac,
+                            m_vertices[ face_idx[2]-1 ] * fac,
+                            m_shader));
+
+    }
+  m_centroid /= static_cast<float>(m_vertices.size());
+  std::cerr << "(Scene): Model centroid = " << m_centroid * fac << std::endl;
+}
+
+void
+Scene::CalcBounds()
+{
+  for(unsigned int i = 0; i < m_primitives.size(); ++i)
+  {
+    m_scene_box.Extend(m_primitives[i]->CalcBounds());
+  }
+}
+
+const Box&
+Scene::GetSceneBox() const
+{
+  return m_scene_box;
+}
This page took 0.023106 seconds and 4 git commands to generate.