stubbed out recursion, changed Scene::getRayHits() to Scene::getRayClosestHit()
git-svn-id: svn://anubis/fart/trunk@160 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
parent
5035c80d94
commit
c78e5941c8
@ -28,6 +28,7 @@ Scene::Scene(const map<string, const char *> & options,
|
|||||||
m_verbose = false;
|
m_verbose = false;
|
||||||
m_data = NULL;
|
m_data = NULL;
|
||||||
m_ambient_light = Color(0.1, 0.1, 0.1);
|
m_ambient_light = Color(0.1, 0.1, 0.1);
|
||||||
|
m_max_depth = 10;
|
||||||
|
|
||||||
load(filename);
|
load(filename);
|
||||||
|
|
||||||
@ -136,35 +137,35 @@ void Scene::renderPixel(int x, int y, unsigned char * pixel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Color Scene::traceRay(const Ray & ray)
|
Color Scene::traceRay(const Ray & ray)
|
||||||
|
{
|
||||||
|
return traceRayDepth(ray, m_max_depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color Scene::traceRayDepth(const Ray & ray, int depth)
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
vector<ShapeDistance> hits = getRayHits(ray);
|
ShapeDistance hit = getRayClosestHit(ray);
|
||||||
|
|
||||||
for (vector<ShapeDistance>::const_iterator it = hits.begin();
|
/* compute the Phong lighting for each hit */
|
||||||
it != hits.end();
|
refptr<Material> material = hit.shape->getMaterial();
|
||||||
it++)
|
|
||||||
{
|
|
||||||
/* compute the Phong lighting for each hit */
|
|
||||||
refptr<Material> material = it->first->getMaterial();
|
|
||||||
|
|
||||||
Vector surfacePoint = ray[it->second];
|
Vector surfacePoint = ray[hit.dist];
|
||||||
|
|
||||||
color = Lighting::computePhong(material,
|
color += Lighting::computePhong(material,
|
||||||
m_lights,
|
m_lights,
|
||||||
ray,
|
ray,
|
||||||
surfacePoint,
|
surfacePoint,
|
||||||
it->first->getNormalAt(surfacePoint),
|
hit.shape->getNormalAt(surfacePoint),
|
||||||
m_ambient_light);
|
m_ambient_light);
|
||||||
}
|
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Scene::ShapeDistance> Scene::getRayHits(const Ray & ray)
|
Scene::ShapeDistance Scene::getRayClosestHit(const Ray & ray)
|
||||||
{
|
{
|
||||||
vector<ShapeDistance> hits;
|
ShapeDistance hit;
|
||||||
double minSolidDist = 0.0;
|
bool foundOne = false;
|
||||||
|
|
||||||
/* loop through all shapes in the scene */
|
/* loop through all shapes in the scene */
|
||||||
for (vector< refptr<Shape> >::iterator it = m_shapes.begin();
|
for (vector< refptr<Shape> >::iterator it = m_shapes.begin();
|
||||||
@ -180,54 +181,21 @@ vector<Scene::ShapeDistance> Scene::getRayHits(const Ray & ray)
|
|||||||
refptr<Shape> shape = intersections[i].shape;
|
refptr<Shape> shape = intersections[i].shape;
|
||||||
const Vector & isect_point = intersections[i].vector;
|
const Vector & isect_point = intersections[i].vector;
|
||||||
Vector normal = shape->getNormalAt(isect_point);
|
Vector normal = shape->getNormalAt(isect_point);
|
||||||
// double dot = normal % ray.getDirection();
|
|
||||||
double intersect_dist = (isect_point - ray.getOrigin()).mag();
|
double intersect_dist = (isect_point - ray.getOrigin()).mag();
|
||||||
// if (dot < 0.0) /* cull back faces */
|
if (foundOne == false || intersect_dist < hit.dist)
|
||||||
// {
|
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
hits.pop_back();
|
hit.shape = shape;
|
||||||
|
hit.dist = intersect_dist;
|
||||||
|
foundOne = true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hits;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Scene::ShapeDistance & sd1,
|
bool operator<(const Scene::ShapeDistance & sd1,
|
||||||
const Scene::ShapeDistance & sd2)
|
const Scene::ShapeDistance & sd2)
|
||||||
{
|
{
|
||||||
return sd1.second < sd2.second;
|
return sd1.dist < sd2.dist;
|
||||||
}
|
}
|
||||||
|
14
main/Scene.h
14
main/Scene.h
@ -23,13 +23,17 @@ class Scene
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* types */
|
/* types */
|
||||||
class ShapeDistance : public std::pair<refptr<Shape>, double>
|
class ShapeDistance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ShapeDistance() {}
|
||||||
ShapeDistance(refptr<Shape> shape, double dist)
|
ShapeDistance(refptr<Shape> shape, double dist)
|
||||||
: std::pair<refptr<Shape>, double>(shape, dist)
|
|
||||||
{
|
{
|
||||||
};
|
this->shape = shape;
|
||||||
|
this->dist = dist;
|
||||||
|
}
|
||||||
|
refptr<Shape> shape;
|
||||||
|
double dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
Scene(const std::map<std::string, const char *> & options,
|
Scene(const std::map<std::string, const char *> & options,
|
||||||
@ -47,7 +51,8 @@ class Scene
|
|||||||
/* private methods */
|
/* private methods */
|
||||||
void renderPixel(int x, int y, unsigned char * pixel);
|
void renderPixel(int x, int y, unsigned char * pixel);
|
||||||
Color traceRay(const Ray & ray);
|
Color traceRay(const Ray & ray);
|
||||||
std::vector<ShapeDistance> getRayHits(const Ray & ray);
|
Color traceRayDepth(const Ray & ray, int depth);
|
||||||
|
ShapeDistance getRayClosestHit(const Ray & ray);
|
||||||
|
|
||||||
/* In Scene-load.cc */
|
/* In Scene-load.cc */
|
||||||
void load(const char * filename);
|
void load(const char * filename);
|
||||||
@ -68,6 +73,7 @@ class Scene
|
|||||||
bool m_verbose;
|
bool m_verbose;
|
||||||
double m_vfov;
|
double m_vfov;
|
||||||
Color m_ambient_light;
|
Color m_ambient_light;
|
||||||
|
int m_max_depth;
|
||||||
|
|
||||||
/* private data */
|
/* private data */
|
||||||
std::vector< refptr<Shape> > m_shapes;
|
std::vector< refptr<Shape> > m_shapes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user