00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_LVIEW_H__
00020 #define __CS_LVIEW_H__
00021
00022 #include "csgeom/math3d.h"
00023 #include "csgeom/frustum.h"
00024 #include "csutil/csvector.h"
00025 #include "iengine/shadows.h"
00026 #include "iengine/fview.h"
00027
00028 class csMatrix3;
00029 class csVector3;
00030 class csLight;
00031 class csFrustumView;
00032 struct csFog;
00033 struct iGraphics3D;
00034 struct iGraphics2D;
00035 struct iPolygon3D;
00036 struct iSector;
00037 struct iClipper2D;
00038
00044 class csShadowFrustum: public csFrustum
00045 {
00046 private:
00047 void* userData;
00048 bool relevant;
00049 public:
00051 csShadowFrustum () :
00052 csFrustum (csVector3 (0), &csPooledVertexArrayPool::GetDefaultPool()),
00053 userData (NULL) { }
00055 csShadowFrustum (const csVector3& origin) :
00056 csFrustum (origin, &csPooledVertexArrayPool::GetDefaultPool()),
00057 userData (NULL) { }
00059 csShadowFrustum (const csVector3& origin, int num_verts) :
00060 csFrustum (origin, num_verts, &csPooledVertexArrayPool::GetDefaultPool()),
00061 userData (NULL) { }
00063 csShadowFrustum (const csShadowFrustum& orig);
00065 void SetUserData (void* ud) { userData = ud; }
00067 void* GetUserData () { return userData; }
00069 void MarkRelevant (bool rel = true) { relevant = rel; }
00071 bool IsRelevant () { return relevant; }
00072 };
00073
00074 class csShadowBlockList;
00075 class csShadowBlock;
00076
00082 class csShadowIterator : public iShadowIterator
00083 {
00084 friend class csShadowBlockList;
00085 friend class csShadowBlock;
00086
00087 private:
00088 csShadowBlock* first_cur;
00089 csShadowBlock* cur;
00090 int i, cur_num;
00091 bool onlycur;
00092 int dir;
00093 csShadowIterator (csShadowBlock* cur, bool onlycur, int dir);
00094 csShadowFrustum* cur_shad;
00095
00096 public:
00098 virtual bool HasNext ()
00099 {
00100 return cur != NULL && i < cur_num && i >= 0;
00101 }
00103 virtual csFrustum* Next ();
00105 virtual void* GetUserData () { return cur_shad->GetUserData (); }
00107 virtual bool IsRelevant () { return cur_shad->IsRelevant (); }
00109 virtual void MarkRelevant (bool rel) { cur_shad->MarkRelevant (rel); }
00111 virtual void Reset ();
00113 virtual void DeleteCurrent ();
00115 virtual iShadowBlock* GetCurrentShadowBlock ();
00117 virtual iShadowBlock* GetNextShadowBlock ();
00119 csShadowBlock* GetCsCurrentShadowBlock ();
00121 csShadowBlock* GetCsNextShadowBlock () { return cur; }
00122
00123 SCF_DECLARE_IBASE;
00124 };
00125
00131 class csShadowBlock : public iShadowBlock
00132 {
00133 friend class csShadowBlockList;
00134 friend class csShadowIterator;
00135
00136 private:
00137 csShadowBlock* next, * prev;
00138 csVector shadows;
00139 iSector* sector;
00140 int draw_busy;
00141
00142 public:
00144 csShadowBlock (iSector* sector, int draw_busy, int max_shadows = 30,
00145 int delta = 30);
00147 csShadowBlock (int max_shadows = 30, int delta = 30);
00148
00150 virtual ~csShadowBlock ();
00151
00153 virtual void DeleteShadows ()
00154 {
00155 int i;
00156 for (i = 0 ; i < shadows.Length () ; i++)
00157 {
00158 csShadowFrustum* sf = (csShadowFrustum*)shadows[i];
00159 CS_ASSERT (sf != NULL);
00160 sf->DecRef ();
00161 }
00162 shadows.DeleteAll ();
00163 }
00164
00171 void AddRelevantShadows (csShadowBlock* source, csTransform* trans = NULL);
00172
00179 virtual void AddRelevantShadows (iShadowBlock* source,
00180 csTransform* trans = NULL);
00181
00187 void AddRelevantShadows (csShadowBlockList* source);
00188
00194 virtual void AddRelevantShadows (iShadowBlockList* source);
00195
00201 void AddAllShadows (csShadowBlockList* source);
00202
00208 virtual void AddAllShadows (iShadowBlockList* source);
00209
00215 void AddUniqueRelevantShadows (csShadowBlockList* source);
00216
00222 virtual void AddUniqueRelevantShadows (iShadowBlockList* source);
00223
00229 virtual csFrustum* AddShadow (const csVector3& origin, void* userData,
00230 int num_verts, csPlane3& backplane);
00231
00233 virtual void UnlinkShadow (int idx);
00234
00236 virtual int GetShadowCount ()
00237 {
00238 return shadows.Length ();
00239 }
00240
00242 csFrustum* GetShadow (int idx)
00243 {
00244 return (csFrustum*)(
00245 (csShadowFrustum*)(idx < shadows.Length () ? shadows[idx] : NULL));
00246 }
00247
00251 void Transform (csTransform* trans)
00252 {
00253 int i;
00254 for (i = 0 ; i < shadows.Length () ; i++)
00255 {
00256 csShadowFrustum* sf = (csShadowFrustum*)shadows[i];
00257 CS_ASSERT (sf != NULL);
00258 sf->Transform (trans);
00259 }
00260 }
00261
00263 csShadowIterator* GetCsShadowIterator (bool reverse = false)
00264 {
00265 return new csShadowIterator (this, true, reverse ? -1 : 1);
00266 }
00267
00269 iShadowIterator* GetShadowIterator (bool reverse = false)
00270 {
00271 return (iShadowIterator*)(new csShadowIterator (this, true,
00272 reverse ? -1 : 1));
00273 }
00274
00276 virtual iSector* GetSector () { return sector; }
00278 virtual int GetRecLevel () { return draw_busy; }
00279
00280 SCF_DECLARE_IBASE;
00281 };
00282
00286 class csShadowBlockList : public iShadowBlockList
00287 {
00288 private:
00289 csShadowBlock* first;
00290 csShadowBlock* last;
00291
00292 public:
00294 csShadowBlockList ();
00296 virtual ~csShadowBlockList ()
00297 {
00298 DeleteAllShadows ();
00299 }
00300
00302 virtual iShadowBlock* NewShadowBlock (iSector* sector,
00303 int draw_busy, int num_shadows = 30);
00305 virtual iShadowBlock* NewShadowBlock ();
00306
00308 void AppendShadowBlock (csShadowBlock* slist)
00309 {
00310 CS_ASSERT (slist->prev == NULL && slist->next == NULL);
00311 CS_ASSERT ((!!first) == (!!last));
00312 slist->next = NULL;
00313 if (!last)
00314 {
00315 first = last = slist;
00316 slist->prev = NULL;
00317 }
00318 else
00319 {
00320 slist->prev = last;
00321 last->next = slist;
00322 last = slist;
00323 }
00324 }
00325
00327 virtual void RemoveLastShadowBlock ()
00328 {
00329 CS_ASSERT ((!!first) == (!!last));
00330 if (last)
00331 {
00332 CS_ASSERT (last->next == NULL);
00333 CS_ASSERT (first->prev == NULL);
00334 csShadowBlock* old = last;
00335 last = old->prev;
00336 if (last) last->next = NULL;
00337 else first = NULL;
00338 old->prev = old->next = NULL;
00339 }
00340 }
00341
00343 void Clear ()
00344 {
00345 CS_ASSERT ((!!first) == (!!last));
00346 # ifdef CS_DEBUG
00347
00348
00349 while (first)
00350 {
00351 csShadowBlock* old = first;
00352 first = old->next;
00353 old->prev = old->next = NULL;
00354 }
00355 # endif
00356 last = NULL;
00357 }
00358
00360 virtual void DeleteAllShadows ()
00361 {
00362 CS_ASSERT ((!!first) == (!!last));
00363 while (first)
00364 {
00365 first->DeleteShadows ();
00366 csShadowBlock* todel = first;
00367 first = first->next;
00368 delete todel;
00369 }
00370 last = NULL;
00371 }
00372
00373 virtual iShadowBlock* GetFirstShadowBlock () { return (iShadowBlock*)first; }
00374 virtual iShadowBlock* GetLastShadowBlock () { return (iShadowBlock*)last; }
00375 virtual iShadowBlock* GetNextShadowBlock (iShadowBlock* s)
00376 {
00377 return (iShadowBlock*)(((csShadowBlock*)s)->next);
00378 }
00379 virtual iShadowBlock* GetPreviousShadowBlock (iShadowBlock* s)
00380 {
00381 return (iShadowBlock*)(((csShadowBlock*)s)->prev);
00382 }
00383
00387 csShadowIterator* GetCsShadowIterator (bool reverse = false)
00388 {
00389 return new csShadowIterator (first, false, reverse ? -1 : 1);
00390 }
00391
00395 virtual iShadowIterator* GetShadowIterator (bool reverse = false)
00396 {
00397 return (iShadowIterator*)(new csShadowIterator (first, false,
00398 reverse ? -1 : 1));
00399 }
00400
00401 SCF_DECLARE_IBASE;
00402 };
00403
00404 class csFrustumView;
00405 class csObject;
00406 class csOctreeNode;
00407 typedef void (csFrustumViewFunc)(csObject* obj, csFrustumView* lview, bool vis);
00408 typedef void (csFrustumViewNodeFunc)(csOctreeNode* node, csFrustumView* lview,
00409 bool vis);
00410
00415 class csFrustumView : public iFrustumView
00416 {
00417 private:
00419 csFrustumViewNodeFunc* node_func;
00421 csFrustumViewFunc* poly_func;
00423 csFrustumViewFunc* curve_func;
00425 iFrustumViewUserdata* userdata;
00426
00428 float radius;
00429
00431 float sq_radius;
00432
00434 bool things_shadow;
00435
00441 unsigned int shadow_thing_mask, shadow_thing_value;
00447 unsigned int process_thing_mask, process_thing_value;
00448
00450 csFrustumContext* ctxt;
00451
00452 public:
00454 csFrustumView ();
00455
00457 virtual ~csFrustumView ();
00458
00460 virtual csFrustumContext* GetFrustumContext () const { return ctxt; }
00462 virtual void CreateFrustumContext ();
00464 virtual csFrustumContext* CopyFrustumContext ();
00466 virtual void SetFrustumContext (csFrustumContext* ctxt);
00468 virtual void RestoreFrustumContext (csFrustumContext* original);
00469
00471 virtual void StartNewShadowBlock ();
00472
00474 void SetNodeFunction (csFrustumViewNodeFunc* func) { node_func = func; }
00476 void SetPolygonFunction (csFrustumViewFunc* func) { poly_func = func; }
00478 void SetCurveFunction (csFrustumViewFunc* func) { curve_func = func; }
00480 virtual void CallNodeFunction (csOctreeNode* onode, bool vis)
00481 {
00482 if (node_func) node_func (onode, this, vis);
00483 }
00485 virtual void CallPolygonFunction (csObject* poly, bool vis)
00486 {
00487 poly_func (poly, this, vis);
00488 }
00490 virtual void CallCurveFunction (csObject* curve, bool vis)
00491 {
00492 curve_func (curve, this, vis);
00493 }
00495 void SetRadius (float rad)
00496 {
00497 radius = rad;
00498 sq_radius = rad*rad;
00499 }
00501 virtual float GetRadius () { return radius; }
00503 float GetSquaredRadius () { return sq_radius; }
00505 void EnableThingShadows (bool e) { things_shadow = e; }
00507 virtual bool ThingShadowsEnabled () { return things_shadow; }
00509 void SetShadowMask (unsigned int mask, unsigned int value)
00510 {
00511 shadow_thing_mask = mask;
00512 shadow_thing_value = value;
00513 }
00515 void SetProcessMask (unsigned int mask, unsigned int value)
00516 {
00517 process_thing_mask = mask;
00518 process_thing_value = value;
00519 }
00521 virtual bool CheckShadowMask (unsigned int mask)
00522 {
00523 return ((mask & shadow_thing_mask) == shadow_thing_value);
00524 }
00526 virtual bool CheckProcessMask (unsigned int mask)
00527 {
00528 return ((mask & process_thing_mask) == process_thing_value);
00529 }
00530
00532 virtual void SetUserdata (iFrustumViewUserdata* data)
00533 {
00534 SCF_SET_REF (userdata, data);
00535 }
00537 virtual iFrustumViewUserdata* GetUserdata ()
00538 {
00539 return userdata;
00540 }
00541 SCF_DECLARE_IBASE;
00542 };
00543
00544 #endif // __CS_LVIEW_H__
00545