Commit 8776aee4 authored by Johannes Frohn's avatar Johannes Frohn

Added function to BSP that only returns the closest ray collision

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@16755 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 2421474c
......@@ -116,7 +116,7 @@ _nearest(Node* _node, NearestNeighborData& _data) const
_nearest(_node->right_child_, _data);
if (dist*dist < _data.dist)
_nearest(_node->left_child_, _data);
}
}
}
}
......@@ -132,7 +132,7 @@ raycollision(const Point& _p, const Point& _r) const
data.ref = _p;
data.ray = _r;
data.hit_handles.clear();
_raycollision_non_directional(this->root_, data);
std::sort(data.hit_handles.begin(), data.hit_handles.end(), less_pair_second<Handle,Scalar>());
......@@ -157,6 +157,21 @@ directionalRaycollision(const Point& _p, const Point& _r) const {
}
template <class BSPCore>
typename BSPImplT<BSPCore>::RayCollision
BSPImplT<BSPCore>::
nearestRaycollision(const Point& _p, const Point& _r) const {
// Prepare the struct for returning the data
RayCollisionData data;
data.ref = _p;
data.ray = _r;
data.hit_handles.clear();
_raycollision_nearest_directional(this->root_, data);
return RayCollision(data.hit_handles);
}
//-----------------------------------------------------------------------------
......@@ -235,5 +250,60 @@ _raycollision_directional(Node* _node, RayCollisionData& _data) const
}
}
//-----------------------------------------------------------------------------
template <class BSPCore>
void
BSPImplT<BSPCore>::
_raycollision_nearest_directional(Node* _node, RayCollisionData& _data) const
{
// terminal node
if (!_node->left_child_)
{
Scalar dist;
Point v0, v1, v2;
Scalar u, v;
for (HandleIter it=_node->begin(); it!=_node->end(); ++it)
{
this->traits_.points(*it, v0, v1, v2);
if (ACG::Geometry::triangleIntersection(_data.ref, _data.ray, v0, v1, v2, dist, u, v)) {
if (dist > 0.0){
_data.hit_handles.push_back(std::pair<Handle,Scalar>(*it, dist));
}
}
}
// only return the closest hit
if(!_data.hit_handles.empty()) {
std::partial_sort(_data.hit_handles.begin(), _data.hit_handles.begin() + 1, _data.hit_handles.end(), less_pair_second<Handle, Scalar>());
_data.hit_handles.resize(1);
}
}
// non-terminal node
else
{
// determine order of traversal
Node* first_node = _node->left_child_, *second_node = _node->right_child_;
if (!_node->plane_(_data.ref)) {
std::swap(first_node, second_node);
}
Scalar tmin, tmax;
if ( first_node && ACG::Geometry::axisAlignedBBIntersection( _data.ref, _data.ray, first_node->bb_min, first_node->bb_max, tmin, tmax) ) {
_raycollision_nearest_directional(first_node, _data);
}
// if the second node is further away than the closeset hit skip it
Scalar dist = ACG::NumLimitsT<Scalar>::max();
if(!_data.hit_handles.empty()) {
dist = _data.hit_handles.front().second;
}
if ( second_node && ACG::Geometry::axisAlignedBBIntersection( _data.ref, _data.ray, second_node->bb_min, second_node->bb_max, tmin, tmax) && (tmin < dist) ) {
_raycollision_nearest_directional(second_node, _data);
}
}
}
//=============================================================================
......@@ -75,7 +75,7 @@ public: //---------------------------------------------------------------------
typedef typename BSPCore::Node Node;
typedef typename BSPCore::Handles Handles;
typedef typename BSPCore::HandleIter HandleIter;
public: //---------------------------------------------------------------------
......@@ -93,13 +93,13 @@ public: //---------------------------------------------------------------------
Handle handle;
Scalar dist;
};
/// Store nearest neighbor information
typedef std::vector< std::pair<Handle,Scalar> > RayCollision;
/// Return handle of the nearest neighbor face
NearestNeighbor nearest(const Point& _p) const;
/** \brief intersect mesh with ray
*
* This function shots a ray through the mesh and collects all intersected triangles and
......@@ -111,7 +111,7 @@ public: //---------------------------------------------------------------------
* @return Collision information
*/
RayCollision raycollision (const Point& _p, const Point& _r) const;
/** \brief intersect mesh with ray
*
* This function shots a ray through the mesh and collects all intersected triangles and
......@@ -125,6 +125,19 @@ public: //---------------------------------------------------------------------
*/
RayCollision directionalRaycollision (const Point& _p, const Point& _r) const;
/** \brief intersect mesh with ray
*
* This function shots a ray through the mesh and determines the first intersected triangle and
* the handle of the closest face ( directional, so the ray direction is taken into account!).
*
* Only hits with a distance > 0.0 to the point p will be collected (_p will be skipped!).
* Note that for compatibility reasons the return type is still a vector of collisions.
*
* @param _p Start point of the ray
* @param _r Ray direction
* @return Collision information
*/
RayCollision nearestRaycollision(const Point& _p, const Point& _r) const;
private: //---------------------------------------------------------------------
......@@ -141,7 +154,7 @@ private: //---------------------------------------------------------------------
return stream;
}
};
/// Store ray collide information
struct RayCollisionData
{
......@@ -153,7 +166,7 @@ private: //---------------------------------------------------------------------
// Recursive part of nearest()
void _nearest(Node* _node, NearestNeighborData& _data) const;
/** \brief recursive part of raycollision()
*
* @param _node The current node in the tree
......@@ -168,6 +181,8 @@ private: //---------------------------------------------------------------------
*/
void _raycollision_directional(Node* _node, RayCollisionData& _data) const;
void _raycollision_nearest_directional(Node* _node, RayCollisionData& _data) const;
template<typename T,typename U>
struct less_pair_second: public std::binary_function<T,U,bool> {
bool operator()(const std::pair<T,U> &left, const std::pair<T,U> &right) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment