code for assignment 2
authorRoland Hieber <rohieb@rohieb.name>
Sun, 17 Jan 2010 18:35:14 +0000 (19:35 +0100)
committerRoland Hieber <rohieb@rohieb.name>
Sun, 17 Jan 2010 18:35:14 +0000 (19:35 +0100)
27 files changed:
Camera.hxx
EyeLightShader.cxx [new file with mode: 0644]
EyeLightShader.hxx [new file with mode: 0644]
FlatShader.cxx [new file with mode: 0644]
FlatShader.hxx [new file with mode: 0644]
InfinitePlane.cxx [new file with mode: 0644]
InfinitePlane.hxx [new file with mode: 0644]
Makefile
MicroTrace.cxx
PerspectiveCamera.cxx
PerspectiveCamera.hxx
Primitive.cxx [new file with mode: 0644]
Primitive.hxx
Ray.cxx
Ray.hxx
ReflectiveEyeLightShader.cxx [new file with mode: 0644]
ReflectiveEyeLightShader.hxx [new file with mode: 0644]
Scene.cxx [new file with mode: 0644]
Scene.hxx [new file with mode: 0644]
Shader.cxx [new file with mode: 0644]
Shader.hxx [new file with mode: 0644]
Sphere.cxx [new file with mode: 0644]
Sphere.hxx [new file with mode: 0644]
Triangle.cxx
Triangle.hxx
Vec3f.cxx
Vec3f.hxx

index 51f9865..b2bc711 100644 (file)
@@ -8,7 +8,7 @@ class Camera
 public:
   Camera(int resX, int resY);
   virtual ~Camera();
-  virtual bool InitRay(float x, float y, Ray &ray) = 0;
+  virtual bool InitRay(float x, float y, Ray &ray) const = 0;
   
   int resX() const;
   int resY() const;
diff --git a/EyeLightShader.cxx b/EyeLightShader.cxx
new file mode 100644 (file)
index 0000000..12578d7
--- /dev/null
@@ -0,0 +1,24 @@
+#include "EyeLightShader.hxx"
+
+EyeLightShader::EyeLightShader(Scene* scene,
+                              const Vec3f& color)
+  : Shader(scene),
+    m_color(color)
+{
+}
+
+EyeLightShader::~EyeLightShader()
+{
+}
+
+EyeLightShader::EyeLightShader()
+  : Shader(0),
+    m_color(Vec3f())
+{
+}
+
+Vec3f
+EyeLightShader::Shade(Ray& ray)
+{
+  return Vec3f();
+}
diff --git a/EyeLightShader.hxx b/EyeLightShader.hxx
new file mode 100644 (file)
index 0000000..9b4777e
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef EYELIGHTSHADER_HXX
+#define EYELIGHTSHADER_HXX
+
+#include "Shader.hxx"
+
+class EyeLightShader : public Shader
+{
+public:
+  EyeLightShader(Scene* scene, const Vec3f& color = Vec3f(0.5,0.5,0.5));
+  virtual ~EyeLightShader();
+
+  virtual Vec3f Shade(Ray& ray);
+
+protected:
+  Vec3f m_color;
+  
+private:
+  EyeLightShader();
+};
+#endif
diff --git a/FlatShader.cxx b/FlatShader.cxx
new file mode 100644 (file)
index 0000000..fcae006
--- /dev/null
@@ -0,0 +1,24 @@
+#include "FlatShader.hxx"
+
+FlatShader::FlatShader(Scene* scene,
+                      const Vec3f& color)
+  : Shader(scene),
+    m_color(color)
+{
+}
+
+FlatShader::~FlatShader()
+{
+}
+
+FlatShader::FlatShader()
+  : Shader(0), 
+    m_color(Vec3f())
+{
+}
+
+Vec3f
+FlatShader::Shade(Ray& ray)
+{
+  return Vec3f(); 
+}
diff --git a/FlatShader.hxx b/FlatShader.hxx
new file mode 100644 (file)
index 0000000..7606fb9
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef FLATSHADER_HXX
+#define FLATSHADER_HXX
+
+#include "Shader.hxx"
+
+class FlatShader : public Shader
+{
+public:
+  FlatShader(Scene* scene, const Vec3f& color = Vec3f(0.5,0.5,0.5));
+  virtual ~FlatShader();
+
+  virtual Vec3f Shade(Ray& ray);
+
+private:
+  FlatShader();
+  
+  Vec3f m_color;
+};
+#endif
diff --git a/InfinitePlane.cxx b/InfinitePlane.cxx
new file mode 100644 (file)
index 0000000..442da19
--- /dev/null
@@ -0,0 +1,30 @@
+#include "InfinitePlane.hxx"
+
+InfinitePlane::InfinitePlane(const Vec3f& a, const Vec3f& n, Shader* shader)
+  : Primitive(shader), 
+    m_a(a),
+    m_n(n)
+{
+  
+}
+
+InfinitePlane::~InfinitePlane()
+{
+}
+
+bool
+InfinitePlane::Intersect(Ray& ray)
+{
+  Vec3f diff = m_a - ray.origin();
+  float t = diff.dot(m_n) / ray.direction().dot(m_n);
+  if (t < 1e-5 || t > ray.t()) 
+    return false;
+  ray.setT(t);
+  return true;
+}
+
+Vec3f
+InfinitePlane::GetNormal(Ray& ray)
+{
+  return Vec3f();
+}
diff --git a/InfinitePlane.hxx b/InfinitePlane.hxx
new file mode 100644 (file)
index 0000000..06a5aa0
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef INFINITE_PLANE_HXX
+#define INFINITE_PLANE_HXX
+
+#include "Primitive.hxx"
+
+class InfinitePlane : public Primitive
+{
+public:
+  InfinitePlane(const Vec3f& a, const Vec3f & n, Shader* shader);
+  virtual ~InfinitePlane();
+  
+  virtual bool Intersect(Ray& ray);
+  virtual Vec3f GetNormal(Ray& ray);
+private:
+  Vec3f m_a, m_n;
+};
+#endif
index a9c458e..982c074 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,19 +3,34 @@
 all: MicroTrace
 
 CC = g++ 
-CFLAGS = -O3 -Wall -g -O0
+CFLAGS = -O3 -Wall
+
 
 OBJ = MicroTrace.o\
       Vec3f.o\
       Camera.o\
       PerspectiveCamera.o\
+      Ray.o\
       Image.o\
-      Ray.o
+      InfinitePlane.o\
+      Sphere.o\
+      Triangle.o\
+      Shader.o\
+      FlatShader.o\
+      EyeLightShader.o\
+      ReflectiveEyeLightShader.o\
+      Scene.o\
+      Primitive.o
 
 %.o: %.cxx *.hxx
        $(CC) $(CFLAGS) -c $< -o $@
 
+%.a:
+       ar r $@ $<
+
+
+
 MicroTrace: $(OBJ)
 
 clean: 
-       rm *.o MicroTrace
+       rm *~ *.o *.a MicroTrace
index feb1eeb..53c56ee 100644 (file)
 #include <string>
-#include <iostream>
 
 #include "Vec3f.hxx"
-//#include "Sphere.hxx"
-//#include "Triangle.hxx"
-//#include "InfinitePlane.hxx"
+#include "Sphere.hxx"
+#include "Triangle.hxx"
+#include "InfinitePlane.hxx"
 
 #include "Image.hxx"
 #include "PerspectiveCamera.hxx"
+#include "FlatShader.hxx"
+#include "EyeLightShader.hxx"
+#include "ReflectiveEyeLightShader.hxx"
+#include "Scene.hxx"
+
+void RenderFrameFlat(const std::string& fileName)
+{
+  /* Scene definition */
+
+  Scene scene;
+  
+  /* Flat shaders */
+  FlatShader shd1(&scene, Vec3f(1,0,0)); // red surface
+  FlatShader shd2(&scene, Vec3f(0,1,0)); // green surface
+  FlatShader shd3(&scene, Vec3f(0,0,1)); // blue surface
+  FlatShader shd4(&scene, Vec3f(1,1,0)); // yellow surface
+  FlatShader shd5(&scene, Vec3f(0,1,1)); // cyan surface
+  FlatShader shd6(&scene, Vec3f(1,1,1)); // white surface
 
-void RenderFrame(Camera &camera, const std::string& fileName) {
   /* scene objects */
+  Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
+  Sphere s2(Vec3f(1,-1,1), 2.2, &shd2);
+  Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
+  InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
+
+    
+  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5); 
+  
+  /* add to scene */
+  scene.Add(&s1);
+  scene.Add(&s2);
+  scene.Add(&s3);
+  scene.Add(&p1);
+  scene.Add(&t1);
+  
+  
+  Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
+  Ray ray;                            // primary ray
+  
+  for(int y = 0; y < scene.camera()->resY(); y++)
+    {
+      for (int x = 0; x < scene.camera()->resX(); x++) 
+       {
+         
+         /* Initialize your ray here */
+         
+         scene.camera()->InitRay(x+0.5,y+0.5,ray); // initialize ray
+       
+         Vec3f col = scene.RayTrace(ray);
+         
+         img(x,y) = col; // store pixel color
+         //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
+       }
+    }
+  img.WritePPM(fileName); // write final image
+}
+
+
+void RenderFrameEyeLight(const std::string& fileName)
+{
+  /* Scene definition */
 
-  /*
-   Sphere s1(Vec3f(-2,1.7,0),2);
-   Sphere s2(Vec3f(1,-1,1),2.2);
-   Sphere s3(Vec3f(3,0.8,-2),2);*/
-  //InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0));
-
-  /*
-   Triangle t1(Vec3f(-2,3.7,0),Vec3f(1,2,1),Vec3f(3,2.8,-2));
-   Triangle t2(Vec3f(3,2,3),Vec3f(3,2,-3),Vec3f(-3,2,-3));
-   */
-  Image img(camera.resX(), camera.resY()); // image array
-  Ray ray; // primary ray
-
-  for(int y = 0; y < camera.resY(); y++)
-    for(int x = 0; x < camera.resX(); x++) {
-
-      /* Initialize your ray here */
-
-      camera.InitRay(x + 0.5, y + 0.5, ray); // initialize ray
-
-      Vec3f col = Vec3f(0, 0, 0); // background color
-
-      /*
-       if (s1.Intersect(ray))
-       col = Vec3f(1,0,0);
-       if (s2.Intersect(ray))
-       col = Vec3f(0,1,0);
-       if (s3.Intersect(ray))
-       col = Vec3f(0,0,1);
-       if (p1.Intersect(ray))
-       col = Vec3f(1,1,0);
-       if (t1.Intersect(ray))
-       col = Vec3f(0,1,1);
-       if (t2.Intersect(ray))
-       col = Vec3f(1,1,1);
-
-       img(x,y) = col; // store pixel color
-       */
+  Scene scene;
+  
+  /* Flat shaders */
+  EyeLightShader shd1(&scene, Vec3f(1,0,0)); // red surface
+  EyeLightShader shd2(&scene, Vec3f(0,1,0)); // green surface
+  EyeLightShader shd3(&scene, Vec3f(0,0,1)); // blue surface
+  EyeLightShader shd4(&scene, Vec3f(1,1,0)); // yellow surface
+  EyeLightShader shd5(&scene, Vec3f(0,1,1)); // cyan surface
+  EyeLightShader shd6(&scene, Vec3f(1,1,1)); // white surface
+
+  /* scene objects */
+  Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
+  Sphere s2(Vec3f(1,-1,1), 2.2, &shd2);
+  Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
+  InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
+
+    
+  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5); 
+  
+  /* add to scene */
+  scene.Add(&s1);
+  scene.Add(&s2);
+  scene.Add(&s3);
+  scene.Add(&p1);
+  scene.Add(&t1);
+  
+  Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
+  Ray ray;                            // primary ray
+  
+  for(int y = 0; y < scene.camera()->resY(); y++)
+    {
+      for (int x = 0; x < scene.camera()->resX(); x++) 
+       {
+         
+         /* Initialize your ray here */
+         
+         scene.camera()->InitRay(x+0.5,y+0.5,ray); // initialize ray
+       
+         Vec3f col = scene.RayTrace(ray);
+         
+         img(x,y) = col; // store pixel color
+         //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
+       }
     }
   img.WritePPM(fileName); // write final image
 }
 
+void RenderFrameReflectiveEyeLight(const std::string& fileName)
+{
+  /* Scene definition */
+
+  Scene scene;
+  
+  /* Flat shaders */
+  ReflectiveEyeLightShader shd1(&scene, 1.0, Vec3f(1,0,0)); // red surface
+  ReflectiveEyeLightShader shd2(&scene, 1.0, Vec3f(0.0,1.0,0.0)); // green surface
+  ReflectiveEyeLightShader shd3(&scene, 1.0, Vec3f(0,0,1)); // blue surface
+  ReflectiveEyeLightShader shd4(&scene, 0.8, Vec3f(1,1,0)); // yellow surface
+  ReflectiveEyeLightShader shd5(&scene, 1.0, Vec3f(0,1,1)); // cyan surface
+  ReflectiveEyeLightShader shd6(&scene, 0.0, Vec3f(1,1,1)); // white surface
+
+  /* scene objects */
+  Sphere s1(Vec3f(-2,1.7,0), 2, &shd1);
+  Sphere s2(Vec3f(0.4,-1,1), 2.0, &shd2);
+  Sphere s3(Vec3f(3,0.8,-2), 2, &shd3);
+  InfinitePlane p1(Vec3f(0,-1,0),Vec3f(0,1,0), &shd4);
+
+    
+  Triangle t1(Vec3f(-2,3,1),Vec3f(1,2,1),Vec3f(3,2.8,3), &shd5); 
+  
+  /* add to scene */
+  scene.Add(&s1);
+  scene.Add(&s2);
+  scene.Add(&s3);
+  scene.Add(&p1);
+  scene.Add(&t1);
+  
+  
+  Image img(scene.camera()->resX(),scene.camera()->resY()); // image array
+  Ray ray;                            // primary ray
+  
+  for(int y = 0; y < scene.camera()->resY(); y++)
+    {
+      for (int x = 0; x < scene.camera()->resX(); x++) 
+       {
+         
+         /* Initialize your ray here */
+         
+         scene.camera()->InitRay(x+0.5,y+0.5,ray); // initialize ray
+       
+         Vec3f col = scene.RayTrace(ray);
+         
+         img(x,y) = col; // store pixel color
+         //std::cerr << "Main: Image color = " << img(x,y) << std::endl;
+       }
+    }
+  img.WritePPM(fileName); // write final image
+}
+
+
+
 #define RESX 640 // image x-resolution
 #define RESY 480 // image y-resolution
-using namespace std;
-
-int main(int, char**) {
-  // test vector implementation
-
-  Vec3f bar(1, 4, 5), foo(3, 2, 1);
-  cout << "Using example vector bar=" << bar << ", foo=" << foo << endl;
-  cout << "bar | foo = " << (bar | foo) << ", should be 16" << endl;
-  cout << "bar | bar = " << (bar | bar) << ", should be 42" << endl;
-  cout << "foo | foo = " << (foo | foo) << ", should be 14" << endl;
-  cout << "bar % foo = " << (bar % foo) << ", should be (-6,14,-10)" << endl;
-  cout << "bar % bar = " << (bar % bar) << ", should be (0,0,0)" << endl;
-  cout << "foo % foo = " << (foo % foo) << ", should be (0,0,0)" << endl;
-  cout << "bar.norm() = " << bar.norm() << ", should be 6.48" << endl;
-  cout << "foo.norm() = " << foo.norm() << ", should be 3.74" << endl;
-  cout << "bar*5 = " << (bar * 5) << ", should be (5,20,25)" << endl;
-  cout << "bar/5 = " << (bar / 5) << ", should be (0.2,0.8,1)" << endl;
-  cout << "bar + foo = " << (bar + foo) << ", should be (4,6,6)" << endl;
-  cout << "bar - foo = " << (bar - foo) << ", should be (-2,2,4)" << endl;
-  cout << "foo - bar = " << (foo - bar) << ", should be (2,-2,-4)" << endl;
-  cout << "bar * foo = " << (bar * foo) << ", should be (3,8,5)" << endl;
-  cout << "bar / foo = " << (bar / foo) << ", should be (0.33,2,5)" << endl;
-  cout << "foo / bar = " << (foo / bar) << ", should be (3,0.5,0.2)" << endl;
-
-  cout << "bar *= 4: " << (bar *= 4) << ", should be (4,16,20)" << endl;
-  cout << "bar /= 2: " << (bar /= 2) << ", should be (2,8,10)" << endl;
-  cout << "bar += foo: " << (bar += foo) << ", should be (5,10,11)" << endl;
-  cout << "bar -= Vec3f(5,6,3): " << (bar -= Vec3f(5, 6, 3))
-    << ", should be (0,4,8)" << endl;
-
-  cout << "bar[0] = " << bar[0] << ", should be 0" << endl;
-  cout << "bar[1] = " << bar[1] << ", should be 4" << endl;
-  cout << "bar[2] = " << bar[2] << ", should be 8" << endl;
-  cout << "foo[0] = " << foo[0] << ", should be 3" << endl;
-  cout << "foo[1] = " << foo[1] << ", should be 2" << endl;
-  cout << "foo[2] = " << foo[2] << ", should be 1" << endl;
-
-  bar.normalize();
-  cout << "bar.normalize(): " << bar << ", should be (0,0.44,0.89)" << endl;
-  foo.normalize();
-  cout << "foo.normalize(): " << foo << ", should be (0.80,0.53,0.26)" << endl;
-  bar = foo;
-  cout << "bar := foo: bar = " << bar << ", should be (0.80,0.53,0.26)" << endl;
-
-  /* render three images with different camera settings */
-  /*
-   PerspectiveCamera c1(Vec3f(0, 0, 10), Vec3f(0, 0, -1), Vec3f(0, 1, 0), 60,
-   RESX, RESY);
-   RenderFrame(c1, "perspective1.ppm");
-
-   PerspectiveCamera c2(Vec3f(-8, 3, 8), Vec3f(1, -.1, -1), Vec3f(0, 1, 0), 45,
-   RESX, RESY);
-   RenderFrame(c2, "perspective2.ppm");
-
-   PerspectiveCamera c3(Vec3f(-8, 3, 8), Vec3f(1, -.1, -1), Vec3f(1, 1, 0), 45,
-   RESX, RESY);
-   RenderFrame(c3, "perspective3.ppm");*/
+
+int main(int, char**)
+{
+  RenderFrameFlat("flatshaded.ppm");
+  RenderFrameEyeLight("eyelight.ppm");
+  RenderFrameReflectiveEyeLight("reflective.ppm");
 }
index b7faff6..fb9282d 100644 (file)
@@ -1,3 +1,6 @@
+#include <limits>
+#include <iostream>
+
 #include "PerspectiveCamera.hxx"
 
 PerspectiveCamera::PerspectiveCamera()
@@ -18,6 +21,21 @@ PerspectiveCamera::PerspectiveCamera(const Vec3f& pos,
     m_angle(angle)    
 {
   // preprocess the values and fill the rest of the member variables here
+  
+  // compute local coordinate system
+  m_zAxis = dir;
+  m_xAxis = dir.cross(up);
+  m_yAxis = m_xAxis.cross(m_zAxis);
+
+  m_xAxis.normalize();
+  m_yAxis.normalize();
+  m_zAxis.normalize();
+
+  m_aspect = resX/static_cast<float>(resY);
+  
+  // derive focal length from opening angle
+  float angle_in_rad = angle * M_PI / 180.0f;
+  m_focus = 1.0 / tan(angle_in_rad * 0.5);
 }
 
 PerspectiveCamera::~PerspectiveCamera()
@@ -39,8 +57,18 @@ bool
 PerspectiveCamera::InitRay(float x, //!< pixel x-coordinate 
                           float y, //!< pixel y-coordinate
                           Ray& ray //!< should be filled by this function
-                          )
+                          ) const
 {
   // define direction,position and maximum hit distance of Ray here
-  return false;
+  Vec3f dir = m_xAxis * ( 2.0f * ((x/static_cast<float>(m_resX) - 0.5 ) * m_aspect ) )
+    + m_yAxis * ( 2.0f * (y/static_cast<float>(m_resY) - 0.5 ) )
+    + ( m_zAxis * m_focus );
+  dir.normalize();
+  
+  ray.setDir(dir);
+  ray.setOrigin(m_pos);
+  float t = std::numeric_limits<float>::max();
+  ray.setT(t);
+  
+  return true;
 }
index 8178087..e171d5b 100644 (file)
@@ -15,7 +15,7 @@ public:
                    );
   ~PerspectiveCamera();
 
-  virtual bool InitRay(float x, float y, Ray &ray);
+  virtual bool InitRay(float x, float y, Ray &ray) const;
 
 private:
   //! hidden constructors to prevent misuse. If you need those at some point, just make them public and implement them properly!
diff --git a/Primitive.cxx b/Primitive.cxx
new file mode 100644 (file)
index 0000000..850cb24
--- /dev/null
@@ -0,0 +1,22 @@
+#include "Primitive.hxx"
+
+Primitive::Primitive(Shader* shader)
+  : m_shader(shader)
+{
+}
+
+Primitive::~Primitive()
+{
+}
+
+bool
+Primitive::Occluded(Ray& ray)
+{
+  return Intersect(ray);
+}
+
+Shader*
+Primitive::shader() 
+{
+  return m_shader;
+}
index f147b35..04e201f 100644 (file)
@@ -2,11 +2,21 @@
 #define PRIMITIVE_HXX
 
 #include "Ray.hxx"
+#include "Shader.hxx"
 
 class Primitive
 {
 public:
+  Primitive(Shader* shader = 0);
+  virtual ~Primitive();
+
   virtual bool Intersect(Ray &ray) = 0;
+  virtual bool Occluded(Ray& ray);
+  virtual Vec3f GetNormal(Ray& ray) = 0;
+  
+  Shader* shader();
+protected:
+  Shader* m_shader;
 };
 
 #endif
diff --git a/Ray.cxx b/Ray.cxx
index be4a4f4..b7e5457 100644 (file)
--- a/Ray.cxx
+++ b/Ray.cxx
@@ -1,12 +1,22 @@
+#include <limits>
+
 #include "Ray.hxx"
 
 Ray::Ray()
+  : m_org(Vec3f()),
+    m_dir(Vec3f()),
+    m_hit(0)
 {
+  m_t = std::numeric_limits<float>::max();
 }
 
 Ray::Ray(const Vec3f& org, 
         const Vec3f& dir)
+  : m_org(org),
+    m_dir(dir),
+    m_hit(0)
 {
+  m_t = std::numeric_limits<float>::max();
 }
 
 Ray::~Ray()
@@ -15,28 +25,75 @@ Ray::~Ray()
 
 Ray::Ray(const Ray& r)
 {
+  m_org = r.m_org;
+  m_dir = r.m_dir;
+  m_t = r.m_t;
+  m_hit = r.m_hit;
 }
 
 Ray&
 Ray::operator=(const Ray& r)
 {
+  if(this != &r)
+    {
+      m_org = r.m_org;
+      m_dir = r.m_dir;
+      m_t = r.m_t;
+      m_hit = r.m_hit;
+    }
   return *this;
 }
 
 const Vec3f&
 Ray::origin() const
 {
-  return Vec3f();
+  return m_org;
 }
 
 const Vec3f&
 Ray::direction() const
 {
-  return Vec3f();
+  return m_dir;
 }
 
 float
 Ray::t() const
 {
-  return 0.0f;
+  return m_t;
+}
+
+void
+Ray::setOrigin(const Vec3f& o)
+{
+  m_org = o;
+}
+
+void
+Ray::setDir(const Vec3f& d)
+{
+  m_dir = d;
+}
+
+void
+Ray::setT(float t)
+{
+  m_t = t;
+}
+
+Primitive*
+Ray::hit()
+{
+  return m_hit;
+}
+
+unsigned int 
+Ray::recursionDepth() const
+{
+  return m_level;
+}
+
+void
+Ray::setRecursionDepth(unsigned int i)
+{
+  m_level = i;
 }
diff --git a/Ray.hxx b/Ray.hxx
index a432830..f37425c 100644 (file)
--- a/Ray.hxx
+++ b/Ray.hxx
@@ -3,6 +3,8 @@
 
 #include "Vec3f.hxx"
 
+class Primitive;
+
 class Ray
 {
 public:
@@ -15,10 +17,22 @@ public:
   const Vec3f& origin() const;
   const Vec3f& direction() const;
   float t() const;
+  Primitive* hit();
+  unsigned int recursionDepth() const;
+
+  void setOrigin(const Vec3f& o);
+  void setDir(const Vec3f& d);
+  void setT(float t);
+  void setRecursionDepth(unsigned int i);
+
 private:
   Vec3f m_org; //!< ray origin
   Vec3f m_dir; //!< ray direction
   float m_t;   //!< current/maximum hit distance
+   
+  unsigned int m_level; //!< level of recursion
+  
+  Primitive* m_hit;
 };
 
 inline std::ostream &operator<<(std::ostream &o,const Ray &ray)
diff --git a/ReflectiveEyeLightShader.cxx b/ReflectiveEyeLightShader.cxx
new file mode 100644 (file)
index 0000000..2bd0db3
--- /dev/null
@@ -0,0 +1,25 @@
+#include "ReflectiveEyeLightShader.hxx"
+
+ReflectiveEyeLightShader::ReflectiveEyeLightShader(Scene* scene,
+                                                  float reflectivity,
+                                                  const Vec3f& color)
+  : EyeLightShader(scene,color),
+    m_reflectivity(reflectivity)
+{
+}
+
+ReflectiveEyeLightShader::~ReflectiveEyeLightShader()
+{
+}
+
+ReflectiveEyeLightShader::ReflectiveEyeLightShader()
+  : EyeLightShader(0),
+    m_reflectivity(0)
+{
+}
+
+Vec3f
+ReflectiveEyeLightShader::Shade(Ray& ray)
+{
+  return Vec3f();
+}
diff --git a/ReflectiveEyeLightShader.hxx b/ReflectiveEyeLightShader.hxx
new file mode 100644 (file)
index 0000000..d7b8798
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef REFLECTIVEEYELIGHTSHADER_HXX
+#define REFLECTIVEEYELIGHTSHADER_HXX
+
+#include "EyeLightShader.hxx"
+
+class ReflectiveEyeLightShader : public EyeLightShader
+{
+public:
+  ReflectiveEyeLightShader(Scene* scene, float reflectivity, const Vec3f& color = Vec3f(0.5,0.5,0.5));
+  virtual ~ReflectiveEyeLightShader();
+
+  virtual Vec3f Shade(Ray& ray);
+
+protected:
+  float m_reflectivity;
+
+private:
+  ReflectiveEyeLightShader();
+};
+#endif
diff --git a/Scene.cxx b/Scene.cxx
new file mode 100644 (file)
index 0000000..184b7e1
--- /dev/null
+++ b/Scene.cxx
@@ -0,0 +1,60 @@
+#include "Scene.hxx"
+#include "PerspectiveCamera.hxx"
+
+Scene::Scene()
+  : m_camera(new PerspectiveCamera(Vec3f(0,0,8), 
+                                  Vec3f(0,0,-1), 
+                                  Vec3f(0,1,0), 
+                                  50, 
+                                  640, 
+                                  480)
+            ),
+    m_bgColor(Vec3f(0,0,0))
+{
+}
+
+Scene::~Scene()
+{
+  delete m_camera;
+}
+
+Scene::Scene(const Scene& s)
+{
+  operator=(s);
+}
+
+Scene&
+Scene::operator=(const Scene& s)
+{
+  return *this;
+}
+
+void 
+Scene::Add(Primitive* p)
+{
+}
+
+
+bool
+Scene::Intersect(Ray& ray)
+{
+  return false;
+}
+
+bool
+Scene::Occluded(Ray& ray)
+{
+  return false;
+}
+
+Vec3f
+Scene::RayTrace(Ray& ray)
+{
+  return Vec3f();
+}
+
+const Camera* 
+Scene::camera() const
+{
+  return m_camera;
+}
diff --git a/Scene.hxx b/Scene.hxx
new file mode 100644 (file)
index 0000000..18deb79
--- /dev/null
+++ b/Scene.hxx
@@ -0,0 +1,39 @@
+#ifndef SCENE_HXX
+#define SCENE_HXX
+
+#include <vector>
+
+#include "Ray.hxx"
+#include "Camera.hxx"
+#include "Primitive.hxx"
+
+class Scene
+{
+public:
+  Scene();
+  virtual ~Scene();
+  
+  // add another primitive to the scene
+  void Add(Primitive* p);
+  // intersect the ray with all objects in the scene
+  virtual bool Intersect(Ray& ray);
+  // find occluder
+  virtual bool Occluded(Ray& ray);
+  
+  // trace the given ray and shade it, returnt the color of the shaded ray
+  Vec3f RayTrace(Ray& ray);
+    
+  const Camera* camera() const; 
+private:
+  Scene(const Scene& );
+  Scene& operator=(const Scene& );
+
+  Camera* m_camera;
+  // background color
+  Vec3f m_bgColor;
+  
+  // primitives
+  std::vector<Primitive*> m_primitives;
+};
+#endif
diff --git a/Shader.cxx b/Shader.cxx
new file mode 100644 (file)
index 0000000..80d31e2
--- /dev/null
@@ -0,0 +1,25 @@
+#include "Shader.hxx"
+
+Shader::Shader(Scene* scene)
+  : m_scene(scene)
+{
+}
+
+Shader::~Shader()
+{
+}
+
+Shader::Shader()
+{
+}
+
+Shader::Shader(const Shader& s)
+{
+  operator=(s);
+}
+
+Shader&
+Shader::operator=(const Shader& )
+{
+  return *this;
+}
diff --git a/Shader.hxx b/Shader.hxx
new file mode 100644 (file)
index 0000000..ac6de1d
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SHADER_HXX
+#define SHADER_HXX
+
+#include "Vec3f.hxx"
+#include "Ray.hxx"
+
+// forward declaration
+class Scene;
+
+class Shader
+{
+public:
+  Shader(Scene* scene);
+  virtual ~Shader();
+  
+  virtual Vec3f Shade(Ray& ray) = 0;
+protected:
+  Scene* m_scene;
+  
+private:
+  Shader();
+  Shader(const Shader& );
+  Shader& operator=(const Shader& );
+};
+#endif
diff --git a/Sphere.cxx b/Sphere.cxx
new file mode 100644 (file)
index 0000000..3c19afa
--- /dev/null
@@ -0,0 +1,43 @@
+#include "Sphere.hxx"
+
+Sphere::Sphere(const Vec3f& center, float radius, Shader* shader)
+  : Primitive(shader), 
+    m_center(center),
+    m_radius(radius)
+{
+}
+
+Sphere::~Sphere()
+{
+}
+
+bool
+Sphere::Intersect(Ray& ray)
+{
+  float A = ray.direction().dot(ray.direction());
+  float C = (ray.origin()-m_center).dot(ray.origin()-m_center) - m_radius*m_radius;
+  float B = 2 * ray.direction().dot(ray.origin()-m_center);
+
+  if( B*B-4*A*C < 0 )
+    return false;
+  
+  float root = sqrtf(B*B-4*A*C);
+  float t = (-B-root)/(2.0f*A);
+  if(t > ray.t())
+    return false;
+      
+  if( t < 1e-6 )
+    {
+      t = (-B+root)/(2.0f*A);
+      if( t < 1e-6 || t > ray.t())
+       return false;
+    }
+  ray.setT(t);
+  return true;
+}
+
+Vec3f
+Sphere::GetNormal(Ray& ray)
+{
+  return Vec3f();
+}
diff --git a/Sphere.hxx b/Sphere.hxx
new file mode 100644 (file)
index 0000000..28604e7
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef SPHERE_HXX
+#define SPHERE_HXX
+
+#include "Primitive.hxx"
+
+
+class Sphere : public Primitive
+{
+public:
+  Sphere(const Vec3f& center, float radius, Shader* shader);
+  virtual ~Sphere();
+
+  virtual bool Intersect(Ray& ray);  
+  virtual Vec3f GetNormal(Ray& ray);
+private:
+  Vec3f m_center;
+  float m_radius;
+};
+#endif
index ffddbc8..761abcb 100644 (file)
@@ -2,8 +2,10 @@
 
 Triangle::Triangle(const Vec3f& a,
                   const Vec3f& b,
-                  const Vec3f& c)
-  : m_a(a),
+                  const Vec3f& c,
+                  Shader* shader)
+  : Primitive(shader),
+    m_a(a),
     m_b(b),
     m_c(c)
 {
@@ -49,3 +51,9 @@ Triangle::Intersect(Ray& ray)
     
   return true;
 }
+
+Vec3f
+Triangle::GetNormal(Ray& ray)
+{
+  return Vec3f();
+}
index 320cca5..fbf4e2c 100644 (file)
@@ -6,10 +6,11 @@
 class Triangle : public Primitive
 {
 public:
-  Triangle(const Vec3f& a, const Vec3f& b, const Vec3f& c);
+  Triangle(const Vec3f& a, const Vec3f& b, const Vec3f& c, Shader* shader);
   virtual ~Triangle();
   
   virtual bool Intersect(Ray& ray);
+  virtual Vec3f GetNormal(Ray& ray);
 private:
   Vec3f m_a, m_b, m_c;
 };
index b68f9e8..f656d29 100644 (file)
--- a/Vec3f.cxx
+++ b/Vec3f.cxx
 
 #include "Vec3f.hxx"
 
-Vec3f::Vec3f() {
+Vec3f::Vec3f()
+{
+  for(int i = 0; i < 3; ++i)
+    {
+      m_values[i] = 0.0f;
+    }
 }
 
-Vec3f::Vec3f(float x, float y, float z) {
+Vec3f::Vec3f(float x, float y, float z)
+{
   m_values[0] = x;
   m_values[1] = y;
   m_values[2] = z;
 }
 
-Vec3f::~Vec3f() {
+Vec3f::~Vec3f()
+{
 }
 
-Vec3f::Vec3f(const Vec3f& o) {
-  for(size_t i = 0; i < DIM; i++) {
-    m_values[i] = o.m_values[i];
-  }
+Vec3f::Vec3f(const Vec3f& o)
+{
+  for(int i = 0; i < 3; ++i)
+    {
+      m_values[i] = o.m_values[i];
+    }
 }
 
-Vec3f& Vec3f::operator=(const Vec3f& o) {
-  for(size_t i = 0; i < DIM; i++) {
-    m_values[i] = o.m_values[i];
-  }
+Vec3f& 
+Vec3f::operator=(const Vec3f& o)
+{
+  if(this != &o)
+    {
+      for(int i = 0; i < 3; ++i)
+       {
+         m_values[i] = o.m_values[i];
+       } 
+    }
   return *this;
 }
 
-float Vec3f::operator|(const Vec3f& o) {
-
-  return dot(o);
-}
-
-float Vec3f::dot(const Vec3f& o) {
-  float prod = 0;
-  for(size_t i = 0; i < DIM; i++) {
-    prod += m_values[i] * o.m_values[i];
-  }
-  return prod;
-}
-
-Vec3f Vec3f::operator%(const Vec3f& o) {
-  return cross(o);
-}
-
-Vec3f Vec3f::cross(const Vec3f& o) {
-  return Vec3f(m_values[1] * o.m_values[2] - m_values[2] * o.m_values[1],
-    m_values[2] * o.m_values[0] - m_values[0] * o.m_values[2], m_values[0]
-      * o.m_values[1] - m_values[1] * o.m_values[0]);
-}
-
-void Vec3f::normalize() {
-  *this /= norm();
-}
-
-float Vec3f::norm() const {
-  return sqrt(m_values[0] * m_values[0] + m_values[1] * m_values[1]
-    + m_values[2] * m_values[2]);
-}
-
-Vec3f Vec3f::operator*(const float t) const {
+float 
+Vec3f::operator|(const Vec3f& o) const
+{
+  return this->dot(o);
+}
+
+float 
+Vec3f::dot(const Vec3f& o) const
+{
+  float dot = 0.0f;
+  for(int i = 0; i < 3; ++i)
+    {
+      dot += m_values[i]*o.m_values[i];
+    }
+  return dot;
+}
+  
+Vec3f 
+Vec3f::operator%(const Vec3f& o) const
+{
+  return this->cross(o);
+}
+
+Vec3f 
+Vec3f::cross(const Vec3f& o) const
+{
+  float x = m_values[1]*o.m_values[2] - m_values[2]*o.m_values[1];
+  float y = m_values[2]*o.m_values[0] - m_values[0]*o.m_values[2];
+  float z = m_values[0]*o.m_values[1] - m_values[1]*o.m_values[0];
+  
+  return Vec3f(x,y,z);
+}
+  
+void 
+Vec3f::normalize()
+{
+  float norm = this->norm();
+  *this *= 1.0f/norm;
+}
+
+float 
+Vec3f::norm() const
+{
+  float n = this->dot(*this);
+  return sqrtf(n);
+}
+
+Vec3f 
+Vec3f::operator*(const float t) const
+{
   Vec3f v(*this);
   return v *= t;
 }
 
-Vec3f& Vec3f::operator*=(const float t) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] *= t;
-  }
+Vec3f& 
+Vec3f::operator*=(const float t)
+{
+  for(int i = 0; i < 3; ++i)
+    {
+      m_values[i] *= t;
+    }
   return *this;
 }
 
-Vec3f Vec3f::operator/(const float t) const {
+Vec3f 
+Vec3f::operator/(const float t) const
+{
   Vec3f v(*this);
   return v /= t;
 }
 
-Vec3f& Vec3f::operator/=(const float t) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] /= t;
-  }
+Vec3f& 
+Vec3f::operator/=(const float t)
+{
+  for(int i = 0; i < 3; ++i)
+    {
+      m_values[i] /= t;
+    }
   return *this;
 }
 
 // example implementation of a standard operator
-Vec3f Vec3f::operator+(const Vec3f& o) const {
+Vec3f 
+Vec3f::operator+(const Vec3f& o) const
+{
   Vec3f v(*this);
+  
   return v += o;
 }
 
 // example implementation of an in-place operator
-Vec3f& Vec3f::operator+=(const Vec3f& o) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] += o.m_values[i];
-  }
+Vec3f& 
+Vec3f::operator+=(const Vec3f& o)
+{
+  for(unsigned int i = 0; i < 3; ++i)
+    {
+      m_values[i] += o.m_values[i];
+    }
+  
   return *this;
 }
-
-Vec3f Vec3f::operator-(const Vec3f& o) const {
+  
+Vec3f 
+Vec3f::operator-(const Vec3f& o) const
+{
   Vec3f v(*this);
+  
   return v -= o;
 }
 
-Vec3f& Vec3f::operator-=(const Vec3f& o) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] -= o.m_values[i];
-  }
+Vec3f& 
+Vec3f::operator-=(const Vec3f& o)
+{
+  for(unsigned int i = 0; i < 3; ++i)
+    {
+      m_values[i] -= o.m_values[i];
+    }
   return *this;
 }
-
-Vec3f Vec3f::operator*(const Vec3f& o) const {
+  
+Vec3f 
+Vec3f::operator*(const Vec3f& o) const
+{
   Vec3f v(*this);
+
   return v *= o;
 }
 
-Vec3f& Vec3f::operator*=(const Vec3f& o) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] *= o.m_values[i];
-  }
+Vec3f& 
+Vec3f::operator*=(const Vec3f& o)
+{
+  for(unsigned int i = 0; i < 3; ++i)
+    {
+      m_values[i] *= o.m_values[i];
+    }
   return *this;
 }
 
-Vec3f Vec3f::operator/(const Vec3f& o) const {
+Vec3f 
+Vec3f::operator/(const Vec3f& o) const
+{
   Vec3f v(*this);
+  
   return v /= o;
 }
 
-Vec3f& Vec3f::operator/=(const Vec3f& o) {
-  for(unsigned int i = 0; i < 3; ++i) {
-    m_values[i] /= o.m_values[i];
-  }
+Vec3f& 
+Vec3f::operator/=(const Vec3f& o)
+{
+  for(unsigned int i = 0; i < 3; ++i)
+    {
+      m_values[i] /= o.m_values[i];
+    }
   return *this;
 }
 
-float Vec3f::operator[](unsigned int i) const {
-  assert(i < DIM);
+float 
+Vec3f::operator[](unsigned int i) const
+{
+  assert( i < 3 );
   return m_values[i];
 }
 
-float& Vec3f::operator[](unsigned int i) {
-  assert(i < DIM);
+float& 
+Vec3f::operator[](unsigned int i)
+{
+  assert(i < 3);
   return m_values[i];
 }
index 908a8fc..6b67d5b 100644 (file)
--- a/Vec3f.hxx
+++ b/Vec3f.hxx
@@ -4,86 +4,80 @@
 #include <cmath>
 #include <iostream>
 
+
 #ifndef MIN
 #define MIN(a,b) ((a)<(b)?(a):(b))
 #define MAX(a,b) ((a)>(b)?(a):(b))
 #endif
 
-#define max(a,b) MAX(a,b)
-#define min(a,b) MIN(a,b)
 
 #define Epsilon 1E-4
 #define Infinity HUGE_VAL
 
-// dimension
-#define DIM 3
-
 //! Standard operators and useful methods for 3d vectors
 //! Fill in the missing parts in Vec3f.cxx
-class Vec3f {
+class Vec3f 
+{
 public:
-       Vec3f();
-       Vec3f(float x, float y, float z);
-
-       ~Vec3f();
-
-       Vec3f(const Vec3f& o);
-       Vec3f& operator=(const Vec3f& o);
-
-       //! dot product
-       float operator|(const Vec3f& o);
-       float dot(const Vec3f& o);
-
-       //! cross product
-       Vec3f operator%(const Vec3f& o);
-       Vec3f cross(const Vec3f& o);
-
-       //! normalize vector
-       void normalize();
-       //! length of a vector
-       float norm() const;
-
-       //! (self-)multiply with scalar
-       Vec3f operator*(const float t) const;
-       Vec3f& operator*=(const float t);
-
-       //! (self-)division by scalar
-       Vec3f operator/(const float t) const;
-       Vec3f& operator/=(const float t);
-
-       //! vector (self-)addition
-       Vec3f operator+(const Vec3f& o) const;
-       Vec3f& operator+=(const Vec3f& o);
-
-       //! vector (self-)subtraction
-       Vec3f operator-(const Vec3f& o) const;
-       Vec3f& operator-=(const Vec3f& o);
-
-       //! component-wise multiplication of two vectors
-       Vec3f operator*(const Vec3f& o) const;
-       Vec3f& operator*=(const Vec3f& o);
-
-       //! component-wise division of two vectors
-       Vec3f operator/(const Vec3f& o) const;
-       Vec3f& operator/=(const Vec3f& o);
-
-       //! element access functions ( read-only and read-write )
-       float operator[](unsigned int i) const;
-       float& operator[](unsigned int i);
-/*
-       inline std::string& operator std::string() {
-         std::string s = "(" + v[0] << "," << v[1] << "," << v[2] << ")");
-         return std::string(
-       }
-*/
+  Vec3f();
+  Vec3f(float x, float y, float z);
+  
+  ~Vec3f();
+
+  Vec3f(const Vec3f& o);
+  Vec3f& operator=(const Vec3f& o);
+
+  //! dot product
+  float operator|(const Vec3f& o) const;
+  float dot(const Vec3f& o) const;
+  
+  //! cross product
+  Vec3f operator%(const Vec3f& o) const;
+  Vec3f cross(const Vec3f& o) const;
+  
+  //! normalize vector
+  void normalize();
+  //! length of a vector
+  float norm() const;
+
+  //! (self-)multiply with scalar
+  Vec3f operator*(const float t) const;
+  Vec3f& operator*=(const float t);
+
+  //! (self-)division by scalar
+  Vec3f operator/(const float t) const;
+  Vec3f& operator/=(const float t);
+
+  //! vector (self-)addition
+  Vec3f operator+(const Vec3f& o) const;
+  Vec3f& operator+=(const Vec3f& o);
+  
+  //! vector (self-)subtraction
+  Vec3f operator-(const Vec3f& o) const;
+  Vec3f& operator-=(const Vec3f& o);
+  
+  //! component-wise multiplication of two vectors
+  Vec3f operator*(const Vec3f& o) const;
+  Vec3f& operator*=(const Vec3f& o);
+
+  //! component-wise division of two vectors
+  Vec3f operator/(const Vec3f& o) const;
+  Vec3f& operator/=(const Vec3f& o);
+
+  //! element access functions ( read-only and read-write )
+  float operator[](unsigned int i) const;
+  float& operator[](unsigned int i);
 private:
-       float m_values[3];
+  float m_values[3];
 };
 
-inline std::ostream& operator<<(std::ostream& o, const Vec3f& v) {
+inline std::ostream& operator<<(std::ostream& o, const Vec3f& v)
+{
   o << "(" << v[0] << "," << v[1] << "," << v[2] << ")";
   return o;
 }
 
 #endif
 
+
This page took 0.078498 seconds and 4 git commands to generate.