common: make float/double versions of aabb3

This commit is contained in:
Eric Wasylishen 2017-04-22 15:11:41 -06:00
parent ee7181521d
commit 28081f50c6
4 changed files with 54 additions and 51 deletions

View File

@ -84,7 +84,7 @@ std::vector<std::vector<glm::vec3>> meshToFaces(const mesh_t &mesh)
}
static aabb3 mesh_face_bbox(const mesh_t &mesh, int facenum)
static aabb3f mesh_face_bbox(const mesh_t &mesh, int facenum)
{
const std::vector<int> &face = mesh.faces.at(facenum);
@ -94,7 +94,7 @@ void cleanupMesh(mesh_t &mesh)
{
using facenum_t = int;
std::vector<std::pair<aabb3, facenum_t>> faces;
std::vector<std::pair<aabb3f, facenum_t>> faces;
octree_t<facenum_t> octree = makeOctree(faces);

View File

@ -140,7 +140,10 @@ public:
}
};
using aabb3 = aabb<3, qvec3f>;
using aabb2 = aabb<2, qvec2f>;
using aabb3d = aabb<3, qvec3d>;
using aabb2d = aabb<2, qvec2d>;
using aabb3f = aabb<3, qvec3f>;
using aabb2f = aabb<2, qvec2f>;
#endif /* __COMMON_AABB_HH__ */

View File

@ -27,7 +27,7 @@
#include <set>
#include <cassert>
static inline aabb3 bboxOctant(const aabb3 &box, int i)
static inline aabb3f bboxOctant(const aabb3f &box, int i)
{
assert(i >= 0 && i < 8);
@ -48,7 +48,7 @@ static inline aabb3 bboxOctant(const aabb3 &box, int i)
}
}
return aabb3(mins, maxs);
return aabb3f(mins, maxs);
}
#define MAX_OCTREE_DEPTH 3
@ -59,12 +59,12 @@ template <typename T>
class octree_node_t {
public:
int m_depth;
aabb3 m_bbox;
aabb3f m_bbox;
bool m_leafNode;
std::vector<std::pair<aabb3, T>> m_leafObjects; // only nonempty if m_leafNode
std::vector<std::pair<aabb3f, T>> m_leafObjects; // only nonempty if m_leafNode
octree_nodeid m_children[8]; // only use if !m_leafNode
octree_node_t(const aabb3 &box, const int depth) :
octree_node_t(const aabb3f &box, const int depth) :
m_depth(depth),
m_bbox(box),
m_leafNode(true),
@ -88,7 +88,7 @@ private:
octree_nodeid createChild(octree_nodeid thisNode, int i) {
octree_node_t<T> *node = &m_nodes[thisNode];
const aabb3 childBox = bboxOctant(node->m_bbox, i);
const aabb3f childBox = bboxOctant(node->m_bbox, i);
octree_node_t<T> newNode(childBox, node->m_depth + 1);
m_nodes.push_back(newNode); // invalidates `node` reference
@ -110,7 +110,7 @@ private:
node->m_leafNode = false;
}
void queryTouchingBBox(octree_nodeid thisNode, const aabb3 &query, std::set<T> &dest) const {
void queryTouchingBBox(octree_nodeid thisNode, const aabb3f &query, std::set<T> &dest) const {
const octree_node_t<T> *node = &m_nodes[thisNode];
if (node->m_leafNode) {
@ -128,14 +128,14 @@ private:
const octree_nodeid child_i_index = node->m_children[i];
const octree_node_t<T> *child_i_node = &m_nodes[child_i_index];
const aabb3::intersection_t intersection = query.intersectWith(child_i_node->m_bbox);
const aabb3f::intersection_t intersection = query.intersectWith(child_i_node->m_bbox);
if (intersection.valid) {
queryTouchingBBox(child_i_index, intersection.bbox, dest);
}
}
}
void insert(octree_nodeid thisNode, const aabb3 &objBox, const T &obj) {
void insert(octree_nodeid thisNode, const aabb3f &objBox, const T &obj) {
octree_node_t<T> *node = &m_nodes[thisNode];
assert(node->m_bbox.contains(objBox));
@ -154,7 +154,7 @@ private:
for (int i=0; i<8; i++) {
const octree_nodeid child_i_index = node->m_children[i];
octree_node_t<T> *child_i_node = &m_nodes[child_i_index];
const aabb3::intersection_t intersection = objBox.intersectWith(child_i_node->m_bbox);
const aabb3f::intersection_t intersection = objBox.intersectWith(child_i_node->m_bbox);
if (intersection.valid) {
insert(child_i_index, intersection.bbox, obj);
@ -165,11 +165,11 @@ private:
}
public:
void insert(const aabb3 &objBox, const T &obj) {
void insert(const aabb3f &objBox, const T &obj) {
insert(0, objBox, obj);
}
std::vector<T> queryTouchingBBox(const aabb3 &query) const {
std::vector<T> queryTouchingBBox(const aabb3f &query) const {
std::set<T> res;
queryTouchingBBox(0, query, res);
@ -180,21 +180,21 @@ public:
return res_vec;
}
octree_t(const aabb3 &box) {
octree_t(const aabb3f &box) {
this->m_nodes.push_back(octree_node_t<T>(box, 0));
}
};
template <typename T>
octree_t<T> makeOctree(const std::vector<std::pair<aabb3, T>> &objects)
octree_t<T> makeOctree(const std::vector<std::pair<aabb3f, T>> &objects)
{
if (objects.empty()) {
octree_t<T> empty{aabb3{qvec3f(), qvec3f()}};
octree_t<T> empty{aabb3f{qvec3f(), qvec3f()}};
return empty;
}
// take bbox of objects
aabb3 box = objects.at(0).first;
aabb3f box = objects.at(0).first;
for (const auto &pr : objects) {
box = box.unionWith(pr.first);
}

View File

@ -654,10 +654,10 @@ TEST(mathlib, qvec_constructor_extra) {
EXPECT_EQ(2, test[1]);
}
// aabb3
// aabb3f
TEST(mathlib, aabb_basic) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
EXPECT_EQ(qvec3f(1,1,1), b1.mins());
EXPECT_EQ(qvec3f(10,10,10), b1.maxs());
@ -665,41 +665,41 @@ TEST(mathlib, aabb_basic) {
}
TEST(mathlib, aabb_grow) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
EXPECT_EQ(aabb3(qvec3f(0,0,0), qvec3f(11,11,11)), b1.grow(qvec3f(1,1,1)));
EXPECT_EQ(aabb3f(qvec3f(0,0,0), qvec3f(11,11,11)), b1.grow(qvec3f(1,1,1)));
}
TEST(mathlib, aabb_unionwith) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3 b2(qvec3f(11,11,11), qvec3f(12,12,12));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b2(qvec3f(11,11,11), qvec3f(12,12,12));
EXPECT_EQ(aabb3(qvec3f(1,1,1), qvec3f(12,12,12)), b1.unionWith(b2));
EXPECT_EQ(aabb3f(qvec3f(1,1,1), qvec3f(12,12,12)), b1.unionWith(b2));
}
TEST(mathlib, aabb_expand) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
EXPECT_EQ(b1, b1.expand(qvec3f(1,1,1)));
EXPECT_EQ(b1, b1.expand(qvec3f(5,5,5)));
EXPECT_EQ(b1, b1.expand(qvec3f(10,10,10)));
const aabb3 b2(qvec3f(1,1,1), qvec3f(100,10,10));
const aabb3f b2(qvec3f(1,1,1), qvec3f(100,10,10));
EXPECT_EQ(b2, b1.expand(qvec3f(100,10,10)));
const aabb3 b3(qvec3f(0,1,1), qvec3f(10,10,10));
const aabb3f b3(qvec3f(0,1,1), qvec3f(10,10,10));
EXPECT_EQ(b3, b1.expand(qvec3f(0,1,1)));
}
TEST(mathlib, aabb_disjoint) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3 yes1(qvec3f(-1,-1,-1), qvec3f(0,0,0));
const aabb3 yes2(qvec3f(11,1,1), qvec3f(12,10,10));
const aabb3f yes1(qvec3f(-1,-1,-1), qvec3f(0,0,0));
const aabb3f yes2(qvec3f(11,1,1), qvec3f(12,10,10));
const aabb3 no1(qvec3f(-1,-1,-1), qvec3f(1,1,1));
const aabb3 no2(qvec3f(10,10,10), qvec3f(10.5,10.5,10.5));
const aabb3 no3(qvec3f(5,5,5), qvec3f(100,6,6));
const aabb3f no1(qvec3f(-1,-1,-1), qvec3f(1,1,1));
const aabb3f no2(qvec3f(10,10,10), qvec3f(10.5,10.5,10.5));
const aabb3f no3(qvec3f(5,5,5), qvec3f(100,6,6));
EXPECT_TRUE(b1.disjoint(yes1));
EXPECT_TRUE(b1.disjoint(yes2));
@ -711,21 +711,21 @@ TEST(mathlib, aabb_disjoint) {
EXPECT_FALSE(b1.intersectWith(yes2).valid);
// these intersections are single points
EXPECT_EQ(aabb3::intersection_t(aabb3(qvec3f(1,1,1), qvec3f(1,1,1))), b1.intersectWith(no1));
EXPECT_EQ(aabb3::intersection_t(aabb3(qvec3f(10,10,10), qvec3f(10,10,10))), b1.intersectWith(no2));
EXPECT_EQ(aabb3f::intersection_t(aabb3f(qvec3f(1,1,1), qvec3f(1,1,1))), b1.intersectWith(no1));
EXPECT_EQ(aabb3f::intersection_t(aabb3f(qvec3f(10,10,10), qvec3f(10,10,10))), b1.intersectWith(no2));
// an intersection with a volume
EXPECT_EQ(aabb3::intersection_t(aabb3(qvec3f(5,5,5), qvec3f(10,6,6))), b1.intersectWith(no3));
EXPECT_EQ(aabb3f::intersection_t(aabb3f(qvec3f(5,5,5), qvec3f(10,6,6))), b1.intersectWith(no3));
}
TEST(mathlib, aabb_contains) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3 yes1(qvec3f(1,1,1), qvec3f(2,2,2));
const aabb3 yes2(qvec3f(9,9,9), qvec3f(10,10,10));
const aabb3f yes1(qvec3f(1,1,1), qvec3f(2,2,2));
const aabb3f yes2(qvec3f(9,9,9), qvec3f(10,10,10));
const aabb3 no1(qvec3f(-1,1,1), qvec3f(2,2,2));
const aabb3 no2(qvec3f(9,9,9), qvec3f(10.5,10,10));
const aabb3f no1(qvec3f(-1,1,1), qvec3f(2,2,2));
const aabb3f no2(qvec3f(9,9,9), qvec3f(10.5,10,10));
EXPECT_TRUE(b1.contains(yes1));
EXPECT_TRUE(b1.contains(yes2));
@ -734,7 +734,7 @@ TEST(mathlib, aabb_contains) {
}
TEST(mathlib, aabb_containsPoint) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(10,10,10));
const aabb3f b1(qvec3f(1,1,1), qvec3f(10,10,10));
const qvec3f yes1(1,1,1);
const qvec3f yes2(2,2,2);
@ -753,8 +753,8 @@ TEST(mathlib, aabb_containsPoint) {
}
TEST(mathlib, aabb_create_invalid) {
const aabb3 b1(qvec3f(1,1,1), qvec3f(-1,-1,-1));
const aabb3 fixed(qvec3f(1,1,1), qvec3f(1,1,1));
const aabb3f b1(qvec3f(1,1,1), qvec3f(-1,-1,-1));
const aabb3f fixed(qvec3f(1,1,1), qvec3f(1,1,1));
EXPECT_EQ(fixed, b1);
EXPECT_EQ(qvec3f(0,0,0), b1.size());
@ -770,7 +770,7 @@ TEST(mathlib, octree_basic) {
const int N = 20000;
// generate some objects
vector<pair<aabb3, int>> objs;
vector<pair<aabb3f, int>> objs;
for (int i=0; i<N; i++) {
int x = dis(engine);
int y = dis(engine);
@ -779,7 +779,7 @@ TEST(mathlib, octree_basic) {
qvec3f mins = center - boxsize;
qvec3f maxs = center + boxsize;
aabb3 bbox(mins, maxs);
aabb3f bbox(mins, maxs);
objs.push_back(make_pair(bbox, i));
}
@ -793,7 +793,7 @@ TEST(mathlib, octree_basic) {
const double exhaustive_query_start = I_FloatTime();
vector<vector<int>> objsTouchingObjs;
for (int i=0; i<N; i++) {
const aabb3 obj_iBBox = objs[i].first;
const aabb3f obj_iBBox = objs[i].first;
vector<int> objsTouchingObj_i;
for (int j=0; j<N; j++) {
@ -810,7 +810,7 @@ TEST(mathlib, octree_basic) {
const double octree_query_start = I_FloatTime();
vector<vector<int>> objsTouchingObjs_octree;
for (int i=0; i<N; i++) {
const aabb3 obj_iBBox = objs[i].first;
const aabb3f obj_iBBox = objs[i].first;
vector<int> objsTouchingObj_i = octree.queryTouchingBBox(obj_iBBox);
objsTouchingObjs_octree.push_back(objsTouchingObj_i);