diff --git a/main/Scene.cc b/main/Scene.cc index f050f73..44dcb27 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -3,8 +3,10 @@ #include #include #include -#include +#include /* pair */ #include +#include /* sort() */ +#include /* binary_function */ #include #include "BMP.h" #include "shapes/Shape.h" @@ -158,7 +160,7 @@ Vector Scene::traceRay(const Ray & ray) { Vector color; - vector< pair > hits = getRayHits(ray, 0.0); + vector hits = getRayHits(ray); if (hits.size() > 0) { color[0] = color[1] = color[2] = 1.0; @@ -167,10 +169,9 @@ Vector Scene::traceRay(const Ray & ray) return color; } -vector< pair > -Scene::getRayHits(const Ray & ray, double minDist) +vector Scene::getRayHits(const Ray & ray) { - vector< pair > hits; + vector hits; /* loop through all shapes in the scene */ for (vector::iterator it = m_shapes.begin(); @@ -179,17 +180,26 @@ Scene::getRayHits(const Ray & ray, double minDist) { Solver::Result intersections = (*it)->intersect(ray); - if (intersections.numResults > 0) + for (int i = 0; i < intersections.numResults; i++) { - for (int i = 0; i < intersections.numResults; i++) + Vector normal = + (*it)->getNormalAt(ray[intersections.results[i]]); + double dot = normal % ray.getDirection(); + if (dot < 0.0) /* cull back faces */ { - if (intersections.results[i] > minDist) - { - hits.push_back(pair(*it, intersections.results[i])); - } + hits.push_back(ShapeDistance(*it, intersections.results[i])); } } } + /* now that we have ALL the hits, sort them by distance */ + sort(hits.begin(), hits.end()); + return hits; } + +bool operator<(const Scene::ShapeDistance & sd1, + const Scene::ShapeDistance & sd2) +{ + return sd1.second < sd2.second; +} diff --git a/main/Scene.h b/main/Scene.h index 221566e..4e1a0ae 100755 --- a/main/Scene.h +++ b/main/Scene.h @@ -16,6 +16,15 @@ class Scene { public: + /* types */ + class ShapeDistance : public std::pair + { + public: + ShapeDistance(Shape *, double) : std::pair() + { + }; + }; + Scene(std::map options, const char * filename); ~Scene(); @@ -26,8 +35,7 @@ class Scene void load(const char * filename); void renderPixel(int x, int y, unsigned char * pixel); Vector traceRay(const Ray & ray); - std::vector< std::pair > - getRayHits(const Ray & ray, double minDist); + std::vector getRayHits(const Ray & ray); /* rendering parameters */ int m_width; @@ -50,5 +58,8 @@ class Scene unsigned char * m_data; }; +bool operator<(const Scene::ShapeDistance & sd1, + const Scene::ShapeDistance & sd2); + #endif