Simbody
|
00001 #ifndef SimTK_SIMBODY_CONTACT_GEOMETRY_H_ 00002 #define SimTK_SIMBODY_CONTACT_GEOMETRY_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-11 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 00039 #include "SimTKcommon.h" 00040 #include "simbody/internal/common.h" 00041 #include "simbody/internal/OrientedBoundingBox.h" 00042 00043 #include <cassert> 00044 00045 namespace SimTK { 00046 00050 SimTK_DEFINE_UNIQUE_INDEX_TYPE(ContactGeometryTypeId); 00051 00052 class ContactGeometryImpl; 00053 class OBBTreeNodeImpl; 00054 00055 00056 00057 //============================================================================== 00058 // CONTACT GEOMETRY 00059 //============================================================================== 00065 class SimTK_SIMBODY_EXPORT ContactGeometry { 00066 public: 00067 class HalfSpace; 00068 class Sphere; 00069 class Ellipsoid; 00070 class TriangleMesh; 00071 class HalfSpaceImpl; 00072 class SphereImpl; 00073 class EllipsoidImpl; 00074 class TriangleMeshImpl; 00075 00077 ContactGeometry() : impl(0) {} 00079 ContactGeometry(const ContactGeometry& src); 00081 ContactGeometry& operator=(const ContactGeometry& src); 00085 ~ContactGeometry(); 00086 00097 Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const; 00098 00110 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, 00111 Real& distance, UnitVec3& normal) const; 00112 00118 void getBoundingSphere(Vec3& center, Real& radius) const; 00119 00193 static void combineParaboloids(const Rotation& R_SP1, const Vec2& k1, 00194 const UnitVec3& x2, const Vec2& k2, 00195 Rotation& R_SP, Vec2& k); 00196 00201 static void combineParaboloids(const Rotation& R_SP1, const Vec2& k1, 00202 const UnitVec3& x2, const Vec2& k2, 00203 Vec2& k); 00204 00208 const std::string& getType() const; 00212 int getTypeIndex() const; 00213 00216 ContactGeometryTypeId getTypeId() const; 00217 00218 explicit ContactGeometry(ContactGeometryImpl* impl); 00219 bool isOwnerHandle() const; 00220 bool isEmptyHandle() const; 00221 bool hasImpl() const {return impl != 0;} 00223 const ContactGeometryImpl& getImpl() const {assert(impl); return *impl;} 00225 ContactGeometryImpl& updImpl() {assert(impl); return *impl; } 00226 00227 protected: 00228 ContactGeometryImpl* impl; 00229 }; 00230 00231 00232 00233 //============================================================================== 00234 // HALF SPACE 00235 //============================================================================== 00238 class SimTK_SIMBODY_EXPORT ContactGeometry::HalfSpace : public ContactGeometry { 00239 public: 00240 HalfSpace(); 00241 00243 static bool isInstance(const ContactGeometry& geo) 00244 { return geo.getTypeId()==classTypeId(); } 00246 static const HalfSpace& getAs(const ContactGeometry& geo) 00247 { assert(isInstance(geo)); return static_cast<const HalfSpace&>(geo); } 00249 static HalfSpace& updAs(ContactGeometry& geo) 00250 { assert(isInstance(geo)); return static_cast<HalfSpace&>(geo); } 00251 00253 static ContactGeometryTypeId classTypeId(); 00254 }; 00255 00256 00257 00258 //============================================================================== 00259 // SPHERE 00260 //============================================================================== 00263 class SimTK_SIMBODY_EXPORT ContactGeometry::Sphere : public ContactGeometry { 00264 public: 00265 explicit Sphere(Real radius); 00266 Real getRadius() const; 00267 void setRadius(Real radius); 00268 00270 static bool isInstance(const ContactGeometry& geo) 00271 { return geo.getTypeId()==classTypeId(); } 00273 static const Sphere& getAs(const ContactGeometry& geo) 00274 { assert(isInstance(geo)); return static_cast<const Sphere&>(geo); } 00276 static Sphere& updAs(ContactGeometry& geo) 00277 { assert(isInstance(geo)); return static_cast<Sphere&>(geo); } 00278 00280 static ContactGeometryTypeId classTypeId(); 00281 00282 const SphereImpl& getImpl() const; 00283 SphereImpl& updImpl(); 00284 }; 00285 00286 00287 00288 //============================================================================== 00289 // ELLIPSOID 00290 //============================================================================== 00312 class SimTK_SIMBODY_EXPORT ContactGeometry::Ellipsoid : public ContactGeometry { 00313 public: 00317 explicit Ellipsoid(const Vec3& radii); 00320 const Vec3& getRadii() const; 00326 void setRadii(const Vec3& radii); 00327 00333 const Vec3& getCurvatures() const; 00334 00347 UnitVec3 findUnitNormalAtPoint(const Vec3& P) const; 00348 00356 Vec3 findPointWithThisUnitNormal(const UnitVec3& n) const; 00357 00366 Vec3 findPointInSameDirection(const Vec3& Q) const; 00367 00390 void findParaboloidAtPoint(const Vec3& Q, Transform& X_EP, Vec2& k) const; 00391 00397 void findParaboloidAtPointWithNormal(const Vec3& Q, const UnitVec3& n, 00398 Transform& X_EP, Vec2& k) const; 00399 00401 static bool isInstance(const ContactGeometry& geo) 00402 { return geo.getTypeId()==classTypeId(); } 00404 static const Ellipsoid& getAs(const ContactGeometry& geo) 00405 { assert(isInstance(geo)); return static_cast<const Ellipsoid&>(geo); } 00407 static Ellipsoid& updAs(ContactGeometry& geo) 00408 { assert(isInstance(geo)); return static_cast<Ellipsoid&>(geo); } 00409 00411 static ContactGeometryTypeId classTypeId(); 00412 00414 const EllipsoidImpl& getImpl() const; 00416 EllipsoidImpl& updImpl(); 00417 }; 00418 00419 00420 00421 //============================================================================== 00422 // TRIANGLE MESH 00423 //============================================================================== 00444 class SimTK_SIMBODY_EXPORT ContactGeometry::TriangleMesh 00445 : public ContactGeometry { 00446 public: 00447 class OBBTreeNode; 00458 TriangleMesh(const ArrayViewConst_<Vec3>& vertices, const ArrayViewConst_<int>& faceIndices, bool smooth=false); 00467 explicit TriangleMesh(const PolygonalMesh& mesh, bool smooth=false); 00469 int getNumEdges() const; 00471 int getNumFaces() const; 00473 int getNumVertices() const; 00477 const Vec3& getVertexPosition(int index) const; 00483 int getFaceEdge(int face, int edge) const; 00488 int getFaceVertex(int face, int vertex) const; 00493 int getEdgeFace(int edge, int face) const; 00498 int getEdgeVertex(int edge, int vertex) const; 00503 void findVertexEdges(int vertex, Array_<int>& edges) const; 00506 const UnitVec3& getFaceNormal(int face) const; 00509 Real getFaceArea(int face) const; 00515 Vec3 findPoint(int face, const Vec2& uv) const; 00520 Vec3 findCentroid(int face) const; 00525 UnitVec3 findNormalAtPoint(int face, const Vec2& uv) const; 00536 Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const; 00549 Vec3 findNearestPoint(const Vec3& position, bool& inside, int& face, Vec2& uv) const; 00561 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const; 00575 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, int& face, Vec2& uv) const; 00578 OBBTreeNode getOBBTreeNode() const; 00579 00582 PolygonalMesh createPolygonalMesh() const; 00583 00585 static bool isInstance(const ContactGeometry& geo) 00586 { return geo.getTypeId()==classTypeId(); } 00588 static const TriangleMesh& getAs(const ContactGeometry& geo) 00589 { assert(isInstance(geo)); return static_cast<const TriangleMesh&>(geo); } 00591 static TriangleMesh& updAs(ContactGeometry& geo) 00592 { assert(isInstance(geo)); return static_cast<TriangleMesh&>(geo); } 00593 00595 static ContactGeometryTypeId classTypeId(); 00596 00598 const TriangleMeshImpl& getImpl() const; 00600 TriangleMeshImpl& updImpl(); 00601 }; 00602 00603 00604 00605 //============================================================================== 00606 // TRIANGLE MESH :: OBB TREE NODE 00607 //============================================================================== 00612 class SimTK_SIMBODY_EXPORT ContactGeometry::TriangleMesh::OBBTreeNode { 00613 public: 00614 OBBTreeNode(const OBBTreeNodeImpl& impl); 00617 const OrientedBoundingBox& getBounds() const; 00619 bool isLeafNode() const; 00622 const OBBTreeNode getFirstChildNode() const; 00625 const OBBTreeNode getSecondChildNode() const; 00628 const Array_<int>& getTriangles() const; 00632 int getNumTriangles() const; 00633 00634 private: 00635 const OBBTreeNodeImpl* impl; 00636 }; 00637 00638 } // namespace SimTK 00639 00640 #endif // SimTK_SIMBODY_CONTACT_GEOMETRY_H_