00001 #ifndef SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_
00002 #define SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "simbody/internal/ContactGeometry.h"
00037
00038 namespace SimTK {
00039
00040 class SimTK_SIMBODY_EXPORT ContactGeometryImpl {
00041 public:
00042 ContactGeometryImpl(const std::string& type);
00043 virtual ~ContactGeometryImpl() {
00044 clearMyHandle();
00045 }
00046 const std::string& getType() const {
00047 return type;
00048 }
00049 int getTypeIndex() const {
00050 return typeIndex;
00051 }
00052 static int getIndexForType(std::string type);
00053 virtual ContactGeometryImpl* clone() const = 0;
00054 virtual Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const = 0;
00055 virtual bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const = 0;
00056 ContactGeometry* getMyHandle() {
00057 return myHandle;
00058 }
00059 void setMyHandle(ContactGeometry& h) {
00060 myHandle = &h;
00061 }
00062 void clearMyHandle() {
00063 myHandle = 0;
00064 }
00065 protected:
00066 ContactGeometry* myHandle;
00067 const std::string& type;
00068 int typeIndex;
00069 };
00070
00071 class ContactGeometry::HalfSpaceImpl : public ContactGeometryImpl {
00072 public:
00073 HalfSpaceImpl() : ContactGeometryImpl(Type()) {
00074 }
00075 ContactGeometryImpl* clone() const {
00076 return new HalfSpaceImpl();
00077 }
00078 static const std::string& Type() {
00079 static std::string type = "halfspace";
00080 return type;
00081 }
00082 Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00083 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00084 };
00085
00086 class ContactGeometry::SphereImpl : public ContactGeometryImpl {
00087 public:
00088 SphereImpl(Real radius) : ContactGeometryImpl(Type()), radius(radius) {
00089 }
00090 ContactGeometryImpl* clone() const {
00091 return new SphereImpl(radius);
00092 }
00093 Real getRadius() const {
00094 return radius;
00095 }
00096 void setRadius(Real r) {
00097 radius = r;
00098 }
00099 static const std::string& Type() {
00100 static std::string type = "sphere";
00101 return type;
00102 }
00103 Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00104 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00105 private:
00106 Real radius;
00107 };
00108
00109 class OBBTreeNodeImpl {
00110 public:
00111 OBBTreeNodeImpl() : child1(NULL), child2(NULL) {
00112 }
00113 OBBTreeNodeImpl(const OBBTreeNodeImpl& copy);
00114 ~OBBTreeNodeImpl();
00115 OrientedBoundingBox bounds;
00116 OBBTreeNodeImpl* child1;
00117 OBBTreeNodeImpl* child2;
00118 std::vector<int> triangles;
00119 Vec3 findNearestPoint(const ContactGeometry::TriangleMeshImpl& mesh, const Vec3& position, Real cutoff2, Real& distance2, int& face, Vec2& uv) const;
00120 bool intersectsRay(const ContactGeometry::TriangleMeshImpl& mesh, const Vec3& origin, const UnitVec3& direction, Real& distance, int& face, Vec2& uv) const;
00121 };
00122
00123 class ContactGeometry::TriangleMeshImpl : public ContactGeometryImpl {
00124 public:
00125 class Edge;
00126 class Face;
00127 class Vertex;
00128 TriangleMeshImpl(const std::vector<Vec3>& vertexPositions, const std::vector<int>& faceIndices, bool smooth);
00129 TriangleMeshImpl(const PolygonalMesh& mesh, bool smooth);
00130 ContactGeometryImpl* clone() const {
00131 return new TriangleMeshImpl(*this);
00132 }
00133 static const std::string& Type() {
00134 static std::string type = "triangle mesh";
00135 return type;
00136 }
00137 UnitVec3 findNormalAtPoint(int face, const Vec2& uv) const;
00138 Vec3 findNearestPoint(const Vec3& position, bool& inside, UnitVec3& normal) const;
00139 Vec3 findNearestPoint(const Vec3& position, bool& inside, int& face, Vec2& uv) const;
00140 Vec3 findNearestPointToFace(const Vec3& position, int face, Vec2& uv) const;
00141 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, UnitVec3& normal) const;
00142 bool intersectsRay(const Vec3& origin, const UnitVec3& direction, Real& distance, int& face, Vec2& uv) const;
00143 private:
00144 void init(const std::vector<Vec3>& vertexPositions, const std::vector<int>& faceIndices);
00145 void createObbTree(OBBTreeNodeImpl& node, const std::vector<int>& faceIndices);
00146 void splitObbAxis(const std::vector<int>& parentIndices, std::vector<int>& child1Indices, std::vector<int>& child2Indices, int axis);
00147 friend class ContactGeometry::TriangleMesh;
00148 friend class OBBTreeNodeImpl;
00149 std::vector<Edge> edges;
00150 std::vector<Face> faces;
00151 std::vector<Vertex> vertices;
00152 OBBTreeNodeImpl obb;
00153 bool smooth;
00154 };
00155
00156 class ContactGeometry::TriangleMeshImpl::Edge {
00157 public:
00158 Edge(int vert1, int vert2, int face1, int face2) {
00159 vertices[0] = vert1;
00160 vertices[1] = vert2;
00161 faces[0] = face1;
00162 faces[1] = face2;
00163 }
00164 int vertices[2];
00165 int faces[2];
00166 };
00167
00168 class ContactGeometry::TriangleMeshImpl::Face {
00169 public:
00170 Face(int vert1, int vert2, int vert3, const Vec3& normal, Real area) : normal(normal), area(area) {
00171 vertices[0] = vert1;
00172 vertices[1] = vert2;
00173 vertices[2] = vert3;
00174 }
00175 int vertices[3];
00176 int edges[3];
00177 UnitVec3 normal;
00178 Real area;
00179 };
00180
00181 class ContactGeometry::TriangleMeshImpl::Vertex {
00182 public:
00183 Vertex(Vec3 pos) : pos(pos), firstEdge(-1) {
00184 }
00185 Vec3 pos;
00186 UnitVec3 normal;
00187 int firstEdge;
00188 };
00189
00190 }
00191
00192 #endif // SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_