fart/shapes/Box.cc
Josh Holtrop 4b0f506522 added Color::yellow, finished shapes/Box, added a couple boxes to sample scene
git-svn-id: svn://anubis/fart/trunk@121 7f9b0f55-74a9-4bce-be96-3c2cd072584d
2009-02-17 05:36:48 +00:00

77 lines
2.2 KiB
C++

#include "Box.h"
#include "util/Solver.h"
#include <math.h>
#include <iostream>
using namespace std;
#define FP_EQUAL(x,y) (fabs((x)-(y)) < 0.000001)
Box::Box(refptr<Vector> size)
{
m_size = *size;
m_size[0] = fabs(m_size[0]) / 2.0;
m_size[1] = fabs(m_size[1]) / 2.0;
m_size[2] = fabs(m_size[2]) / 2.0;
}
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);
}