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:
parent
437fa8b07a
commit
9e4191fb61
@ -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()
|
||||||
|
@ -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
21
util/AABB.h
Normal 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 */
|
Loading…
x
Reference in New Issue
Block a user