ContactImpl.h

Go to the documentation of this file.
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 //                            TRIANGLE MESH IMPL
00182 //==============================================================================
00184 class TriangleMeshContactImpl : public ContactImpl {
00185 public:
00186     TriangleMeshContactImpl(ContactSurfaceIndex     surf1, 
00187                             ContactSurfaceIndex     surf2,
00188                             const Transform&        X_S1S2,
00189                             const std::set<int>&    faces1, 
00190                             const std::set<int>&    faces2);
00191 
00192     ContactTypeId getTypeId() const {return classTypeId();}
00193     static ContactTypeId classTypeId() {
00194         static const ContactTypeId tid = createNewContactTypeId();
00195         return tid;
00196     }
00197 
00198 private:
00199 friend class TriangleMeshContact;
00200 
00201     const std::set<int> faces1;
00202     const std::set<int> faces2;
00203 };
00204 
00205 
00206 
00207 //==============================================================================
00208 //                        POINT CONTACT IMPL (OBSOLETE)
00209 //==============================================================================
00211 class PointContactImpl : public ContactImpl {
00212 public:
00213     PointContactImpl(ContactSurfaceIndex surf1, ContactSurfaceIndex surf2, 
00214                      Vec3& location, Vec3& normal, Real radius, Real depth);
00215 
00216     ContactTypeId getTypeId() const {return classTypeId();}
00217     static ContactTypeId classTypeId() {
00218         static const ContactTypeId tid = createNewContactTypeId();
00219         return tid;
00220     }
00221 
00222 private:
00223 friend class PointContact;
00224 
00225     Vec3 location, normal;
00226     Real radius, depth;
00227 };
00228 
00229 
00230 
00231 } // namespace SimTK
00232 
00233 #endif // SimTK_SIMBODY_CONTACT_IMPL_H_

Generated on Thu Aug 12 16:37:06 2010 for SimTKcore by  doxygen 1.6.1