diff --git a/trunk/fcl/include/fcl/geometric_shapes_utility.h b/trunk/fcl/include/fcl/geometric_shapes_utility.h index 2e2868077243c4f93b99037248607133ff53f605..94c9e02720e521afb0453b8a19d343e4a3ab11e9 100644 --- a/trunk/fcl/include/fcl/geometric_shapes_utility.h +++ b/trunk/fcl/include/fcl/geometric_shapes_utility.h @@ -43,74 +43,89 @@ namespace fcl { - template<typename BV> - void computeBV(const Box& s, const SimpleTransform& tf, BV& bv) {} - template<typename BV> - void computeBV(const Sphere& s, const SimpleTransform& tf, BV& bv) {} +namespace details +{ +std::vector<Vec3f> getBoundVertices(const Box& box, const SimpleTransform& tf); +std::vector<Vec3f> getBoundVertices(const Sphere& sphere, const SimpleTransform& tf); +std::vector<Vec3f> getBoundVertices(const Capsule& capsule, const SimpleTransform& tf); +std::vector<Vec3f> getBoundVertices(const Cone& cone, const SimpleTransform& tf); +std::vector<Vec3f> getBoundVertices(const Cylinder& cylinder, const SimpleTransform& tf); + +} // end detail + + +template<typename BV, typename S> +void computeBV(const S& s, const SimpleTransform& tf, BV& bv) +{ + std::vector<Vec3f> convex_bound_vertices = details::getBoundVertices(s, tf); + fit(&convex_bound_vertices[0], (int)convex_bound_vertices.size(), bv); +} + +template<> +void computeBV<AABB, Box>(const Box& s, const SimpleTransform& tf, AABB& bv); + +template<> +void computeBV<AABB, Sphere>(const Sphere& s, const SimpleTransform& tf, AABB& bv); + +template<> +void computeBV<AABB, Capsule>(const Capsule& s, const SimpleTransform& tf, AABB& bv); + +template<> +void computeBV<AABB, Cone>(const Cone& s, const SimpleTransform& tf, AABB& bv); - template<typename BV> - void computeBV(const Capsule& s, const SimpleTransform& tf, BV& bv) {} +template<> +void computeBV<AABB, Cylinder>(const Cylinder& s, const SimpleTransform& tf, AABB& bv); - template<typename BV> - void computeBV(const Cone& s, const SimpleTransform& tf, BV& bv) {} +template<> +void computeBV<AABB, Convex>(const Convex& s, const SimpleTransform& tf, AABB& bv); - template<typename BV> - void computeBV(const Cylinder& s, const SimpleTransform& tf, BV& bv) {} - template<typename BV> - void computeBV(const Convex& s, const SimpleTransform& tf, BV& bv) {} +/** the bounding volume for half space back of plane for OBB, it is the plane itself */ +template<> +void computeBV<AABB, Plane>(const Plane& s, const SimpleTransform& tf, AABB& bv); - /** the bounding volume for half space back of plane - * for OBB, it is the plane itself - */ - template<typename BV> - void computeBV(const Plane& s, const SimpleTransform& tf, BV& bv) {} - /** For AABB */ - template<> - void computeBV<AABB>(const Box& s, const SimpleTransform& tf, AABB& bv); - template<> - void computeBV<AABB>(const Sphere& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Box>(const Box& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<AABB>(const Capsule& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Sphere>(const Sphere& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<AABB>(const Cone& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Capsule>(const Capsule& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<AABB>(const Cylinder& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Cone>(const Cone& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<AABB>(const Convex& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Cylinder>(const Cylinder& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<AABB>(const Plane& s, const SimpleTransform& tf, AABB& bv); +template<> +void computeBV<OBB, Convex>(const Convex& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<OBB>(const Box& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<OBB, Plane>(const Plane& s, const SimpleTransform& tf, OBB& bv); - template<> - void computeBV<OBB>(const Sphere& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<RSS, Plane>(const Plane& s, const SimpleTransform& tf, RSS& bv); - template<> - void computeBV<OBB>(const Capsule& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<OBBRSS, Plane>(const Plane& s, const SimpleTransform& tf, OBBRSS& bv); - template<> - void computeBV<OBB>(const Cone& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<kIOS, Plane>(const Plane& s, const SimpleTransform& tf, kIOS& bv); - template<> - void computeBV<OBB>(const Cylinder& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<KDOP<16>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<16>& bv); - template<> - void computeBV<OBB>(const Convex& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<KDOP<18>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<18>& bv); - template<> - void computeBV<OBB>(const Plane& s, const SimpleTransform& tf, OBB& bv); +template<> +void computeBV<KDOP<24>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<24>& bv); - // TODO: implement computeBV for RSS and KDOP } #endif diff --git a/trunk/fcl/include/fcl/simple_setup.h b/trunk/fcl/include/fcl/simple_setup.h index 9735f336eac6a7eccca7789a1b165b99f307b039..35369ea8d8f2edc1b0a09e8eb0e139d0d0bab29b 100644 --- a/trunk/fcl/include/fcl/simple_setup.h +++ b/trunk/fcl/include/fcl/simple_setup.h @@ -95,6 +95,8 @@ bool initialize(MeshShapeCollisionTraversalNode<BV, S>& node, node.model2 = &model2; node.tf2 = tf2; + computeBV(model2, tf2, node.model2_bv); + node.vertices = model1.vertices; node.tri_indices = model1.tri_indices; node.num_max_contacts = num_max_contacts; @@ -138,6 +140,8 @@ bool initialize(ShapeMeshCollisionTraversalNode<S, BV>& node, node.model2 = &model2; node.tf2 = tf2; + computeBV(model1, tf1, node.model1_bv); + node.vertices = model2.vertices; node.tri_indices = model2.tri_indices; node.num_max_contacts = num_max_contacts; @@ -164,6 +168,8 @@ bool initialize(MeshShapeCollisionTraversalNodeOBB<S>& node, node.model2 = &model2; node.tf2 = tf2; + computeBV(model2, tf2, node.model2_bv); + node.vertices = model1.vertices; node.tri_indices = model1.tri_indices; node.num_max_contacts = num_max_contacts; @@ -192,6 +198,8 @@ bool initialize(ShapeMeshCollisionTraversalNodeOBB<S>& node, node.model2 = &model2; node.tf2 = tf2; + computeBV(model1, tf1, node.model1_bv); + node.vertices = model2.vertices; node.tri_indices = model2.tri_indices; node.num_max_contacts = num_max_contacts; diff --git a/trunk/fcl/include/fcl/traversal_node_bvh_shape.h b/trunk/fcl/include/fcl/traversal_node_bvh_shape.h index 90292ca956f72b92b1094c22ddec3d8def76ac96..6a9ffbbbb893b9cb8f490b10f72810eafab21b8f 100644 --- a/trunk/fcl/include/fcl/traversal_node_bvh_shape.h +++ b/trunk/fcl/include/fcl/traversal_node_bvh_shape.h @@ -78,13 +78,12 @@ public: bool BVTesting(int b1, int b2) const { if(this->enable_statistics) num_bv_tests++; - BV bv_shape; - computeBV(*model2, tf2, bv_shape); - return !model1->getBV(b1).bv.overlap(bv_shape); + return !model1->getBV(b1).bv.overlap(model2_bv); } const BVHModel<BV>* model1; const S* model2; + BV model2_bv; mutable int num_bv_tests; mutable int num_leaf_tests; @@ -129,13 +128,12 @@ public: bool BVTesting(int b1, int b2) const { if(this->enable_statistics) num_bv_tests++; - BV bv_shape; - computeBV(*model1, tf1, bv_shape); - return !model2->getBV(b2).bv.overlap(bv_shape); + return !model2->getBV(b2).bv.overlap(model1_bv); } const S* model1; const BVHModel<BV>* model2; + BV model1_bv; mutable int num_bv_tests; mutable int num_leaf_tests; @@ -250,9 +248,7 @@ public: bool BVTesting(int b1, int b2) const { if(this->enable_statistics) this->num_bv_tests++; - OBB bv_shape; - computeBV(*this->model2, this->tf2, bv_shape); - return !overlap(R, T, bv_shape, this->model1->getBV(b1).bv); + return !overlap(R, T, this->model2_bv, this->model1->getBV(b1).bv); } void leafTesting(int b1, int b2) const @@ -368,9 +364,7 @@ public: bool BVTesting(int b1, int b2) const { if(this->enable_statistics) this->num_bv_tests++; - OBB bv_shape; - computeBV(*this->model1, this->tf1, bv_shape); - return !overlap(R, T, bv_shape, this->model2->getBV(b2).bv); + return !overlap(R, T, this->model1_bv, this->model2->getBV(b2).bv); } void leafTesting(int b1, int b2) const diff --git a/trunk/fcl/src/geometric_shapes_utility.cpp b/trunk/fcl/src/geometric_shapes_utility.cpp index d39a2d117ef4344145852b841c1048fafb7ecc8e..e1c7efc4bf88ccb431a3a028b2982cdf2eae8201 100644 --- a/trunk/fcl/src/geometric_shapes_utility.cpp +++ b/trunk/fcl/src/geometric_shapes_utility.cpp @@ -41,8 +41,162 @@ namespace fcl { +namespace details +{ + +std::vector<Vec3f> getBoundVertices(const Box& box, const SimpleTransform& tf) +{ + std::vector<Vec3f> result(8); + BVH_REAL a = box.side[0] / 2; + BVH_REAL b = box.side[1] / 2; + BVH_REAL c = box.side[2] / 2; + result[0] = tf.transform(Vec3f(a, b, c)); + result[1] = tf.transform(Vec3f(a, b, -c)); + result[2] = tf.transform(Vec3f(a, -b, c)); + result[3] = tf.transform(Vec3f(a, -b, -c)); + result[4] = tf.transform(Vec3f(-a, b, c)); + result[5] = tf.transform(Vec3f(-a, b, -c)); + result[6] = tf.transform(Vec3f(-a, -b, c)); + result[7] = tf.transform(Vec3f(-a, -b, -c)); + + return result; +} + +// we use icosahedron to bound the sphere +std::vector<Vec3f> getBoundVertices(const Sphere& sphere, const SimpleTransform& tf) +{ + std::vector<Vec3f> result(12); + const BVH_REAL m = (1 + sqrt(5.0)) / 2.0; + BVH_REAL edge_size = sphere.radius * 6 / (sqrt(27.0) + sqrt(15.0)); + + BVH_REAL a = edge_size; + BVH_REAL b = m * edge_size; + result[0] = tf.transform(Vec3f(0, a, b)); + result[1] = tf.transform(Vec3f(0, -a, b)); + result[2] = tf.transform(Vec3f(0, a, -b)); + result[3] = tf.transform(Vec3f(0, -a, -b)); + result[4] = tf.transform(Vec3f(a, b, 0)); + result[5] = tf.transform(Vec3f(-a, b, 0)); + result[6] = tf.transform(Vec3f(a, -b, 0)); + result[7] = tf.transform(Vec3f(-a, -b, 0)); + result[8] = tf.transform(Vec3f(b, 0, a)); + result[9] = tf.transform(Vec3f(b, 0, -a)); + result[10] = tf.transform(Vec3f(-b, 0, a)); + result[11] = tf.transform(Vec3f(-b, 0, -a)); + + return result; +} + +std::vector<Vec3f> getBoundVertices(const Capsule& capsule, const SimpleTransform& tf) +{ + std::vector<Vec3f> result(36); + const BVH_REAL m = (1 + sqrt(5.0)) / 2.0; + + BVH_REAL hl = capsule.lz * 0.5; + BVH_REAL edge_size = capsule.radius * 6 / (sqrt(27.0) + sqrt(15.0)); + BVH_REAL a = edge_size; + BVH_REAL b = m * edge_size; + BVH_REAL r2 = capsule.radius * 2 / sqrt(3.0); + + + result[0] = tf.transform(Vec3f(0, a, b + hl)); + result[1] = tf.transform(Vec3f(0, -a, b + hl)); + result[2] = tf.transform(Vec3f(0, a, -b + hl)); + result[3] = tf.transform(Vec3f(0, -a, -b + hl)); + result[4] = tf.transform(Vec3f(a, b, hl)); + result[5] = tf.transform(Vec3f(-a, b, hl)); + result[6] = tf.transform(Vec3f(a, -b, hl)); + result[7] = tf.transform(Vec3f(-a, -b, hl)); + result[8] = tf.transform(Vec3f(b, 0, a + hl)); + result[9] = tf.transform(Vec3f(b, 0, -a + hl)); + result[10] = tf.transform(Vec3f(-b, 0, a + hl)); + result[11] = tf.transform(Vec3f(-b, 0, -a + hl)); + + result[12] = tf.transform(Vec3f(0, a, b - hl)); + result[13] = tf.transform(Vec3f(0, -a, b - hl)); + result[14] = tf.transform(Vec3f(0, a, -b - hl)); + result[15] = tf.transform(Vec3f(0, -a, -b - hl)); + result[16] = tf.transform(Vec3f(a, b, -hl)); + result[17] = tf.transform(Vec3f(-a, b, -hl)); + result[18] = tf.transform(Vec3f(a, -b, -hl)); + result[19] = tf.transform(Vec3f(-a, -b, -hl)); + result[20] = tf.transform(Vec3f(b, 0, a - hl)); + result[21] = tf.transform(Vec3f(b, 0, -a - hl)); + result[22] = tf.transform(Vec3f(-b, 0, a - hl)); + result[23] = tf.transform(Vec3f(-b, 0, -a - hl)); + + BVH_REAL c = 0.5 * r2; + BVH_REAL d = capsule.radius; + result[24] = tf.transform(Vec3f(r2, 0, hl)); + result[25] = tf.transform(Vec3f(c, d, hl)); + result[26] = tf.transform(Vec3f(-c, d, hl)); + result[27] = tf.transform(Vec3f(-r0, 0, hl)); + result[28] = tf.transform(Vec3f(-c, -d, hl)); + result[29] = tf.transform(Vec3f(c, -d, hl)); + + result[30] = tf.transform(Vec3f(r2, 0, -hl)); + result[31] = tf.transform(Vec3f(c, d, -hl)); + result[32] = tf.transform(Vec3f(-c, d, -hl)); + result[33] = tf.transform(Vec3f(-r0, 0, -hl)); + result[34] = tf.transform(Vec3f(-c, -d, -hl)); + result[35] = tf.transform(Vec3f(c, -d, -hl)); + + return result; +} + + +std::vector<Vec3f> getBoundVertices(const Cone& cone, const SimpleTransform& tf) +{ + std::vector<Vec3f> result(7); + + BVH_REAL hl = cone.lz * 0.5; + BVH_REAL r2 = cone.radius * 2 / sqrt(3.0); + BVH_REAL a = 0.5 * r2; + BVH_REAL b = cone.radius; + + result[0] = tf.transform(Vec3f(r2, 0, -hl)); + result[1] = tf.transform(Vec3f(c, d, -hl)); + result[2] = tf.transform(Vec3f(-c, d, -hl)); + result[3] = tf.transform(Vec3f(-r0, 0, -hl)); + result[4] = tf.transform(Vec3f(-c, -d, -hl)); + result[5] = tf.transform(Vec3f(c, -d, -hl)); + + result[6] = tf.transform(Vec3f(0, 0, hl)); + + return result; +} + +std::vector<Vec3f> getBoundVertices(const Cylinder& cylinder, const SimpleTransform& tf) +{ + std::vector<Vec3f> result; + + BVH_REAL hl = cylinder.lz * 0.5; + BVH_REAL r2 = cylinder.radius * 2 / sqrt(3.0); + BVH_REAL a = 0.5 * r2; + BVH_REAL b = cylinder.radius; + + result[0] = tf.transform(Vec3f(r2, 0, -hl)); + result[1] = tf.transform(Vec3f(c, d, -hl)); + result[2] = tf.transform(Vec3f(-c, d, -hl)); + result[3] = tf.transform(Vec3f(-r0, 0, -hl)); + result[4] = tf.transform(Vec3f(-c, -d, -hl)); + result[5] = tf.transform(Vec3f(c, -d, -hl)); + + result[6] = tf.transform(Vec3f(r2, 0, hl)); + result[7] = tf.transform(Vec3f(c, d, hl)); + result[8] = tf.transform(Vec3f(-c, d, hl)); + result[9] = tf.transform(Vec3f(-r0, 0, hl)); + result[10] = tf.transform(Vec3f(-c, -d, hl)); + result[11] = tf.transform(Vec3f(c, -d, hl)); + + return result; +} + +} // end detail + + template<> -void computeBV<AABB>(const Box& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Box>(const Box& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -56,7 +210,7 @@ void computeBV<AABB>(const Box& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Sphere& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Sphere>(const Sphere& s, const SimpleTransform& tf, AABB& bv) { const Vec3f& T = tf.getTranslation(); @@ -65,7 +219,7 @@ void computeBV<AABB>(const Sphere& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Capsule& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Capsule>(const Capsule& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -79,7 +233,7 @@ void computeBV<AABB>(const Capsule& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Cone& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Cone>(const Cone& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -93,7 +247,7 @@ void computeBV<AABB>(const Cone& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Cylinder& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Cylinder>(const Cylinder& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -107,7 +261,7 @@ void computeBV<AABB>(const Cylinder& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Convex& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Convex>(const Convex& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -123,7 +277,7 @@ void computeBV<AABB>(const Convex& s, const SimpleTransform& tf, AABB& bv) } template<> -void computeBV<AABB>(const Plane& s, const SimpleTransform& tf, AABB& bv) +void computeBV<AABB, Plane>(const Plane& s, const SimpleTransform& tf, AABB& bv) { const Matrix3f& R = tf.getRotation(); @@ -154,7 +308,7 @@ void computeBV<AABB>(const Plane& s, const SimpleTransform& tf, AABB& bv) template<> -void computeBV<OBB>(const Box& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Box>(const Box& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -167,7 +321,7 @@ void computeBV<OBB>(const Box& s, const SimpleTransform& tf, OBB& bv) } template<> -void computeBV<OBB>(const Sphere& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Sphere>(const Sphere& s, const SimpleTransform& tf, OBB& bv) { const Vec3f& T = tf.getTranslation(); @@ -179,7 +333,7 @@ void computeBV<OBB>(const Sphere& s, const SimpleTransform& tf, OBB& bv) } template<> -void computeBV<OBB>(const Capsule& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Capsule>(const Capsule& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -192,7 +346,7 @@ void computeBV<OBB>(const Capsule& s, const SimpleTransform& tf, OBB& bv) } template<> -void computeBV<OBB>(const Cone& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Cone>(const Cone& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -205,7 +359,7 @@ void computeBV<OBB>(const Cone& s, const SimpleTransform& tf, OBB& bv) } template<> -void computeBV<OBB>(const Cylinder& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Cylinder>(const Cylinder& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -218,7 +372,7 @@ void computeBV<OBB>(const Cylinder& s, const SimpleTransform& tf, OBB& bv) } template<> -void computeBV<OBB>(const Convex& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Convex>(const Convex& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -230,11 +384,10 @@ void computeBV<OBB>(const Convex& s, const SimpleTransform& tf, OBB& bv) bv.axis[2] = R * bv.axis[2]; bv.To = R * bv.To + T; - } template<> -void computeBV<OBB>(const Plane& s, const SimpleTransform& tf, OBB& bv) +void computeBV<OBB, Plane>(const Plane& s, const SimpleTransform& tf, OBB& bv) { const Matrix3f& R = tf.getRotation(); const Vec3f& T = tf.getTranslation(); @@ -249,6 +402,46 @@ void computeBV<OBB>(const Plane& s, const SimpleTransform& tf, OBB& bv) bv.To = R * p + T; } +template<> +void computeBV<RSS, Plane>(const Plane& s, const SimpleTransform& tf, RSS& bv) +{ + const Matrix3f& R = tf.getRotation(); + const Vec3f& T = tf.getTranslation(); + + generateCoordinateSystem(s.n, bv.axis[1], bv.axis[2]); + bv.axis[0] = s.n; + + bv.l[0] = std::numeric_limits<BVH_REAL>::max(); + bv.l[1] = std::numeric_limits<BVH_REAL>::max(); + + bv.r = std::numeric_limits<BVH_REAL>::max(); +} + +template<> +void computeBV<OBBRSS, Plane>(const Plane& s, const SimpleTransform& tf, OBBRSS& bv) +{ +} + +template<> +void computeBV<kIOS, Plane>(const Plane& s, const SimpleTransform& tf, kIOS& bv) +{ +} + +template<> +void computeBV<KDOP<16>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<16>& bv) +{ +} + +template<> +void computeBV<KDOP<18>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<18>& bv) +{ +} + +template<> +void computeBV<KDOP<24>, Plane>(const Plane& s, const SimpleTransform& tf, KDOP<24>& bv) +{ +} + void Box::computeLocalAABB() { AABB aabb;