$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2011, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00038 #include "collision_checking/proximity.h" 00039 #include "collision_checking/intersect.h" 00040 00041 namespace collision_checking 00042 { 00043 00044 int distance(const BVHModel<RSS>& model1, const Vec3f R1[3], const Vec3f& T1, 00045 const BVHModel<RSS>& model2, const Vec3f R2[3], const Vec3f& T2, BVH_DistanceResult* res, BVHFrontList* front_list) 00046 { 00047 if(model1.build_state != BVH_BUILD_STATE_PROCESSED && model1.build_state != BVH_BUILD_STATE_UPDATED) 00048 { 00049 std::cerr << "BVH Error: Must finish BVH model construction before call distance()!" << std::endl; 00050 return BVH_ERR_BUILD_OUT_OF_SEQUENCE; 00051 } 00052 00053 if(model2.build_state != BVH_BUILD_STATE_PROCESSED && model2.build_state != BVH_BUILD_STATE_UPDATED) 00054 { 00055 std::cerr << "BVH Error: Must finish BVH model construction before call distance()!" << std::endl; 00056 return BVH_ERR_BUILD_OUT_OF_SEQUENCE; 00057 } 00058 00059 // currently only support the mesh-mesh collision 00060 if(model1.getModelType() != BVH_MODEL_TRIANGLES || model2.getModelType()!= BVH_MODEL_TRIANGLES) 00061 { 00062 std::cerr << "BVH Error: Distance query only supported between two triangle models." << std::endl; 00063 return BVH_ERR_UNSUPPORTED_FUNCTION; 00064 } 00065 00066 00067 res->resetRecord(); 00068 00069 // compute the transform from 1 to 2 00070 Vec3f R1_col[3]; 00071 R1_col[0] = Vec3f(R1[0][0], R1[1][0], R1[2][0]); 00072 R1_col[1] = Vec3f(R1[0][1], R1[1][1], R1[2][1]); 00073 R1_col[2] = Vec3f(R1[0][2], R1[1][2], R1[2][2]); 00074 00075 Vec3f R2_col[3]; 00076 R2_col[0] = Vec3f(R2[0][0], R2[1][0], R2[2][0]); 00077 R2_col[1] = Vec3f(R2[0][1], R2[1][1], R2[2][1]); 00078 R2_col[2] = Vec3f(R2[0][2], R2[1][2], R2[2][2]); 00079 00080 Vec3f R[3]; 00081 R[0] = Vec3f(R1_col[0].dot(R2_col[0]), R1_col[0].dot(R2_col[1]), R1_col[0].dot(R2_col[2])); 00082 R[1] = Vec3f(R1_col[1].dot(R2_col[0]), R1_col[1].dot(R2_col[1]), R1_col[1].dot(R2_col[2])); 00083 R[2] = Vec3f(R1_col[2].dot(R2_col[0]), R1_col[2].dot(R2_col[1]), R1_col[2].dot(R2_col[2])); 00084 00085 Vec3f Ttemp = T2 - T1; 00086 Vec3f T(R1_col[0].dot(Ttemp), R1_col[1].dot(Ttemp), R1_col[2].dot(Ttemp)); 00087 00088 00089 if(res->last_tri_id1 >= model1.num_tris) 00090 { 00091 std::cerr << "BVH Error: last_tri_id1 out of bound." << std::endl; 00092 return BVH_ERR_UNKNOWN; 00093 } 00094 00095 if(res->last_tri_id2 >= model2.num_tris) 00096 { 00097 std::cerr << "BVH Error: last_tri_id2 out of bound." << std::endl; 00098 return BVH_ERR_UNKNOWN; 00099 } 00100 00101 Triangle last_tri1 = model1.tri_indices[res->last_tri_id1]; 00102 Triangle last_tri2 = model2.tri_indices[res->last_tri_id2]; 00103 00104 Vec3f last_tri1_points[3]; 00105 Vec3f last_tri2_points[3]; 00106 00107 last_tri1_points[0] = model1.vertices[last_tri1[0]]; 00108 last_tri1_points[1] = model1.vertices[last_tri1[1]]; 00109 last_tri1_points[2] = model1.vertices[last_tri1[2]]; 00110 00111 last_tri2_points[0] = model2.vertices[last_tri2[0]]; 00112 last_tri2_points[1] = model2.vertices[last_tri2[1]]; 00113 last_tri2_points[2] = model2.vertices[last_tri2[2]]; 00114 00115 00116 Vec3f last_tri_P, last_tri_Q; 00117 00118 res->distance = TriangleDistance::triDistance(last_tri1_points[0], last_tri1_points[1], last_tri1_points[2], 00119 last_tri2_points[0], last_tri2_points[1], last_tri2_points[2], 00120 R, T, last_tri_P, last_tri_Q); 00121 res->p1 = last_tri_P; 00122 res->p2 = last_tri_Q; 00123 00124 if(res->qsize <= 2) 00125 { 00126 distanceRecurse(model1.bvs, model2.bvs, R, T, 0, 0, model1.vertices, model2.vertices, model1.tri_indices, model2.tri_indices, res, front_list); 00127 } 00128 else 00129 { 00130 distanceQueueRecurse(model1.bvs, model2.bvs, R, T, 0, 0, model1.vertices, model2.vertices, model1.tri_indices, model2.tri_indices, res, front_list); 00131 } 00132 00133 // change res->p2 to coordinate system of model2 00134 00135 Vec3f u = res->p2 - T; 00136 res->p2 = MTxV(R, u); 00137 00138 return BVH_OK; 00139 00140 } 00141 00142 00143 }