Fix performance bottleneck in IGL
This commit is contained in:
parent
dac301e3b6
commit
eba8c39846
2 changed files with 17 additions and 15 deletions
|
@ -1,12 +1,12 @@
|
||||||
// This file is part of libigl, a simple c++ geometry processing library.
|
// This file is part of libigl, a simple c++ geometry processing library.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
#include "ray_box_intersect.h"
|
#include "ray_box_intersect.h"
|
||||||
#include <vector>
|
#include <array>
|
||||||
|
|
||||||
template <
|
template <
|
||||||
typename Derivedsource,
|
typename Derivedsource,
|
||||||
|
@ -27,7 +27,7 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
const Eigen::Vector3f& rayo,
|
const Eigen::Vector3f& rayo,
|
||||||
const Eigen::Vector3f& rayd,
|
const Eigen::Vector3f& rayd,
|
||||||
const Eigen::Vector3f& bmin,
|
const Eigen::Vector3f& bmin,
|
||||||
const Eigen::Vector3f& bmax,
|
const Eigen::Vector3f& bmax,
|
||||||
float & tnear,
|
float & tnear,
|
||||||
float & tfar
|
float & tfar
|
||||||
)->bool
|
)->bool
|
||||||
|
@ -35,12 +35,12 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
Eigen::Vector3f bnear;
|
Eigen::Vector3f bnear;
|
||||||
Eigen::Vector3f bfar;
|
Eigen::Vector3f bfar;
|
||||||
// Checks for intersection testing on each direction coordinate
|
// Checks for intersection testing on each direction coordinate
|
||||||
// Computes
|
// Computes
|
||||||
float t1, t2;
|
float t1, t2;
|
||||||
tnear = -1e+6f, tfar = 1e+6f; //, tCube;
|
tnear = -1e+6f, tfar = 1e+6f; //, tCube;
|
||||||
bool intersectFlag = true;
|
bool intersectFlag = true;
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
// std::cout << "coordinate " << i << ": bmin " << bmin(i) << ", bmax " << bmax(i) << std::endl;
|
// std::cout << "coordinate " << i << ": bmin " << bmin(i) << ", bmax " << bmax(i) << std::endl;
|
||||||
assert(bmin(i) <= bmax(i));
|
assert(bmin(i) <= bmax(i));
|
||||||
if (::fabs(rayd(i)) < 1e-6) { // Ray parallel to axis i-th
|
if (::fabs(rayd(i)) < 1e-6) { // Ray parallel to axis i-th
|
||||||
if (rayo(i) < bmin(i) || rayo(i) > bmax(i)) {
|
if (rayo(i) < bmin(i) || rayo(i) > bmax(i)) {
|
||||||
|
@ -59,12 +59,12 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
}
|
}
|
||||||
// std::cout << " bnear " << bnear(i) << ", bfar " << bfar(i) << std::endl;
|
// std::cout << " bnear " << bnear(i) << ", bfar " << bfar(i) << std::endl;
|
||||||
// Finds the distance parameters t1 and t2 of the two ray-box intersections:
|
// Finds the distance parameters t1 and t2 of the two ray-box intersections:
|
||||||
// t1 must be the closest to the ray origin rayo.
|
// t1 must be the closest to the ray origin rayo.
|
||||||
t1 = (bnear(i) - rayo(i)) / rayd(i);
|
t1 = (bnear(i) - rayo(i)) / rayd(i);
|
||||||
t2 = (bfar(i) - rayo(i)) / rayd(i);
|
t2 = (bfar(i) - rayo(i)) / rayd(i);
|
||||||
if (t1 > t2) {
|
if (t1 > t2) {
|
||||||
std::swap(t1,t2);
|
std::swap(t1,t2);
|
||||||
}
|
}
|
||||||
// The two intersection values are used to saturate tnear and tfar
|
// The two intersection values are used to saturate tnear and tfar
|
||||||
if (t1 > tnear) {
|
if (t1 > tnear) {
|
||||||
tnear = t1;
|
tnear = t1;
|
||||||
|
@ -72,7 +72,7 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
if (t2 < tfar) {
|
if (t2 < tfar) {
|
||||||
tfar = t2;
|
tfar = t2;
|
||||||
}
|
}
|
||||||
// std::cout << " t1 " << t1 << ", t2 " << t2 << ", tnear " << tnear << ", tfar " << tfar
|
// std::cout << " t1 " << t1 << ", t2 " << t2 << ", tnear " << tnear << ", tfar " << tfar
|
||||||
// << " tnear > tfar? " << (tnear > tfar) << ", tfar < 0? " << (tfar < 0) << std::endl;
|
// << " tnear > tfar? " << (tnear > tfar) << ", tfar < 0? " << (tfar < 0) << std::endl;
|
||||||
if(tnear > tfar) {
|
if(tnear > tfar) {
|
||||||
intersectFlag = false;
|
intersectFlag = false;
|
||||||
|
@ -101,11 +101,11 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
// This should be precomputed and provided as input
|
// This should be precomputed and provided as input
|
||||||
typedef Matrix<Scalar,1,3> RowVector3S;
|
typedef Matrix<Scalar,1,3> RowVector3S;
|
||||||
const RowVector3S inv_dir( 1./dir(0),1./dir(1),1./dir(2));
|
const RowVector3S inv_dir( 1./dir(0),1./dir(1),1./dir(2));
|
||||||
const std::vector<bool> sign = { inv_dir(0)<0, inv_dir(1)<0, inv_dir(2)<0};
|
const std::array<bool, 3> sign = { inv_dir(0)<0, inv_dir(1)<0, inv_dir(2)<0};
|
||||||
// http://people.csail.mit.edu/amy/papers/box-jgt.pdf
|
// http://people.csail.mit.edu/amy/papers/box-jgt.pdf
|
||||||
// "An Efficient and Robust Ray–Box Intersection Algorithm"
|
// "An Efficient and Robust Ray–Box Intersection Algorithm"
|
||||||
Scalar tymin, tymax, tzmin, tzmax;
|
Scalar tymin, tymax, tzmin, tzmax;
|
||||||
std::vector<RowVector3S> bounds = {box.min(),box.max()};
|
std::array<RowVector3S, 2> bounds = {box.min(),box.max()};
|
||||||
tmin = ( bounds[sign[0]](0) - origin(0)) * inv_dir(0);
|
tmin = ( bounds[sign[0]](0) - origin(0)) * inv_dir(0);
|
||||||
tmax = ( bounds[1-sign[0]](0) - origin(0)) * inv_dir(0);
|
tmax = ( bounds[1-sign[0]](0) - origin(0)) * inv_dir(0);
|
||||||
tymin = (bounds[sign[1]](1) - origin(1)) * inv_dir(1);
|
tymin = (bounds[sign[1]](1) - origin(1)) * inv_dir(1);
|
||||||
|
@ -146,4 +146,4 @@ IGL_INLINE bool igl::ray_box_intersect(
|
||||||
|
|
||||||
#ifdef IGL_STATIC_LIBRARY
|
#ifdef IGL_STATIC_LIBRARY
|
||||||
template bool igl::ray_box_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::AlignedBox<double, 3> const&, double const&, double const&, double&, double&);
|
template bool igl::ray_box_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, double>(Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::MatrixBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::AlignedBox<double, 3> const&, double const&, double const&, double&, double&);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,7 +29,9 @@ IGL_INLINE bool igl::ray_mesh_intersect(
|
||||||
// Should be but can't be const
|
// Should be but can't be const
|
||||||
Vector3d s_d = s.template cast<double>();
|
Vector3d s_d = s.template cast<double>();
|
||||||
Vector3d dir_d = dir.template cast<double>();
|
Vector3d dir_d = dir.template cast<double>();
|
||||||
hits.clear();
|
hits.clear();
|
||||||
|
hits.reserve(F.rows());
|
||||||
|
|
||||||
// loop over all triangles
|
// loop over all triangles
|
||||||
for(int f = 0;f<F.rows();f++)
|
for(int f = 0;f<F.rows();f++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue