Simbody
3.5
|
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 BrickHalfSpaceContactImpl; 00065 class TriangleMeshContactImpl; 00066 00067 class PointContactImpl; // deprecated 00068 00069 00070 //============================================================================== 00071 // CONTACT 00072 //============================================================================== 00083 class SimTK_SIMMATH_EXPORT Contact { 00084 public: 00087 enum Condition { 00088 Unknown, 00089 Untracked, 00090 Anticipated, 00091 NewContact, 00092 Ongoing, 00093 Broken 00094 }; 00098 static const char* nameOfCondition(Condition); 00099 00101 Contact() : impl(0) {} 00104 Contact(const Contact& source); 00107 ~Contact() {clear();} 00110 Contact& operator=(const Contact& source); 00113 void clear(); 00115 bool isEmpty() const {return impl==0;} 00116 00120 ContactId getContactId() const; 00122 Condition getCondition() const; 00125 ContactSurfaceIndex getSurface1() const; 00128 ContactSurfaceIndex getSurface2() const; 00132 const Transform& getTransform() const; 00133 00136 Contact& setContactId(ContactId id); 00138 Contact& setCondition(Condition condition); 00140 Contact& setSurfaces(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2); 00142 Contact& setTransform(const Transform& X_S1S2); 00143 00146 ContactTypeId getTypeId() const; 00147 00151 static ContactId createNewContactId(); 00152 00153 const ContactImpl& getImpl() const {assert(impl); return *impl;} 00154 ContactImpl& updImpl() {assert(impl); return *impl;} 00155 protected: 00156 explicit Contact(ContactImpl* impl); 00157 private: 00158 ContactImpl* impl; 00159 }; 00160 00161 inline std::ostream& operator<<(std::ostream& o, const Contact& c) { 00162 o << "Contact id=" << c.getContactId() 00163 << " (typeId=" << c.getTypeId() << "):\n"; 00164 o << " surf1,surf2=" << c.getSurface1() << "," 00165 << c.getSurface2() << "\n"; 00166 o << " condition=" << Contact::nameOfCondition(c.getCondition()) << "\n"; 00167 return o; 00168 } 00169 00170 00171 00172 //============================================================================== 00173 // UNTRACKED CONTACT 00174 //============================================================================== 00180 class SimTK_SIMMATH_EXPORT UntrackedContact : public Contact { 00181 public: 00183 UntrackedContact() {} 00189 UntrackedContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2); 00190 00192 static bool isInstance(const Contact& contact); 00194 static ContactTypeId classTypeId(); 00195 00196 private: 00197 const UntrackedContactImpl& getImpl() const 00198 { assert(isInstance(*this)); 00199 return reinterpret_cast<const UntrackedContactImpl&> 00200 (Contact::getImpl()); } 00201 }; 00202 00203 00204 00205 //============================================================================== 00206 // BROKEN CONTACT 00207 //============================================================================== 00214 class SimTK_SIMMATH_EXPORT BrokenContact : public Contact { 00215 public: 00222 BrokenContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00223 const Transform& X_S1S2, Real separation); 00224 00228 Real getSeparation() const; 00229 00231 static bool isInstance(const Contact& contact); 00233 static ContactTypeId classTypeId(); 00234 00235 private: 00236 const BrokenContactImpl& getImpl() const 00237 { assert(isInstance(*this)); 00238 return reinterpret_cast<const BrokenContactImpl&>(Contact::getImpl()); } 00239 }; 00240 00241 00242 00243 //============================================================================== 00244 // CIRCULAR POINT CONTACT 00245 //============================================================================== 00258 class SimTK_SIMMATH_EXPORT CircularPointContact : public Contact { 00259 public: 00274 CircularPointContact 00275 (ContactSurfaceIndex surf1, Real radius1, 00276 ContactSurfaceIndex surf2, Real radius2, 00277 const Transform& X_S1S2, Real radius, Real depth, 00278 const Vec3& origin_S1, const UnitVec3& normal_S1); 00279 00281 Real getRadius1() const; 00283 Real getRadius2() const; 00286 Real getEffectiveRadius() const; 00291 Real getDepth() const; 00293 const Vec3& getOrigin() const; 00297 const UnitVec3& getNormal() const; 00298 00300 static bool isInstance(const Contact& contact); 00301 static const CircularPointContact& getAs(const Contact& contact) 00302 { assert(isInstance(contact)); 00303 return static_cast<const CircularPointContact&>(contact); } 00304 static CircularPointContact& updAs(Contact& contact) 00305 { assert(isInstance(contact)); 00306 return static_cast<CircularPointContact&>(contact); } 00307 00309 static ContactTypeId classTypeId(); 00310 00311 private: 00312 const CircularPointContactImpl& getImpl() const 00313 { assert(isInstance(*this)); 00314 return reinterpret_cast<const CircularPointContactImpl&> 00315 (Contact::getImpl()); } 00316 }; 00317 00318 00319 00320 //============================================================================== 00321 // ELLIPTICAL POINT CONTACT 00322 //============================================================================== 00353 class SimTK_SIMMATH_EXPORT EllipticalPointContact : public Contact { 00354 public: 00368 EllipticalPointContact 00369 (ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00370 const Transform& X_S1S2, 00371 const Transform& X_S1C, const Vec2& k, Real depth); 00372 00375 const Vec2& getCurvatures() const; 00382 const Transform& getContactFrame() const; 00387 Real getDepth() const; 00388 00390 static bool isInstance(const Contact& contact); 00391 static const EllipticalPointContact& getAs(const Contact& contact) 00392 { assert(isInstance(contact)); 00393 return static_cast<const EllipticalPointContact&>(contact); } 00394 static EllipticalPointContact& updAs(Contact& contact) 00395 { assert(isInstance(contact)); 00396 return static_cast<EllipticalPointContact&>(contact); } 00397 00399 static ContactTypeId classTypeId(); 00400 00401 private: 00402 const EllipticalPointContactImpl& getImpl() const 00403 { assert(isInstance(*this)); 00404 return reinterpret_cast<const EllipticalPointContactImpl&> 00405 (Contact::getImpl()); } 00406 }; 00407 00408 00409 00410 //============================================================================== 00411 // BRICK HALFSPACE CONTACT 00412 //============================================================================== 00416 class SimTK_SIMMATH_EXPORT BrickHalfSpaceContact : public Contact { 00417 public: 00428 BrickHalfSpaceContact(ContactSurfaceIndex halfSpace, 00429 ContactSurfaceIndex brick, 00430 const Transform& X_HB, 00431 int lowestVertex, 00432 Real depth); 00433 00436 int getLowestVertex() const; 00437 00440 Real getDepth() const; 00441 00443 static bool isInstance(const Contact& contact); 00444 00447 static const BrickHalfSpaceContact& getAs(const Contact& contact) 00448 { assert(isInstance(contact)); 00449 return static_cast<const BrickHalfSpaceContact&>(contact); } 00450 00453 static BrickHalfSpaceContact& updAs(Contact& contact) 00454 { assert(isInstance(contact)); 00455 return static_cast<BrickHalfSpaceContact&>(contact); } 00456 00459 static ContactTypeId classTypeId(); 00460 00461 private: 00462 const BrickHalfSpaceContactImpl& getImpl() const 00463 { assert(isInstance(*this)); 00464 return reinterpret_cast<const BrickHalfSpaceContactImpl&> 00465 (Contact::getImpl()); } 00466 }; 00467 00468 00469 00470 //============================================================================== 00471 // TRIANGLE MESH CONTACT 00472 //============================================================================== 00476 class SimTK_SIMMATH_EXPORT TriangleMeshContact : public Contact { 00477 public: 00489 TriangleMeshContact(ContactSurfaceIndex surf1, 00490 ContactSurfaceIndex surf2, 00491 const Transform& X_S1S2, 00492 const std::set<int>& faces1, 00493 const std::set<int>& faces2); 00494 00498 const std::set<int>& getSurface1Faces() const; 00502 const std::set<int>& getSurface2Faces() const; 00503 00505 static bool isInstance(const Contact& contact); 00508 static const TriangleMeshContact& getAs(const Contact& contact) 00509 { assert(isInstance(contact)); 00510 return static_cast<const TriangleMeshContact&>(contact); } 00513 static TriangleMeshContact& updAs(Contact& contact) 00514 { assert(isInstance(contact)); 00515 return static_cast<TriangleMeshContact&>(contact); } 00516 00519 static ContactTypeId classTypeId(); 00520 00521 private: 00522 const TriangleMeshContactImpl& getImpl() const 00523 { assert(isInstance(*this)); 00524 return reinterpret_cast<const TriangleMeshContactImpl&> 00525 (Contact::getImpl()); } 00526 }; 00527 00528 00529 00530 00531 //============================================================================== 00532 // POINT CONTACT 00533 //============================================================================== 00540 class SimTK_SIMMATH_EXPORT PointContact : public Contact { 00541 public: 00558 PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00559 Vec3& location, Vec3& normal, Real radius1, Real radius2, Real depth); 00575 PointContact(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 00576 Vec3& location, Vec3& normal, Real radius, Real depth); 00582 Vec3 getLocation() const; 00587 Vec3 getNormal() const; 00591 Real getRadiusOfCurvature1() const; 00595 Real getRadiusOfCurvature2() const; 00600 Real getEffectiveRadiusOfCurvature() const; 00606 Real getDepth() const; 00610 static bool isInstance(const Contact& contact); 00614 static ContactTypeId classTypeId(); 00615 00616 private: 00617 const PointContactImpl& getImpl() const 00618 { assert(isInstance(*this)); 00619 return reinterpret_cast<const PointContactImpl&>(Contact::getImpl()); } 00620 }; 00621 00622 } // namespace SimTK 00623 00624 #endif // SimTK_SIMMATH_CONTACT_H_