ContactGeometryImpl.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_
00002 #define SimTK_SIMBODY_CONTACT_GEOMETRY_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 
00036 #include "simbody/internal/ContactGeometry.h"
00037 
00038 namespace SimTK {
00039 
00040 //==============================================================================
00041 //                             CONTACT GEOMETRY IMPL
00042 //==============================================================================
00043 class SimTK_SIMBODY_EXPORT ContactGeometryImpl {
00044 public:
00045     ContactGeometryImpl(const std::string& type);
00046     virtual ~ContactGeometryImpl() {
00047         clearMyHandle();
00048     }
00049     const std::string& getType() const {
00050         return type;
00051     }
00052     int getTypeIndex() const {
00053         return typeIndex;
00054     }
00055     static int getIndexForType(std::string type);
00056 
00057     /* Create a new ContactGeometryTypeId and return this unique integer 
00058     (thread safe). Each distinct type of ContactGeometry should use this to
00059     initialize a static variable for that concrete class. */
00060     static ContactGeometryTypeId  createNewContactGeometryTypeId()
00061     {   static AtomicInteger nextAvailableId = 1;
00062         return ContactGeometryTypeId(nextAvailableId++); }
00063 
00064     virtual ContactGeometryTypeId getTypeId() const = 0;
00065 
00066     virtual ContactGeometryImpl* clone() const = 0;
00067     virtual Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const = 0;
00068     virtual bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const = 0;
00069     virtual void getBoundingSphere(Vec3& center, Real& radius) const = 0;
00070     ContactGeometry* getMyHandle() {
00071         return myHandle;
00072     }
00073     void setMyHandle(ContactGeometry& h) {
00074         myHandle = &h;
00075     }
00076     void clearMyHandle() {
00077         myHandle = 0;
00078     }
00079 protected:
00080     ContactGeometry* myHandle;
00081     const std::string& type;
00082     int typeIndex;
00083 };
00084 
00085 
00086 
00087 //==============================================================================
00088 //                             HALF SPACE IMPL
00089 //==============================================================================
00090 class ContactGeometry::HalfSpaceImpl : public ContactGeometryImpl {
00091 public:
00092     HalfSpaceImpl() : ContactGeometryImpl(Type()) {
00093     }
00094     ContactGeometryImpl* clone() const {
00095         return new HalfSpaceImpl();
00096     }
00097 
00098     ContactGeometryTypeId getTypeId() const {return classTypeId();}
00099     static ContactGeometryTypeId classTypeId() {
00100         static const ContactGeometryTypeId id = 
00101             createNewContactGeometryTypeId();
00102         return id;
00103     }
00104 
00105     static const std::string& Type() {
00106         static std::string type = "halfspace";
00107         return type;
00108     }
00109     Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00110     bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00111     void getBoundingSphere(Vec3& center, Real& radius) const;
00112 };
00113 
00114 
00115 
00116 //==============================================================================
00117 //                                SPHERE IMPL
00118 //==============================================================================
00119 class ContactGeometry::SphereImpl : public ContactGeometryImpl {
00120 public:
00121     SphereImpl(Real radius) : ContactGeometryImpl(Type()), radius(radius) {
00122     }
00123     ContactGeometryImpl* clone() const {
00124         return new SphereImpl(radius);
00125     }
00126     Real getRadius() const {
00127         return radius;
00128     }
00129     void setRadius(Real r) {
00130         radius = r;
00131     }
00132 
00133     ContactGeometryTypeId getTypeId() const {return classTypeId();}
00134     static ContactGeometryTypeId classTypeId() {
00135         static const ContactGeometryTypeId id = 
00136             createNewContactGeometryTypeId();
00137         return id;
00138     }
00139 
00140     static const std::string& Type() {
00141         static std::string type = "sphere";
00142         return type;
00143     }
00144     Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00145     bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00146     void getBoundingSphere(Vec3& center, Real& radius) const;
00147 private:
00148     Real radius;
00149 };
00150 
00151 
00152 
00153 //==============================================================================
00154 //                            OBB TREE NODE IMPL
00155 //==============================================================================
00156 class OBBTreeNodeImpl {
00157 public:
00158     OBBTreeNodeImpl() : child1(NULL), child2(NULL) {
00159     }
00160     OBBTreeNodeImpl(const OBBTreeNodeImpl& copy);
00161     ~OBBTreeNodeImpl();
00162     OrientedBoundingBox bounds;
00163     OBBTreeNodeImpl* child1;
00164     OBBTreeNodeImpl* child2;
00165     Array_<int> triangles;
00166     int numTriangles;
00167     Vec3 findNearestPoint(const ContactGeometry::TriangleMeshImpl& mesh, const Vec3& position, Real cutoff2, Real& distance2, int& face, Vec2& uv) const;
00168     bool intersectsRay(const ContactGeometry::TriangleMeshImpl& mesh, const Vec3& origin, const UnitVec3& direction, Real& distance, int& face, Vec2& uv) const;
00169 };
00170 
00171 
00172 
00173 //==============================================================================
00174 //                            TRIANGLE MESH IMPL
00175 //==============================================================================
00176 class ContactGeometry::TriangleMeshImpl : public ContactGeometryImpl {
00177 public:
00178     class Edge;
00179     class Face;
00180     class Vertex;
00181 
00182     TriangleMeshImpl(const ArrayViewConst_<Vec3>& vertexPositions, const ArrayViewConst_<int>& faceIndices, bool smooth);
00183     TriangleMeshImpl(const PolygonalMesh& mesh, bool smooth);
00184     ContactGeometryImpl* clone() const {
00185         return new TriangleMeshImpl(*this);
00186     }
00187 
00188     ContactGeometryTypeId getTypeId() const {return classTypeId();}
00189     static ContactGeometryTypeId classTypeId() {
00190         static const ContactGeometryTypeId id = 
00191             createNewContactGeometryTypeId();
00192         return id;
00193     }
00194 
00195     static const std::string& Type() {
00196         static std::string type = "triangle mesh";
00197         return type;
00198     }
00199     Vec3     findPoint(int face, const Vec2& uv) const;
00200     Vec3     findCentroid(int face) const;
00201     UnitVec3 findNormalAtPoint(int face, const Vec2& uv) const;
00202     Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00203     Vec3 findNearestPoint(const Vec3& position, bool& inside, int& face, Vec2& uv) const;
00204     Vec3 findNearestPointToFace(const Vec3& position, int face, Vec2& uv) const;
00205     bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00206     bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, int& face, Vec2& uv) const;
00207     void getBoundingSphere(Vec3& center, Real& radius) const;
00208 
00209     void createPolygonalMesh(PolygonalMesh& mesh) const;
00210 private:
00211     void init(const Array_<Vec3>& vertexPositions, const Array_<int>& faceIndices);
00212     void createObbTree(OBBTreeNodeImpl& node, const Array_<int>& faceIndices);
00213     void splitObbAxis(const Array_<int>& parentIndices, Array_<int>& child1Indices, Array_<int>& child2Indices, int axis);
00214     void findBoundingSphere(Vec3* point[], int p, int b, Vec3& center, Real& radius);
00215     friend class ContactGeometry::TriangleMesh;
00216     friend class OBBTreeNodeImpl;
00217 
00218     Array_<Edge>    edges;
00219     Array_<Face>    faces;
00220     Array_<Vertex>  vertices;
00221     Vec3            boundingSphereCenter;
00222     Real            boundingSphereRadius;
00223     OBBTreeNodeImpl obb;
00224     bool            smooth;
00225 };
00226 
00227 
00228 
00229 //==============================================================================
00230 //                          TriangleMeshImpl EDGE
00231 //==============================================================================
00232 class ContactGeometry::TriangleMeshImpl::Edge {
00233 public:
00234     Edge(int vert1, int vert2, int face1, int face2) {
00235         vertices[0] = vert1;
00236         vertices[1] = vert2;
00237         faces[0] = face1;
00238         faces[1] = face2;
00239     }
00240     int     vertices[2];
00241     int     faces[2];
00242 };
00243 
00244 
00245 
00246 //==============================================================================
00247 //                           TriangleMeshImpl FACE
00248 //==============================================================================
00249 class ContactGeometry::TriangleMeshImpl::Face {
00250 public:
00251     Face(int vert1, int vert2, int vert3, 
00252          const Vec3& normal, Real area) 
00253     :   normal(normal), area(area) {
00254         vertices[0] = vert1;
00255         vertices[1] = vert2;
00256         vertices[2] = vert3;
00257     }
00258     int         vertices[3];
00259     int         edges[3];
00260     UnitVec3    normal;
00261     Real        area;
00262 };
00263 
00264 
00265 
00266 //==============================================================================
00267 //                          TriangleMeshImpl VERTEX
00268 //==============================================================================
00269 class ContactGeometry::TriangleMeshImpl::Vertex {
00270 public:
00271     Vertex(Vec3 pos) : pos(pos), firstEdge(-1) {
00272     }
00273     Vec3        pos;
00274     UnitVec3    normal;
00275     int         firstEdge;
00276 };
00277 
00278 } // namespace SimTK
00279 
00280 #endif // SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_

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