00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _PHYSICS_POLYHEDRON_
00026 #define _PHYSICS_POLYHEDRON_
00027
00028 #include <base/MemoryTracer>
00029
00030 #include <base/reflist>
00031 #include <base/SmallObj>
00032 #include <base/Dimension3>
00033 #include <base/VFile>
00034 #include <base/Serializable>
00035 #include <base/Serializer>
00036 #include <gfx/TriangleContainer>
00037 #include <physics/physics>
00038 #include <physics/Shape>
00039 #include <physics/ComplexShape>
00040
00041
00042
00043 namespace physics {
00044
00045
00046 class Polyhedron : virtual public ComplexShape
00047 {
00048 public:
00049 Polyhedron();
00050 explicit Polyhedron(ref<base::VFile> file) throw(std::invalid_argument, base::io_error);
00051 Polyhedron(const Polyhedron& p);
00052 Polyhedron(const gfx::TriangleContainer& tris);
00053 Polyhedron(osg::Node& n);
00054 Polyhedron(const Shape& s);
00055 virtual ~Polyhedron();
00056
00057 virtual String className() const { return String("Polyhedron"); }
00058 virtual Object& clone() const { return *NewNamedObj(className()) Polyhedron(*this); }
00059
00060 class Vertex;
00061 class Edge;
00062 class Polygon;
00063
00064 typedef base::reflist<Vertex> VertexList;
00065 typedef base::reflist<Edge> EdgeList;
00066 typedef base::reflist<Polygon> PolygonList;
00067
00068
00069 class Vertex : public base::ReferencedObject, public base::Serializable, public base::SmallObject<>
00070 {
00071 public:
00072 Vertex() {}
00073 Vertex(const Vertex& v)
00074 : coord(v.coord), edges(v.edges) {}
00075 virtual ~Vertex() {}
00076
00077 virtual String className() const { return String("Vertex"); }
00078 virtual Object& clone() const { return *NewObj Vertex(*this); }
00079
00080 Vertex& operator=(const Vertex& v)
00081 { coord=v.coord; edges = v.edges; return *this; }
00082
00083 const Point3& coordinate() const
00084 { return coord; }
00085
00086 bool operator==(const Vertex& v) const { return this==&v; }
00087 bool operator!=(const Vertex& v) const { return this!=&v; }
00088
00089 EdgeList::const_iterator_const edges_begin() const { return edges.const_begin(); }
00090 EdgeList::const_iterator_const edges_end() const { return edges.const_end(); }
00091
00092 EdgeList::const_iterator edges_begin() { return edges.begin(); }
00093 EdgeList::const_iterator edges_end() { return edges.end(); }
00094
00095 virtual void serialize(base::Serializer& s) {
00096 s(coord.x)(coord.y)(coord.z);
00097 s(edges);
00098 }
00099
00100 protected:
00101 Vertex(const Point3& p)
00102 : coord(p) {}
00103 Point3 coord;
00104 EdgeList edges;
00105
00106 friend class Polyhedron;
00107 };
00108
00109 class Edge : public ReferencedObject, public base::Serializable, public base::SmallObject<>
00110 {
00111 public:
00112 Edge()
00113 : polys(0) {}
00114 Edge(const Edge& e)
00115 : v1(e.v1), v2(e.v2), polys(e.polys), poly1(e.poly1), poly2(e.poly2)
00116 {}
00117 virtual ~Edge() {}
00118
00119 virtual String className() const { return String("Edge"); }
00120 virtual Object& clone() const { return *NewObj Edge(*this); }
00121
00122 Edge& operator=(const Edge& e)
00123 { v1=e.v1; v2=e.v2; polys=e.polys; poly1=e.poly1; poly2=e.poly2; return *this; }
00124
00125 bool operator==(const Edge& e) const { return this==&e; }
00126 bool operator!=(const Edge& e) const { return this!=&e; }
00127
00128 ref<const Vertex> vertex1() const { return v1; }
00129 ref<const Vertex> vertex2() const { return v2; }
00130
00131 ref<const Vertex> otherVertex(ref<const Vertex> v) const
00132 { if (v == v1) return v2; else return v1; }
00133
00134 virtual void serialize(base::Serializer& s) {
00135 s(v1)(v2)(polys);
00136 if (polys>0) {
00137 s(poly1);
00138 if (polys>1)
00139 s(poly2);
00140 }
00141 }
00142
00143 protected:
00144 Edge(ref<Vertex> v1, ref<Vertex> v2) : v1(v1), v2(v2), polys(0) {}
00145 void addPoly(ref<Polygon> poly)
00146 {
00147 if (polys==0)
00148 poly1 = poly;
00149 else
00150 poly2 = poly;
00151 polys++;
00152 }
00153 ref<Vertex> v1, v2;
00154 Int polys;
00155 ref<Polygon> poly1, poly2;
00156
00157 friend class Polyhedron;
00158 };
00159
00160
00161 class Polygon : public ReferencedObject, public base::Serializable, public base::SmallObject<>
00162 {
00163 public:
00164 Polygon() {}
00165 virtual ~Polygon() {}
00166
00167 virtual String className() const { return String("Polygon"); }
00168 virtual Object& clone() const { return *NewObj Polygon(*this); }
00169
00170 Polygon& operator=(const Polygon& p)
00171 { edges=p.edges; return *this; }
00172
00173 virtual void serialize(base::Serializer& s) {
00174 s(edges);
00175 }
00176
00177 protected:
00178 Polygon(const Polygon& p)
00179 : edges(p.edges) {}
00180 void addEdge(ref<Edge> e)
00181 { edges.push_back(e); }
00182 EdgeList edges;
00183
00184 friend class Polyhedron;
00185 };
00186
00187
00188
00189 VertexList::const_iterator_const vertices_begin() const { return verts.const_begin(); }
00190 VertexList::const_iterator_const vertices_end() const { return verts.const_end(); }
00191
00192 EdgeList::const_iterator_const edges_begin() const { return edges.const_begin(); }
00193 EdgeList::const_iterator_const edges_end() const { return edges.const_end(); }
00194
00195 PolygonList::const_iterator_const polygon_begin() const { return polys.const_begin(); }
00196 PolygonList::const_iterator_const polygon_end() const { return polys.const_end(); }
00197
00198
00199
00200
00201
00202 virtual BoundingBox getBoundingBox() const;
00203 virtual BoundingSphere getBoundingSphere() const;
00204
00205 virtual const MassProperties& getMassProperties(ref<const Material> material) const;
00206
00207 virtual gfx::Segment3 shortestSegmentBetween(const base::Transform& t, const Point3& p) const;
00208 virtual gfx::Segment3 shortestSegmentBetween(const base::Transform& t, const gfx::Segment3& s) const;
00209 virtual gfx::Segment3 shortestSegmentBetween(const base::Transform& t, const gfx::Triangle3& tri) const;
00210 virtual gfx::Segment3 shortestSegmentBetween(const base::Transform& t, const gfx::Quad3& q) const;
00211 virtual gfx::Segment3 shortestSegmentBetween(const base::Transform& t1, ref<const Shape> s, const base::Transform& t2) const;
00212
00213
00214 virtual ref<CollisionModel> getCollisionModel(CollisionModel::CollisionModelType modelType) const;
00215
00216
00217 virtual bool visualTypeSupported(VisualType type) const { return (type==OSGVisual); }
00218 virtual osg::Node* createOSGVisual(Attributes visualAttributes=0) const;
00219
00220 virtual void serialize(base::Serializer& s);
00221
00222
00223 virtual bool formatSupported(String format, Real version = 1.0, ExternalizationType type = IO) const;
00224 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0);
00225 virtual void externalize(base::Externalizer& e, String format = "", Real version = 1.0) const
00226 { Externalizable::externalize(e,format,version); }
00227
00228 protected:
00229 mutable bool boundsCached;
00230 mutable BoundingBox boundingBox;
00231 mutable BoundingSphere boundingSphere;
00232
00233 mutable bool massPropertiesCached;
00234 mutable Real density;
00235 mutable MassProperties massProperties;
00236
00237
00238 VertexList verts;
00239 EdgeList edges;
00240 PolygonList polys;
00241 ref<Vertex> vertex(const Point3& p);
00242 ref<Edge> edge(ref<Vertex> v1, ref<Vertex> v2);
00243
00244
00245
00246
00247 void buildGeometry(const gfx::TriangleContainer& tris);
00248
00249 void getAdjacentVertices(const Point3& v, array<Point3>& adjacent) const;
00250
00251 mutable Visual::Attributes attributes;
00252 mutable ref_ptr<osg::Node> model;
00253 mutable ref_ptr<osg::Node> node;
00254
00255 mutable ref<CollisionModel> collisionModel;
00256 mutable CollisionModel::CollisionModelType modelType;
00257
00258 void computeBounds() const;
00259 };
00260
00261
00262 }
00263
00264 #endif