added AABB class, calculating AABB in Extrude objects, added Extrude intersect() optimization to throw out rays not hitting the AABB

git-svn-id: svn://anubis/fart/trunk@306 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-09-28 16:37:27 +00:00
parent 437fa8b07a
commit 9e4191fb61
3 changed files with 124 additions and 3 deletions

View File

@ -35,12 +35,43 @@ Shape::IntersectionList Extrude::intersect(refptr<Shape> _this, const Ray & ray)
{ {
Ray ray_inv = m_inverse.transform_ray(ray); Ray ray_inv = m_inverse.transform_ray(ray);
IntersectionList res; IntersectionList res;
/*** optimization ***/
if (ray_inv.getOrigin()[0] > m_aabb.max[0])
{
if (ray_inv.getDirection() % Vector::X > 0)
return res;
}
else if (ray_inv.getOrigin()[0] < m_aabb.min[0])
{
if (ray_inv.getDirection() % Vector::X < 0)
return res;
}
if (ray_inv.getOrigin()[1] > m_aabb.max[1])
{
if (ray_inv.getDirection() % Vector::Y > 0)
return res;
}
else if (ray_inv.getOrigin()[1] < m_aabb.min[1])
{
if (ray_inv.getDirection() % Vector::Y < 0)
return res;
}
if (ray_inv.getOrigin()[2] > m_aabb.max[2])
{
if (ray_inv.getDirection() % Vector::Z > 0)
return res;
}
else if (ray_inv.getOrigin()[2] < m_aabb.min[2])
{
if (ray_inv.getDirection() % Vector::Z < 0)
return res;
}
/*** end optimization ***/
int n_polygons = m_polygons.size(); int n_polygons = m_polygons.size();
int n_offsets = m_offsets.size(); int n_offsets = m_offsets.size();
if (n_polygons < 1 || n_offsets < 1)
return res;
double distance = 0.0; double distance = 0.0;
Vector scale(1.0, 1.0, 1.0); Vector scale(1.0, 1.0, 1.0);
Vector shift(0.0, 0.0, 0.0); Vector shift(0.0, 0.0, 0.0);
@ -159,12 +190,75 @@ Shape::IntersectionList Extrude::intersect(refptr<Shape> _this, const Ray & ray)
void Extrude::addPolygon(refptr<Polygon> polygon) void Extrude::addPolygon(refptr<Polygon> polygon)
{ {
m_polygons.push_back(polygon); m_polygons.push_back(polygon);
updateAABB();
} }
void Extrude::addOffset(double distance, void Extrude::addOffset(double distance,
const Vector & scale, const Vector & shift) const Vector & scale, const Vector & shift)
{ {
m_offsets.push_back(Offset(distance, scale, shift)); m_offsets.push_back(Offset(distance, scale, shift));
updateAABB();
}
void Extrude::updateAABB()
{
int n_polygons = m_polygons.size();
int n_offsets = m_offsets.size();
bool first = true;
double distance = 0.0;
Vector scale(1.0, 1.0, 1.0);
Vector shift(0.0, 0.0, 0.0);
for (int p = 0; p < n_polygons; p++)
{
refptr<Polygon> polygon = m_polygons[p];
for (int o = 0; o < n_offsets; o++)
{
Offset & offset = m_offsets[o];
for (int pt = 0, n_pts = polygon->size(); pt < n_pts; pt++)
{
Vector p1 = scale.mult(*(*polygon)[pt]) + shift;
Vector p2 = scale.mult(*(*polygon)[(pt+1) % n_pts]) + shift;
Vector p3 = scale.mult(offset.scale)
.mult(*(*polygon)[(pt+1) % n_pts])
+ shift + offset.shift;
Vector p4 = scale.mult(offset.scale).mult(*(*polygon)[pt])
+ shift + offset.shift;
p1[2] += distance;
p2[2] += distance;
p3[2] += distance + offset.distance;
p4[2] += distance + offset.distance;
if (first)
{
m_aabb.min = p1;
m_aabb.max = p1;
first = false;
}
expandAABB(p1);
expandAABB(p2);
expandAABB(p3);
expandAABB(p4);
}
distance += offset.distance;
scale = scale.mult(offset.scale);
shift += offset.shift;
}
}
}
void Extrude::expandAABB(const Vector & v)
{
if (v[0] < m_aabb.min[0])
m_aabb.min[0] = v[0];
if (v[0] > m_aabb.max[0])
m_aabb.max[0] = v[0];
if (v[1] < m_aabb.min[1])
m_aabb.min[1] = v[1];
if (v[1] > m_aabb.max[1])
m_aabb.max[1] = v[1];
if (v[2] < m_aabb.min[2])
m_aabb.min[2] = v[2];
if (v[2] > m_aabb.max[2])
m_aabb.max[2] = v[2];
} }
refptr<Shape> Extrude::clone() refptr<Shape> Extrude::clone()

View File

@ -5,6 +5,8 @@
#include <vector> #include <vector>
#include "util/Polygon.h" #include "util/Polygon.h"
#include "util/AABB.h"
#include "Shape.h" #include "Shape.h"
class Extrude : public Shape class Extrude : public Shape
@ -31,6 +33,10 @@ class Extrude : public Shape
protected: protected:
std::vector< refptr<Polygon> > m_polygons; std::vector< refptr<Polygon> > m_polygons;
std::vector<Offset> m_offsets; std::vector<Offset> m_offsets;
AABB m_aabb;
void updateAABB();
void expandAABB(const Vector & v);
}; };
#endif #endif

21
util/AABB.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef AABB_H
#define AABB_H
class AABB
{
public:
Vector min;
Vector max;
AABB()
{
}
AABB(const Vector & min, const Vector & max)
: min(min), max(max)
{
}
};
#endif /* AABB_H */