diff --git a/trunk/fcl/CMakeLists.txt b/trunk/fcl/CMakeLists.txt index 385c74f7e208c2f22dca8eb1132b9445557b74bd..5fae2c406d8bde5ddda9261c15b29e92c9823267 100644 --- a/trunk/fcl/CMakeLists.txt +++ b/trunk/fcl/CMakeLists.txt @@ -53,4 +53,7 @@ rosbuild_add_gtest(test_core_broad_phase test/test_core_broad_phase.cpp) target_link_libraries(test_core_broad_phase fcl) rosbuild_add_gtest(test_core_front_list test/test_core_front_list.cpp) -target_link_libraries(test_core_front_list fcl) \ No newline at end of file +target_link_libraries(test_core_front_list fcl) + +rosbuild_add_gtest(test_core_continuous_collision test/test_core_continuous_collision.cpp) +target_link_libraries(test_core_continuous_collision fcl) \ No newline at end of file diff --git a/trunk/fcl/test/test_core_continuous_collision.cpp b/trunk/fcl/test/test_core_continuous_collision.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8fd1bd53ee142793057cd73a3c1cb6d6d353292d --- /dev/null +++ b/trunk/fcl/test/test_core_continuous_collision.cpp @@ -0,0 +1,233 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** \author Jia Pan */ + +#include "fcl/traversal_node_bvhs.h" +#include "fcl/collision_node.h" +#include "fcl/simple_setup.h" +#include "test_core_utility.h" +#include <gtest/gtest.h> + +using namespace fcl; + +template<typename BV> +bool continuous_collide_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + bool refit_bottomup, bool verbose); + +template<typename BV> +bool discrete_continuous_collide_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + unsigned int nsamples, + bool verbose); + +int num_max_contacts = -1; +bool exhaustive = true; +bool enable_contact = true; +unsigned int n_dcd_samples = 10; + +TEST(ccd_test, mesh_mesh) +{ + std::vector<Vec3f> p1, p2; + std::vector<Triangle> t1, t2; + loadOBJFile("test/env.obj", p1, t1); + loadOBJFile("test/rob.obj", p2, t2); + + std::vector<Transform> transforms; // t0 + std::vector<Transform> transforms2; // t1 + BVH_REAL extents[] = {-3000, -3000, 0, 3000, 3000, 3000}; + BVH_REAL delta_trans[] = {10, 10, 10}; + int n = 1000; + bool verbose = false; + + generateRandomTransform(extents, transforms, transforms2, delta_trans, 0.005 * 2 * 3.1415, n); + + bool res, res2; + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = discrete_continuous_collide_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, n_dcd_samples, verbose); + res2 = continuous_collide_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, true, verbose); + if(res) + ASSERT_TRUE(res == res2); + else + { + if(res2) + std::cout << "CCD detects collision missed in DCD" << std::endl; + } + } + +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +template<typename BV> +bool continuous_collide_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + bool refit_bottomup, bool verbose) +{ + BVHModel<BV> m1; + BVHModel<BV> m2; + m1.bv_splitter.reset(new BVSplitter<BV>(split_method)); + m2.bv_splitter.reset(new BVSplitter<BV>(split_method)); + + std::vector<Vec3f> vertices1_new(vertices1.size()); + for(unsigned int i = 0; i < vertices1_new.size(); ++i) + { + vertices1_new[i] = matMulVec(tf1.R, vertices1[i]) + tf1.T; + } + + m1.beginModel(); + m1.addSubModel(vertices1_new, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + MeshCollisionTraversalNode<BV> node0; + + if(!initialize<BV>(node0, m1, m2)) + std::cout << "initialize error" << std::endl; + + node0.enable_statistics = verbose; + node0.num_max_contacts = num_max_contacts; + node0.exhaustive = exhaustive; + node0.enable_contact = enable_contact; + + collide(&node0); + if(node0.pairs.size() > 0) + return true; + + // update + for(unsigned int i = 0; i < vertices1_new.size(); ++i) + { + vertices1_new[i] = matMulVec(tf2.R, vertices1[i]) + tf2.T; + } + + m1.beginUpdateModel(); + m1.updateSubModel(vertices1_new); + m1.endUpdateModel(true, refit_bottomup); + + m2.beginUpdateModel(); + m2.updateSubModel(vertices2); + m2.endUpdateModel(true, refit_bottomup); + + MeshContinuousCollisionTraversalNode<BV> node; + + if(!initialize<BV>(node, m1, m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = num_max_contacts; + node.exhaustive = exhaustive; + node.enable_contact = enable_contact; + + collide(&node); + + if(node.pairs.size() > 0) + return true; + else + return false; +} + +template<typename BV> +bool discrete_continuous_collide_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + unsigned int nsamples, + bool verbose) +{ + std::vector<Vec3f> vertices1_t1(vertices1.size()); + for(unsigned int i = 0; i < vertices1_t1.size(); ++i) + { + vertices1_t1[i] = matMulVec(tf1.R, vertices1[i]) + tf1.T; + } + + std::vector<Vec3f> vertices1_t2(vertices1.size()); + for(unsigned int i = 0; i < vertices1_t2.size(); ++i) + { + vertices1_t2[i] = matMulVec(tf2.R, vertices1[i]) + tf2.T; + } + + std::vector<Vec3f> vertices1_t(vertices1.size()); + + for(unsigned int i = 0; i <= nsamples; ++i) + { + BVHModel<BV> m1; + BVHModel<BV> m2; + m1.bv_splitter.reset(new BVSplitter<BV>(split_method)); + m2.bv_splitter.reset(new BVSplitter<BV>(split_method)); + + BVH_REAL delta = i / (BVH_REAL)nsamples; + + for(unsigned int j = 0; j < vertices1_t.size(); ++j) + vertices1_t[j] = vertices1_t1[j] * (1 - delta) + vertices1_t2[j] * delta; + + m1.beginModel(); + m1.addSubModel(vertices1_t, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + MeshCollisionTraversalNode<BV> node; + if(!initialize<BV>(node, m1, m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = num_max_contacts; + node.exhaustive = exhaustive; + node.enable_contact = enable_contact; + + collide(&node); + + if(node.pairs.size() > 0) return true; + } + + return false; +} diff --git a/trunk/fcl/test/test_core_front_list.cpp b/trunk/fcl/test/test_core_front_list.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1cf230398947a40f959609cd5f0f37e938d4fbab --- /dev/null +++ b/trunk/fcl/test/test_core_front_list.cpp @@ -0,0 +1,431 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2011, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** \author Jia Pan */ + +#include "fcl/traversal_node_bvhs.h" +#include "fcl/collision_node.h" +#include "fcl/simple_setup.h" +#include "test_core_utility.h" +#include <gtest/gtest.h> + +using namespace fcl; + +template<typename BV> +bool collide_front_list_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + bool refit_bottomup, bool verbose); + +bool collide_front_list_OBB_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, bool verbose); + +bool collide_front_list_RSS_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, bool verbose); + +template<typename BV> +bool collide_Test(const Transform& tf, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose); + +// TODO: randomly still have some runtime error +TEST(collision_test, front_list) +{ + //srand(time(NULL)); + std::vector<Vec3f> p1, p2; + std::vector<Triangle> t1, t2; + loadOBJFile("test/env.obj", p1, t1); + loadOBJFile("test/rob.obj", p2, t2); + + std::vector<Transform> transforms; // t0 + std::vector<Transform> transforms2; // t1 + BVH_REAL extents[] = {-3000, -3000, 0, 3000, 3000, 3000}; + BVH_REAL delta_trans[] = {1, 1, 1}; + int n = 10; + bool verbose = false; + + generateRandomTransform(extents, transforms, transforms2, delta_trans, 0.005 * 2 * 3.1415, n); + + bool res, res2; + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<AABB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<AABB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<OBB>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<RSS>(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<KDOP<16> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<KDOP<16> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<16> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<KDOP<16> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<KDOP<18> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<KDOP<18> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<18> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<KDOP<18> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_Test<KDOP<24> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_Test<KDOP<24> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, false, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<KDOP<24> >(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_Test<KDOP<24> >(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, false, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_OBB_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_OBB_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<OBB>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_OBB_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + ASSERT_TRUE(res == res2); + } + + for(unsigned int i = 0; i < transforms.size(); ++i) + { + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + res2 = collide_front_list_RSS_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + res2 = collide_front_list_RSS_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose); + ASSERT_TRUE(res == res2); + res = collide_Test<RSS>(transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + res2 = collide_front_list_RSS_Test(transforms[i], transforms2[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose); + ASSERT_TRUE(res == res2); + } +} + + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + + +template<typename BV> +bool collide_front_list_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, + bool refit_bottomup, bool verbose) +{ + BVHModel<BV> m1; + BVHModel<BV> m2; + m1.bv_splitter.reset(new BVSplitter<BV>(split_method)); + m2.bv_splitter.reset(new BVSplitter<BV>(split_method)); + + BVHFrontList front_list; + + + std::vector<Vec3f> vertices1_new(vertices1.size()); + for(unsigned int i = 0; i < vertices1_new.size(); ++i) + { + vertices1_new[i] = matMulVec(tf1.R, vertices1[i]) + tf1.T; + } + + m1.beginModel(); + m1.addSubModel(vertices1_new, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + MeshCollisionTraversalNode<BV> node; + + if(!initialize<BV>(node, m1, m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = std::numeric_limits<int>::max(); // front technique needs all the contacts; + node.exhaustive = true; + node.enable_contact = false; + + collide(&node, &front_list); + + if(verbose) std::cout << "front list size " << front_list.size() << std::endl; + + + // update the mesh + for(unsigned int i = 0; i < vertices1.size(); ++i) + { + vertices1_new[i] = matMulVec(tf2.R, vertices1[i]) + tf2.T; + } + + m1.beginReplaceModel(); + m1.replaceSubModel(vertices1_new); + m1.endReplaceModel(true, refit_bottomup); + + m2.beginReplaceModel(); + m2.replaceSubModel(vertices2); + m2.endReplaceModel(true, refit_bottomup); + + node.pairs.clear(); + collide(&node, &front_list); + + if(node.pairs.size() > 0) + return true; + else + return false; +} + + +bool collide_front_list_OBB_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, bool verbose) +{ + BVHModel<OBB> m1; + BVHModel<OBB> m2; + m1.bv_splitter.reset(new BVSplitter<OBB>(split_method)); + m2.bv_splitter.reset(new BVSplitter<OBB>(split_method)); + + BVHFrontList front_list; + + m1.beginModel(); + m1.addSubModel(vertices1, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + Vec3f R2[3]; + R2[0] = Vec3f(1, 0, 0); + R2[1] = Vec3f(0, 1, 0); + R2[2] = Vec3f(0, 0, 1); + Vec3f T2; + + m1.setTransform(tf1.R, tf1.T); + m2.setTransform(R2, T2); + + MeshCollisionTraversalNodeOBB node; + + if(!initialize(node, (const BVHModel<OBB>&)m1, (const BVHModel<OBB>&)m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = std::numeric_limits<int>::max(); // front technique needs all the contacts; + node.exhaustive = true; + node.enable_contact = false; + + collide(&node, &front_list); + + if(verbose) std::cout << "front list size " << front_list.size() << std::endl; + + + // update the mesh + m1.setTransform(tf2.R, tf2.T); + if(!initialize(node, (const BVHModel<OBB>&)m1, (const BVHModel<OBB>&)m2)) + std::cout << "initialize error" << std::endl; + + node.pairs.clear(); + collide(&node, &front_list); + + if(node.pairs.size() > 0) + return true; + else + return false; +} + + +bool collide_front_list_RSS_Test(const Transform& tf1, const Transform& tf2, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, + SplitMethodType split_method, bool verbose) +{ + BVHModel<RSS> m1; + BVHModel<RSS> m2; + m1.bv_splitter.reset(new BVSplitter<RSS>(split_method)); + m2.bv_splitter.reset(new BVSplitter<RSS>(split_method)); + + BVHFrontList front_list; + + m1.beginModel(); + m1.addSubModel(vertices1, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + Vec3f R2[3]; + R2[0] = Vec3f(1, 0, 0); + R2[1] = Vec3f(0, 1, 0); + R2[2] = Vec3f(0, 0, 1); + Vec3f T2; + + m1.setTransform(tf1.R, tf1.T); + m2.setTransform(R2, T2); + + MeshCollisionTraversalNodeRSS node; + + if(!initialize(node, (const BVHModel<RSS>&)m1, (const BVHModel<RSS>&)m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = std::numeric_limits<int>::max(); // front technique needs all the contacts; + node.exhaustive = true; + node.enable_contact = false; + + collide(&node, &front_list); + + if(verbose) std::cout << "front list size " << front_list.size() << std::endl; + + + // update the mesh + m1.setTransform(tf2.R, tf2.T); + if(!initialize(node, (const BVHModel<RSS>&)m1, (const BVHModel<RSS>&)m2)) + std::cout << "initialize error" << std::endl; + + node.pairs.clear(); + collide(&node, &front_list); + + if(node.pairs.size() > 0) + return true; + else + return false; +} + + +template<typename BV> +bool collide_Test(const Transform& tf, + const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, + const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose) +{ + BVHModel<BV> m1; + BVHModel<BV> m2; + m1.bv_splitter.reset(new BVSplitter<BV>(split_method)); + m2.bv_splitter.reset(new BVSplitter<BV>(split_method)); + + m1.beginModel(); + m1.addSubModel(vertices1, triangles1); + m1.endModel(); + + m2.beginModel(); + m2.addSubModel(vertices2, triangles2); + m2.endModel(); + + Vec3f R2[3]; + R2[0] = Vec3f(1, 0, 0); + R2[1] = Vec3f(0, 1, 0); + R2[2] = Vec3f(0, 0, 1); + Vec3f T2; + + m1.setTransform(tf.R, tf.T); + m2.setTransform(R2, T2); + + MeshCollisionTraversalNode<BV> node; + + if(!initialize<BV>(node, m1, m2)) + std::cout << "initialize error" << std::endl; + + node.enable_statistics = verbose; + node.num_max_contacts = std::numeric_limits<int>::max(); + node.exhaustive = true; + node.enable_contact = false; + + collide(&node); + + + if(node.pairs.size() > 0) + return true; + else + return false; +} +