diff --git a/include/hpp/fcl/BV/BV.h b/include/hpp/fcl/BV/BV.h index c9f4f02522e867f7cc02dac93fc8e4233263984b..22f0f61baf3953ba297359a34728f9d97cd10fc7 100644 --- a/include/hpp/fcl/BV/BV.h +++ b/include/hpp/fcl/BV/BV.h @@ -125,12 +125,9 @@ public: bv2.axis[2] = R.col(id[2]); */ - bv2.To = tf1.transform(bv1.center()); - bv2.extent = (bv1.max_ - bv1.min_) * 0.5; - const Matrix3f& R = tf1.getRotation(); - bv2.axis[0] = R.col(0); - bv2.axis[1] = R.col(1); - bv2.axis[2] = R.col(2); + bv2.To.noalias() = tf1.transform(bv1.center()); + bv2.extent.noalias() = (bv1.max_ - bv1.min_) * 0.5; + bv2.axes.noalias() = tf1.getRotation(); } }; @@ -140,11 +137,9 @@ class Converter<OBB, OBB> public: static void convert(const OBB& bv1, const Transform3f& tf1, OBB& bv2) { - bv2.extent = bv1.extent; - bv2.To = tf1.transform(bv1.To); - bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]); - bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]); - bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]); + bv2.extent.noalias() = bv1.extent; + bv2.To.noalias() = tf1.transform(bv1.To); + bv2.axes.noalias() = tf1.getRotation() * bv1.axes; } }; @@ -164,11 +159,9 @@ class Converter<RSS, OBB> public: static void convert(const RSS& bv1, const Transform3f& tf1, OBB& bv2) { - bv2.extent = Vec3f(bv1.l[0] * 0.5 + bv1.r, bv1.l[1] * 0.5 + bv1.r, bv1.r); - bv2.To = tf1.transform(bv1.Tr); - bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]); - bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]); - bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]); + bv2.extent.noalias() = Vec3f(bv1.l[0] * 0.5 + bv1.r, bv1.l[1] * 0.5 + bv1.r, bv1.r); + bv2.To.noalias() = tf1.transform(bv1.Tr); + bv2.axes.noalias() = tf1.getRotation() * bv1.axes; } }; @@ -207,9 +200,7 @@ public: static void convert(const OBB& bv1, const Transform3f& tf1, RSS& bv2) { bv2.Tr = tf1.transform(bv1.To); - bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]); - bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]); - bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]); + bv2.axes.noalias() = tf1.getRotation() * bv1.axes; bv2.r = bv1.extent[2]; bv2.l[0] = 2 * (bv1.extent[0] - bv2.r); @@ -223,10 +214,8 @@ class Converter<RSS, RSS> public: static void convert(const RSS& bv1, const Transform3f& tf1, RSS& bv2) { - bv2.Tr = tf1.transform(bv1.Tr); - bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]); - bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]); - bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]); + bv2.Tr.noalias() = tf1.transform(bv1.Tr); + bv2.axes.noalias() = tf1.getRotation() * bv1.axes; bv2.r = bv1.r; bv2.l[0] = bv1.l[0]; @@ -283,9 +272,10 @@ public: const Matrix3f& R = tf1.getRotation(); bool left_hand = (id[0] == (id[1] + 1) % 3); - if (left_hand) bv2.axis[0] = -R.col(id[0]); else bv2.axis[0] = R.col(id[0]); - bv2.axis[1] = R.col(id[1]); - bv2.axis[2] = R.col(id[2]); + if (left_hand) bv2.axes.col(0).noalias() = -R.col(id[0]); + else bv2.axes.col(0).noalias() = R.col(id[0]); + bv2.axes.col(1).noalias() = R.col(id[1]); + bv2.axes.col(2).noalias() = R.col(id[2]); } }; diff --git a/include/hpp/fcl/BV/BV_node.h b/include/hpp/fcl/BV/BV_node.h index 52a40baa4567c98e55354c3dc29731965ddff256..fc70c99a05c01330fcde059547a107568c8d3e8e 100644 --- a/include/hpp/fcl/BV/BV_node.h +++ b/include/hpp/fcl/BV/BV_node.h @@ -111,25 +111,19 @@ struct BVNode : public BVNodeBase template<> inline Matrix3f BVNode<OBB>::getOrientation() const { - return (Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(); + return bv.axes; } template<> inline Matrix3f BVNode<RSS>::getOrientation() const { - return (Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(); + return bv.axes; } template<> inline Matrix3f BVNode<OBBRSS>::getOrientation() const { - return (Matrix3f() << bv.obb.axis[0][0], bv.obb.axis[1][0], bv.obb.axis[2][0], - bv.obb.axis[0][1], bv.obb.axis[1][1], bv.obb.axis[2][1], - bv.obb.axis[0][2], bv.obb.axis[1][2], bv.obb.axis[2][2]).finished(); + return bv.obb.axes; } diff --git a/include/hpp/fcl/BV/OBB.h b/include/hpp/fcl/BV/OBB.h index 9159941cd567ecd993d6335780a7af90f8c67de5..6bb1127988aabe4985e9f72816fd36ef66effbce 100644 --- a/include/hpp/fcl/BV/OBB.h +++ b/include/hpp/fcl/BV/OBB.h @@ -51,7 +51,7 @@ class OBB public: /// @brief Orientation of OBB. axis[i] is the ith column of the orientation matrix for the box; it is also the i-th principle direction of the box. /// We assume that axis[0] corresponds to the axis with the longest box edge, axis[1] corresponds to the shorter one and axis[2] corresponds to the shortest one. - Vec3f axis[3]; + Matrix3f axes; /// @brief Center of OBB Vec3f To; diff --git a/include/hpp/fcl/BV/RSS.h b/include/hpp/fcl/BV/RSS.h index 7dc79c3c0fc0e0cf0e2f5bbe6bba55e678a8d6ad..2c5b80898ab301f890f1808135172849edf83ab0 100644 --- a/include/hpp/fcl/BV/RSS.h +++ b/include/hpp/fcl/BV/RSS.h @@ -52,7 +52,7 @@ class RSS public: /// @brief Orientation of RSS. axis[i] is the ith column of the orientation matrix for the RSS; it is also the i-th principle direction of the RSS. /// We assume that axis[0] corresponds to the axis with the longest length, axis[1] corresponds to the shorter one and axis[2] corresponds to the shortest one. - Vec3f axis[3]; + Matrix3f axes; /// @brief Origin of the rectangle in RSS Vec3f Tr; diff --git a/include/hpp/fcl/BVH/BVH_model.h b/include/hpp/fcl/BVH/BVH_model.h index 5794850c94a6c89af55b49aa7a2cfbf3c879359d..761c6789ee8ecc96c6fac0bcd276d5e324a2e547 100644 --- a/include/hpp/fcl/BVH/BVH_model.h +++ b/include/hpp/fcl/BVH/BVH_model.h @@ -188,7 +188,7 @@ public: /// BV node. When traversing the BVH, this can save one matrix transformation. void makeParentRelative() { - Vec3f I[3] = {Vec3f(1, 0, 0), Vec3f(0, 1, 0), Vec3f(0, 0, 1)}; + Matrix3f I (Matrix3f::Identity()); makeParentRelativeRecurse(0, I, Vec3f()); } @@ -303,13 +303,13 @@ private: /// @recursively compute each bv's transform related to its parent. For default BV, only the translation works. /// For oriented BV (OBB, RSS, OBBRSS), special implementation is provided. - void makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c) + void makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c) { if(!bvs[bv_id].isLeaf()) { - makeParentRelativeRecurse(bvs[bv_id].first_child, parent_axis, bvs[bv_id].getCenter()); + makeParentRelativeRecurse(bvs[bv_id].first_child, parent_axes, bvs[bv_id].getCenter()); - makeParentRelativeRecurse(bvs[bv_id].first_child + 1, parent_axis, bvs[bv_id].getCenter()); + makeParentRelativeRecurse(bvs[bv_id].first_child + 1, parent_axes, bvs[bv_id].getCenter()); } bvs[bv_id].bv = translate(bvs[bv_id].bv, -parent_c); @@ -318,13 +318,13 @@ private: template<> -void BVHModel<OBB>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c); +void BVHModel<OBB>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c); template<> -void BVHModel<RSS>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c); +void BVHModel<RSS>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c); template<> -void BVHModel<OBBRSS>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c); +void BVHModel<OBBRSS>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c); /// @brief Specialization of getNodeType() for BVHModel with different BV types diff --git a/include/hpp/fcl/BVH/BVH_utility.h b/include/hpp/fcl/BVH/BVH_utility.h index b5783ed785c06ccade80bec2fbc35acb09e6a302..dc9796e42d6cbe2269774f91e31edb8731e7bb71 100644 --- a/include/hpp/fcl/BVH/BVH_utility.h +++ b/include/hpp/fcl/BVH/BVH_utility.h @@ -81,10 +81,10 @@ void BVHExpand(BVHModel<RSS>& model, const Variance3f* ucs, FCL_REAL r); void getCovariance(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Matrix3f& M); /// @brief Compute the RSS bounding volume parameters: radius, rectangle size and the origin, given the BV axises. -void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Vec3f axis[3], Vec3f& origin, FCL_REAL l[2], FCL_REAL& r); +void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, const Matrix3f& axes, Vec3f& origin, FCL_REAL l[2], FCL_REAL& r); /// @brief Compute the bounding volume extent and center for a set or subset of points, given the BV axises. -void getExtentAndCenter(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Vec3f axis[3], Vec3f& center, Vec3f& extent); +void getExtentAndCenter(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Matrix3f& axes, Vec3f& center, Vec3f& extent); /// @brief Compute the center and radius for a triangle's circumcircle void circumCircleComputation(const Vec3f& a, const Vec3f& b, const Vec3f& c, Vec3f& center, FCL_REAL& radius); diff --git a/include/hpp/fcl/collision_object.h b/include/hpp/fcl/collision_object.h index ec9ecdce999484cd39ff19f0c539d5b13dc407f1..fe1f816d9f405f15a9d0464d731b3441a9842573 100644 --- a/include/hpp/fcl/collision_object.h +++ b/include/hpp/fcl/collision_object.h @@ -206,7 +206,7 @@ public: } else { - Vec3f center = t.transform(cgeom->aabb_center); + Vec3f center (t.transform(cgeom->aabb_center)); Vec3f delta(Vec3f::Constant(cgeom->aabb_radius)); aabb.min_ = center - delta; aabb.max_ = center + delta; diff --git a/include/hpp/fcl/math/transform.h b/include/hpp/fcl/math/transform.h index 5dfbe7c9772da41cd4bb0630e8a9ed268d081683..ebb19e16877928210a89eec346dca76e01a29f54 100644 --- a/include/hpp/fcl/math/transform.h +++ b/include/hpp/fcl/math/transform.h @@ -85,10 +85,10 @@ public: void toEuler(FCL_REAL& a, FCL_REAL& b, FCL_REAL& c) const; /// @brief Axes to quaternion - void fromAxes(const Vec3f axis[3]); + void fromAxes(const Matrix3f& axes); /// @brief Axes to matrix - void toAxes(Vec3f axis[3]) const; + void toAxes(Matrix3f& axis) const; /// @brief Axis and angle to quaternion void fromAxisAngle(const Vec3f& axis, FCL_REAL angle); diff --git a/include/hpp/fcl/traversal/traversal_node_bvhs.h b/include/hpp/fcl/traversal/traversal_node_bvhs.h index 9b3f4efd8b509f2e9206216fb66344e7560447c2..515fd9ec2230d5a774ffb96ade2dea3d0563fc89 100644 --- a/include/hpp/fcl/traversal/traversal_node_bvhs.h +++ b/include/hpp/fcl/traversal/traversal_node_bvhs.h @@ -860,15 +860,15 @@ namespace details { template<typename BV> -const Vec3f& getBVAxis(const BV& bv, int i) +inline const Matrix3f& getBVAxes(const BV& bv) { - return bv.axis[i]; + return bv.axes; } template<> -inline const Vec3f& getBVAxis<OBBRSS>(const OBBRSS& bv, int i) +inline const Matrix3f& getBVAxes<OBBRSS>(const OBBRSS& bv) { - return bv.obb.axis[i]; + return bv.obb.axes; } @@ -906,10 +906,7 @@ bool meshConservativeAdvancementTraversalNodeCanStop(FCL_REAL c, assert(c == d); - Vec3f n_transformed = - getBVAxis(model1->getBV(c1).bv, 0) * n[0] + - getBVAxis(model1->getBV(c1).bv, 1) * n[1] + - getBVAxis(model1->getBV(c1).bv, 2) * n[2]; + Vec3f n_transformed (getBVAxes(model1->getBV(c1).bv) * n); TBVMotionBoundVisitor<BV> mb_visitor1(model1->getBV(c1).bv, n_transformed), mb_visitor2(model2->getBV(c2).bv, n_transformed); FCL_REAL bound1 = motion1->computeMotionBound(mb_visitor1); diff --git a/src/BV/OBB.cpp b/src/BV/OBB.cpp index bf045f803d1ca176e3bf95c6a923373401f7f96f..2628e9214fdc23a110ca59245401033849684afa 100644 --- a/src/BV/OBB.cpp +++ b/src/BV/OBB.cpp @@ -48,22 +48,15 @@ namespace fcl /// @brief Compute the 8 vertices of a OBB inline void computeVertices(const OBB& b, Vec3f vertices[8]) { - const Vec3f* axis = b.axis; - const Vec3f& extent = b.extent; - const Vec3f& To = b.To; - - Vec3f extAxis0 = axis[0] * extent[0]; - Vec3f extAxis1 = axis[1] * extent[1]; - Vec3f extAxis2 = axis[2] * extent[2]; - - vertices[0] = To - extAxis0 - extAxis1 - extAxis2; - vertices[1] = To + extAxis0 - extAxis1 - extAxis2; - vertices[2] = To + extAxis0 + extAxis1 - extAxis2; - vertices[3] = To - extAxis0 + extAxis1 - extAxis2; - vertices[4] = To - extAxis0 - extAxis1 + extAxis2; - vertices[5] = To + extAxis0 - extAxis1 + extAxis2; - vertices[6] = To + extAxis0 + extAxis1 + extAxis2; - vertices[7] = To - extAxis0 + extAxis1 + extAxis2; + Matrix3f extAxes (b.axes * b.extent.asDiagonal()); + vertices[0].noalias() = b.To + extAxes * Vec3f(-1,-1,-1); + vertices[1].noalias() = b.To + extAxes * Vec3f( 1,-1,-1); + vertices[2].noalias() = b.To + extAxes * Vec3f( 1, 1,-1); + vertices[3].noalias() = b.To + extAxes * Vec3f(-1, 1,-1); + vertices[4].noalias() = b.To + extAxes * Vec3f(-1,-1, 1); + vertices[5].noalias() = b.To + extAxes * Vec3f( 1,-1, 1); + vertices[6].noalias() = b.To + extAxes * Vec3f( 1, 1, 1); + vertices[7].noalias() = b.To + extAxes * Vec3f(-1, 1, 1); } /// @brief OBB merge method when the centers of two smaller OBB are far away @@ -78,16 +71,11 @@ inline OBB merge_largedist(const OBB& b1, const OBB& b2) Matrix3f::Scalar s[3] = {0, 0, 0}; // obb axes - Vec3f& R0 = b.axis[0]; - Vec3f& R1 = b.axis[1]; - Vec3f& R2 = b.axis[2]; - - R0 = b1.To - b2.To; - R0.normalize(); + b.axes.col(0).noalias() = (b1.To - b2.To).normalized(); Vec3f vertex_proj[16]; for(int i = 0; i < 16; ++i) - vertex_proj[i] = vertex[i] - R0 * vertex[i].dot(R0); + vertex_proj[i] = vertex[i] - b.axes.col(0) * vertex[i].dot(b.axes.col(0)); getCovariance(vertex_proj, NULL, NULL, NULL, 16, M); eigen(M, s, E); @@ -100,12 +88,12 @@ inline OBB merge_largedist(const OBB& b1, const OBB& b2) else { mid = 2; } - R1 << E[0][max], E[1][max], E[2][max]; - R2 << E[0][mid], E[1][mid], E[2][mid]; + b.axes.col(1) << E[0][max], E[1][max], E[2][max]; + b.axes.col(2) << E[0][mid], E[1][mid], E[2][mid]; // set obb centers and extensions Vec3f center, extent; - getExtentAndCenter(vertex, NULL, NULL, NULL, 16, b.axis, center, extent); + getExtentAndCenter(vertex, NULL, NULL, NULL, 16, b.axes, center, extent); b.To = center; b.extent = extent; @@ -120,15 +108,15 @@ inline OBB merge_smalldist(const OBB& b1, const OBB& b2) OBB b; b.To = (b1.To + b2.To) * 0.5; Quaternion3f q0, q1; - q0.fromAxes(b1.axis); - q1.fromAxes(b2.axis); + q0.fromAxes(b1.axes); + q1.fromAxes(b2.axes); if(q0.dot(q1) < 0) q1 = -q1; Quaternion3f q = q0 + q1; FCL_REAL inv_length = 1.0 / std::sqrt(q.dot(q)); q = q * inv_length; - q.toAxes(b.axis); + q.toAxes(b.axes); Vec3f vertex[8], diff; @@ -142,7 +130,7 @@ inline OBB merge_smalldist(const OBB& b1, const OBB& b2) diff = vertex[i] - b.To; for(int j = 0; j < 3; ++j) { - FCL_REAL dot = diff.dot(b.axis[j]); + FCL_REAL dot = diff.dot(b.axes.col(j)); if(dot > pmax[j]) pmax[j] = dot; else if(dot < pmin[j]) @@ -156,7 +144,7 @@ inline OBB merge_smalldist(const OBB& b1, const OBB& b2) diff = vertex[i] - b.To; for(int j = 0; j < 3; ++j) { - FCL_REAL dot = diff.dot(b.axis[j]); + FCL_REAL dot = diff.dot(b.axes.col(j)); if(dot > pmax[j]) pmax[j] = dot; else if(dot < pmin[j]) @@ -166,7 +154,7 @@ inline OBB merge_smalldist(const OBB& b1, const OBB& b2) for(int j = 0; j < 3; ++j) { - b.To += (b.axis[j] * (0.5 * (pmax[j] + pmin[j]))); + b.To.noalias() += (b.axes.col(j) * (0.5 * (pmax[j] + pmin[j]))); b.extent[j] = 0.5 * (pmax[j] - pmin[j]); } @@ -545,12 +533,8 @@ bool OBB::overlap(const OBB& other) const /// compute what transform [R,T] that takes us from cs1 to cs2. /// [R,T] = [R1,T1]'[R2,T2] = [R1',-R1'T][R2,T2] = [R1'R2, R1'(T2-T1)] /// First compute the rotation part, then translation part - Vec3f t = other.To - To; // T2 - T1 - Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2])); // R1'(T2-T1) - Matrix3f R; - R << axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), axis[0].dot(other.axis[2]), - axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), axis[1].dot(other.axis[2]), - axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), axis[2].dot(other.axis[2]); + Vec3f T (axes.transpose() * (other.To - To)); + Matrix3f R (axes.transpose() * other.axes); return !obbDisjoint(R, T, extent, other.extent); } @@ -560,15 +544,16 @@ bool OBB::overlap(const OBB& other) const /// compute what transform [R,T] that takes us from cs1 to cs2. /// [R,T] = [R1,T1]'[R2,T2] = [R1',-R1'T][R2,T2] = [R1'R2, R1'(T2-T1)] /// First compute the rotation part, then translation part - Vec3f t = other.To - To; // T2 - T1 - Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2])); // R1'(T2-T1) - Matrix3f R; - R << axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), - axis[0].dot(other.axis[2]), - axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), - axis[1].dot(other.axis[2]), - axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), - axis[2].dot(other.axis[2]); + // Vec3f t = other.To - To; // T2 - T1 + // Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2])); // R1'(T2-T1) + // Matrix3f R(axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), + // axis[0].dot(other.axis[2]), + // axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), + // axis[1].dot(other.axis[2]), + // axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), + // axis[2].dot(other.axis[2])); + Vec3f T (axes.transpose() * (other.To - To)); + Matrix3f R (axes.transpose() * other.axes); return !obbDisjointAndLowerBoundDistance (R, T, extent, other.extent, sqrDistLowerBound); @@ -578,15 +563,15 @@ bool OBB::overlap(const OBB& other) const bool OBB::contain(const Vec3f& p) const { Vec3f local_p = p - To; - FCL_REAL proj = local_p.dot(axis[0]); + FCL_REAL proj = local_p.dot(axes.col(0)); if((proj > extent[0]) || (proj < -extent[0])) return false; - proj = local_p.dot(axis[1]); + proj = local_p.dot(axes.col(1)); if((proj > extent[1]) || (proj < -extent[1])) return false; - proj = local_p.dot(axis[2]); + proj = local_p.dot(axes.col(2)); if((proj > extent[2]) || (proj < -extent[2])) return false; @@ -596,10 +581,8 @@ bool OBB::contain(const Vec3f& p) const OBB& OBB::operator += (const Vec3f& p) { OBB bvp; - bvp.To = p; - bvp.axis[0] = axis[0]; - bvp.axis[1] = axis[1]; - bvp.axis[2] = axis[2]; + bvp.To.noalias() = p; + bvp.axes.noalias() = axes; bvp.extent.setZero(); *this += bvp; @@ -631,18 +614,9 @@ FCL_REAL OBB::distance(const OBB& /*other*/, Vec3f* /*P*/, Vec3f* /*Q*/) const bool overlap(const Matrix3f& R0, const Vec3f& T0, const OBB& b1, const OBB& b2) { - Matrix3f R0b2; - R0b2 << R0.row(0).dot(b2.axis[0]), R0.row(0).dot(b2.axis[1]), R0.row(0).dot(b2.axis[2]), - R0.row(1).dot(b2.axis[0]), R0.row(1).dot(b2.axis[1]), R0.row(1).dot(b2.axis[2]), - R0.row(2).dot(b2.axis[0]), R0.row(2).dot(b2.axis[1]), R0.row(2).dot(b2.axis[2]); - - Matrix3f R; - R << R0b2.col(0).dot(b1.axis[0]), R0b2.col(1).dot(b1.axis[0]), R0b2.col(2).dot(b1.axis[0]), - R0b2.col(0).dot(b1.axis[1]), R0b2.col(1).dot(b1.axis[1]), R0b2.col(2).dot(b1.axis[1]), - R0b2.col(0).dot(b1.axis[2]), R0b2.col(1).dot(b1.axis[2]), R0b2.col(2).dot(b1.axis[2]); - - Vec3f Ttemp = R0 * b2.To + T0 - b1.To; - Vec3f T(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2])); + Vec3f Ttemp (R0 * b2.To + T0 - b1.To); + Vec3f T (b1.axes.transpose() * Ttemp); + Matrix3f R (b1.axes.transpose() * R0 * b2.axes); return !obbDisjoint(R, T, b1.extent, b2.extent); } @@ -650,18 +624,9 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const OBB& b1, const OBB& b2) bool overlap(const Matrix3f& R0, const Vec3f& T0, const OBB& b1, const OBB& b2, FCL_REAL& sqrDistLowerBound) { - Matrix3f R0b2; - R0b2 << R0.row(0).dot(b2.axis[0]), R0.row(0).dot(b2.axis[1]), R0.row(0).dot(b2.axis[2]), - R0.row(1).dot(b2.axis[0]), R0.row(1).dot(b2.axis[1]), R0.row(1).dot(b2.axis[2]), - R0.row(2).dot(b2.axis[0]), R0.row(2).dot(b2.axis[1]), R0.row(2).dot(b2.axis[2]); - - Matrix3f R; - R << R0b2.col(0).dot(b1.axis[0]), R0b2.col(1).dot(b1.axis[0]), R0b2.col(2).dot(b1.axis[0]), - R0b2.col(0).dot(b1.axis[1]), R0b2.col(1).dot(b1.axis[1]), R0b2.col(2).dot(b1.axis[1]), - R0b2.col(0).dot(b1.axis[2]), R0b2.col(1).dot(b1.axis[2]), R0b2.col(2).dot(b1.axis[2]); - - Vec3f Ttemp = R0 * b2.To + T0 - b1.To; - Vec3f T(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2])); + Vec3f Ttemp (R0 * b2.To + T0 - b1.To); + Vec3f T (b1.axes.transpose() * Ttemp); + Matrix3f R (b1.axes.transpose() * R0 * b2.axes); return !obbDisjointAndLowerBoundDistance (R, T, b1.extent, b2.extent, sqrDistLowerBound); diff --git a/src/BV/RSS.cpp b/src/BV/RSS.cpp index 435a1b2afe91da051ce8defdf079aeab7c3717f7..240171d71173218016007cfb3efaa7f114da107d 100644 --- a/src/BV/RSS.cpp +++ b/src/BV/RSS.cpp @@ -835,17 +835,11 @@ bool RSS::overlap(const RSS& other) const /// [R,T] = [R1,T1]'[R2,T2] = [R1',-R1'T][R2,T2] = [R1'R2, R1'(T2-T1)] /// First compute the rotation part, then translation part - /// First compute T2 - T1 - Vec3f t = other.Tr - Tr; - /// Then compute R1'(T2 - T1) - Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2])); + Vec3f T (axes.transpose() * (other.Tr - Tr)); /// Now compute R1'R2 - Matrix3f R; - R << axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), axis[0].dot(other.axis[2]), - axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), axis[1].dot(other.axis[2]), - axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), axis[2].dot(other.axis[2]); + Matrix3f R (axes.transpose() * other.axes); FCL_REAL dist = rectDistance(R, T, l, other.l); return (dist <= (r + other.r)); @@ -855,20 +849,12 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2) { // ROb2 = R0 . b2 // where b2 = [ b2.axis [0] | b2.axis [1] | b2.axis [2] ] - Matrix3f R0b2; - R0b2 << R0.row(0).dot(b2.axis[0]), R0.row(0).dot(b2.axis[1]), R0.row(0).dot(b2.axis[2]), - R0.row(1).dot(b2.axis[0]), R0.row(1).dot(b2.axis[1]), R0.row(1).dot(b2.axis[2]), - R0.row(2).dot(b2.axis[0]), R0.row(2).dot(b2.axis[1]), R0.row(2).dot(b2.axis[2]); // (1 0 0)^T R0b2^T axis [0] = (1 0 0)^T b2^T R0^T axis [0] // R = b2^T RO^T b1 - Matrix3f R; - R << R0b2.col(0).dot(b1.axis[0]), R0b2.col(1).dot(b1.axis[0]), R0b2.col(2).dot(b1.axis[0]), - R0b2.col(0).dot(b1.axis[1]), R0b2.col(1).dot(b1.axis[1]), R0b2.col(2).dot(b1.axis[1]), - R0b2.col(0).dot(b1.axis[2]), R0b2.col(1).dot(b1.axis[2]), R0b2.col(2).dot(b1.axis[2]); - - Vec3f Ttemp = R0 * b2.Tr + T0 - b1.Tr; - Vec3f T(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2])); + Vec3f Ttemp (R0 * b2.Tr + T0 - b1.Tr); + Vec3f T(b1.axes.transpose() * Ttemp); + Matrix3f R(b2.axes.transpose() * R0.transpose() * b1.axes); FCL_REAL dist = rectDistance(R, T, b1.l, b2.l); return (dist <= (b1.r + b2.r)); @@ -877,9 +863,10 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2) bool RSS::contain(const Vec3f& p) const { Vec3f local_p = p - Tr; - FCL_REAL proj0 = local_p.dot(axis[0]); - FCL_REAL proj1 = local_p.dot(axis[1]); - FCL_REAL proj2 = local_p.dot(axis[2]); + // FIXME: Vec3f proj (axes.transpose() * local_p); + FCL_REAL proj0 = local_p.dot(axes.col(0)); + FCL_REAL proj1 = local_p.dot(axes.col(1)); + FCL_REAL proj2 = local_p.dot(axes.col(2)); FCL_REAL abs_proj2 = fabs(proj2); Vec3f proj(proj0, proj1, proj2); @@ -912,9 +899,9 @@ bool RSS::contain(const Vec3f& p) const RSS& RSS::operator += (const Vec3f& p) { Vec3f local_p = p - Tr; - FCL_REAL proj0 = local_p.dot(axis[0]); - FCL_REAL proj1 = local_p.dot(axis[1]); - FCL_REAL proj2 = local_p.dot(axis[2]); + FCL_REAL proj0 = local_p.dot(axes.col(0)); + FCL_REAL proj1 = local_p.dot(axes.col(1)); + FCL_REAL proj2 = local_p.dot(axes.col(2)); FCL_REAL abs_proj2 = fabs(proj2); Vec3f proj(proj0, proj1, proj2); @@ -1049,37 +1036,37 @@ RSS RSS::operator + (const RSS& other) const RSS bv; Vec3f v[16]; - Vec3f d0_pos = other.axis[0] * (other.l[0] + other.r); - Vec3f d1_pos = other.axis[1] * (other.l[1] + other.r); - Vec3f d0_neg = other.axis[0] * (-other.r); - Vec3f d1_neg = other.axis[1] * (-other.r); - Vec3f d2_pos = other.axis[2] * other.r; - Vec3f d2_neg = other.axis[2] * (-other.r); - - v[0] = other.Tr + d0_pos + d1_pos + d2_pos; - v[1] = other.Tr + d0_pos + d1_pos + d2_neg; - v[2] = other.Tr + d0_pos + d1_neg + d2_pos; - v[3] = other.Tr + d0_pos + d1_neg + d2_neg; - v[4] = other.Tr + d0_neg + d1_pos + d2_pos; - v[5] = other.Tr + d0_neg + d1_pos + d2_neg; - v[6] = other.Tr + d0_neg + d1_neg + d2_pos; - v[7] = other.Tr + d0_neg + d1_neg + d2_neg; - - d0_pos = axis[0] * (l[0] + r); - d1_pos = axis[1] * (l[1] + r); - d0_neg = axis[0] * (-r); - d1_neg = axis[1] * (-r); - d2_pos = axis[2] * r; - d2_neg = axis[2] * (-r); - - v[8] = Tr + d0_pos + d1_pos + d2_pos; - v[9] = Tr + d0_pos + d1_pos + d2_neg; - v[10] = Tr + d0_pos + d1_neg + d2_pos; - v[11] = Tr + d0_pos + d1_neg + d2_neg; - v[12] = Tr + d0_neg + d1_pos + d2_pos; - v[13] = Tr + d0_neg + d1_pos + d2_neg; - v[14] = Tr + d0_neg + d1_neg + d2_pos; - v[15] = Tr + d0_neg + d1_neg + d2_neg; + Vec3f d0_pos (other.axes.col(0) * (other.l[0] + other.r)); + Vec3f d1_pos (other.axes.col(1) * (other.l[1] + other.r)); + Vec3f d0_neg (other.axes.col(0) * (-other.r)); + Vec3f d1_neg (other.axes.col(1) * (-other.r)); + Vec3f d2_pos (other.axes.col(2) * other.r); + Vec3f d2_neg (other.axes.col(2) * (-other.r)); + + v[0].noalias() = other.Tr + d0_pos + d1_pos + d2_pos; + v[1].noalias() = other.Tr + d0_pos + d1_pos + d2_neg; + v[2].noalias() = other.Tr + d0_pos + d1_neg + d2_pos; + v[3].noalias() = other.Tr + d0_pos + d1_neg + d2_neg; + v[4].noalias() = other.Tr + d0_neg + d1_pos + d2_pos; + v[5].noalias() = other.Tr + d0_neg + d1_pos + d2_neg; + v[6].noalias() = other.Tr + d0_neg + d1_neg + d2_pos; + v[7].noalias() = other.Tr + d0_neg + d1_neg + d2_neg; + + d0_pos.noalias() = axes.col(0) * (l[0] + r); + d1_pos.noalias() = axes.col(1) * (l[1] + r); + d0_neg.noalias() = axes.col(0) * (-r); + d1_neg.noalias() = axes.col(1) * (-r); + d2_pos.noalias() = axes.col(2) * r; + d2_neg.noalias() = axes.col(2) * (-r); + + v[ 8].noalias() = Tr + d0_pos + d1_pos + d2_pos; + v[ 9].noalias() = Tr + d0_pos + d1_pos + d2_neg; + v[10].noalias() = Tr + d0_pos + d1_neg + d2_pos; + v[11].noalias() = Tr + d0_pos + d1_neg + d2_neg; + v[12].noalias() = Tr + d0_neg + d1_pos + d2_pos; + v[13].noalias() = Tr + d0_neg + d1_pos + d2_neg; + v[14].noalias() = Tr + d0_neg + d1_neg + d2_pos; + v[15].noalias() = Tr + d0_neg + d1_neg + d2_neg; Matrix3f M; // row first matrix @@ -1097,14 +1084,14 @@ RSS RSS::operator + (const RSS& other) const else { mid = 2; } // column first matrix, as the axis in RSS - bv.axis[0] << E[0][max], E[1][max], E[2][max]; - bv.axis[1] << E[0][mid], E[1][mid], E[2][mid]; - bv.axis[2] << E[1][max]*E[2][mid] - E[1][mid]*E[2][max], - E[0][mid]*E[2][max] - E[0][max]*E[2][mid], - E[0][max]*E[1][mid] - E[0][mid]*E[1][max]; + bv.axes.col(0) << E[0][max], E[1][max], E[2][max]; + bv.axes.col(1) << E[0][mid], E[1][mid], E[2][mid]; + bv.axes.col(2) << E[1][max]*E[2][mid] - E[1][mid]*E[2][max], + E[0][mid]*E[2][max] - E[0][max]*E[2][mid], + E[0][max]*E[1][mid] - E[0][mid]*E[1][max]; // set rss origin, rectangle size and radius - getRadiusAndOriginAndRectangleSize(v, NULL, NULL, NULL, 16, bv.axis, bv.Tr, bv.l, bv.r); + getRadiusAndOriginAndRectangleSize(v, NULL, NULL, NULL, 16, bv.axes, bv.Tr, bv.l, bv.r); return bv; } @@ -1114,12 +1101,8 @@ FCL_REAL RSS::distance(const RSS& other, Vec3f* P, Vec3f* Q) const // compute what transform [R,T] that takes us from cs1 to cs2. // [R,T] = [R1,T1]'[R2,T2] = [R1',-R1'T][R2,T2] = [R1'R2, R1'(T2-T1)] // First compute the rotation part, then translation part - Vec3f t = other.Tr - Tr; // T2 - T1 - Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2])); // R1'(T2-T1) - Matrix3f R; - R << axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), axis[0].dot(other.axis[2]), - axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), axis[1].dot(other.axis[2]), - axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), axis[2].dot(other.axis[2]); + Matrix3f R (axes.transpose() * other.axes); + Vec3f T (axes.transpose() * (other.Tr - Tr)); FCL_REAL dist = rectDistance(R, T, l, other.l, P, Q); dist -= (r + other.r); @@ -1128,19 +1111,10 @@ FCL_REAL RSS::distance(const RSS& other, Vec3f* P, Vec3f* Q) const FCL_REAL distance(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2, Vec3f* P, Vec3f* Q) { - Matrix3f R0b2; - R0b2 << R0.row(0).dot(b2.axis[0]), R0.row(0).dot(b2.axis[1]), R0.row(0).dot(b2.axis[2]), - R0.row(1).dot(b2.axis[0]), R0.row(1).dot(b2.axis[1]), R0.row(1).dot(b2.axis[2]), - R0.row(2).dot(b2.axis[0]), R0.row(2).dot(b2.axis[1]), R0.row(2).dot(b2.axis[2]); - - Matrix3f R; - R << R0b2.col(0).dot(b1.axis[0]), R0b2.col(1).dot(b1.axis[0]), R0b2.col(2).dot(b1.axis[0]), - R0b2.col(0).dot(b1.axis[1]), R0b2.col(1).dot(b1.axis[1]), R0b2.col(2).dot(b1.axis[1]), - R0b2.col(0).dot(b1.axis[2]), R0b2.col(1).dot(b1.axis[2]), R0b2.col(2).dot(b1.axis[2]); - - Vec3f Ttemp = R0 * b2.Tr + T0 - b1.Tr; + Matrix3f R (b1.axes.transpose() * R0 * b2.axes); + Vec3f Ttemp (R0 * b2.Tr + T0 - b1.Tr); - Vec3f T(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2])); + Vec3f T(b1.axes.transpose() * Ttemp); FCL_REAL dist = rectDistance(R, T, b1.l, b2.l, P, Q); dist -= (b1.r + b2.r); diff --git a/src/BV/kIOS.cpp b/src/BV/kIOS.cpp index acc8150dedc78024144d6659c42833b713a4bb06..a482c4d0b150c7dc080bb49a1e25a38416f56fc8 100644 --- a/src/BV/kIOS.cpp +++ b/src/BV/kIOS.cpp @@ -183,9 +183,7 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2 b2_temp.obb.To = R0 * b2_temp.obb.To + T0; - b2_temp.obb.axis[0] = R0 * b2_temp.obb.axis[0]; - b2_temp.obb.axis[1] = R0 * b2_temp.obb.axis[1]; - b2_temp.obb.axis[2] = R0 * b2_temp.obb.axis[2]; + b2_temp.obb.axes = R0 * b2_temp.obb.axes; return b1.overlap(b2_temp); } diff --git a/src/BVH/BVH_model.cpp b/src/BVH/BVH_model.cpp index b283bfc4d9469f41ac6865f31f1f62ae349f02e8..ae4e903dac6352801adb3c10429a87d133b72a24 100644 --- a/src/BVH/BVH_model.cpp +++ b/src/BVH/BVH_model.cpp @@ -879,69 +879,60 @@ void BVHModel<BV>::computeLocalAABB() template<> -void BVHModel<OBB>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c) +void BVHModel<OBB>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c) { OBB& obb = bvs[bv_id].bv; if(!bvs[bv_id].isLeaf()) { - makeParentRelativeRecurse(bvs[bv_id].first_child, obb.axis, obb.To); + makeParentRelativeRecurse(bvs[bv_id].first_child, obb.axes, obb.To); - makeParentRelativeRecurse(bvs[bv_id].first_child + 1, obb.axis, obb.To); + makeParentRelativeRecurse(bvs[bv_id].first_child + 1, obb.axes, obb.To); } // make self parent relative - obb.axis[0] = Vec3f(parent_axis[0].dot(obb.axis[0]), parent_axis[1].dot(obb.axis[0]), parent_axis[2].dot(obb.axis[0])); - obb.axis[1] = Vec3f(parent_axis[0].dot(obb.axis[1]), parent_axis[1].dot(obb.axis[1]), parent_axis[2].dot(obb.axis[1])); - obb.axis[2] = Vec3f(parent_axis[0].dot(obb.axis[2]), parent_axis[1].dot(obb.axis[2]), parent_axis[2].dot(obb.axis[2])); + obb.axes = parent_axes.transpose() * obb.axes; - Vec3f t = obb.To - parent_c; - obb.To = Vec3f(parent_axis[0].dot(t), parent_axis[1].dot(t), parent_axis[2].dot(t)); + Vec3f t (obb.To - parent_c); + obb.To.noalias() = parent_axes.transpose() * t; } template<> -void BVHModel<RSS>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c) +void BVHModel<RSS>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c) { RSS& rss = bvs[bv_id].bv; if(!bvs[bv_id].isLeaf()) { - makeParentRelativeRecurse(bvs[bv_id].first_child, rss.axis, rss.Tr); + makeParentRelativeRecurse(bvs[bv_id].first_child, rss.axes, rss.Tr); - makeParentRelativeRecurse(bvs[bv_id].first_child + 1, rss.axis, rss.Tr); + makeParentRelativeRecurse(bvs[bv_id].first_child + 1, rss.axes, rss.Tr); } // make self parent relative - rss.axis[0] = Vec3f(parent_axis[0].dot(rss.axis[0]), parent_axis[1].dot(rss.axis[0]), parent_axis[2].dot(rss.axis[0])); - rss.axis[1] = Vec3f(parent_axis[0].dot(rss.axis[1]), parent_axis[1].dot(rss.axis[1]), parent_axis[2].dot(rss.axis[1])); - rss.axis[2] = Vec3f(parent_axis[0].dot(rss.axis[2]), parent_axis[1].dot(rss.axis[2]), parent_axis[2].dot(rss.axis[2])); + rss.axes = parent_axes.transpose() * rss.axes; - Vec3f t = rss.Tr - parent_c; - rss.Tr = Vec3f(parent_axis[0].dot(t), parent_axis[1].dot(t), parent_axis[2].dot(t)); + Vec3f t (rss.Tr - parent_c); + rss.Tr.noalias() = parent_axes.transpose() * t; } template<> -void BVHModel<OBBRSS>::makeParentRelativeRecurse(int bv_id, Vec3f parent_axis[], const Vec3f& parent_c) +void BVHModel<OBBRSS>::makeParentRelativeRecurse(int bv_id, Matrix3f& parent_axes, const Vec3f& parent_c) { OBB& obb = bvs[bv_id].bv.obb; RSS& rss = bvs[bv_id].bv.rss; if(!bvs[bv_id].isLeaf()) { - makeParentRelativeRecurse(bvs[bv_id].first_child, obb.axis, obb.To); + makeParentRelativeRecurse(bvs[bv_id].first_child, obb.axes, obb.To); - makeParentRelativeRecurse(bvs[bv_id].first_child + 1, obb.axis, obb.To); + makeParentRelativeRecurse(bvs[bv_id].first_child + 1, obb.axes, obb.To); } // make self parent relative - obb.axis[0] = Vec3f(parent_axis[0].dot(obb.axis[0]), parent_axis[1].dot(obb.axis[0]), parent_axis[2].dot(obb.axis[0])); - obb.axis[1] = Vec3f(parent_axis[0].dot(obb.axis[1]), parent_axis[1].dot(obb.axis[1]), parent_axis[2].dot(obb.axis[1])); - obb.axis[2] = Vec3f(parent_axis[0].dot(obb.axis[2]), parent_axis[1].dot(obb.axis[2]), parent_axis[2].dot(obb.axis[2])); + rss.axes.noalias() = parent_axes.transpose() * obb.axes; + obb.axes.noalias() = rss.axes; - rss.axis[0] = obb.axis[0]; - rss.axis[1] = obb.axis[1]; - rss.axis[2] = obb.axis[2]; - - Vec3f t = obb.To - parent_c; - obb.To = Vec3f(parent_axis[0].dot(t), parent_axis[1].dot(t), parent_axis[2].dot(t)); - rss.Tr = obb.To; + Vec3f t (obb.To - parent_c); + obb.To.noalias() = parent_axes.transpose() *t; + rss.Tr.noalias() = obb.To; } diff --git a/src/BVH/BVH_utility.cpp b/src/BVH/BVH_utility.cpp index e06b1a6e68f97debcdb1b22698554ea96afa6908..7316b412e2390557bf2b00b635d1029c5be0e829 100644 --- a/src/BVH/BVH_utility.cpp +++ b/src/BVH/BVH_utility.cpp @@ -192,7 +192,7 @@ void getCovariance(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, i /** \brief Compute the RSS bounding volume parameters: radius, rectangle size and the origin. * The bounding volume axes are known. */ -void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Vec3f axis[3], Vec3f& origin, FCL_REAL l[2], FCL_REAL& r) +void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, const Matrix3f& axes, Vec3f& origin, FCL_REAL l[2], FCL_REAL& r) { bool indirect_index = true; if(!indices) indirect_index = false; @@ -215,9 +215,9 @@ void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, uns int point_id = t[j]; const Vec3f& p = ps[point_id]; Vec3f v(p[0], p[1], p[2]); - P[P_id][0] = axis[0].dot(v); - P[P_id][1] = axis[1].dot(v); - P[P_id][2] = axis[2].dot(v); + P[P_id][0] = axes.col(0).dot(v); + P[P_id][1] = axes.col(1).dot(v); + P[P_id][2] = axes.col(2).dot(v); P_id++; } @@ -227,10 +227,11 @@ void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, uns { int point_id = t[j]; const Vec3f& p = ps2[point_id]; + // FIXME Is this right ????? Vec3f v(p[0], p[1], p[2]); - P[P_id][0] = axis[0].dot(v); - P[P_id][1] = axis[0].dot(v); - P[P_id][2] = axis[1].dot(v); + P[P_id][0] = axes.col(0).dot(v); + P[P_id][1] = axes.col(0).dot(v); + P[P_id][2] = axes.col(1).dot(v); P_id++; } } @@ -244,17 +245,17 @@ void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, uns const Vec3f& p = ps[index]; Vec3f v(p[0], p[1], p[2]); - P[P_id][0] = axis[0].dot(v); - P[P_id][1] = axis[1].dot(v); - P[P_id][2] = axis[2].dot(v); + P[P_id][0] = axes.col(0).dot(v); + P[P_id][1] = axes.col(1).dot(v); + P[P_id][2] = axes.col(2).dot(v); P_id++; if(ps2) { const Vec3f& v = ps2[index]; - P[P_id][0] = axis[0].dot(v); - P[P_id][1] = axis[1].dot(v); - P[P_id][2] = axis[2].dot(v); + P[P_id][0] = axes.col(0).dot(v); + P[P_id][1] = axes.col(1).dot(v); + P[P_id][2] = axes.col(2).dot(v); P_id++; } } @@ -457,7 +458,7 @@ void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, uns } } - origin = axis[0] * minx + axis[1] * miny + axis[2] * cz; + origin.noalias() = axes * Vec3f(minx, miny, cz); l[0] = maxx - minx; if(l[0] < 0) l[0] = 0; @@ -472,7 +473,7 @@ void getRadiusAndOriginAndRectangleSize(Vec3f* ps, Vec3f* ps2, Triangle* ts, uns /** \brief Compute the bounding volume extent and center for a set or subset of points. * The bounding volume axes are known. */ -static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned int* indices, int n, Vec3f axis[3], Vec3f& center, Vec3f& extent) +static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned int* indices, int n, Matrix3f& axes, Vec3f& center, Vec3f& extent) { bool indirect_index = true; if(!indices) indirect_index = false; @@ -488,10 +489,7 @@ static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned const Vec3f& p = ps[index]; Vec3f v(p[0], p[1], p[2]); - FCL_REAL proj[3]; - proj[0] = axis[0].dot(v); - proj[1] = axis[1].dot(v); - proj[2] = axis[2].dot(v); + Vec3f proj (axes.transpose() * v); for(int j = 0; j < 3; ++j) { @@ -502,9 +500,7 @@ static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned if(ps2) { const Vec3f& v = ps2[index]; - proj[0] = axis[0].dot(v); - proj[1] = axis[1].dot(v); - proj[2] = axis[2].dot(v); + proj.noalias() = axes.transpose() * v; for(int j = 0; j < 3; ++j) { @@ -518,7 +514,7 @@ static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned (max_coord[1] + min_coord[1]) / 2, (max_coord[2] + min_coord[2]) / 2); - center = axis[0] * o[0] + axis[1] * o[1] + axis[2] * o[2]; + center.noalias() = axes * o; extent << (max_coord[0] - min_coord[0]) / 2, (max_coord[1] - min_coord[1]) / 2, @@ -530,7 +526,7 @@ static inline void getExtentAndCenter_pointcloud(Vec3f* ps, Vec3f* ps2, unsigned /** \brief Compute the bounding volume extent and center for a set or subset of points. * The bounding volume axes are known. */ -static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Vec3f axis[3], Vec3f& center, Vec3f& extent) +static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Matrix3f& axes, Vec3f& center, Vec3f& extent) { bool indirect_index = true; if(!indices) indirect_index = false; @@ -550,10 +546,7 @@ static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, int point_id = t[j]; const Vec3f& p = ps[point_id]; Vec3f v(p[0], p[1], p[2]); - FCL_REAL proj[3]; - proj[0] = axis[0].dot(v); - proj[1] = axis[1].dot(v); - proj[2] = axis[2].dot(v); + Vec3f proj (axes.transpose() * v); for(int k = 0; k < 3; ++k) { @@ -569,10 +562,7 @@ static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, int point_id = t[j]; const Vec3f& p = ps2[point_id]; Vec3f v(p[0], p[1], p[2]); - FCL_REAL proj[3]; - proj[0] = axis[0].dot(v); - proj[1] = axis[1].dot(v); - proj[2] = axis[2].dot(v); + Vec3f proj (axes.transpose() * v); for(int k = 0; k < 3; ++k) { @@ -587,7 +577,7 @@ static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, (max_coord[1] + min_coord[1]) / 2, (max_coord[2] + min_coord[2]) / 2); - center = axis[0] * o[0] + axis[1] * o[1] + axis[2] * o[2]; + center.noalias() = axes * o; extent << (max_coord[0] - min_coord[0]) / 2, (max_coord[1] - min_coord[1]) / 2, @@ -595,12 +585,12 @@ static inline void getExtentAndCenter_mesh(Vec3f* ps, Vec3f* ps2, Triangle* ts, } -void getExtentAndCenter(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Vec3f axis[3], Vec3f& center, Vec3f& extent) +void getExtentAndCenter(Vec3f* ps, Vec3f* ps2, Triangle* ts, unsigned int* indices, int n, Matrix3f& axes, Vec3f& center, Vec3f& extent) { if(ts) - getExtentAndCenter_mesh(ps, ps2, ts, indices, n, axis, center, extent); + getExtentAndCenter_mesh(ps, ps2, ts, indices, n, axes, center, extent); else - getExtentAndCenter_pointcloud(ps, ps2, indices, n, axis, center, extent); + getExtentAndCenter_pointcloud(ps, ps2, indices, n, axes, center, extent); } void circumCircleComputation(const Vec3f& a, const Vec3f& b, const Vec3f& c, Vec3f& center, FCL_REAL& radius) diff --git a/src/BVH/BV_fitter.cpp b/src/BVH/BV_fitter.cpp index 548bc4f4b0b4053238038a6736b46b5bec9cc0e8..a303d8a5ba9a93aba8ede5ebda50065032f9d57b 100644 --- a/src/BVH/BV_fitter.cpp +++ b/src/BVH/BV_fitter.cpp @@ -49,7 +49,7 @@ static const double invCosA = 2.0 / sqrt(3.0); static const double sinA = 0.5; static const double cosA = sqrt(3.0) / 2.0; -static inline void axisFromEigen(Vec3f eigenV[3], Matrix3f::Scalar eigenS[3], Vec3f axis[3]) +static inline void axisFromEigen(Vec3f eigenV[3], Matrix3f::Scalar eigenS[3], Matrix3f& axes) { int min, mid, max; if(eigenS[0] > eigenS[1]) { max = 0; min = 1; } @@ -58,11 +58,11 @@ static inline void axisFromEigen(Vec3f eigenV[3], Matrix3f::Scalar eigenS[3], Ve else if(eigenS[2] > eigenS[max]) { mid = max; max = 2; } else { mid = 2; } - axis[0] << eigenV[0][max], eigenV[1][max], eigenV[2][max]; - axis[1] << eigenV[0][mid], eigenV[1][mid], eigenV[2][mid]; - axis[2] << eigenV[1][max]*eigenV[2][mid] - eigenV[1][mid]*eigenV[2][max], - eigenV[0][mid]*eigenV[2][max] - eigenV[0][max]*eigenV[2][mid], - eigenV[0][max]*eigenV[1][mid] - eigenV[0][mid]*eigenV[1][max]; + axes.col(0) << eigenV[0][max], eigenV[1][max], eigenV[2][max]; + axes.col(1) << eigenV[0][mid], eigenV[1][mid], eigenV[2][mid]; + axes.col(2) << eigenV[1][max]*eigenV[2][mid] - eigenV[1][mid]*eigenV[2][max], + eigenV[0][mid]*eigenV[2][max] - eigenV[0][max]*eigenV[2][mid], + eigenV[0][max]*eigenV[1][mid] - eigenV[0][mid]*eigenV[1][max]; } namespace OBB_fit_functions @@ -70,10 +70,8 @@ namespace OBB_fit_functions void fit1(Vec3f* ps, OBB& bv) { - bv.To = ps[0]; - bv.axis[0] << 1, 0, 0; - bv.axis[1] << 0, 1, 0; - bv.axis[2] << 0, 0, 1; + bv.To.noalias() = ps[0]; + bv.axes.setIdentity(); bv.extent.setZero(); } @@ -85,13 +83,11 @@ void fit2(Vec3f* ps, OBB& bv) FCL_REAL len_p1p2 = p1p2.norm(); p1p2.normalize(); - bv.axis[0] = p1p2; - generateCoordinateSystem(bv.axis[0], bv.axis[1], bv.axis[2]); + bv.axes.col(0).noalias() = p1p2; + generateCoordinateSystem(bv.axes.col(0), bv.axes.col(1), bv.axes.col(2)); bv.extent << len_p1p2 * 0.5, 0, 0; - bv.To << 0.5 * (p1[0] + p2[0]), - 0.5 * (p1[1] + p2[1]), - 0.5 * (p1[2] + p2[2]); + bv.To.noalias() = (p1 + p2) / 2; } void fit3(Vec3f* ps, OBB& bv) @@ -112,17 +108,11 @@ void fit3(Vec3f* ps, OBB& bv) if(len[1] > len[0]) imax = 1; if(len[2] > len[imax]) imax = 2; - Vec3f& u = bv.axis[0]; - Vec3f& v = bv.axis[1]; - Vec3f& w = bv.axis[2]; + bv.axes.col(2).noalias() = e[0].cross(e[1]).normalized(); + bv.axes.col(0).noalias() = e[imax].normalized(); + bv.axes.col(1).noalias() = bv.axes.col(2).cross(bv.axes.col(0)); - w = e[0].cross(e[1]); - w.normalize(); - u = e[imax]; - u.normalize(); - v = w.cross(u); - - getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.axis, bv.To, bv.extent); + getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.axes, bv.To, bv.extent); } void fit6(Vec3f* ps, OBB& bv) @@ -142,10 +132,10 @@ void fitn(Vec3f* ps, int n, OBB& bv) getCovariance(ps, NULL, NULL, NULL, n, M); eigen(M, s, E); - axisFromEigen(E, s, bv.axis); + axisFromEigen(E, s, bv.axes); // set obb centers and extensions - getExtentAndCenter(ps, NULL, NULL, NULL, n, bv.axis, bv.To, bv.extent); + getExtentAndCenter(ps, NULL, NULL, NULL, n, bv.axes, bv.To, bv.extent); } } @@ -155,10 +145,8 @@ namespace RSS_fit_functions { void fit1(Vec3f* ps, RSS& bv) { - bv.Tr = ps[0]; - bv.axis[0] << 1, 0, 0; - bv.axis[1] << 0, 1, 0; - bv.axis[2] << 0, 0, 1; + bv.Tr.noalias() = ps[0]; + bv.axes.setIdentity(); bv.l[0] = 0; bv.l[1] = 0; bv.r = 0; @@ -172,8 +160,8 @@ void fit2(Vec3f* ps, RSS& bv) FCL_REAL len_p1p2 = p1p2.norm(); p1p2.normalize(); - bv.axis[0] = p1p2; - generateCoordinateSystem(bv.axis[0], bv.axis[1], bv.axis[2]); + bv.axes.col(0) = p1p2; + generateCoordinateSystem(bv.axes.col(0), bv.axes.col(1), bv.axes.col(2)); bv.l[0] = len_p1p2; bv.l[1] = 0; @@ -199,17 +187,11 @@ void fit3(Vec3f* ps, RSS& bv) if(len[1] > len[0]) imax = 1; if(len[2] > len[imax]) imax = 2; - Vec3f& u = bv.axis[0]; - Vec3f& v = bv.axis[1]; - Vec3f& w = bv.axis[2]; - - w = e[0].cross(e[1]); - w.normalize(); - u = e[imax]; - u.normalize(); - v = w.cross(u); + bv.axes.col(2).noalias() = e[0].cross(e[1]).normalized(); + bv.axes.col(0).noalias() = e[imax].normalized(); + bv.axes.col(1).noalias() = bv.axes.col(2).cross(bv.axes.col(0)); - getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, 3, bv.axis, bv.Tr, bv.l, bv.r); + getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, 3, bv.axes, bv.Tr, bv.l, bv.r); } void fit6(Vec3f* ps, RSS& bv) @@ -228,10 +210,10 @@ void fitn(Vec3f* ps, int n, RSS& bv) getCovariance(ps, NULL, NULL, NULL, n, M); eigen(M, s, E); - axisFromEigen(E, s, bv.axis); + axisFromEigen(E, s, bv.axes); // set rss origin, rectangle size and radius - getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, n, bv.axis, bv.Tr, bv.l, bv.r); + getRadiusAndOriginAndRectangleSize(ps, NULL, NULL, NULL, n, bv.axes, bv.Tr, bv.l, bv.r); } } @@ -242,14 +224,12 @@ namespace kIOS_fit_functions void fit1(Vec3f* ps, kIOS& bv) { bv.num_spheres = 1; - bv.spheres[0].o = ps[0]; + bv.spheres[0].o.noalias() = ps[0]; bv.spheres[0].r = 0; - bv.obb.axis[0] << 1, 0, 0; - bv.obb.axis[1] << 0, 1, 0; - bv.obb.axis[2] << 0, 0, 1; + bv.obb.axes.setIdentity(); bv.obb.extent.setZero(); - bv.obb.To = ps[0]; + bv.obb.To.noalias() = ps[0]; } void fit2(Vec3f* ps, kIOS& bv) @@ -262,9 +242,9 @@ void fit2(Vec3f* ps, kIOS& bv) FCL_REAL len_p1p2 = p1p2.norm(); p1p2.normalize(); - Vec3f* axis = bv.obb.axis; - axis[0] = p1p2; - generateCoordinateSystem(axis[0], axis[1], axis[2]); + Matrix3f& axes = bv.obb.axes; + axes.col(0).noalias() = p1p2; + generateCoordinateSystem(axes.col(0), axes.col(1), axes.col(2)); FCL_REAL r0 = len_p1p2 * 0.5; bv.obb.extent << r0, 0, 0; @@ -277,13 +257,13 @@ void fit2(Vec3f* ps, kIOS& bv) FCL_REAL r1cosA = r1 * cosA; bv.spheres[1].r = r1; bv.spheres[2].r = r1; - Vec3f delta = axis[1] * r1cosA; + Vec3f delta = axes.col(1) * r1cosA; bv.spheres[1].o = bv.spheres[0].o - delta; bv.spheres[2].o = bv.spheres[0].o + delta; bv.spheres[3].r = r1; bv.spheres[4].r = r1; - delta = axis[2] * r1cosA; + delta = axes.col(2) * r1cosA; bv.spheres[3].o = bv.spheres[0].o - delta; bv.spheres[4].o = bv.spheres[0].o + delta; } @@ -308,17 +288,11 @@ void fit3(Vec3f* ps, kIOS& bv) if(len[1] > len[0]) imax = 1; if(len[2] > len[imax]) imax = 2; - Vec3f& u = bv.obb.axis[0]; - Vec3f& v = bv.obb.axis[1]; - Vec3f& w = bv.obb.axis[2]; - - w = e[0].cross(e[1]); - w.normalize(); - u = e[imax]; - u.normalize(); - v = w.cross(u); + bv.obb.axes.col(2).noalias() = e[0].cross(e[1]).normalized(); + bv.obb.axes.col(0).noalias() = e[imax].normalized(); + bv.obb.axes.col(1).noalias() = bv.obb.axes.col(2).cross(bv.obb.axes.col(0)); - getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.obb.axis, bv.obb.To, bv.obb.extent); + getExtentAndCenter(ps, NULL, NULL, NULL, 3, bv.obb.axes, bv.obb.To, bv.obb.extent); // compute radius and center FCL_REAL r0; @@ -329,7 +303,7 @@ void fit3(Vec3f* ps, kIOS& bv) bv.spheres[0].r = r0; FCL_REAL r1 = r0 * invSinA; - Vec3f delta = bv.obb.axis[2] * (r1 * cosA); + Vec3f delta = bv.obb.axes.col(2) * (r1 * cosA); bv.spheres[1].r = r1; bv.spheres[1].o = center - delta; @@ -346,10 +320,10 @@ void fitn(Vec3f* ps, int n, kIOS& bv) getCovariance(ps, NULL, NULL, NULL, n, M); eigen(M, s, E); - Vec3f* axis = bv.obb.axis; - axisFromEigen(E, s, axis); + Matrix3f& axes = bv.obb.axes; + axisFromEigen(E, s, axes); - getExtentAndCenter(ps, NULL, NULL, NULL, n, axis, bv.obb.To, bv.obb.extent); + getExtentAndCenter(ps, NULL, NULL, NULL, n, axes, bv.obb.To, bv.obb.extent); // get center and extension const Vec3f& center = bv.obb.To; @@ -371,15 +345,15 @@ void fitn(Vec3f* ps, int n, kIOS& bv) if(bv.num_spheres >= 3) { FCL_REAL r10 = sqrt(r0 * r0 - extent[2] * extent[2]) * invSinA; - Vec3f delta = axis[2] * (r10 * cosA - extent[2]); + Vec3f delta = axes.col(2) * (r10 * cosA - extent[2]); bv.spheres[1].o = center - delta; bv.spheres[2].o = center + delta; FCL_REAL r11 = 0, r12 = 0; r11 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[1].o); r12 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[2].o); - bv.spheres[1].o += axis[2] * (-r10 + r11); - bv.spheres[2].o += axis[2] * (r10 - r12); + bv.spheres[1].o += axes.col(2) * (-r10 + r11); + bv.spheres[2].o += axes.col(2) * (r10 - r12); bv.spheres[1].r = r10; bv.spheres[2].r = r10; @@ -388,7 +362,7 @@ void fitn(Vec3f* ps, int n, kIOS& bv) if(bv.num_spheres >= 5) { FCL_REAL r10 = bv.spheres[1].r; - Vec3f delta = axis[1] * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]); + Vec3f delta = axes.col(1) * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]); bv.spheres[3].o = bv.spheres[0].o - delta; bv.spheres[4].o = bv.spheres[0].o + delta; @@ -396,8 +370,8 @@ void fitn(Vec3f* ps, int n, kIOS& bv) r21 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[3].o); r22 = maximumDistance(ps, NULL, NULL, NULL, n, bv.spheres[4].o); - bv.spheres[3].o += axis[1] * (-r10 + r21); - bv.spheres[4].o += axis[1] * (r10 - r22); + bv.spheres[3].o += axes.col(1) * (-r10 + r21); + bv.spheres[4].o += axes.col(1) * (r10 - r22); bv.spheres[3].r = r10; bv.spheres[4].r = r10; @@ -528,10 +502,10 @@ OBB BVFitter<OBB>::fit(unsigned int* primitive_indices, int num_primitives) getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M); eigen(M, s, E); - axisFromEigen(E, s, bv.axis); + axisFromEigen(E, s, bv.axes); // set obb centers and extensions - getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axis, bv.To, bv.extent); + getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axes, bv.To, bv.extent); return bv; } @@ -546,17 +520,15 @@ OBBRSS BVFitter<OBBRSS>::fit(unsigned int* primitive_indices, int num_primitives getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M); eigen(M, s, E); - axisFromEigen(E, s, bv.obb.axis); - bv.rss.axis[0] = bv.obb.axis[0]; - bv.rss.axis[1] = bv.obb.axis[1]; - bv.rss.axis[2] = bv.obb.axis[2]; + axisFromEigen(E, s, bv.obb.axes); + bv.rss.axes.noalias() = bv.obb.axes; - getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.obb.axis, bv.obb.To, bv.obb.extent); + getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.obb.axes, bv.obb.To, bv.obb.extent); Vec3f origin; FCL_REAL l[2]; FCL_REAL r; - getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.rss.axis, origin, l, r); + getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.rss.axes, origin, l, r); bv.rss.Tr = origin; bv.rss.l[0] = l[0]; @@ -575,14 +547,14 @@ RSS BVFitter<RSS>::fit(unsigned int* primitive_indices, int num_primitives) Matrix3f::Scalar s[3]; // three eigen values getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M); eigen(M, s, E); - axisFromEigen(E, s, bv.axis); + axisFromEigen(E, s, bv.axes); // set rss origin, rectangle size and radius Vec3f origin; FCL_REAL l[2]; FCL_REAL r; - getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axis, origin, l, r); + getRadiusAndOriginAndRectangleSize(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.axes, origin, l, r); bv.Tr = origin; bv.l[0] = l[0]; @@ -605,11 +577,11 @@ kIOS BVFitter<kIOS>::fit(unsigned int* primitive_indices, int num_primitives) getCovariance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, M); eigen(M, s, E); - Vec3f* axis = bv.obb.axis; - axisFromEigen(E, s, axis); + Matrix3f& axes = bv.obb.axes; + axisFromEigen(E, s, axes); // get centers and extensions - getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, axis, bv.obb.To, bv.obb.extent); + getExtentAndCenter(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, axes, bv.obb.To, bv.obb.extent); const Vec3f& center = bv.obb.To; const Vec3f& extent = bv.obb.extent; @@ -629,15 +601,15 @@ kIOS BVFitter<kIOS>::fit(unsigned int* primitive_indices, int num_primitives) if(bv.num_spheres >= 3) { FCL_REAL r10 = sqrt(r0 * r0 - extent[2] * extent[2]) * invSinA; - Vec3f delta = axis[2] * (r10 * cosA - extent[2]); + Vec3f delta = axes.col(2) * (r10 * cosA - extent[2]); bv.spheres[1].o = center - delta; bv.spheres[2].o = center + delta; FCL_REAL r11 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[1].o); FCL_REAL r12 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[2].o); - bv.spheres[1].o += axis[2] * (-r10 + r11); - bv.spheres[2].o += axis[2] * (r10 - r12); + bv.spheres[1].o += axes.col(2) * (-r10 + r11); + bv.spheres[2].o += axes.col(2) * (r10 - r12); bv.spheres[1].r = r10; bv.spheres[2].r = r10; @@ -646,7 +618,7 @@ kIOS BVFitter<kIOS>::fit(unsigned int* primitive_indices, int num_primitives) if(bv.num_spheres >= 5) { FCL_REAL r10 = bv.spheres[1].r; - Vec3f delta = axis[1] * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]); + Vec3f delta = axes.col(1) * (sqrt(r10 * r10 - extent[0] * extent[0] - extent[2] * extent[2]) - extent[1]); bv.spheres[3].o = bv.spheres[0].o - delta; bv.spheres[4].o = bv.spheres[0].o + delta; @@ -654,8 +626,8 @@ kIOS BVFitter<kIOS>::fit(unsigned int* primitive_indices, int num_primitives) r21 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[3].o); r22 = maximumDistance(vertices, prev_vertices, tri_indices, primitive_indices, num_primitives, bv.spheres[4].o); - bv.spheres[3].o += axis[1] * (-r10 + r21); - bv.spheres[4].o += axis[1] * (r10 - r22); + bv.spheres[3].o += axes.col(1) * (-r10 + r21); + bv.spheres[4].o += axes.col(1) * (r10 - r22); bv.spheres[3].r = r10; bv.spheres[4].r = r10; diff --git a/src/BVH/BV_splitter.cpp b/src/BVH/BV_splitter.cpp index a7f53f48d9c1ba567aa9575134d633578e722b37..1cce58f1ac10896ffa10858ba8e79568db920106 100644 --- a/src/BVH/BV_splitter.cpp +++ b/src/BVH/BV_splitter.cpp @@ -44,7 +44,7 @@ namespace fcl template<typename BV> void computeSplitVector(const BV& bv, Vec3f& split_vector) { - split_vector = bv.axis[0]; + split_vector.noalias() = bv.axes.col(0); } template<> @@ -78,13 +78,13 @@ void computeSplitVector<kIOS>(const kIOS& bv, Vec3f& split_vector) ; } */ - split_vector = bv.obb.axis[0]; + split_vector.noalias() = bv.obb.axes.col(0); } template<> void computeSplitVector<OBBRSS>(const OBBRSS& bv, Vec3f& split_vector) { - split_vector = bv.obb.axis[0]; + split_vector.noalias() = bv.obb.axes.col(0); } template<typename BV> diff --git a/src/broadphase/broadphase_SSaP.cpp b/src/broadphase/broadphase_SSaP.cpp index 4a7cee1497818907623386f466f5f6578e59dba9..5595bde03f195d3cd1431abba66e8445c09158ce 100644 --- a/src/broadphase/broadphase_SSaP.cpp +++ b/src/broadphase/broadphase_SSaP.cpp @@ -354,7 +354,7 @@ bool SSaPCollisionManager::distance_(CollisionObject* obj, void* cdata, Distance else // need more loop { if(isEqual(dummy_vector, obj->getAABB().max_)) - dummy_vector = dummy_vector + delta; + dummy_vector.noalias() += delta; else dummy_vector = dummy_vector * 2 - obj->getAABB().max_; } diff --git a/src/ccd/motion.cpp b/src/ccd/motion.cpp index 58d8792c57886ee368d9ace41fc1298074102c5a..554131ae6b2d8e5fefce95db18b7af2c7d1e667c 100644 --- a/src/ccd/motion.cpp +++ b/src/ccd/motion.cpp @@ -48,9 +48,9 @@ FCL_REAL TBVMotionBoundVisitor<RSS>::visit(const SplineMotion& motion) const FCL_REAL tf_t = motion.getCurrentTime(); Vec3f c1 = bv.Tr; - Vec3f c2 = bv.Tr + bv.axis[0] * bv.l[0]; - Vec3f c3 = bv.Tr + bv.axis[1] * bv.l[1]; - Vec3f c4 = bv.Tr + bv.axis[0] * bv.l[0] + bv.axis[1] * bv.l[1]; + Vec3f c2 = bv.Tr + bv.axes.col(0) * bv.l[0]; + Vec3f c3 = bv.Tr + bv.axes.col(1) * bv.l[1]; + Vec3f c4 = bv.Tr + bv.axes.col(0) * bv.l[0] + bv.axes.col(1) * bv.l[1]; FCL_REAL tmp; // max_i |c_i * n| @@ -327,11 +327,11 @@ FCL_REAL TBVMotionBoundVisitor<RSS>::visit(const ScrewMotion& motion) const FCL_REAL c_proj_max = ((tf.getQuatRotation().transform(bv.Tr)).cross(axis)).squaredNorm(); FCL_REAL tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[0] * bv.l[0])).cross(axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(0) * bv.l[0])).cross(axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[1] * bv.l[1])).cross(axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(1) * bv.l[1])).cross(axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[0] * bv.l[0] + bv.axis[1] * bv.l[1])).cross(axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(0) * bv.l[0] + bv.axes.col(1) * bv.l[1])).cross(axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; c_proj_max = sqrt(c_proj_max); @@ -392,11 +392,11 @@ FCL_REAL TBVMotionBoundVisitor<RSS>::visit(const InterpMotion& motion) const FCL_REAL c_proj_max = ((tf.getQuatRotation().transform(bv.Tr - reference_p)).cross(angular_axis)).squaredNorm(); FCL_REAL tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[0] * bv.l[0] - reference_p)).cross(angular_axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(0) * bv.l[0] - reference_p)).cross(angular_axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[1] * bv.l[1] - reference_p)).cross(angular_axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(1) * bv.l[1] - reference_p)).cross(angular_axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; - tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axis[0] * bv.l[0] + bv.axis[1] * bv.l[1] - reference_p)).cross(angular_axis)).squaredNorm(); + tmp = ((tf.getQuatRotation().transform(bv.Tr + bv.axes.col(0) * bv.l[0] + bv.axes.col(1) * bv.l[1] - reference_p)).cross(angular_axis)).squaredNorm(); if(tmp > c_proj_max) c_proj_max = tmp; c_proj_max = std::sqrt(c_proj_max); diff --git a/src/math/transform.cpp b/src/math/transform.cpp index c5f406d2a8a01229e62e5750814bdb02ffd2c205..279e0c50ec75928d59eaf1d9acfd0469eceace43 100644 --- a/src/math/transform.cpp +++ b/src/math/transform.cpp @@ -108,15 +108,14 @@ void Quaternion3f::toRotation(Matrix3f& R) const twoXZ - twoWY, twoYZ + twoWX, 1.0 - (twoXX + twoYY); } - -void Quaternion3f::fromAxes(const Vec3f axis[3]) +void Quaternion3f::fromAxes(const Matrix3f& axes) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". const int next[3] = {1, 2, 0}; - FCL_REAL trace = axis[0][0] + axis[1][1] + axis[2][2]; + FCL_REAL trace = axes.trace(); FCL_REAL root; if(trace > 0.0) @@ -125,36 +124,36 @@ void Quaternion3f::fromAxes(const Vec3f axis[3]) root = sqrt(trace + 1.0); // 2w data[0] = 0.5 * root; root = 0.5 / root; // 1/(4w) - data[1] = (axis[1][2] - axis[2][1])*root; - data[2] = (axis[2][0] - axis[0][2])*root; - data[3] = (axis[0][1] - axis[1][0])*root; + data[1] = (axes(1,2) - axes(2,1))*root; + data[2] = (axes(2,0) - axes(0,2))*root; + data[3] = (axes(0,1) - axes(1,0))*root; } else { // |w| <= 1/2 int i = 0; - if(axis[1][1] > axis[0][0]) + if(axes(1,1) > axes(0,0)) { i = 1; } - if(axis[2][2] > axis[i][i]) + if(axes(2,2) > axes(i,i)) { i = 2; } int j = next[i]; int k = next[j]; - root = sqrt(axis[i][i] - axis[j][j] - axis[k][k] + 1.0); + root = sqrt(axes(i,i) - axes(j,j) - axes(k,k) + 1.0); FCL_REAL* quat[3] = { &data[1], &data[2], &data[3] }; *quat[i] = 0.5 * root; root = 0.5 / root; - data[0] = (axis[j][k] - axis[k][j]) * root; - *quat[j] = (axis[i][j] + axis[j][i]) * root; - *quat[k] = (axis[i][k] + axis[k][i]) * root; + data[0] = (axes(j,k) - axes(k,j)) * root; + *quat[j] = (axes(i,j) + axes(j,i)) * root; + *quat[k] = (axes(i,k) + axes(k,i)) * root; } } -void Quaternion3f::toAxes(Vec3f axis[3]) const +void Quaternion3f::toAxes(Matrix3f& axes) const { FCL_REAL twoX = 2.0*data[1]; FCL_REAL twoY = 2.0*data[2]; @@ -169,9 +168,9 @@ void Quaternion3f::toAxes(Vec3f axis[3]) const FCL_REAL twoYZ = twoZ*data[2]; FCL_REAL twoZZ = twoZ*data[3]; - axis[0] << 1.0 - (twoYY + twoZZ), twoXY + twoWZ, twoXZ - twoWY; - axis[1] << twoXY - twoWZ, 1.0 - (twoXX + twoZZ), twoYZ + twoWX; - axis[2] << twoXZ + twoWY, twoYZ - twoWX, 1.0 - (twoXX + twoYY); + axes << 1.0 - (twoYY + twoZZ), twoXY + twoWZ, twoXZ - twoWY, + twoXY - twoWZ, 1.0 - (twoXX + twoZZ), twoYZ + twoWX, + twoXZ + twoWY, twoYZ - twoWX, 1.0 - (twoXX + twoYY); } diff --git a/src/shape/geometric_shapes_utility.cpp b/src/shape/geometric_shapes_utility.cpp index 058a59088c3f1834e9ffa4acb4c444f6b407e642..97d0a8d5c02a3e4dcff8b8e2f45b1c21166bb5ab 100644 --- a/src/shape/geometric_shapes_utility.cpp +++ b/src/shape/geometric_shapes_utility.cpp @@ -412,9 +412,7 @@ void computeBV<OBB, Box>(const Box& s, const Transform3f& tf, OBB& bv) const Vec3f& T = tf.getTranslation(); bv.To = T; - bv.axis[0] = R.col(0); - bv.axis[1] = R.col(1); - bv.axis[2] = R.col(2); + bv.axes.noalias() = R; bv.extent = s.side * (FCL_REAL)0.5; } @@ -424,9 +422,7 @@ void computeBV<OBB, Sphere>(const Sphere& s, const Transform3f& tf, OBB& bv) const Vec3f& T = tf.getTranslation(); bv.To = T; - bv.axis[0] << 1, 0, 0; - bv.axis[1] << 0, 1, 0; - bv.axis[2] << 0, 0, 1; + bv.axes.setIdentity(); bv.extent.setConstant(s.radius); } @@ -437,9 +433,7 @@ void computeBV<OBB, Capsule>(const Capsule& s, const Transform3f& tf, OBB& bv) const Vec3f& T = tf.getTranslation(); bv.To = T; - bv.axis[0] = R.col(0); - bv.axis[1] = R.col(1); - bv.axis[2] = R.col(2); + bv.axes.noalias() = R; bv.extent << s.radius, s.radius, s.lz / 2 + s.radius; } @@ -450,9 +444,7 @@ void computeBV<OBB, Cone>(const Cone& s, const Transform3f& tf, OBB& bv) const Vec3f& T = tf.getTranslation(); bv.To = T; - bv.axis[0] = R.col(0); - bv.axis[1] = R.col(1); - bv.axis[2] = R.col(2); + bv.axes.noalias() = R; bv.extent << s.radius, s.radius, s.lz / 2; } @@ -463,9 +455,7 @@ void computeBV<OBB, Cylinder>(const Cylinder& s, const Transform3f& tf, OBB& bv) const Vec3f& T = tf.getTranslation(); bv.To = T; - bv.axis[0] = R.col(0); - bv.axis[1] = R.col(1); - bv.axis[2] = R.col(2); + bv.axes.noalias() = R; bv.extent << s.radius, s.radius, s.lz / 2; } @@ -477,9 +467,7 @@ void computeBV<OBB, Convex>(const Convex& s, const Transform3f& tf, OBB& bv) fit(s.points, s.num_points, bv); - bv.axis[0] = R * bv.axis[0]; - bv.axis[1] = R * bv.axis[1]; - bv.axis[2] = R * bv.axis[2]; + bv.axes = R * bv.axes; bv.To = R * bv.To + T; } @@ -488,10 +476,8 @@ template<> void computeBV<OBB, Halfspace>(const Halfspace& s, const Transform3f& tf, OBB& bv) { /// Half space can only have very rough OBB - bv.axis[0] = Vec3f(1, 0, 0); - bv.axis[1] = Vec3f(0, 1, 0); - bv.axis[2] = Vec3f(0, 0, 1); - bv.To = Vec3f(0, 0, 0); + bv.axes.setIdentity(); + bv.To.setZero(); bv.extent.setConstant(std::numeric_limits<FCL_REAL>::max()); } @@ -499,10 +485,8 @@ template<> void computeBV<RSS, Halfspace>(const Halfspace& s, const Transform3f& tf, RSS& bv) { /// Half space can only have very rough RSS - bv.axis[0] = Vec3f(1, 0, 0); - bv.axis[1] = Vec3f(0, 1, 0); - bv.axis[2] = Vec3f(0, 0, 1); - bv.Tr = Vec3f(0, 0, 0); + bv.axes.setIdentity(); + bv.Tr.setZero(); bv.l[0] = bv.l[1] = bv.r = std::numeric_limits<FCL_REAL>::max(); } @@ -720,8 +704,8 @@ template<> void computeBV<OBB, Plane>(const Plane& s, const Transform3f& tf, OBB& bv) { Vec3f n = tf.getQuatRotation().transform(s.n); - generateCoordinateSystem(n, bv.axis[1], bv.axis[2]); - bv.axis[0] = n; + generateCoordinateSystem(n, bv.axes.col(1), bv.axes.col(2)); + bv.axes.col(0).noalias() = n; bv.extent << 0, std::numeric_limits<FCL_REAL>::max(), std::numeric_limits<FCL_REAL>::max(); @@ -734,8 +718,8 @@ void computeBV<RSS, Plane>(const Plane& s, const Transform3f& tf, RSS& bv) { Vec3f n = tf.getQuatRotation().transform(s.n); - generateCoordinateSystem(n, bv.axis[1], bv.axis[2]); - bv.axis[0] = n; + generateCoordinateSystem(n, bv.axes.col(1), bv.axes.col(2)); + bv.axes.col(0).noalias() = n; bv.l[0] = std::numeric_limits<FCL_REAL>::max(); bv.l[1] = std::numeric_limits<FCL_REAL>::max(); @@ -945,33 +929,25 @@ void constructBox(const AABB& bv, Box& box, Transform3f& tf) void constructBox(const OBB& bv, Box& box, Transform3f& tf) { box = Box(bv.extent * 2); - tf = Transform3f((Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(), bv.To); + tf = Transform3f(bv.axes, bv.To); } void constructBox(const OBBRSS& bv, Box& box, Transform3f& tf) { box = Box(bv.obb.extent * 2); - tf = Transform3f((Matrix3f() << bv.obb.axis[0][0], bv.obb.axis[1][0], bv.obb.axis[2][0], - bv.obb.axis[0][1], bv.obb.axis[1][1], bv.obb.axis[2][1], - bv.obb.axis[0][2], bv.obb.axis[1][2], bv.obb.axis[2][2]).finished(), bv.obb.To); + tf = Transform3f(bv.obb.axes, bv.obb.To); } void constructBox(const kIOS& bv, Box& box, Transform3f& tf) { box = Box(bv.obb.extent * 2); - tf = Transform3f((Matrix3f() << bv.obb.axis[0][0], bv.obb.axis[1][0], bv.obb.axis[2][0], - bv.obb.axis[0][1], bv.obb.axis[1][1], bv.obb.axis[2][1], - bv.obb.axis[0][2], bv.obb.axis[1][2], bv.obb.axis[2][2]).finished(), bv.obb.To); + tf = Transform3f(bv.obb.axes, bv.obb.To); } void constructBox(const RSS& bv, Box& box, Transform3f& tf) { box = Box(bv.width(), bv.height(), bv.depth()); - tf = Transform3f((Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(), bv.Tr); + tf = Transform3f(bv.axes, bv.Tr); } void constructBox(const KDOP<16>& bv, Box& box, Transform3f& tf) @@ -1003,33 +979,25 @@ void constructBox(const AABB& bv, const Transform3f& tf_bv, Box& box, Transform3 void constructBox(const OBB& bv, const Transform3f& tf_bv, Box& box, Transform3f& tf) { box = Box(bv.extent * 2); - tf = tf_bv *Transform3f((Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(), bv.To); + tf = tf_bv * Transform3f(bv.axes, bv.To); } void constructBox(const OBBRSS& bv, const Transform3f& tf_bv, Box& box, Transform3f& tf) { box = Box(bv.obb.extent * 2); - tf = tf_bv * Transform3f((Matrix3f() << bv.obb.axis[0][0], bv.obb.axis[1][0], bv.obb.axis[2][0], - bv.obb.axis[0][1], bv.obb.axis[1][1], bv.obb.axis[2][1], - bv.obb.axis[0][2], bv.obb.axis[1][2], bv.obb.axis[2][2]).finished(), bv.obb.To); + tf = tf_bv * Transform3f(bv.obb.axes, bv.obb.To); } void constructBox(const kIOS& bv, const Transform3f& tf_bv, Box& box, Transform3f& tf) { box = Box(bv.obb.extent * 2); - tf = tf_bv * Transform3f((Matrix3f() << bv.obb.axis[0][0], bv.obb.axis[1][0], bv.obb.axis[2][0], - bv.obb.axis[0][1], bv.obb.axis[1][1], bv.obb.axis[2][1], - bv.obb.axis[0][2], bv.obb.axis[1][2], bv.obb.axis[2][2]).finished(), bv.obb.To); + tf = tf_bv * Transform3f(bv.obb.axes, bv.obb.To); } void constructBox(const RSS& bv, const Transform3f& tf_bv, Box& box, Transform3f& tf) { box = Box(bv.width(), bv.height(), bv.depth()); - tf = tf_bv * Transform3f((Matrix3f() << bv.axis[0][0], bv.axis[1][0], bv.axis[2][0], - bv.axis[0][1], bv.axis[1][1], bv.axis[2][1], - bv.axis[0][2], bv.axis[1][2], bv.axis[2][2]).finished(), bv.Tr); + tf = tf_bv * Transform3f(bv.axes, bv.Tr); } void constructBox(const KDOP<16>& bv, const Transform3f& tf_bv, Box& box, Transform3f& tf) diff --git a/src/traversal/traversal_node_bvhs.cpp b/src/traversal/traversal_node_bvhs.cpp index edd316d3ebdddeb46c1e7b82c5884aaa7e334c83..5682606c403d0049063ec12259a344ba0d064474 100644 --- a/src/traversal/traversal_node_bvhs.cpp +++ b/src/traversal/traversal_node_bvhs.cpp @@ -488,10 +488,8 @@ bool meshConservativeAdvancementOrientedNodeCanStop(FCL_REAL c, assert(c == d); // n is in local frame of c1, so we need to turn n into the global frame - Vec3f n_transformed = - getBVAxis(model1->getBV(c1).bv, 0) * n[0] + - getBVAxis(model1->getBV(c1).bv, 1) * n[2] + - getBVAxis(model1->getBV(c1).bv, 2) * n[2]; + // TODO: Erase me. There was a bug here + Vec3f n_transformed (getBVAxes(model1->getBV(c1).bv) * n); Quaternion3f R0; motion1->getCurrentRotation(R0); n_transformed = R0.transform(n_transformed); diff --git a/test/test_fcl_collision.cpp b/test/test_fcl_collision.cpp index 7ce96904b55f35711932d93b94f4cec7919611ad..24386b909377f53fc0ba46553651f7750c1ff12c 100644 --- a/test/test_fcl_collision.cpp +++ b/test/test_fcl_collision.cpp @@ -220,8 +220,8 @@ BOOST_AUTO_TEST_CASE(OBB_AABB_test) { std::cout << aabb1.min_ << " " << aabb1.max_ << std::endl; std::cout << aabb2.min_ << " " << aabb2.max_ << std::endl; - std::cout << obb1.To << " " << obb1.extent << " " << obb1.axis[0] << " " << obb1.axis[1] << " " << obb1.axis[2] << std::endl; - std::cout << obb2.To << " " << obb2.extent << " " << obb2.axis[0] << " " << obb2.axis[1] << " " << obb2.axis[2] << std::endl; + std::cout << obb1.To << " " << obb1.extent << " " << obb1.axes << std::endl; + std::cout << obb2.To << " " << obb2.extent << " " << obb2.axes << std::endl; } BOOST_CHECK(overlap_aabb == overlap_obb);