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
00041
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
00058
00059
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
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
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
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
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
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
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
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 }
00279
00280 #endif // SimTK_SIMBODY_CONTACT_GEOMETRY_IMPL_H_