From 22519b5a0c7418c33b5e09a450b599a0f47566fa Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 17 Feb 2009 05:20:38 +0000 Subject: [PATCH] fixed bug in shapes/Plane, added shapes/Box git-svn-id: svn://anubis/fart/trunk@119 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- shapes/Box.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ shapes/Box.h | 19 +++++++++++++ shapes/Plane.cc | 12 ++++---- 3 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 shapes/Box.cc create mode 100644 shapes/Box.h diff --git a/shapes/Box.cc b/shapes/Box.cc new file mode 100644 index 0000000..cdc7112 --- /dev/null +++ b/shapes/Box.cc @@ -0,0 +1,76 @@ + +#include "Box.h" +#include "util/Solver.h" +#include +#include +using namespace std; + +#define FP_EQUAL(x,y) (fabs((x)-(y)) < 0.000001) + +Box::Box(refptr size) +{ + m_size = *size; + m_size[0] = fabs(m_size[0]); + m_size[1] = fabs(m_size[1]); + m_size[2] = fabs(m_size[2]); +} + +Shape::IntersectList Box::intersect(const Ray & ray) +{ + Ray ray_inv = m_inverse.transform_ray(ray); + + IntersectList res; + /* + * Ray equation: R = R0 + tRd + * x = R0x + tRdx + * y = R0y + tRdy + * z = R0z + tRdz + * Side equation: x - size_x = 0 + * Combined: R0x + (t)Rdx - size_x = 0 + */ + for (int dim = 0; dim < 3; dim++) + { + for (int side = -1; side <= 1; side += 2) + { + LinearSolver solver(ray_inv.getDirection()[dim], + ray_inv.getOrigin()[dim] + + side * m_size[dim]); + Solver::Result solutions = solver.solve(); + for (int i = 0; i < solutions.numResults; i++) + { + if (solutions.results[i] >= 0.0) + { + Vector isect_point = ray_inv[solutions.results[i]]; + if ( (dim == 0 || fabs(isect_point[0]) <= m_size[0]) + && (dim == 1 || fabs(isect_point[1]) <= m_size[1]) + && (dim == 2 || fabs(isect_point[2]) <= m_size[2]) ) + { + res.push_back(m_transform.transform_point(isect_point)); + } + } + } + } + } + + 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); +} diff --git a/shapes/Box.h b/shapes/Box.h new file mode 100644 index 0000000..caf809d --- /dev/null +++ b/shapes/Box.h @@ -0,0 +1,19 @@ + +#ifndef BOX_H +#define BOX_H BOX_H + +#include "Shape.h" + +class Box : public Shape +{ + public: + Box(refptr size); + IntersectList intersect(const Ray & ray); + Vector getNormalAt(const Vector & pt); + + protected: + Vector m_size; +}; + +#endif + diff --git a/shapes/Plane.cc b/shapes/Plane.cc index 513e7f4..b04bfce 100644 --- a/shapes/Plane.cc +++ b/shapes/Plane.cc @@ -28,12 +28,12 @@ Shape::IntersectList Plane::intersect(const Ray & ray) * aR0x + (t)aRdx + bR0y + (t)bRdy + cR0z + (t)cRdz + d = 0 * (t)(aRdx + bRdy + cRdz) + aR0x + bR0y + cR0z + d = 0 */ - LinearSolver solver( m_a * ray.getDirection()[0] - + m_b * ray.getDirection()[1] - + m_c * ray.getDirection()[2], - m_a * ray.getOrigin()[0] - + m_b * ray.getOrigin()[1] - + m_c * ray.getOrigin()[2] + LinearSolver solver( m_a * ray_inv.getDirection()[0] + + m_b * ray_inv.getDirection()[1] + + m_c * ray_inv.getDirection()[2], + m_a * ray_inv.getOrigin()[0] + + m_b * ray_inv.getOrigin()[1] + + m_c * ray_inv.getOrigin()[2] + m_d); Solver::Result solutions = solver.solve(); if (solutions.numResults > 0)