Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMMATH_CONTACT_H_ 00002 #define SimTK_SIMMATH_CONTACT_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, Michael Sherman * 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 00030 namespace SimTK { 00031 00032 00037 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactSurfaceIndex); 00038 00048 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactId); 00049 00056 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactTypeId); 00057 00058 00059 class ContactImpl; 00060 class UntrackedContactImpl; 00061 class BrokenContactImpl; 00062 class CircularPointContactImpl; 00063 class EllipticalPointContactImpl; 00064 class TriangleMeshContactImpl; 00065 class PointContactImpl; 00066 00067 00068 //============================================================================== 00069 // CONTACT 00070 //============================================================================== 00081 class SimTK_SIMMATH_EXPORT Contact { 00082 public: 00085 enum Condition { 00086 Unknown, 00087 Untracked, 00088 Anticipated, 00089 NewContact, 00090 Ongoing, 00091 Broken 00092 }; 00096 static const char* nameOfCondition(Condition); 00097 00099 Contact() : impl(0) {} 00102 Contact(const Contact& source); 00105 ~Contact() {clear();} 00108 Contact& operator=(const Contact& source); 00111 void clear(); 00113 bool isEmpty() const {return impl==0;} 00114 00118 ContactId getContactId() const; 00120 Condition getCondition() const; 00123 ContactSurfaceIndex getSurface1() const; 00126 ContactSurfaceIndex getSurface2() const; 00130 const Transform& getTransform() const; 00131 00134 Contact& setContactId(ContactId id); 00136 Contact& setCondition(Condition condition); 00138 Contact& setSurfaces(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2); 00140 Contact& setTransform(const Transform& X_S1S2); 00141 00144 ContactTypeId getTypeId() const; 00145 00149 static ContactId createNewContactId(); 00150 00151 const ContactImpl& getImpl() const {assert(impl); return *impl;} 00152 ContactImpl& updImpl() {assert(impl); return *impl;} 00153 protected: 00154 explicit Contact(ContactImpl* impl); 00155 private: 00156 ContactImpl* impl; 00157 }; 00158 00159 inline std::ostream& operator<<(std::ostream& o, const Contact& c) { 00160 o << "Contact id=" << c.getContactId() 00161 << " (typeId=" << c.getTypeId() << "):\n"; 00162 o << " surf1,surf2=" << c.getSurface1() << "," 00163 << c.getSurface2() << "\n"; 00164 o << " condition=" << Contact::nameOfCondition(c.getCondition()) << "\n"; 00165 return o; 00166 } 00167 00168 00169 00170 //============================================================================== 00171 // UNTRACKED CONTACT 00172 //============================================================================== 00178 class SimTK_SIMMATH_EXPORT UntrackedContact : public Contact { 00179 public: 00181 UntrackedContact() {} 00187 UntrackedContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2); 00188 00190 static bool isInstance(const Contact& contact); 00192 static ContactTypeId classTypeId(); 00193 00194 private: 00195 const UntrackedContactImpl& getImpl() const 00196 { assert(isInstance(*this)); 00197 return reinterpret_cast<const UntrackedContactImpl&> 00198 (Contact::getImpl()); } 00199 }; 00200 00201 00202 00203 //============================================================================== 00204 // BROKEN CONTACT 00205 //============================================================================== 00212 class SimTK_SIMMATH_EXPORT BrokenContact : public Contact { 00213 public: 00220 BrokenContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00221 const Transform& X_S1S2, Real separation); 00222 00226 Real getSeparation() const; 00227 00229 static bool isInstance(const Contact& contact); 00231 static ContactTypeId classTypeId(); 00232 00233 private: 00234 const BrokenContactImpl& getImpl() const 00235 { assert(isInstance(*this)); 00236 return reinterpret_cast<const BrokenContactImpl&>(Contact::getImpl()); } 00237 }; 00238 00239 00240 00241 //============================================================================== 00242 // CIRCULAR POINT CONTACT 00243 //============================================================================== 00256 class SimTK_SIMMATH_EXPORT CircularPointContact : public Contact { 00257 public: 00272 CircularPointContact 00273 (ContactSurfaceIndex surf1, Real radius1, 00274 ContactSurfaceIndex surf2, Real radius2, 00275 const Transform& X_S1S2, Real radius, Real depth, 00276 const Vec3& origin_S1, const UnitVec3& normal_S1); 00277 00279 Real getRadius1() const; 00281 Real getRadius2() const; 00284 Real getEffectiveRadius() const; 00289 Real getDepth() const; 00291 const Vec3& getOrigin() const; 00295 const UnitVec3& getNormal() const; 00296 00298 static bool isInstance(const Contact& contact); 00299 static const CircularPointContact& getAs(const Contact& contact) 00300 { assert(isInstance(contact)); 00301 return static_cast<const CircularPointContact&>(contact); } 00302 static CircularPointContact& updAs(Contact& contact) 00303 { assert(isInstance(contact)); 00304 return static_cast<CircularPointContact&>(contact); } 00305 00307 static ContactTypeId classTypeId(); 00308 00309 private: 00310 const CircularPointContactImpl& getImpl() const 00311 { assert(isInstance(*this)); 00312 return reinterpret_cast<const CircularPointContactImpl&> 00313 (Contact::getImpl()); } 00314 }; 00315 00316 00317 00318 //============================================================================== 00319 // ELLIPTICAL POINT CONTACT 00320 //============================================================================== 00351 class SimTK_SIMMATH_EXPORT EllipticalPointContact : public Contact { 00352 public: 00366 EllipticalPointContact 00367 (ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00368 const Transform& X_S1S2, 00369 const Transform& X_S1C, const Vec2& k, Real depth); 00370 00373 const Vec2& getCurvatures() const; 00380 const Transform& getContactFrame() const; 00385 Real getDepth() const; 00386 00388 static bool isInstance(const Contact& contact); 00389 static const EllipticalPointContact& getAs(const Contact& contact) 00390 { assert(isInstance(contact)); 00391 return static_cast<const EllipticalPointContact&>(contact); } 00392 static EllipticalPointContact& updAs(Contact& contact) 00393 { assert(isInstance(contact)); 00394 return static_cast<EllipticalPointContact&>(contact); } 00395 00397 static ContactTypeId classTypeId(); 00398 00399 private: 00400 const EllipticalPointContactImpl& getImpl() const 00401 { assert(isInstance(*this)); 00402 return reinterpret_cast<const EllipticalPointContactImpl&> 00403 (Contact::getImpl()); } 00404 }; 00405 00406 00407 00408 00409 //============================================================================== 00410 // TRIANGLE MESH CONTACT 00411 //============================================================================== 00415 class SimTK_SIMMATH_EXPORT TriangleMeshContact : public Contact { 00416 public: 00428 TriangleMeshContact(ContactSurfaceIndex surf1, 00429 ContactSurfaceIndex surf2, 00430 const Transform& X_S1S2, 00431 const std::set<int>& faces1, 00432 const std::set<int>& faces2); 00433 00437 const std::set<int>& getSurface1Faces() const; 00441 const std::set<int>& getSurface2Faces() const; 00442 00444 static bool isInstance(const Contact& contact); 00447 static const TriangleMeshContact& getAs(const Contact& contact) 00448 { assert(isInstance(contact)); 00449 return static_cast<const TriangleMeshContact&>(contact); } 00452 static TriangleMeshContact& updAs(Contact& contact) 00453 { assert(isInstance(contact)); 00454 return static_cast<TriangleMeshContact&>(contact); } 00455 00458 static ContactTypeId classTypeId(); 00459 00460 private: 00461 const TriangleMeshContactImpl& getImpl() const 00462 { assert(isInstance(*this)); 00463 return reinterpret_cast<const TriangleMeshContactImpl&> 00464 (Contact::getImpl()); } 00465 }; 00466 00467 00468 00469 00470 //============================================================================== 00471 // POINT CONTACT 00472 //============================================================================== 00479 class SimTK_SIMMATH_EXPORT PointContact : public Contact { 00480 public: 00497 PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00498 Vec3& location, Vec3& normal, Real radius1, Real radius2, Real depth); 00514 PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00515 Vec3& location, Vec3& normal, Real radius, Real depth); 00521 Vec3 getLocation() const; 00526 Vec3 getNormal() const; 00530 Real getRadiusOfCurvature1() const; 00534 Real getRadiusOfCurvature2() const; 00539 Real getEffectiveRadiusOfCurvature() const; 00545 Real getDepth() const; 00549 static bool isInstance(const Contact& contact); 00553 static ContactTypeId classTypeId(); 00554 00555 private: 00556 const PointContactImpl& getImpl() const 00557 { assert(isInstance(*this)); 00558 return reinterpret_cast<const PointContactImpl&>(Contact::getImpl()); } 00559 }; 00560 00561 } // namespace SimTK 00562 00563 #endif // SimTK_SIMMATH_CONTACT_H_