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:
1 parent
186bd0f8b5
commit
60b29d658d
18 files changed
+100
-171
No files matched your search
+15
-21
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user