Simbody
|
00001 #ifndef SimTK_SIMBODY_CONTACT_IMPL_H_ 00002 #define SimTK_SIMBODY_CONTACT_IMPL_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simbody(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core 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. * 00011 * * 00012 * Portions copyright (c) 2008-10 Stanford University and the Authors. * 00013 * Authors: Peter Eastman * 00014 * Contributors: Michael Sherman * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00035 #include "simbody/internal/Contact.h" 00036 00037 namespace SimTK { 00038 00039 00040 //============================================================================== 00041 // CONTACT IMPL 00042 //============================================================================== 00044 class ContactImpl { 00045 public: 00046 ContactImpl(ContactSurfaceIndex surf1, 00047 ContactSurfaceIndex surf2, 00048 Contact::Condition condition=Contact::Unknown) 00049 : m_referenceCount(0), m_condition(condition), 00050 m_id(), m_surf1(surf1), m_surf2(surf2), m_X_S1S2() {} 00051 00052 ContactImpl(ContactSurfaceIndex surf1, 00053 ContactSurfaceIndex surf2, 00054 const Transform& X_S1S2, 00055 Contact::Condition condition=Contact::Unknown) 00056 : m_referenceCount(0), m_condition(condition), 00057 m_id(), m_surf1(surf1), m_surf2(surf2), m_X_S1S2(X_S1S2) {} 00058 00059 void setTransform(const Transform& X_S1S2) {m_X_S1S2 = X_S1S2;} 00060 const Transform& getTransform() const {return m_X_S1S2;} 00061 00062 void setCondition(Contact::Condition cond) {m_condition=cond;} 00063 Contact::Condition getCondition() const {return m_condition;} 00064 00065 void setContactId(ContactId id) {m_id=id;} 00066 ContactId getContactId() const {return m_id;} 00067 00068 virtual ~ContactImpl() { 00069 assert(m_referenceCount == 0); 00070 } 00071 virtual ContactTypeId getTypeId() const = 0; 00072 00073 /* Create a new ContactTypeId and return this unique small integer 00074 (thread safe). Each distinct type of Contact should use this to 00075 initialize a static variable for that concrete class. */ 00076 static ContactTypeId createNewContactTypeId() 00077 { static AtomicInteger nextAvailableId = 1; 00078 return ContactTypeId(nextAvailableId++); } 00079 00080 00081 /* Create a new ContactId and return this unique integer 00082 (thread safe). Each distinct type of Contact should use this to 00083 initialize a static variable for that concrete class. This will 00084 roll over at approximately 1 billion. */ 00085 static ContactId createNewContactId() 00086 { static AtomicInteger nextAvailableId = 1; 00087 const int MaxContactId = 999999999; // 1 billion-1 00088 const int id = nextAvailableId++; 00089 // Other threads might get a few more high-numbered ids here before 00090 // we reset the next available to 1, but since only one thread gets 00091 // exactly MaxContactId as its id, only one will execute the reset. 00092 if (id == MaxContactId) 00093 nextAvailableId = 1; 00094 return ContactId(id); } 00095 00096 protected: 00097 friend class Contact; 00098 00099 mutable int m_referenceCount; 00100 Contact::Condition m_condition; 00101 ContactId m_id; 00102 ContactSurfaceIndex m_surf1, 00103 m_surf2; 00104 Transform m_X_S1S2; 00105 }; 00106 00107 00108 00109 //============================================================================== 00110 // UNTRACKED CONTACT IMPL 00111 //============================================================================== 00113 class UntrackedContactImpl : public ContactImpl { 00114 public: 00115 UntrackedContactImpl(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2) 00116 : ContactImpl(surf1, surf2, Contact::Untracked) {} 00117 00118 ContactTypeId getTypeId() const {return classTypeId();} 00119 static ContactTypeId classTypeId() { 00120 static const ContactTypeId tid = createNewContactTypeId(); 00121 return tid; 00122 } 00123 }; 00124 00125 00126 //============================================================================== 00127 // BROKEN CONTACT IMPL 00128 //============================================================================== 00130 class BrokenContactImpl : public ContactImpl { 00131 public: 00132 BrokenContactImpl 00133 (ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00134 const Transform& X_S1S2, Real separation) 00135 : ContactImpl(surf1, surf2, X_S1S2), separation(separation) {} 00136 00137 ContactTypeId getTypeId() const {return classTypeId();} 00138 static ContactTypeId classTypeId() { 00139 static const ContactTypeId tid = createNewContactTypeId(); 00140 return tid; 00141 } 00142 00143 private: 00144 friend class BrokenContact; 00145 Real separation; 00146 }; 00147 00148 00149 00150 //============================================================================== 00151 // CIRCULAR POINT CONTACT IMPL 00152 //============================================================================== 00154 class CircularPointContactImpl : public ContactImpl { 00155 public: 00156 CircularPointContactImpl 00157 (ContactSurfaceIndex surf1, Real radius1, 00158 ContactSurfaceIndex surf2 ,Real radius2, 00159 const Transform& X_S1S2, Real radiusEff, Real depth, 00160 const Vec3& origin_S1, const UnitVec3& normal_S1) 00161 : ContactImpl(surf1, surf2, X_S1S2), 00162 radius1(radius1), radius2(radius2), radiusEff(radiusEff), 00163 depth(depth), origin_S1(origin_S1), normal_S1(normal_S1) {} 00164 00165 ContactTypeId getTypeId() const {return classTypeId();} 00166 static ContactTypeId classTypeId() { 00167 static const ContactTypeId tid = createNewContactTypeId(); 00168 return tid; 00169 } 00170 00171 private: 00172 friend class CircularPointContact; 00173 Real radius1, radius2, radiusEff, depth; 00174 Vec3 origin_S1; 00175 UnitVec3 normal_S1; 00176 }; 00177 00178 00179 00180 //============================================================================== 00181 // ELLIPTICAL POINT CONTACT IMPL 00182 //============================================================================== 00184 class EllipticalPointContactImpl : public ContactImpl { 00185 public: 00186 EllipticalPointContactImpl 00187 (ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00188 const Transform& X_S1S2, const Transform& X_S1C, 00189 const Vec2& k, Real depth) 00190 : ContactImpl(surf1, surf2, X_S1S2), 00191 X_S1C(X_S1C), k(k), depth(depth) {} 00192 00193 ContactTypeId getTypeId() const {return classTypeId();} 00194 static ContactTypeId classTypeId() { 00195 static const ContactTypeId tid = createNewContactTypeId(); 00196 return tid; 00197 } 00198 00199 private: 00200 friend class EllipticalPointContact; 00201 Transform X_S1C; 00202 Vec2 k; // kmax, kmin 00203 Real depth; 00204 }; 00205 00206 00207 00208 //============================================================================== 00209 // TRIANGLE MESH IMPL 00210 //============================================================================== 00212 class TriangleMeshContactImpl : public ContactImpl { 00213 public: 00214 TriangleMeshContactImpl(ContactSurfaceIndex surf1, 00215 ContactSurfaceIndex surf2, 00216 const Transform& X_S1S2, 00217 const std::set<int>& faces1, 00218 const std::set<int>& faces2); 00219 00220 ContactTypeId getTypeId() const {return classTypeId();} 00221 static ContactTypeId classTypeId() { 00222 static const ContactTypeId tid = createNewContactTypeId(); 00223 return tid; 00224 } 00225 00226 private: 00227 friend class TriangleMeshContact; 00228 00229 const std::set<int> faces1; 00230 const std::set<int> faces2; 00231 }; 00232 00233 00234 00235 //============================================================================== 00236 // POINT CONTACT IMPL 00237 //============================================================================== 00239 class PointContactImpl : public ContactImpl { 00240 public: 00241 PointContactImpl(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00242 Vec3& location, Vec3& normal, Real radius1, Real radius2, Real depth); 00243 PointContactImpl(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00244 Vec3& location, Vec3& normal, Real radius, Real depth); 00245 00246 ContactTypeId getTypeId() const {return classTypeId();} 00247 static ContactTypeId classTypeId() { 00248 static const ContactTypeId tid = createNewContactTypeId(); 00249 return tid; 00250 } 00251 00252 private: 00253 friend class PointContact; 00254 00255 Vec3 location, normal; 00256 Real radius1, radius2, effectiveRadius, depth; 00257 }; 00258 00259 00260 00261 } // namespace SimTK 00262 00263 #endif // SimTK_SIMBODY_CONTACT_IMPL_H_