merged in branches/2009-03-09_intersect_returning_normals
git-svn-id: svn://anubis/fart/trunk@202 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
commit
4716b200fd
1
.todo
1
.todo
@ -1,6 +1,5 @@
|
|||||||
FART To-Do List
|
FART To-Do List
|
||||||
===============
|
===============
|
||||||
- Fix subtractions of subtractions (inverting normals problem)
|
|
||||||
- Shape definitions / reusability
|
- Shape definitions / reusability
|
||||||
- Add distribution infrastructure
|
- Add distribution infrastructure
|
||||||
- Add maximum recursion depth option / parameter
|
- Add maximum recursion depth option / parameter
|
||||||
|
@ -148,27 +148,27 @@ Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor)
|
|||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
ShapeDistance hit = getRayClosestHit(ray);
|
Shape::Intersection hit = getRayClosestHit(ray);
|
||||||
|
|
||||||
if ( ! hit.shape.isNull() )
|
if ( ! hit.shape.isNull() )
|
||||||
{
|
{
|
||||||
/* compute the Phong lighting for each hit */
|
/* compute the Phong lighting for each hit */
|
||||||
refptr<Material> material = hit.shape->getMaterial();
|
refptr<Material> material = hit.shape->getMaterial();
|
||||||
|
|
||||||
Vector surfacePoint = ray[hit.dist];
|
/* TODO: make sure this can be removed */
|
||||||
Vector surfaceNormal = hit.shape->getNormalAt(surfacePoint);
|
#if 0
|
||||||
|
|
||||||
/* check for backfaces */
|
/* check for backfaces */
|
||||||
if (ray.getDirection() % surfaceNormal > 0.0)
|
if (ray.getDirection() % surfaceNormal > 0.0)
|
||||||
{
|
{
|
||||||
/* if dot product is positive, this is a back-face */
|
/* if dot product is positive, this is a back-face */
|
||||||
surfaceNormal = -surfaceNormal;
|
surfaceNormal = -surfaceNormal;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
color = computePhong(material,
|
color = computePhong(material,
|
||||||
ray,
|
ray,
|
||||||
surfacePoint,
|
hit.position,
|
||||||
surfaceNormal);
|
hit.normal);
|
||||||
|
|
||||||
if (depth > 0 && factor > SCENE_FACTOR_THRESHOLD)
|
if (depth > 0 && factor > SCENE_FACTOR_THRESHOLD)
|
||||||
{
|
{
|
||||||
@ -177,8 +177,8 @@ Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor)
|
|||||||
{
|
{
|
||||||
color *= (1.0 - reflectance);
|
color *= (1.0 - reflectance);
|
||||||
Vector reflected_direction =
|
Vector reflected_direction =
|
||||||
(-ray.getDirection()).reflect(surfaceNormal);
|
(-ray.getDirection()).reflect(hit.normal);
|
||||||
Ray newRay(surfacePoint, reflected_direction);
|
Ray newRay(hit.position, reflected_direction);
|
||||||
Vector jitter_surface_point = newRay[0.0001];
|
Vector jitter_surface_point = newRay[0.0001];
|
||||||
Ray jitterNewRay(jitter_surface_point, reflected_direction);
|
Ray jitterNewRay(jitter_surface_point, reflected_direction);
|
||||||
Color c = traceRayRecurse(jitterNewRay,
|
Color c = traceRayRecurse(jitterNewRay,
|
||||||
@ -191,7 +191,8 @@ Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor)
|
|||||||
if (factor * transparency > SCENE_FACTOR_THRESHOLD)
|
if (factor * transparency > SCENE_FACTOR_THRESHOLD)
|
||||||
{
|
{
|
||||||
color *= (1.0 - transparency);
|
color *= (1.0 - transparency);
|
||||||
Vector jitter_surface_point = ray[hit.dist + 0.0001];
|
Vector jitter_surface_point = hit.position
|
||||||
|
+ ray.getDirection() * 0.0001;
|
||||||
Ray newRay(jitter_surface_point, ray.getDirection());
|
Ray newRay(jitter_surface_point, ray.getDirection());
|
||||||
Color c = traceRayRecurse(newRay,
|
Color c = traceRayRecurse(newRay,
|
||||||
depth - 1,
|
depth - 1,
|
||||||
@ -204,9 +205,10 @@ Color Scene::traceRayRecurse(const Ray & ray, int depth, double factor)
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::ShapeDistance Scene::getRayClosestHit(const Ray & ray)
|
Shape::Intersection Scene::getRayClosestHit(const Ray & ray)
|
||||||
{
|
{
|
||||||
ShapeDistance hit;
|
Shape::Intersection hit;
|
||||||
|
double min_dist = 0.0;
|
||||||
bool foundOne = false;
|
bool foundOne = false;
|
||||||
|
|
||||||
/* loop through all shapes in the scene */
|
/* loop through all shapes in the scene */
|
||||||
@ -221,12 +223,12 @@ Scene::ShapeDistance Scene::getRayClosestHit(const Ray & ray)
|
|||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
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].position;
|
||||||
double intersect_dist = (isect_point - ray.getOrigin()).mag();
|
double intersect_dist = ray.getOrigin().dist_to(isect_point);
|
||||||
if (foundOne == false || intersect_dist < hit.dist)
|
if (foundOne == false || intersect_dist < min_dist)
|
||||||
{
|
{
|
||||||
hit.shape = shape;
|
hit = intersections[i];
|
||||||
hit.dist = intersect_dist;
|
min_dist = intersect_dist;
|
||||||
foundOne = true;
|
foundOne = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,12 +308,12 @@ double Scene::calculateLightContribution(const Ray & toLight,
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
ShapeDistance hit = getRayClosestHit(currentRay);
|
Shape::Intersection hit = getRayClosestHit(currentRay);
|
||||||
|
|
||||||
if ( hit.shape.isNull() )
|
if ( hit.shape.isNull() )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
double offset = hit.dist + 0.0001;
|
double offset = currentRay.getOrigin().dist_to(hit.position) + 0.0001;
|
||||||
|
|
||||||
if ( dist_so_far + offset > dist_to_light )
|
if ( dist_so_far + offset > dist_to_light )
|
||||||
break;
|
break;
|
||||||
@ -327,9 +329,3 @@ double Scene::calculateLightContribution(const Ray & toLight,
|
|||||||
|
|
||||||
return contrib;
|
return contrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const Scene::ShapeDistance & sd1,
|
|
||||||
const Scene::ShapeDistance & sd2)
|
|
||||||
{
|
|
||||||
return sd1.dist < sd2.dist;
|
|
||||||
}
|
|
||||||
|
19
main/Scene.h
19
main/Scene.h
@ -22,20 +22,6 @@
|
|||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* types */
|
|
||||||
class ShapeDistance
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShapeDistance() {}
|
|
||||||
ShapeDistance(refptr<Shape> shape, double 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,
|
||||||
const char * filename);
|
const char * filename);
|
||||||
~Scene();
|
~Scene();
|
||||||
@ -51,7 +37,7 @@ class Scene
|
|||||||
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);
|
||||||
Color traceRayRecurse(const Ray & ray, int depth, double factor);
|
Color traceRayRecurse(const Ray & ray, int depth, double factor);
|
||||||
ShapeDistance getRayClosestHit(const Ray & ray);
|
Shape::Intersection getRayClosestHit(const Ray & ray);
|
||||||
Color computePhong(const refptr<Material> material,
|
Color computePhong(const refptr<Material> material,
|
||||||
const Ray & viewRay,
|
const Ray & viewRay,
|
||||||
const Vector & surfacePoint,
|
const Vector & surfacePoint,
|
||||||
@ -102,8 +88,5 @@ class Scene
|
|||||||
unsigned char * m_data;
|
unsigned char * m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator<(const Scene::ShapeDistance & sd1,
|
|
||||||
const Scene::ShapeDistance & sd2);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ scene
|
|||||||
{
|
{
|
||||||
options
|
options
|
||||||
{
|
{
|
||||||
multisample 2
|
multisample 3
|
||||||
}
|
}
|
||||||
|
|
||||||
camera
|
camera
|
||||||
@ -17,6 +17,15 @@ scene
|
|||||||
position <-1, -3, 4>
|
position <-1, -3, 4>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plane
|
||||||
|
{
|
||||||
|
position <0, 0, 1>, 1
|
||||||
|
material
|
||||||
|
{
|
||||||
|
color <0, 1, 1>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
subtract
|
subtract
|
||||||
{
|
{
|
||||||
box
|
box
|
||||||
|
@ -45,8 +45,22 @@ Shape::IntersectionList Box::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
&& (dim == 1 || fabs(isect_point[1]) <= m_size[1])
|
&& (dim == 1 || fabs(isect_point[1]) <= m_size[1])
|
||||||
&& (dim == 2 || fabs(isect_point[2]) <= m_size[2]) )
|
&& (dim == 2 || fabs(isect_point[2]) <= m_size[2]) )
|
||||||
{
|
{
|
||||||
|
Vector normal(0, 0, -1);
|
||||||
|
|
||||||
|
if ( FP_EQUAL(isect_point[0], m_size[0]) )
|
||||||
|
normal = Vector(1, 0, 0);
|
||||||
|
else if ( FP_EQUAL(isect_point[0], -m_size[0]) )
|
||||||
|
normal = Vector(-1, 0, 0);
|
||||||
|
else if ( FP_EQUAL(isect_point[1], m_size[1]) )
|
||||||
|
normal = Vector(0, 1, 0);
|
||||||
|
else if ( FP_EQUAL(isect_point[1], -m_size[1]) )
|
||||||
|
normal = Vector(0, -1, 0);
|
||||||
|
else if ( FP_EQUAL(isect_point[2], m_size[2]) )
|
||||||
|
normal = Vector(0, 0, 1);
|
||||||
|
|
||||||
res.add(Intersection(_this,
|
res.add(Intersection(_this,
|
||||||
m_transform.transform_point(isect_point))
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(normal))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,23 +70,3 @@ Shape::IntersectionList Box::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Box::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
Vector local_pt = m_inverse.transform_point(pt);
|
|
||||||
|
|
||||||
Vector normal(0, 0, -1);
|
|
||||||
|
|
||||||
if ( FP_EQUAL(local_pt[0], m_size[0]) )
|
|
||||||
normal = Vector(1, 0, 0);
|
|
||||||
else if ( FP_EQUAL(local_pt[0], -m_size[0]) )
|
|
||||||
normal = Vector(-1, 0, 0);
|
|
||||||
else if ( FP_EQUAL(local_pt[1], m_size[1]) )
|
|
||||||
normal = Vector(0, 1, 0);
|
|
||||||
else if ( FP_EQUAL(local_pt[1], -m_size[1]) )
|
|
||||||
normal = Vector(0, -1, 0);
|
|
||||||
else if ( FP_EQUAL(local_pt[2], m_size[2]) )
|
|
||||||
normal = Vector(0, 0, 1);
|
|
||||||
|
|
||||||
return m_transform.transform_normal(normal);
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ class Box : public Shape
|
|||||||
public:
|
public:
|
||||||
Box(refptr<Vector> size);
|
Box(refptr<Vector> size);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vector m_size;
|
Vector m_size;
|
||||||
|
@ -39,7 +39,8 @@ Shape::IntersectionList Cyl::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
<= m_bottom_radius_2)
|
<= m_bottom_radius_2)
|
||||||
{
|
{
|
||||||
res.add(Intersection(_this,
|
res.add(Intersection(_this,
|
||||||
m_transform.transform_point(isect_point)));
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(Vector(0, 0, -1))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +58,8 @@ Shape::IntersectionList Cyl::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
<= m_top_radius_2)
|
<= m_top_radius_2)
|
||||||
{
|
{
|
||||||
res.add(Intersection(_this,
|
res.add(Intersection(_this,
|
||||||
m_transform.transform_point(isect_point)));
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(Vector(0, 0, 1))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,41 +103,18 @@ Shape::IntersectionList Cyl::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
Vector isect_point = ray_inv[solutions.results[i]];
|
Vector isect_point = ray_inv[solutions.results[i]];
|
||||||
if (isect_point[2] > 0.0 && isect_point[2] < m_height)
|
if (isect_point[2] > 0.0 && isect_point[2] < m_height)
|
||||||
{
|
{
|
||||||
res.add(Intersection(_this,
|
|
||||||
m_transform.transform_point(isect_point)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector Cyl::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
Vector local_pt = m_inverse.transform_point(pt);
|
|
||||||
|
|
||||||
Vector normal;
|
Vector normal;
|
||||||
|
|
||||||
if ( FP_EQUAL(local_pt[2], 0.0) && m_bottom_radius > 0.0 )
|
|
||||||
{
|
|
||||||
normal = Vector(0, 0, -1);
|
|
||||||
}
|
|
||||||
else if ( FP_EQUAL(local_pt[2], m_height) && m_top_radius > 0.0 )
|
|
||||||
{
|
|
||||||
normal = Vector(0, 0, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( FP_EQUAL(m_slope, 0.0) )
|
if ( FP_EQUAL(m_slope, 0.0) )
|
||||||
{
|
{
|
||||||
normal = Vector(local_pt[0], local_pt[1], 0.0);
|
normal = Vector(isect_point[0], isect_point[1], 0.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double x = local_pt[0];
|
double x = isect_point[0];
|
||||||
double y = local_pt[1];
|
double y = isect_point[1];
|
||||||
double dist = sqrt( local_pt[0] * local_pt[0]
|
double dist = sqrt( isect_point[0] * isect_point[0]
|
||||||
+ local_pt[1] * local_pt[1] );
|
+ isect_point[1] * isect_point[1] );
|
||||||
if (dist > 0.0)
|
if (dist > 0.0)
|
||||||
{
|
{
|
||||||
double scale = 1.0 / dist;
|
double scale = 1.0 / dist;
|
||||||
@ -145,7 +124,13 @@ Vector Cyl::getNormalAt(const Vector & pt)
|
|||||||
normal = Vector(x, y, m_inv_slope);
|
normal = Vector(x, y, m_inv_slope);
|
||||||
}
|
}
|
||||||
normal.normalize();
|
normal.normalize();
|
||||||
|
|
||||||
|
res.add(Intersection(_this,
|
||||||
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(normal)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_transform.transform_normal(normal);
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ class Cyl : public Shape
|
|||||||
public:
|
public:
|
||||||
Cyl(double bottom_radius, double top_radius, double height);
|
Cyl(double bottom_radius, double top_radius, double height);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double m_bottom_radius;
|
double m_bottom_radius;
|
||||||
|
@ -21,8 +21,7 @@ Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ra
|
|||||||
|
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.shape->getNormalAt(
|
Vector normal = merged[i].intersection.normal;
|
||||||
merged[i].intersection.vector);
|
|
||||||
double dot = - (ray.getDirection() % normal);
|
double dot = - (ray.getDirection() % normal);
|
||||||
bool front = dot > 0.0;
|
bool front = dot > 0.0;
|
||||||
bool left = merged[i].left;
|
bool left = merged[i].left;
|
||||||
@ -56,11 +55,3 @@ Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ra
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Intersect::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
/* this should not be called */
|
|
||||||
cerr << __FILE__ << ": " << __LINE__ <<
|
|
||||||
": error: Intersect::getNormalAt() was called!" << endl;
|
|
||||||
return Vector(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ class Intersect : public Shape
|
|||||||
public:
|
public:
|
||||||
Intersect(refptr<Shape> shape1, refptr<Shape> shape2);
|
Intersect(refptr<Shape> shape1, refptr<Shape> shape2);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
refptr<Shape> m_shape1;
|
refptr<Shape> m_shape1;
|
||||||
|
@ -11,6 +11,8 @@ Plane::Plane(double a, double b, double c, double d)
|
|||||||
m_b = b;
|
m_b = b;
|
||||||
m_c = c;
|
m_c = c;
|
||||||
m_d = d;
|
m_d = d;
|
||||||
|
m_normal = Vector(m_a, m_b, m_c);
|
||||||
|
m_normal.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::IntersectionList Plane::intersect(refptr<Shape> _this, const Ray & ray)
|
Shape::IntersectionList Plane::intersect(refptr<Shape> _this, const Ray & ray)
|
||||||
@ -42,15 +44,9 @@ Shape::IntersectionList Plane::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
{
|
{
|
||||||
Vector isect_point = ray_inv[solutions.results[0]];
|
Vector isect_point = ray_inv[solutions.results[0]];
|
||||||
res.add(Intersection(_this,
|
res.add(Intersection(_this,
|
||||||
m_transform.transform_point(isect_point)));
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(m_normal)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Plane::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
Vector normal(m_a, m_b, m_c);
|
|
||||||
normal.normalize();
|
|
||||||
return m_transform.transform_normal(normal);
|
|
||||||
}
|
|
||||||
|
@ -9,10 +9,10 @@ class Plane : public Shape
|
|||||||
public:
|
public:
|
||||||
Plane(double a, double b, double c, double d);
|
Plane(double a, double b, double c, double d);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double m_a, m_b, m_c, m_d;
|
double m_a, m_b, m_c, m_d;
|
||||||
|
Vector m_normal;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,8 +35,8 @@ class BoolIntersectionComparator
|
|||||||
bool operator()(const Shape::BoolIntersection & i1,
|
bool operator()(const Shape::BoolIntersection & i1,
|
||||||
const Shape::BoolIntersection & i2) const
|
const Shape::BoolIntersection & i2) const
|
||||||
{
|
{
|
||||||
return (m_refPoint.dist_to(i1.intersection.vector)
|
return ( m_refPoint.dist_to(i1.intersection.position)
|
||||||
< m_refPoint.dist_to(i2.intersection.vector));
|
< m_refPoint.dist_to(i2.intersection.position) );
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
Vector m_refPoint;
|
Vector m_refPoint;
|
||||||
|
@ -18,13 +18,17 @@ class Shape
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Intersection() {};
|
Intersection() {};
|
||||||
Intersection(refptr<Shape> shape, const Vector & vector)
|
Intersection(refptr<Shape> shape,
|
||||||
|
const Vector & position,
|
||||||
|
const Vector & normal)
|
||||||
{
|
{
|
||||||
this->shape = shape;
|
this->shape = shape;
|
||||||
this->vector = vector;
|
this->position = position;
|
||||||
|
this->normal = normal;
|
||||||
}
|
}
|
||||||
refptr<Shape> shape;
|
refptr<Shape> shape;
|
||||||
Vector vector;
|
Vector position;
|
||||||
|
Vector normal;
|
||||||
};
|
};
|
||||||
class BoolIntersection
|
class BoolIntersection
|
||||||
{
|
{
|
||||||
@ -97,7 +101,6 @@ class Shape
|
|||||||
virtual ~Shape();
|
virtual ~Shape();
|
||||||
virtual IntersectionList intersect(refptr<Shape> _this,
|
virtual IntersectionList intersect(refptr<Shape> _this,
|
||||||
const Ray & ray) = 0;
|
const Ray & ray) = 0;
|
||||||
virtual Vector getNormalAt(const Vector & pt) = 0;
|
|
||||||
|
|
||||||
void setTransform(Transform & t)
|
void setTransform(Transform & t)
|
||||||
{
|
{
|
||||||
|
@ -30,19 +30,14 @@ Shape::IntersectionList Sphere::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
if (quadSolutions.results[i] >= 0.0)
|
if (quadSolutions.results[i] >= 0.0)
|
||||||
{
|
{
|
||||||
Vector isect_point = ray_inv[quadSolutions.results[i]];
|
Vector isect_point = ray_inv[quadSolutions.results[i]];
|
||||||
|
Vector normal = isect_point;
|
||||||
|
normal.normalize();
|
||||||
res.add(
|
res.add(
|
||||||
Intersection(_this, m_transform.transform_point(isect_point))
|
Intersection(_this,
|
||||||
|
m_transform.transform_point(isect_point),
|
||||||
|
m_transform.transform_normal(normal))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Sphere::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
Vector normal = m_inverse.transform_point(pt);
|
|
||||||
|
|
||||||
normal.normalize();
|
|
||||||
|
|
||||||
return m_transform.transform_normal(normal);
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ class Sphere : public Shape
|
|||||||
public:
|
public:
|
||||||
Sphere(double radius);
|
Sphere(double radius);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double m_radius;
|
double m_radius;
|
||||||
|
@ -21,8 +21,7 @@ Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray
|
|||||||
|
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.shape->getNormalAt(
|
Vector normal = merged[i].intersection.normal;
|
||||||
merged[i].intersection.vector);
|
|
||||||
double dot = - (ray.getDirection() % normal);
|
double dot = - (ray.getDirection() % normal);
|
||||||
bool front = dot > 0.0;
|
bool front = dot > 0.0;
|
||||||
bool left = merged[i].left;
|
bool left = merged[i].left;
|
||||||
@ -32,25 +31,27 @@ Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray
|
|||||||
in2 = front;
|
in2 = front;
|
||||||
if (!in_bool && in1 && !in2)
|
if (!in_bool && in1 && !in2)
|
||||||
{
|
{
|
||||||
/* we found an intersection point with the boolean object */
|
/* we found an intersection point
|
||||||
|
* to get into the boolean object */
|
||||||
in_bool = true;
|
in_bool = true;
|
||||||
res.add( merged[i].intersection );
|
BoolIntersection bi = merged[i];
|
||||||
|
Intersection i = bi.intersection;
|
||||||
|
if ( ! left ) /* if this point came from object B (A - B) */
|
||||||
|
i.normal = - i.normal;
|
||||||
|
res.add(i);
|
||||||
}
|
}
|
||||||
else if (in_bool && !(in1 && !in2))
|
else if (in_bool && !(in1 && !in2))
|
||||||
{
|
{
|
||||||
/* we found an intersection point with the boolean object */
|
/* we found an intersection point
|
||||||
res.add( merged[i].intersection );
|
* to get out of the boolean object */
|
||||||
|
BoolIntersection bi = merged[i];
|
||||||
|
Intersection i = bi.intersection;
|
||||||
|
if ( ! left ) /* if this point came from object B (A - B) */
|
||||||
|
i.normal = - i.normal;
|
||||||
|
res.add(i);
|
||||||
in_bool = false;
|
in_bool = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Subtract::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
/* this should not be called */
|
|
||||||
cerr << __FILE__ << ": " << __LINE__ <<
|
|
||||||
": error: Subtract::getNormalAt() was called!" << endl;
|
|
||||||
return Vector(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ class Subtract : public Shape
|
|||||||
public:
|
public:
|
||||||
Subtract(refptr<Shape> shape1, refptr<Shape> shape2);
|
Subtract(refptr<Shape> shape1, refptr<Shape> shape2);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
refptr<Shape> m_shape1;
|
refptr<Shape> m_shape1;
|
||||||
|
@ -21,8 +21,7 @@ Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
|
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.shape->getNormalAt(
|
Vector normal = merged[i].intersection.normal;
|
||||||
merged[i].intersection.vector);
|
|
||||||
double dot = - (ray.getDirection() % normal);
|
double dot = - (ray.getDirection() % normal);
|
||||||
bool front = dot > 0.0;
|
bool front = dot > 0.0;
|
||||||
bool left = merged[i].left;
|
bool left = merged[i].left;
|
||||||
@ -56,11 +55,3 @@ Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Union::getNormalAt(const Vector & pt)
|
|
||||||
{
|
|
||||||
/* this should not be called */
|
|
||||||
cerr << __FILE__ << ": " << __LINE__ <<
|
|
||||||
": error: Union::getNormalAt() was called!" << endl;
|
|
||||||
return Vector(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,6 @@ class Union : public Shape
|
|||||||
public:
|
public:
|
||||||
Union(refptr<Shape> shape1, refptr<Shape> shape2);
|
Union(refptr<Shape> shape1, refptr<Shape> shape2);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
Vector getNormalAt(const Vector & pt);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
refptr<Shape> m_shape1;
|
refptr<Shape> m_shape1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user