Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMMATH_COLLISION_DETECTION_ALGORITHM_H_ 00002 #define SimTK_SIMMATH_COLLISION_DETECTION_ALGORITHM_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKmath * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2008-12 Stanford University and the Authors. * 00013 * Authors: Peter Eastman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 #include "SimTKcommon.h" 00028 #include "simmath/internal/common.h" 00029 #include "simmath/internal/ContactGeometry.h" 00030 #include "simmath/internal/Contact.h" 00031 00032 #include <map> 00033 00034 namespace SimTK { 00035 00043 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm { 00044 public: 00045 class HalfSpaceSphere; 00046 class SphereSphere; 00047 class HalfSpaceEllipsoid; 00048 class HalfSpaceTriangleMesh; 00049 class SphereTriangleMesh; 00050 class TriangleMeshTriangleMesh; 00051 class ConvexConvex; 00052 virtual ~CollisionDetectionAlgorithm() {} 00068 virtual void processObjects 00069 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00070 const Transform& transform1, 00071 ContactSurfaceIndex index2, const ContactGeometry& object2, 00072 const Transform& transform2, 00073 Array_<Contact>& contacts) const = 0; 00084 static void registerAlgorithm(ContactGeometryTypeId type1, 00085 ContactGeometryTypeId type2, 00086 CollisionDetectionAlgorithm* algorithm); 00096 static CollisionDetectionAlgorithm* 00097 getAlgorithm(ContactGeometryTypeId type1, ContactGeometryTypeId type2); 00098 private: 00099 struct AlgorithmMap 00100 : public std::map<std::pair<ContactGeometryTypeId, ContactGeometryTypeId>, 00101 CollisionDetectionAlgorithm*> 00102 { 00103 ~AlgorithmMap(); 00104 }; 00105 00106 static AlgorithmMap algorithmMap; 00107 }; 00108 00113 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::HalfSpaceSphere 00114 : public CollisionDetectionAlgorithm { 00115 public: 00116 virtual ~HalfSpaceSphere() {} 00117 void processObjects 00118 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00119 const Transform& transform1, 00120 ContactSurfaceIndex index2, const ContactGeometry& object2, 00121 const Transform& transform2, 00122 Array_<Contact>& contacts) const; 00123 }; 00124 00129 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::HalfSpaceEllipsoid 00130 : public CollisionDetectionAlgorithm { 00131 public: 00132 virtual ~HalfSpaceEllipsoid() {} 00133 void processObjects 00134 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00135 const Transform& transform1, 00136 ContactSurfaceIndex index2, const ContactGeometry& object2, 00137 const Transform& transform2, 00138 Array_<Contact>& contacts) const; 00139 }; 00140 00144 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::SphereSphere 00145 : public CollisionDetectionAlgorithm { 00146 public: 00147 virtual ~SphereSphere() {} 00148 void processObjects 00149 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00150 const Transform& transform1, 00151 ContactSurfaceIndex index2, const ContactGeometry& object2, 00152 const Transform& transform2, 00153 Array_<Contact>& contacts) const; 00154 }; 00155 00160 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::HalfSpaceTriangleMesh 00161 : public CollisionDetectionAlgorithm { 00162 public: 00163 virtual ~HalfSpaceTriangleMesh() {} 00164 void processObjects 00165 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00166 const Transform& transform1, 00167 ContactSurfaceIndex index2, const ContactGeometry& object2, 00168 const Transform& transform2, 00169 Array_<Contact>& contacts) const; 00170 private: 00171 void processBox(const ContactGeometry::TriangleMesh& mesh, 00172 const ContactGeometry::TriangleMesh::OBBTreeNode& node, 00173 const Transform& transform, const Vec3& axisDir, 00174 Real xoffset, std::set<int>& insideFaces) const; 00175 void addAllTriangles(const ContactGeometry::TriangleMesh::OBBTreeNode& node, 00176 std::set<int>& insideFaces) const; 00177 }; 00178 00183 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::SphereTriangleMesh 00184 : public CollisionDetectionAlgorithm { 00185 public: 00186 virtual ~SphereTriangleMesh() {} 00187 void processObjects 00188 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00189 const Transform& transform1, 00190 ContactSurfaceIndex index2, const ContactGeometry& object2, 00191 const Transform& transform2, 00192 Array_<Contact>& contacts) const; 00193 private: 00194 void processBox(const Vec3& center, Real radius2, 00195 const ContactGeometry::TriangleMesh& mesh, 00196 const ContactGeometry::TriangleMesh::OBBTreeNode& node, 00197 std::set<int>& insideFaces) const; 00198 }; 00199 00204 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::TriangleMeshTriangleMesh 00205 : public CollisionDetectionAlgorithm { 00206 public: 00207 virtual ~TriangleMeshTriangleMesh() {} 00208 void processObjects 00209 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00210 const Transform& transform1, 00211 ContactSurfaceIndex index2, const ContactGeometry& object2, 00212 const Transform& transform2, 00213 Array_<Contact>& contacts) const; 00214 private: 00215 void processNodes(const ContactGeometry::TriangleMesh& mesh1, 00216 const ContactGeometry::TriangleMesh& mesh2, 00217 const ContactGeometry::TriangleMesh::OBBTreeNode& node1, 00218 const ContactGeometry::TriangleMesh::OBBTreeNode& node2, 00219 const OrientedBoundingBox& node2Bounds, 00220 const Transform& transform, std::set<int>& triangles1, 00221 std::set<int>& triangles2) const; 00222 void findInsideTriangles(const ContactGeometry::TriangleMesh& mesh, 00223 const ContactGeometry::TriangleMesh& otherMesh, 00224 const Transform& transform, 00225 std::set<int>& triangles) const; 00226 void tagFaces(const ContactGeometry::TriangleMesh& mesh, 00227 Array_<int>& faceType, std::set<int>& triangles, 00228 int index, int depth) const; 00229 static const int OUTSIDE = -1; 00230 static const int UNKNOWN = 0; 00231 static const int BOUNDARY = 1; 00232 static const int INSIDE = 2; 00233 }; 00234 00238 class SimTK_SIMMATH_EXPORT CollisionDetectionAlgorithm::ConvexConvex 00239 : public CollisionDetectionAlgorithm { 00240 public: 00241 virtual ~ConvexConvex() {} 00242 void processObjects 00243 (ContactSurfaceIndex index1, const ContactGeometry& object1, 00244 const Transform& transform1, 00245 ContactSurfaceIndex index2, const ContactGeometry& object2, 00246 const Transform& transform2, 00247 Array_<Contact>& contacts) const; 00248 private: 00249 static Vec3 computeSupport(const ContactGeometry& object1, 00250 const ContactGeometry& object2, 00251 const Transform& transform, UnitVec3 direction); 00252 static void addContact 00253 (ContactSurfaceIndex index1, ContactSurfaceIndex index2, 00254 const ContactGeometry& object1, 00255 const ContactGeometry& object2, 00256 const Transform& transform1, const Transform& transform2, 00257 const Transform& transform12, 00258 Vec3 point1, Vec3 point2, Array_<Contact>& contacts); 00259 static Vec6 computeErrorVector(const ContactGeometry& object1, 00260 const ContactGeometry& object2, 00261 Vec3 pos1, Vec3 pos2, 00262 const Transform& transform12); 00263 static Mat66 computeJacobian(const ContactGeometry& object1, 00264 const ContactGeometry& object2, 00265 Vec3 pos1, Vec3 pos2, 00266 const Transform& transform12); 00267 }; 00268 00269 } // namespace SimTK 00270 00271 #endif // SimTK_SIMMATH_COLLISION_DETECTION_ALGORITHM_H_