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
00028 #include "cstypes.h"
00029 #include "csgeom/math3d.h"
00030 #include "csgeom/vtpool.h"
00031
00032 class csTransform;
00033
00039
00040 #define CS_FRUST_OUTSIDE 0
00041
00042 #define CS_FRUST_INSIDE 1
00043
00044 #define CS_FRUST_COVERED 2
00045
00046 #define CS_FRUST_PARTIAL 3
00047
00055 struct csClipInfo
00056 {
00057 # define CS_CLIPINFO_ORIGINAL 0
00058 # define CS_CLIPINFO_ONEDGE 1
00059 # define CS_CLIPINFO_INSIDE 2
00060 int type;
00061 union
00062 {
00063 struct { int idx; } original;
00064 struct { int i1, i2; float r; } onedge;
00065 struct { csClipInfo* ci1, * ci2; float r; } inside;
00066 };
00067
00068 csClipInfo () : type (CS_CLIPINFO_ORIGINAL) { }
00069 void Clear ();
00070 ~csClipInfo () { Clear (); }
00071
00073 void Copy (csClipInfo& other)
00074 {
00075 if (&other == this) return;
00076 Clear ();
00077 type = other.type;
00078 if (type == CS_CLIPINFO_INSIDE)
00079 {
00080 inside.r = other.inside.r;
00081 inside.ci1 = new csClipInfo ();
00082 inside.ci1->Copy (*other.inside.ci1);
00083 inside.ci2 = new csClipInfo ();
00084 inside.ci2->Copy (*other.inside.ci2);
00085 }
00086 else if (type == CS_CLIPINFO_ORIGINAL)
00087 original.idx = other.original.idx;
00088 else
00089 onedge = other.onedge;
00090 }
00091
00093 void Move (csClipInfo& other)
00094 {
00095 if (&other == this) return;
00096 Clear ();
00097 type = other.type;
00098 if (type == CS_CLIPINFO_INSIDE)
00099 inside = other.inside;
00100 else if (type == CS_CLIPINFO_ORIGINAL)
00101 original.idx = other.original.idx;
00102 else
00103 onedge = other.onedge;
00104 other.type = CS_CLIPINFO_ORIGINAL;
00105 }
00106
00107 void Dump (int indent)
00108 {
00109 char ind[255];
00110 int i;
00111 for (i = 0 ; i < indent ; i++) ind[i] = ' ';
00112 ind[i] = 0;
00113 switch (type)
00114 {
00115 case CS_CLIPINFO_ORIGINAL:
00116 printf ("%s ORIGINAL idx=%d\n", ind, original.idx);
00117 break;
00118 case CS_CLIPINFO_ONEDGE:
00119 printf ("%s ONEDGE i1=%d i2=%d r=%g\n", ind, onedge.i1, onedge.i2,
00120 onedge.r);
00121 break;
00122 case CS_CLIPINFO_INSIDE:
00123 printf ("%s INSIDE r=%g\n", ind, inside.r);
00124 inside.ci1->Dump (indent+2);
00125 inside.ci2->Dump (indent+2);
00126 break;
00127 }
00128 fflush (stdout);
00129 }
00130 };
00131
00142 class csFrustum
00143 {
00144 private:
00146 csVertexArrayPool* pool;
00147
00149 csVector3 origin;
00150
00156 csVector3* vertices;
00158 int num_vertices;
00160 int max_vertices;
00161
00163 csPlane3* backplane;
00164
00172 bool wide;
00173
00178 bool mirrored;
00179
00181 int ref_count;
00182
00184 void Clear ();
00185
00187 void ExtendVertexArray (int num);
00188
00189 public:
00190
00192 csFrustum (const csVector3& o) : pool (&csDefaultVertexArrayPool::GetDefaultPool()),
00193 origin (o), vertices (0), num_vertices (0), max_vertices (0),
00194 backplane (0), wide (false), mirrored (false), ref_count (1)
00195 { }
00196
00198 csFrustum (const csVector3& o, csVertexArrayPool* pl) : pool (pl),
00199 origin (o), vertices (0), num_vertices (0), max_vertices (0),
00200 backplane (0), wide (false), mirrored (false), ref_count (1)
00201 { }
00202
00208 csFrustum (const csVector3& o, csVector3* verts, int num_verts,
00209 csPlane3* backp = 0);
00210
00216 csFrustum (const csVector3& o, int num_verts,
00217 csVertexArrayPool* pl, csPlane3* backp = 0);
00218
00220 csFrustum (const csFrustum ©);
00221
00223 virtual ~csFrustum ();
00224
00226 void SetOrigin (const csVector3& o) { origin = o; }
00227
00229 csVector3& GetOrigin () { return origin; }
00230
00232 const csVector3& GetOrigin () const { return origin; }
00233
00239 void SetMirrored (bool m) { mirrored = m; }
00240
00242 bool IsMirrored () { return mirrored; }
00243
00250 void SetBackPlane (csPlane3& plane);
00251
00255 csPlane3* GetBackPlane () { return backplane; }
00256
00260 void RemoveBackPlane ();
00261
00265 void AddVertex (const csVector3& v);
00266
00270 int GetVertexCount () { return num_vertices; }
00271
00275 csVector3& GetVertex (int idx)
00276 {
00277 CS_ASSERT (idx >= 0 && idx < num_vertices);
00278 return vertices[idx];
00279 }
00280
00284 csVector3* GetVertices () { return vertices; }
00285
00289 void Transform (csTransform* trans);
00290
00296 void ClipToPlane (csVector3& v1, csVector3& v2);
00297
00306 static void ClipToPlane (csVector3* vertices, int& num_vertices,
00307 csClipInfo* clipinfo, const csVector3& v1, const csVector3& v2);
00308
00317 static void ClipToPlane (csVector3* vertices, int& num_vertices,
00318 csClipInfo* clipinfo, const csPlane3& plane);
00319
00326 void ClipPolyToPlane (csPlane3* plane);
00327
00336 csPtr<csFrustum> Intersect (const csFrustum& other);
00337
00352 csPtr<csFrustum> Intersect (csVector3* poly, int num);
00353
00368 static csPtr<csFrustum> Intersect (
00369 const csVector3& frust_origin, csVector3* frust, int num_frust,
00370 csVector3* poly, int num);
00371
00386 static csPtr<csFrustum> Intersect (
00387 const csVector3& frust_origin, csVector3* frust, int num_frust,
00388 const csVector3& v1, const csVector3& v2, const csVector3& v3);
00389
00395 static int Classify (csVector3* frustum, int num_frust,
00396 csVector3* poly, int num_poly);
00397
00402 static int BatchClassify (csVector3* frustum, csVector3* frustumNormals, int num_frust,
00403 csVector3* poly, int num_poly);
00404
00409 bool Contains (const csVector3& point);
00410
00417 static bool Contains (csVector3* frustum, int num_frust,
00418 const csVector3& point);
00419
00425 static bool Contains (csVector3* frustum, int num_frust,
00426 const csPlane3& plane, const csVector3& point);
00427
00429 bool IsEmpty () const { return !wide && vertices == 0; }
00430
00432 bool IsInfinite () const { return wide && vertices == 0 && backplane == 0; }
00433
00435 bool IsWide () const { return wide && vertices == 0; }
00436
00441 void MakeInfinite ();
00442
00446 void MakeEmpty ();
00447
00449 void IncRef () { ref_count++; }
00451 void DecRef () { if (ref_count == 1) delete this; else ref_count--; }
00452 };
00453
00456 #endif // __CS_FRUSTRUM_H__