|
@@ -8,6 +8,7 @@
|
|
|
#ifndef IGL_AABB_H
|
|
|
#define IGL_AABB_H
|
|
|
|
|
|
+#include "Hit.h"
|
|
|
#include <Eigen/Core>
|
|
|
#include <Eigen/Geometry>
|
|
|
#include <vector>
|
|
@@ -134,7 +135,8 @@ public:
|
|
|
const Eigen::VectorXi & I);
|
|
|
// Return whether at leaf node
|
|
|
inline bool is_leaf() const;
|
|
|
- // Find the indices of elements containing given point.
|
|
|
+ // Find the indices of elements containing given point: this makes sense
|
|
|
+ // when Ele is a co-dimension 0 simplex (tets in 3D, triangles in 2D).
|
|
|
//
|
|
|
// Inputs:
|
|
|
// V #V by dim list of mesh vertex positions. **Should be same as used to
|
|
@@ -185,19 +187,43 @@ public:
|
|
|
// Known bugs: currently assumes Elements are triangles regardless of
|
|
|
// dimension.
|
|
|
inline Scalar squared_distance(
|
|
|
- const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
- const Eigen::MatrixXi & Ele,
|
|
|
- const RowVectorDIMS & p,
|
|
|
- int & i,
|
|
|
- RowVectorDIMS & c) const;
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & p,
|
|
|
+ int & i,
|
|
|
+ RowVectorDIMS & c) const;
|
|
|
//private:
|
|
|
inline Scalar squared_distance(
|
|
|
- const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
- const Eigen::MatrixXi & Ele,
|
|
|
- const RowVectorDIMS & p,
|
|
|
- const Scalar min_sqr_d,
|
|
|
- int & i,
|
|
|
- RowVectorDIMS & c) const;
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & p,
|
|
|
+ const Scalar min_sqr_d,
|
|
|
+ int & i,
|
|
|
+ RowVectorDIMS & c) const;
|
|
|
+ // All hits
|
|
|
+ inline bool intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ std::vector<igl::Hit> & hits) const;
|
|
|
+ // First hit
|
|
|
+ inline bool intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ igl::Hit & hit) const;
|
|
|
+//private:
|
|
|
+ inline bool intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ const Scalar min_t,
|
|
|
+ igl::Hit & hit) const;
|
|
|
+
|
|
|
+
|
|
|
public:
|
|
|
template <
|
|
|
typename DerivedP,
|
|
@@ -281,6 +307,8 @@ public:
|
|
|
#include "project_to_line_segment.h"
|
|
|
#include "sort.h"
|
|
|
#include "volume.h"
|
|
|
+#include "ray_box_intersect.h"
|
|
|
+#include "ray_mesh_intersect.h"
|
|
|
#include <iostream>
|
|
|
#include <iomanip>
|
|
|
#include <limits>
|
|
@@ -1149,4 +1177,108 @@ igl::AABB<DerivedV,DIM>::barycentric_coordinates(
|
|
|
bary(0) = 1.0f - bary(1) - bary(2);
|
|
|
}
|
|
|
|
|
|
+template <typename DerivedV, int DIM>
|
|
|
+inline bool
|
|
|
+igl::AABB<DerivedV,DIM>::intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ std::vector<igl::Hit> & hits) const
|
|
|
+{
|
|
|
+ hits.clear();
|
|
|
+ const Scalar t0 = 0;
|
|
|
+ const Scalar t1 = std::numeric_limits<Scalar>::infinity();
|
|
|
+ if(!ray_box_intersect(origin,dir,m_box,t0,t1))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(this->is_leaf())
|
|
|
+ {
|
|
|
+ // Actually process elements
|
|
|
+ assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
|
|
|
+ // Cheesecake way of hitting element
|
|
|
+ return ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive).eval(),hits);
|
|
|
+ }
|
|
|
+ std::vector<igl::Hit> left_hits;
|
|
|
+ std::vector<igl::Hit> right_hits;
|
|
|
+ const bool left_ret = m_left->intersect_ray(V,Ele,origin,dir,left_hits);
|
|
|
+ const bool right_ret = m_right->intersect_ray(V,Ele,origin,dir,right_hits);
|
|
|
+ hits.insert(hits.end(),left_hits.begin(),left_hits.end());
|
|
|
+ hits.insert(hits.end(),right_hits.begin(),right_hits.end());
|
|
|
+ return left_ret || right_ret;
|
|
|
+}
|
|
|
+
|
|
|
+template <typename DerivedV, int DIM>
|
|
|
+inline bool
|
|
|
+igl::AABB<DerivedV,DIM>::intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ igl::Hit & hit) const
|
|
|
+{
|
|
|
+ return intersect_ray(
|
|
|
+ V,Ele,origin,dir,std::numeric_limits<Scalar>::infinity(),hit);
|
|
|
+}
|
|
|
+
|
|
|
+template <typename DerivedV, int DIM>
|
|
|
+inline bool
|
|
|
+igl::AABB<DerivedV,DIM>::intersect_ray(
|
|
|
+ const Eigen::PlainObjectBase<DerivedV> & V,
|
|
|
+ const Eigen::MatrixXi & Ele,
|
|
|
+ const RowVectorDIMS & origin,
|
|
|
+ const RowVectorDIMS & dir,
|
|
|
+ const Scalar _min_t,
|
|
|
+ igl::Hit & hit) const
|
|
|
+{
|
|
|
+ //// Naive, slow
|
|
|
+ //std::vector<igl::Hit> hits;
|
|
|
+ //intersect_ray(V,Ele,origin,dir,hits);
|
|
|
+ //if(hits.size() > 0)
|
|
|
+ //{
|
|
|
+ // hit = hits.front();
|
|
|
+ // return true;
|
|
|
+ //}else
|
|
|
+ //{
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+ Scalar min_t = _min_t;
|
|
|
+ const Scalar t0 = 0;
|
|
|
+ if(!ray_box_intersect(origin,dir,m_box,t0,min_t))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(this->is_leaf())
|
|
|
+ {
|
|
|
+ // Actually process elements
|
|
|
+ assert((Ele.size() == 0 || Ele.cols() == 3) && "Elements should be triangles");
|
|
|
+ // Cheesecake way of hitting element
|
|
|
+ return ray_mesh_intersect(origin,dir,V,Ele.row(m_primitive).eval(),hit);
|
|
|
+ }
|
|
|
+ igl::Hit left_hit;
|
|
|
+ igl::Hit right_hit;
|
|
|
+ bool left_ret = m_left->intersect_ray(V,Ele,origin,dir,min_t,left_hit);
|
|
|
+ if(left_ret && left_hit.t<min_t)
|
|
|
+ {
|
|
|
+ min_t = left_hit.t;
|
|
|
+ hit = left_hit;
|
|
|
+ left_ret = true;
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ left_ret = false;
|
|
|
+ }
|
|
|
+ bool right_ret = m_right->intersect_ray(V,Ele,origin,dir,min_t,right_hit);
|
|
|
+ if(right_ret && right_hit.t<min_t)
|
|
|
+ {
|
|
|
+ min_t = right_hit.t;
|
|
|
+ hit = right_hit;
|
|
|
+ right_ret = true;
|
|
|
+ }else
|
|
|
+ {
|
|
|
+ right_ret = false;
|
|
|
+ }
|
|
|
+ return left_ret || right_ret;
|
|
|
+}
|
|
|
+
|
|
|
#endif
|