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 "csgeom/box.h"
00025 #include "csutil/refarr.h"
00026 #include "iengine/shadows.h"
00027 #include "iengine/fview.h"
00028
00029 class csMatrix3;
00030 class csVector3;
00031 class csLight;
00032 class csFrustumView;
00033 struct csFog;
00034 struct iGraphics3D;
00035 struct iGraphics2D;
00036 struct iPolygon3D;
00037 struct iSector;
00038 struct iClipper2D;
00039
00045 class csShadowFrustum: public csFrustum
00046 {
00047 private:
00048 void* userData;
00049 bool relevant;
00050 public:
00052 csShadowFrustum () :
00053 csFrustum (csVector3 (0), &csPooledVertexArrayPool::GetDefaultPool()),
00054 userData (0), relevant (false) { }
00056 csShadowFrustum (const csVector3& origin) :
00057 csFrustum (origin, &csPooledVertexArrayPool::GetDefaultPool()),
00058 userData (0), relevant (false) { }
00060 csShadowFrustum (const csVector3& origin, int num_verts) :
00061 csFrustum (origin, num_verts, &csPooledVertexArrayPool::GetDefaultPool()),
00062 userData (0), relevant (false) { }
00064 csShadowFrustum (const csShadowFrustum& orig);
00066 void SetUserData (void* ud) { userData = ud; }
00068 void* GetUserData () { return userData; }
00070 void MarkRelevant (bool rel = true) { relevant = rel; }
00072 bool IsRelevant () { return relevant; }
00073 };
00074
00075 class csShadowBlockList;
00076 class csShadowBlock;
00077
00083 class csShadowIterator : public iShadowIterator
00084 {
00085 friend class csShadowBlockList;
00086 friend class csShadowBlock;
00087
00088 private:
00089 csShadowBlock* first_cur;
00090 csShadowBlock* cur;
00091 int i, cur_num;
00092 bool onlycur;
00093 int dir;
00094 csBox3 bbox;
00095 bool use_bbox;
00096 csShadowIterator (csShadowBlock* cur, bool onlycur, int dir);
00097 csShadowIterator (const csBox3& bbox, csShadowBlock* cur,
00098 bool onlycur, int dir);
00099 csShadowFrustum* cur_shad;
00100
00101 public:
00103 virtual bool HasNext ();
00105 virtual csFrustum* Next ();
00107 virtual void* GetUserData () { return cur_shad->GetUserData (); }
00109 virtual bool IsRelevant () { return cur_shad->IsRelevant (); }
00111 virtual void MarkRelevant (bool rel) { cur_shad->MarkRelevant (rel); }
00113 virtual void Reset ();
00115 virtual void DeleteCurrent ();
00117 virtual iShadowBlock* GetCurrentShadowBlock ();
00119 virtual iShadowBlock* GetNextShadowBlock ();
00121 csShadowBlock* GetCsCurrentShadowBlock ();
00123 csShadowBlock* GetCsNextShadowBlock () { return cur; }
00124
00125 SCF_DECLARE_IBASE;
00126 };
00127
00133 class csShadowBlock : public iShadowBlock
00134 {
00135 friend class csShadowBlockList;
00136 friend class csShadowIterator;
00137
00138 private:
00139 csShadowBlock* next, * prev;
00140 csRefArray<csShadowFrustum> shadows;
00141 uint32 shadow_region;
00142 csBox3 bbox;
00143 bool bbox_valid;
00144
00145 void IntAddShadow (csShadowFrustum* csf);
00146
00147 public:
00149 csShadowBlock (uint32 region = (uint32)~0, int max_shadows = 30,
00150 int delta = 30);
00151
00153 virtual ~csShadowBlock ();
00154
00156 virtual void DeleteShadows ()
00157 {
00158 shadows.DeleteAll ();
00159 bbox_valid = false;
00160 }
00161
00163 virtual const csBox3& GetBoundingBox ();
00164
00171 void AddRelevantShadows (csShadowBlock* source, csTransform* trans = 0);
00172
00179 virtual void AddRelevantShadows (iShadowBlock* source,
00180 csTransform* trans = 0);
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 (idx < shadows.Length () ? (csFrustum*)shadows[idx] : 0);
00245 }
00246
00250 void Transform (csTransform* trans)
00251 {
00252 int i;
00253 for (i = 0 ; i < shadows.Length () ; i++)
00254 {
00255 csShadowFrustum* sf = shadows[i];
00256 CS_ASSERT (sf != 0);
00257 sf->Transform (trans);
00258 }
00259 bbox_valid = false;
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 uint32 GetShadowRegion () const { return shadow_region; }
00277
00278 SCF_DECLARE_IBASE;
00279 };
00280
00284 class csShadowBlockList : public iShadowBlockList
00285 {
00286 private:
00287 csShadowBlock* first;
00288 csShadowBlock* last;
00289 uint32 cur_shadow_region;
00290
00291 public:
00293 csShadowBlockList ();
00295 virtual ~csShadowBlockList ()
00296 {
00297 DeleteAllShadows ();
00298 }
00299
00301 virtual iShadowBlock* NewShadowBlock (int num_shadows = 30);
00302
00304 void AppendShadowBlock (csShadowBlock* slist)
00305 {
00306 CS_ASSERT (slist->prev == 0 && slist->next == 0);
00307 CS_ASSERT ((!!first) == (!!last));
00308 slist->next = 0;
00309 if (!last)
00310 {
00311 first = last = slist;
00312 slist->prev = 0;
00313 }
00314 else
00315 {
00316 slist->prev = last;
00317 last->next = slist;
00318 last = slist;
00319 }
00320 }
00321
00323 virtual void RemoveLastShadowBlock ()
00324 {
00325 CS_ASSERT ((!!first) == (!!last));
00326 if (last)
00327 {
00328 CS_ASSERT (last->next == 0);
00329 CS_ASSERT (first->prev == 0);
00330 csShadowBlock* old = last;
00331 last = old->prev;
00332 if (last) last->next = 0;
00333 else first = 0;
00334 old->prev = old->next = 0;
00335 }
00336 }
00337
00339 void Clear ()
00340 {
00341 CS_ASSERT ((!!first) == (!!last));
00342 # ifdef CS_DEBUG
00343
00344
00345 while (first)
00346 {
00347 csShadowBlock* old = first;
00348 first = old->next;
00349 old->prev = old->next = 0;
00350 }
00351 # endif
00352 last = 0;
00353 }
00354
00356 virtual void DeleteAllShadows ()
00357 {
00358 CS_ASSERT ((!!first) == (!!last));
00359 while (first)
00360 {
00361 first->DeleteShadows ();
00362 csShadowBlock* todel = first;
00363 first = first->next;
00364 delete todel;
00365 }
00366 last = 0;
00367 }
00368
00369 virtual iShadowBlock* GetFirstShadowBlock () { return (iShadowBlock*)first; }
00370 virtual iShadowBlock* GetLastShadowBlock () { return (iShadowBlock*)last; }
00371 virtual iShadowBlock* GetNextShadowBlock (iShadowBlock* s)
00372 {
00373 return (iShadowBlock*)(((csShadowBlock*)s)->next);
00374 }
00375 virtual iShadowBlock* GetPreviousShadowBlock (iShadowBlock* s)
00376 {
00377 return (iShadowBlock*)(((csShadowBlock*)s)->prev);
00378 }
00379
00383 csShadowIterator* GetCsShadowIterator (bool reverse = false)
00384 {
00385 return new csShadowIterator (first, false, reverse ? -1 : 1);
00386 }
00387
00391 virtual iShadowIterator* GetShadowIterator (bool reverse = false)
00392 {
00393 return (iShadowIterator*)(new csShadowIterator (first, false,
00394 reverse ? -1 : 1));
00395 }
00396 virtual iShadowIterator* GetShadowIterator (
00397 const csBox3& bbox, bool reverse = false)
00398 {
00399 return (iShadowIterator*)(new csShadowIterator (bbox, first, false,
00400 reverse ? -1 : 1));
00401 }
00402
00403 virtual uint32 MarkNewRegion ()
00404 {
00405 cur_shadow_region++;
00406 return cur_shadow_region-1;
00407 }
00408
00409 virtual void RestoreRegion (uint32 prev)
00410 {
00411 cur_shadow_region = prev;
00412 }
00413
00414 virtual bool FromCurrentRegion (iShadowBlock* block)
00415 {
00416 return ((csShadowBlock*)block)->GetShadowRegion () == cur_shadow_region;
00417 }
00418
00419 SCF_DECLARE_IBASE;
00420 };
00421
00426 class csFrustumView : public iFrustumView
00427 {
00428 private:
00430 csFrustumViewObjectFunc* object_func;
00432 csRef<iFrustumViewUserdata> userdata;
00433
00435 float radius;
00436
00438 float sq_radius;
00439
00441 bool things_shadow;
00442
00448 unsigned int shadow_thing_mask, shadow_thing_value;
00454 unsigned int process_thing_mask, process_thing_value;
00455
00457 csFrustumContext* ctxt;
00458
00459 public:
00461 csFrustumView ();
00462
00464 virtual ~csFrustumView ();
00465
00467 virtual csFrustumContext* GetFrustumContext () const { return ctxt; }
00469 virtual void CreateFrustumContext ();
00471 virtual csFrustumContext* CopyFrustumContext ();
00473 virtual void SetFrustumContext (csFrustumContext* ctxt);
00475 virtual void RestoreFrustumContext (csFrustumContext* original);
00476
00478 virtual void StartNewShadowBlock ();
00479
00481 virtual void SetObjectFunction (csFrustumViewObjectFunc* func)
00482 {
00483 object_func = func;
00484 }
00486 virtual void CallObjectFunction (iMeshWrapper* mesh, bool vis)
00487 {
00488 if (object_func) object_func (mesh, this, vis);
00489 }
00491 void SetRadius (float rad)
00492 {
00493 radius = rad;
00494 sq_radius = rad*rad;
00495 }
00497 virtual float GetRadius () const { return radius; }
00499 virtual float GetSquaredRadius () const { return sq_radius; }
00501 void EnableThingShadows (bool e) { things_shadow = e; }
00503 virtual bool ThingShadowsEnabled () { return things_shadow; }
00505 void SetShadowMask (unsigned int mask, unsigned int value)
00506 {
00507 shadow_thing_mask = mask;
00508 shadow_thing_value = value;
00509 }
00511 void SetProcessMask (unsigned int mask, unsigned int value)
00512 {
00513 process_thing_mask = mask;
00514 process_thing_value = value;
00515 }
00517 virtual bool CheckShadowMask (unsigned int mask)
00518 {
00519 return ((mask & shadow_thing_mask) == shadow_thing_value);
00520 }
00522 virtual bool CheckProcessMask (unsigned int mask)
00523 {
00524 return ((mask & process_thing_mask) == process_thing_value);
00525 }
00526
00528 virtual void SetUserdata (iFrustumViewUserdata* data)
00529 {
00530 userdata = data;
00531 }
00533 virtual iFrustumViewUserdata* GetUserdata ()
00534 {
00535 return userdata;
00536 }
00537 virtual csPtr<iShadowBlock> CreateShadowBlock ()
00538 {
00539 return csPtr<iShadowBlock> (new csShadowBlock ());
00540 }
00541 SCF_DECLARE_IBASE;
00542 };
00543
00544 #endif // __CS_LVIEW_H__
00545