00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_POLY3D_H__
00020 #define __CS_POLY3D_H__
00021
00029 #include "csextern.h"
00030
00031 #include "csgeom/plane3.h"
00032 #include "csgeom/vector3.h"
00033 #include "csutil/dirtyaccessarray.h"
00034
00035 class csPoly2D;
00036
00038 enum
00039 {
00041 CS_POL_SAME_PLANE = 0,
00043 CS_POL_FRONT = 1,
00045 CS_POL_BACK = 2,
00047 CS_POL_SPLIT_NEEDED = 3
00048 };
00049
00053 class CS_CRYSTALSPACE_EXPORT csPoly3D
00054 {
00055 protected:
00057 csDirtyAccessArray<csVector3> vertices;
00058
00059 public:
00063 csPoly3D (size_t start_size = 10);
00064
00066 csPoly3D (const csPoly3D& copy);
00067
00069 virtual ~csPoly3D ();
00070
00074 void MakeEmpty ();
00075
00079 inline size_t GetVertexCount () const { return vertices.GetSize (); }
00080
00084 inline const csVector3* GetVertices () const { return vertices.GetArray (); }
00085
00089 inline csVector3* GetVertices () { return vertices.GetArray (); }
00090
00094 inline const csVector3* GetVertex (size_t i) const
00095 {
00096 if (i >= vertices.GetSize ()) return 0;
00097 return &(vertices.GetArray ()[i]);
00098 }
00099
00103 inline csVector3& operator[] (size_t i)
00104 {
00105 return vertices[i];
00106 }
00107
00111 inline const csVector3& operator[] (size_t i) const
00112 {
00113 return vertices[i];
00114 }
00115
00119 inline const csVector3* GetFirst () const
00120 {
00121 if (vertices.GetSize ()<=0) return 0;
00122 else return vertices.GetArray ();
00123 }
00124
00128 inline const csVector3* GetLast () const
00129 {
00130 if (vertices.GetSize ()<=0) return 0;
00131 else return
00132 &(vertices.GetArray ())[vertices.GetSize ()-1];
00133 }
00134
00138 bool In (const csVector3& v) const;
00139
00143 static bool In (csVector3* poly, size_t num_poly, const csVector3& v);
00144
00148 void MakeRoom (size_t new_max);
00149
00153 inline void SetVertexCount (size_t n)
00154 {
00155 MakeRoom (n);
00156 vertices.SetSize (n);
00157 }
00158
00163 inline size_t AddVertex (const csVector3& v)
00164 {
00165 return AddVertex (v.x, v.y, v.z);
00166 }
00167
00172 size_t AddVertex (float x, float y, float z);
00173
00177 inline void SetVertices (csVector3 const* v, size_t num)
00178 {
00179 MakeRoom (num);
00180 memcpy (vertices.GetArray (), v, num * sizeof (csVector3));
00181 }
00182
00190 bool ProjectXPlane (const csVector3& point, float plane_x,
00191 csPoly2D* poly2d) const;
00192
00200 bool ProjectYPlane (const csVector3& point, float plane_y,
00201 csPoly2D* poly2d) const;
00202
00210 bool ProjectZPlane (const csVector3& point, float plane_z,
00211 csPoly2D* poly2d) const;
00212
00220 inline bool ProjectAxisPlane (const csVector3& point, int plane_nr,
00221 float plane_pos, csPoly2D* poly2d) const
00222 {
00223 switch (plane_nr)
00224 {
00225 case CS_AXIS_X: return ProjectXPlane (point, plane_pos, poly2d);
00226 case CS_AXIS_Y: return ProjectYPlane (point, plane_pos, poly2d);
00227 case CS_AXIS_Z: return ProjectZPlane (point, plane_pos, poly2d);
00228 }
00229 return false;
00230 }
00231
00239 static int Classify (const csPlane3& pl,
00240 const csVector3* vertices, size_t num_vertices);
00241
00249 inline int Classify (const csPlane3& pl) const
00250 {
00251 return Classify (pl, vertices.GetArray (), vertices.GetSize ());
00252 }
00253
00255 int ClassifyX (float x) const;
00256
00258 int ClassifyY (float y) const;
00259
00261 int ClassifyZ (float z) const;
00262
00264 inline int ClassifyAxis (int axis, float where) const
00265 {
00266 switch (axis)
00267 {
00268 case CS_AXIS_X: return ClassifyX (where);
00269 case CS_AXIS_Y: return ClassifyY (where);
00270 case CS_AXIS_Z: return ClassifyZ (where);
00271 }
00272 return 0;
00273 }
00274
00282 int IsAxisAligned (float& where, float epsilon = SMALL_EPSILON) const;
00283
00288 int ComputeMainNormalAxis () const;
00289
00291 void CutToPlane (const csPlane3& split_plane);
00292
00294 void SplitWithPlane (csPoly3D& front, csPoly3D& back,
00295 const csPlane3& split_plane) const;
00296
00298 void SplitWithPlaneX (csPoly3D& front, csPoly3D& back, float x) const;
00299
00301 void SplitWithPlaneY (csPoly3D& front, csPoly3D& back, float y) const;
00302
00304 void SplitWithPlaneZ (csPoly3D& front, csPoly3D& back, float z) const;
00305
00307 static csVector3 ComputeNormal (const csVector3* vertices, size_t num);
00308
00310 static csVector3 ComputeNormal (const csArray<csVector3>& poly);
00311
00313 static csVector3 ComputeNormal (int* poly, size_t num, csVector3* vertices);
00314
00316 inline csVector3 ComputeNormal () const
00317 {
00318 return ComputeNormal (vertices.GetArray (), vertices.GetSize ());
00319 }
00320
00322 static csPlane3 ComputePlane (const csVector3* vertices, size_t num);
00323
00325 static csPlane3 ComputePlane (const csArray<csVector3>& poly);
00326
00328 static csPlane3 ComputePlane (int* poly, size_t num, csVector3* vertices);
00329
00331 inline csPlane3 ComputePlane () const
00332 {
00333 return ComputePlane (vertices.GetArray (), vertices.GetSize ());
00334 }
00335
00339 float GetArea() const;
00340
00344 csVector3 GetCenter () const;
00345
00347 bool InSphere(const csVector3& center, float radius);
00348 };
00349
00351 struct csCompressVertex
00352 {
00353 size_t orig_idx;
00354 int x, y, z;
00355 size_t new_idx;
00356 bool used;
00357 };
00358
00365 class CS_CRYSTALSPACE_EXPORT csVector3Array : public csPoly3D
00366 {
00367 public:
00368 csVector3Array (size_t start_size = 10) : csPoly3D (start_size) { }
00369
00374 inline size_t AddVertexSmart (const csVector3& v)
00375 { return AddVertexSmart (v.x, v.y, v.z); }
00376
00381 size_t AddVertexSmart (float x, float y, float z);
00382
00394 static csCompressVertex* CompressVertices (csVector3* vertices,
00395 size_t num_vertices, csVector3*& new_vertices, size_t& new_count);
00396
00405 static csCompressVertex* CompressVertices (csArray<csVector3>& vertices);
00406 };
00407
00410 #endif // __CS_POLY3D_H__