modified shapes and Scene to return surface normal in the intersect object

git-svn-id: svn://anubis/fart/branches/2009-03-09_intersect_returning_normals@200 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop committed 2009-03-09 23:17:31 +00:00
1 parent 186bd0f8b5
commit 60b29d658d
18 files changed
+100 -171

No files matched your search

+15 -21
View File
@@ -45,8 +45,22 @@ Shape::IntersectionList Box::intersect(refptr<Shape> _this, const Ray & ray)
&& (dim == 1 || fabs(isect_point[1]) <= m_size[1])
&& (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,
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;
}
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);
}
-1
View File
@@ -9,7 +9,6 @@ class Box : public Shape
public:
Box(refptr<Vector> size);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
Vector m_size;
+28 -43
View File
@@ -39,7 +39,8 @@ Shape::IntersectionList Cyl::intersect(refptr<Shape> _this, const Ray & ray)
<= m_bottom_radius_2)
{
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)
{
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,51 +103,34 @@ Shape::IntersectionList Cyl::intersect(refptr<Shape> _this, const Ray & ray)
Vector isect_point = ray_inv[solutions.results[i]];
if (isect_point[2] > 0.0 && isect_point[2] < m_height)
{
Vector normal;
if ( FP_EQUAL(m_slope, 0.0) )
{
normal = Vector(isect_point[0], isect_point[1], 0.0);
}
else
{
double x = isect_point[0];
double y = isect_point[1];
double dist = sqrt( isect_point[0] * isect_point[0]
+ isect_point[1] * isect_point[1] );
if (dist > 0.0)
{
double scale = 1.0 / dist;
x *= scale;
y *= scale;
}
normal = Vector(x, y, m_inv_slope);
}
normal.normalize();
res.add(Intersection(_this,
m_transform.transform_point(isect_point)));
m_transform.transform_point(isect_point),
m_transform.transform_normal(normal)));
}
}
}
return res;
}
Vector Cyl::getNormalAt(const Vector & pt)
{
Vector local_pt = m_inverse.transform_point(pt);
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) )
{
normal = Vector(local_pt[0], local_pt[1], 0.0);
}
else
{
double x = local_pt[0];
double y = local_pt[1];
double dist = sqrt( local_pt[0] * local_pt[0]
+ local_pt[1] * local_pt[1] );
if (dist > 0.0)
{
double scale = 1.0 / dist;
x *= scale;
y *= scale;
}
normal = Vector(x, y, m_inv_slope);
}
normal.normalize();
}
return m_transform.transform_normal(normal);
}
-1
View File
@@ -9,7 +9,6 @@ class Cyl : public Shape
public:
Cyl(double bottom_radius, double top_radius, double height);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
double m_bottom_radius;
+1 -10
View File
@@ -21,8 +21,7 @@ Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ra
for (int i = 0, sz = merged.size(); i < sz; i++)
{
Vector normal = merged[i].intersection.shape->getNormalAt(
merged[i].intersection.vector);
Vector normal = merged[i].intersection.normal;
double dot = - (ray.getDirection() % normal);
bool front = dot > 0.0;
bool left = merged[i].left;
@@ -56,11 +55,3 @@ Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ra
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);
}
-1
View File
@@ -9,7 +9,6 @@ class Intersect : public Shape
public:
Intersect(refptr<Shape> shape1, refptr<Shape> shape2);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
refptr<Shape> m_shape1;
+4 -8
View File
@@ -11,6 +11,8 @@ Plane::Plane(double a, double b, double c, double d)
m_b = b;
m_c = c;
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)
@@ -42,15 +44,9 @@ Shape::IntersectionList Plane::intersect(refptr<Shape> _this, const Ray & ray)
{
Vector isect_point = ray_inv[solutions.results[0]];
res.add(Intersection(_this,
m_transform.transform_point(isect_point)));
m_transform.transform_point(isect_point),
m_transform.transform_normal(m_normal)));
}
}
return res;
}
Vector Plane::getNormalAt(const Vector & pt)
{
Vector normal(m_a, m_b, m_c);
normal.normalize();
return m_transform.transform_normal(normal);
}
+1 -1
View File
@@ -9,10 +9,10 @@ class Plane : public Shape
public:
Plane(double a, double b, double c, double d);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
double m_a, m_b, m_c, m_d;
Vector m_normal;
};
#endif
+2 -2
View File
@@ -35,8 +35,8 @@ class BoolIntersectionComparator
bool operator()(const Shape::BoolIntersection & i1,
const Shape::BoolIntersection & i2) const
{
return (m_refPoint.dist_to(i1.intersection.vector)
< m_refPoint.dist_to(i2.intersection.vector));
return ( m_refPoint.dist_to(i1.intersection.position)
< m_refPoint.dist_to(i2.intersection.position) );
}
protected:
Vector m_refPoint;
+7 -4
View File
@@ -18,13 +18,17 @@ class Shape
{
public:
Intersection() {};
Intersection(refptr<Shape> shape, const Vector & vector)
Intersection(refptr<Shape> shape,
const Vector & position,
const Vector & normal)
{
this->shape = shape;
this->vector = vector;
this->position = position;
this->normal = normal;
}
refptr<Shape> shape;
Vector vector;
Vector position;
Vector normal;
};
class BoolIntersection
{
@@ -97,7 +101,6 @@ class Shape
virtual ~Shape();
virtual IntersectionList intersect(refptr<Shape> _this,
const Ray & ray) = 0;
virtual Vector getNormalAt(const Vector & pt) = 0;
void setTransform(Transform & t)
{
+5 -10
View File
@@ -30,19 +30,14 @@ Shape::IntersectionList Sphere::intersect(refptr<Shape> _this, const Ray & ray)
if (quadSolutions.results[i] >= 0.0)
{
Vector isect_point = ray_inv[quadSolutions.results[i]];
Vector normal = isect_point;
normal.normalize();
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;
}
Vector Sphere::getNormalAt(const Vector & pt)
{
Vector normal = m_inverse.transform_point(pt);
normal.normalize();
return m_transform.transform_normal(normal);
}
-1
View File
@@ -9,7 +9,6 @@ class Sphere : public Shape
public:
Sphere(double radius);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
double m_radius;
+15 -14
View File
@@ -21,8 +21,7 @@ Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray
for (int i = 0, sz = merged.size(); i < sz; i++)
{
Vector normal = merged[i].intersection.shape->getNormalAt(
merged[i].intersection.vector);
Vector normal = merged[i].intersection.normal;
double dot = - (ray.getDirection() % normal);
bool front = dot > 0.0;
bool left = merged[i].left;
@@ -32,25 +31,27 @@ Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray
in2 = front;
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;
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))
{
/* we found an intersection point with the boolean object */
res.add( merged[i].intersection );
/* we found an intersection point
* 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;
}
}
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);
}
-1
View File
@@ -9,7 +9,6 @@ class Subtract : public Shape
public:
Subtract(refptr<Shape> shape1, refptr<Shape> shape2);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
refptr<Shape> m_shape1;
+1 -10
View File
@@ -21,8 +21,7 @@ Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
for (int i = 0, sz = merged.size(); i < sz; i++)
{
Vector normal = merged[i].intersection.shape->getNormalAt(
merged[i].intersection.vector);
Vector normal = merged[i].intersection.normal;
double dot = - (ray.getDirection() % normal);
bool front = dot > 0.0;
bool left = merged[i].left;
@@ -56,11 +55,3 @@ Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
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);
}
-1
View File
@@ -9,7 +9,6 @@ class Union : public Shape
public:
Union(refptr<Shape> shape1, refptr<Shape> shape2);
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
Vector getNormalAt(const Vector & pt);
protected:
refptr<Shape> m_shape1;