56 #include "BSPImplT.hh" 65 template <
class BSPCore>
70 NearestNeighborData data;
72 data.dist = infinity_;
74 throw std::runtime_error(
"It seems like the BSP hasn't been built, yet. Did you call build(...)?");
75 _nearest(this->root_, data);
76 return NearestNeighbor(data.nearest, sqrt(data.dist));
83 template <
class BSPCore>
86 _nearest(Node* _node, NearestNeighborData& _data)
const 89 if (!_node->left_child_)
92 for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
94 dist = this->traits_.sqrdist(*it, _data.ref);
95 if (dist < _data.dist)
106 Scalar dist = _node->plane_.distance(_data.ref);
109 _nearest(_node->left_child_, _data);
110 if (dist*dist < _data.dist)
111 _nearest(_node->right_child_, _data);
115 _nearest(_node->right_child_, _data);
116 if (dist*dist < _data.dist)
117 _nearest(_node->left_child_, _data);
124 template <
class BSPCore>
130 RayCollisionData data;
133 data.hit_handles.clear();
135 _raycollision_non_directional(this->root_, data);
137 std::sort(data.hit_handles.begin(), data.hit_handles.end(), less_pair_second<Handle,Scalar>());
141 template <
class BSPCore>
147 RayCollisionData data;
150 data.hit_handles.clear();
152 _raycollision_directional(this->root_, data);
154 std::sort(data.hit_handles.begin(), data.hit_handles.end(), less_pair_second<Handle,Scalar>());
159 template <
class BSPCore>
165 RayCollisionData data;
168 data.hit_handles.clear();
170 _raycollision_nearest_directional(this->root_, data);
175 template<
class BSPCore>
176 template<
class Callback>
181 _intersect_ball(*(this->root_), _c, _r, _callback);
188 template <
class BSPCore>
194 if (!_node->left_child_)
200 for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
202 this->traits_.points(*it, v0, v1, v2);
205 _data.hit_handles.push_back(std::pair<Handle,Scalar>(*it,dist));
215 _raycollision_non_directional(_node->left_child_, _data);
218 _raycollision_non_directional(_node->right_child_, _data);
226 template <
class BSPCore>
232 if (!_node->left_child_)
238 for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
240 this->traits_.points(*it, v0, v1, v2);
243 _data.hit_handles.push_back(std::pair<Handle,Scalar>(*it,dist));
254 _raycollision_directional(_node->left_child_, _data);
257 _raycollision_directional(_node->right_child_, _data);
265 template <
class BSPCore>
271 if (!_node->left_child_)
277 for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
279 this->traits_.points(*it, v0, v1, v2);
282 _data.hit_handles.push_back(std::pair<Handle,Scalar>(*it, dist));
287 if(!_data.hit_handles.empty()) {
288 std::partial_sort(_data.hit_handles.begin(), _data.hit_handles.begin() + 1, _data.hit_handles.end(), less_pair_second<Handle, Scalar>());
289 _data.hit_handles.resize(1);
297 Node* first_node = _node->left_child_, *second_node = _node->right_child_;
298 if (!_node->plane_(_data.ref)) {
299 std::swap(first_node, second_node);
304 _raycollision_nearest_directional(first_node, _data);
308 if(!_data.hit_handles.empty()) {
309 dist = _data.hit_handles.front().second;
312 _raycollision_nearest_directional(second_node, _data);
316 template<
class BSPCore>
317 template<
class Callback>
322 Callback _callback)
const 325 if (!_node.left_child_)
327 const double r_sqr = _r * _r;
328 for (
const auto &fh: _node) {
329 const double dist = this->traits_.sqrdist(fh, _c);
337 const Scalar dist = _node.plane_.distance(_c);
338 const Node &left = *_node.left_child_;
339 const Node &right = *_node.right_child_;
342 _intersect_ball(left, _c, _r, _callback);
345 _intersect_ball(right, _c, _r, _callback);
RayCollision directionalRaycollision(const Point &_p, const Point &_r) const
intersect mesh with ray
RayCollision nearestRaycollision(const Point &_p, const Point &_r) const
intersect mesh with ray
std::vector< std::pair< Handle, Scalar > > RayCollision
Store nearest neighbor information.
bool triangleIntersection(const Vec &_o, const Vec &_dir, const Vec &_v0, const Vec &_v1, const Vec &_v2, typename Vec::value_type &_t, typename Vec::value_type &_u, typename Vec::value_type &_v)
Intersect a ray and a triangle.
RayCollision raycollision(const Point &_p, const Point &_r) const
intersect mesh with ray
Store nearest neighbor information.
void _raycollision_non_directional(Node *_node, RayCollisionData &_data) const
recursive part of raycollision()
NearestNeighbor nearest(const Point &_p) const
Return handle of the nearest neighbor face.
void _raycollision_directional(Node *_node, RayCollisionData &_data) const
recursive part of directionalRaycollision()
bool axisAlignedBBIntersection(const Vec &_o, const Vec &_dir, const Vec &_bbmin, const Vec &_bbmax, typename Vec::value_type &tmin, typename Vec::value_type &tmax)
Intersect a ray and an axis aligned bounding box.
static Scalar max()
Return the maximum absolte value a scalar type can store.
void intersectBall(const Point &_c, Scalar _r, Callback _callback) const
intersect mesh with open ball