00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_FRUSTRUM_H__
00020 #define __CS_FRUSTRUM_H__
00021
00022 #include "cstypes.h"
00023 #include "csgeom/math3d.h"
00024 #include "csgeom/vtpool.h"
00025
00026 class csTransform;
00027
00033
00034 #define CS_FRUST_OUTSIDE 0
00035
00036 #define CS_FRUST_INSIDE 1
00037
00038 #define CS_FRUST_COVERED 2
00039
00040 #define CS_FRUST_PARTIAL 3
00041
00048 struct csClipInfo
00049 {
00050 # define CS_CLIPINFO_ORIGINAL 0
00051 # define CS_CLIPINFO_ONEDGE 1
00052 # define CS_CLIPINFO_INSIDE 2
00053 int type;
00054 union
00055 {
00056 struct { int idx; } original;
00057 struct { int i1, i2; float r; } onedge;
00058 struct { csClipInfo* ci1, * ci2; float r; } inside;
00059 };
00060
00061 csClipInfo () : type (CS_CLIPINFO_ORIGINAL) { }
00062 void Clear ();
00063 ~csClipInfo () { Clear (); }
00064
00066 void Copy (csClipInfo& other)
00067 {
00068 if (&other == this) return;
00069 Clear ();
00070 type = other.type;
00071 if (type == CS_CLIPINFO_INSIDE)
00072 {
00073 inside.r = other.inside.r;
00074 inside.ci1 = new csClipInfo ();
00075 inside.ci1->Copy (*other.inside.ci1);
00076 inside.ci2 = new csClipInfo ();
00077 inside.ci2->Copy (*other.inside.ci2);
00078 }
00079 else if (type == CS_CLIPINFO_ORIGINAL)
00080 original.idx = other.original.idx;
00081 else
00082 onedge = other.onedge;
00083 }
00084
00086 void Move (csClipInfo& other)
00087 {
00088 if (&other == this) return;
00089 Clear ();
00090 type = other.type;
00091 if (type == CS_CLIPINFO_INSIDE)
00092 inside = other.inside;
00093 else if (type == CS_CLIPINFO_ORIGINAL)
00094 original.idx = other.original.idx;
00095 else
00096 onedge = other.onedge;
00097 other.type = CS_CLIPINFO_ORIGINAL;
00098 }
00099
00100 void Dump (int indent)
00101 {
00102 char ind[255];
00103 int i;
00104 for (i = 0 ; i < indent ; i++) ind[i] = ' ';
00105 ind[i] = 0;
00106 switch (type)
00107 {
00108 case CS_CLIPINFO_ORIGINAL:
00109 printf ("%s ORIGINAL idx=%d\n", ind, original.idx);
00110 break;
00111 case CS_CLIPINFO_ONEDGE:
00112 printf ("%s ONEDGE i1=%d i2=%d r=%g\n", ind, onedge.i1, onedge.i2,
00113 onedge.r);
00114 break;
00115 case CS_CLIPINFO_INSIDE:
00116 printf ("%s INSIDE r=%g\n", ind, inside.r);
00117 inside.ci1->Dump (indent+2);
00118 inside.ci2->Dump (indent+2);
00119 break;
00120 }
00121 fflush (stdout);
00122 }
00123 };
00124
00135 class csFrustum
00136 {
00137 private:
00139 csVertexArrayPool* pool;
00140
00142 csVector3 origin;
00143
00149 csVector3* vertices;
00151 int num_vertices;
00153 int max_vertices;
00154
00156 csPlane3* backplane;
00157
00165 bool wide;
00166
00171 bool mirrored;
00172
00174 int ref_count;
00175
00177 void Clear ();
00178
00180 void ExtendVertexArray (int num);
00181
00182 public:
00183
00185 csFrustum (const csVector3& o) : pool (&csDefaultVertexArrayPool::GetDefaultPool()),
00186 origin (o), vertices (NULL), num_vertices (0), max_vertices (0),
00187 backplane (NULL), wide (false), mirrored (false), ref_count (1)
00188 { }
00189
00191 csFrustum (const csVector3& o, csVertexArrayPool* pl) : pool (pl),
00192 origin (o), vertices (NULL), num_vertices (0), max_vertices (0),
00193 backplane (NULL), wide (false), mirrored (false), ref_count (1)
00194 { }
00195
00201 csFrustum (const csVector3& o, csVector3* verts, int num_verts,
00202 csPlane3* backp = NULL);
00203
00209 csFrustum (const csVector3& o, int num_verts,
00210 csVertexArrayPool* pl, csPlane3* backp = NULL);
00211
00213 csFrustum (const csFrustum ©);
00214
00216 virtual ~csFrustum ();
00217
00219 void SetOrigin (const csVector3& o) { origin = o; }
00220
00222 csVector3& GetOrigin () { return origin; }
00223
00225 const csVector3& GetOrigin () const { return origin; }
00226
00232 void SetMirrored (bool m) { mirrored = m; }
00233
00235 bool IsMirrored () { return mirrored; }
00236
00243 void SetBackPlane (csPlane3& plane);
00244
00248 csPlane3* GetBackPlane () { return backplane; }
00249
00253 void RemoveBackPlane ();
00254
00258 void AddVertex (const csVector3& v);
00259
00263 int GetVertexCount () { return num_vertices; }
00264
00268 csVector3& GetVertex (int idx)
00269 {
00270 CS_ASSERT (idx >= 0 && idx < num_vertices);
00271 return vertices[idx];
00272 }
00273
00277 csVector3* GetVertices () { return vertices; }
00278
00282 void Transform (csTransform* trans);
00283
00289 void ClipToPlane (csVector3& v1, csVector3& v2);
00290
00299 static void ClipToPlane (csVector3* vertices, int& num_vertices,
00300 csClipInfo* clipinfo, const csVector3& v1, const csVector3& v2);
00301
00310 static void ClipToPlane (csVector3* vertices, int& num_vertices,
00311 csClipInfo* clipinfo, const csPlane3& plane);
00312
00319 void ClipPolyToPlane (csPlane3* plane);
00320
00329 csFrustum* Intersect (const csFrustum& other);
00330
00345 csFrustum* Intersect (csVector3* poly, int num);
00346
00361 static csFrustum* Intersect (
00362 const csVector3& frust_origin, csVector3* frust, int num_frust,
00363 csVector3* poly, int num);
00364
00379 static csFrustum* Intersect (
00380 const csVector3& frust_origin, csVector3* frust, int num_frust,
00381 const csVector3& v1, const csVector3& v2, const csVector3& v3);
00382
00388 static int Classify (csVector3* frustum, int num_frust,
00389 csVector3* poly, int num_poly);
00390
00395 static int BatchClassify (csVector3* frustum, csVector3* frustumNormals, int num_frust,
00396 csVector3* poly, int num_poly);
00397
00402 bool Contains (const csVector3& point);
00403
00410 static bool Contains (csVector3* frustum, int num_frust,
00411 const csVector3& point);
00412
00418 static bool Contains (csVector3* frustum, int num_frust,
00419 const csPlane3& plane, const csVector3& point);
00420
00422 bool IsEmpty () const { return !wide && vertices == NULL; }
00423
00425 bool IsInfinite () const { return wide && vertices == NULL && backplane == NULL; }
00426
00428 bool IsWide () const { return wide && vertices == NULL; }
00429
00434 void MakeInfinite ();
00435
00439 void MakeEmpty ();
00440
00442 void IncRef () { ref_count++; }
00444 void DecRef () { if (ref_count == 1) delete this; else ref_count--; }
00445 };
00446
00447 #endif // __CS_FRUSTRUM_H__