Improved aabb search

This commit is contained in:
hodasemi 2019-01-25 09:14:17 +01:00
parent 999b6f1577
commit c9a04efdfa

View file

@ -347,6 +347,56 @@ class AABBTree
return best; return best;
} }
ResultEntry ClosestPrimitiveAABBSearch(const Eigen::Vector3f &q) const{
AABBNode* node = root;
while(1) {
// TODO: dynamic cast to check for leaf- or split-node
// if split node: check BB of childs
// -> node = child with shorter distance
// if leaf node: iterate through primitives
if (node->IsLeaf()) {
AABBLeafNode* leaf_node = dynamic_cast<AABBLeafNode*>(node);
if (leaf_node != nullptr) {
ResultEntry best;
for (auto pit = leaf_node->begin(); pit != leaf_node->end(); ++pit)
{
float dist = pit->SqrDistance(q);
if (dist < best.sqrDistance)
{
best.sqrDistance = dist;
best.prim = &(*pit);
}
}
return best;
} else {
abort();
}
} else {
AABBSplitNode* split_node = dynamic_cast<AABBSplitNode*>(node);
if (split_node != nullptr) {
AABBNode* left_child = split_node->Left();
AABBNode* right_child = split_node->Right();
float left_distance = left_child->GetBounds().SqrDistance(q);
float right_distance = right_child->GetBounds().SqrDistance(q);
if (left_distance < right_distance) {
node = left_child;
} else {
node = right_child;
}
} else {
abort();
}
}
}
}
//computes the k nearest neighbor primitives via linear search //computes the k nearest neighbor primitives via linear search
std::vector<ResultEntry> ClosestKPrimitivesLinearSearch(size_t k, const Eigen::Vector3f &q) const std::vector<ResultEntry> ClosestKPrimitivesLinearSearch(size_t k, const Eigen::Vector3f &q) const
{ {
@ -393,46 +443,7 @@ class AABBTree
if (root == nullptr) if (root == nullptr)
return ResultEntry(); return ResultEntry();
AABBNode* node = root; return ClosestPrimitiveAABBSearch(q);
while(1) {
// TODO: dynamic cast to check for leaf- or split-node
// if split node: check BB of childs
// -> node = child with shorter distance
// if leaf node: iterate through primitives
AABBSplitNode* split_node = dynamic_cast<AABBSplitNode*>(node);
AABBLeafNode* leaf_node = dynamic_cast<AABBLeafNode*>(node);
if (split_node != nullptr) {
AABBNode* left_child = split_node->Left();
AABBNode* right_child = split_node->Right();
float left_distance = left_child->GetBounds().SqrDistance(q);
float right_distance = right_child->GetBounds().SqrDistance(q);
if (left_distance < right_distance) {
node = left_child;
} else {
node = right_child;
}
} else if (leaf_node != nullptr) {
ResultEntry best;
for (auto pit = leaf_node->begin(); pit != leaf_node->end(); ++pit)
{
float dist = pit->SqrDistance(q);
if (dist < best.sqrDistance)
{
best.sqrDistance = dist;
best.prim = &(*pit);
}
}
return best;
} else {
abort();
}
}
//return ClosestPrimitiveLinearSearch(q); //return ClosestPrimitiveLinearSearch(q);
} }