diff --git a/main/Scene.cc b/main/Scene.cc index f50dd5a..3a5c215 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -28,6 +28,7 @@ Scene::Scene(const map & options, m_verbose = false; m_data = NULL; m_ambient_light = Color(0.1, 0.1, 0.1); + m_max_depth = 10; load(filename); @@ -136,35 +137,35 @@ void Scene::renderPixel(int x, int y, unsigned char * pixel) } Color Scene::traceRay(const Ray & ray) +{ + return traceRayDepth(ray, m_max_depth); +} + +Color Scene::traceRayDepth(const Ray & ray, int depth) { Color color; - vector hits = getRayHits(ray); + ShapeDistance hit = getRayClosestHit(ray); - for (vector::const_iterator it = hits.begin(); - it != hits.end(); - it++) - { - /* compute the Phong lighting for each hit */ - refptr material = it->first->getMaterial(); + /* compute the Phong lighting for each hit */ + refptr material = hit.shape->getMaterial(); - Vector surfacePoint = ray[it->second]; + Vector surfacePoint = ray[hit.dist]; - color = Lighting::computePhong(material, - m_lights, - ray, - surfacePoint, - it->first->getNormalAt(surfacePoint), - m_ambient_light); - } + color += Lighting::computePhong(material, + m_lights, + ray, + surfacePoint, + hit.shape->getNormalAt(surfacePoint), + m_ambient_light); return color; } -vector Scene::getRayHits(const Ray & ray) +Scene::ShapeDistance Scene::getRayClosestHit(const Ray & ray) { - vector hits; - double minSolidDist = 0.0; + ShapeDistance hit; + bool foundOne = false; /* loop through all shapes in the scene */ for (vector< refptr >::iterator it = m_shapes.begin(); @@ -180,54 +181,21 @@ vector Scene::getRayHits(const Ray & ray) refptr shape = intersections[i].shape; const Vector & isect_point = intersections[i].vector; Vector normal = shape->getNormalAt(isect_point); -// double dot = normal % ray.getDirection(); double intersect_dist = (isect_point - ray.getOrigin()).mag(); -// if (dot < 0.0) /* cull back faces */ -// { - double transparency = (*it)->getTransparency(); - if (transparency == 0.0 && - (minSolidDist == 0.0 || minSolidDist > intersect_dist)) - { - minSolidDist = intersect_dist; - } - if (minSolidDist == 0.0 || minSolidDist >= intersect_dist) - { - hits.push_back(ShapeDistance(shape, intersect_dist)); - } -// } - } - } - - /* now that we have ALL the hits, sort them by distance */ - sort(hits.begin(), hits.end()); - - double transparency = 1.0; - /* now go through them all until we get to the maximum number - * of hits, or until the transparency left is below the threshold */ - for (unsigned int hits_index = 0, sz = hits.size(); - hits_index < sz; - hits_index++) - { - transparency *= hits[hits_index].first->getTransparency(); - if (hits_index >= (SCENE_MAX_TRANSPARENT_HITS - 1) - || transparency < SCENE_TRANSPARENCY_THRESHOLD) - { - /* delete the rest of the hits */ - for (int i = 0, num_to_del = sz - hits_index - 1; - i < num_to_del; - i++) + if (foundOne == false || intersect_dist < hit.dist) { - hits.pop_back(); + hit.shape = shape; + hit.dist = intersect_dist; + foundOne = true; } - break; } } - return hits; + return hit; } bool operator<(const Scene::ShapeDistance & sd1, const Scene::ShapeDistance & sd2) { - return sd1.second < sd2.second; + return sd1.dist < sd2.dist; } diff --git a/main/Scene.h b/main/Scene.h index 3c4d451..d311680 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -23,13 +23,17 @@ class Scene { public: /* types */ - class ShapeDistance : public std::pair, double> + class ShapeDistance { public: + ShapeDistance() {} ShapeDistance(refptr shape, double dist) - : std::pair, double>(shape, dist) { - }; + this->shape = shape; + this->dist = dist; + } + refptr shape; + double dist; }; Scene(const std::map & options, @@ -47,7 +51,8 @@ class Scene /* private methods */ void renderPixel(int x, int y, unsigned char * pixel); Color traceRay(const Ray & ray); - std::vector getRayHits(const Ray & ray); + Color traceRayDepth(const Ray & ray, int depth); + ShapeDistance getRayClosestHit(const Ray & ray); /* In Scene-load.cc */ void load(const char * filename); @@ -68,6 +73,7 @@ class Scene bool m_verbose; double m_vfov; Color m_ambient_light; + int m_max_depth; /* private data */ std::vector< refptr > m_shapes;