Improved aabb search
This commit is contained in:
parent
999b6f1577
commit
c9a04efdfa
1 changed files with 51 additions and 40 deletions
|
@ -347,6 +347,56 @@ class AABBTree
|
|||
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
|
||||
std::vector<ResultEntry> ClosestKPrimitivesLinearSearch(size_t k, const Eigen::Vector3f &q) const
|
||||
{
|
||||
|
@ -393,46 +443,7 @@ class AABBTree
|
|||
if (root == nullptr)
|
||||
return ResultEntry();
|
||||
|
||||
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
|
||||
|
||||
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 ClosestPrimitiveAABBSearch(q);
|
||||
|
||||
//return ClosestPrimitiveLinearSearch(q);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue