csplugincommon/rendermanager/occluvis.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csplugincommon/rendermanager/occluvis.h

    00001 /*
    00002   Copyright (C) 2010 by Mike Gist and Claudiu Mihail
    00003
    00004   This library is free software; you can redistribute it and/or
    00005   modify it under the terms of the GNU Lesser General Public
    00006   License as published by the Free Software Foundation; either
    00007   version 2 of the License, or (at your option) any later version.
    00008
    00009   This library is distributed in the hope that it will be useful,
    00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012   Library General Public License for more details.
    00013
    00014   You should have received a copy of the GNU Library General Public
    00015   License along with this library; if not, write to the Free
    00016   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00017 */
    00018
    00019 #ifndef __CS_RENDERMANAGER_OCCLUVIS_H__
    00020 #define __CS_RENDERMANAGER_OCCLUVIS_H__
    00021
    00022 #include "csgeom/aabbtree.h"
    00023 #include "csutil/hash.h"
    00024 #include "csutil/refarr.h"
    00025 #include "csutil/scf_implementation.h"
    00026 #include "iengine/engine.h"
    00027 #include "iengine/movable.h"
    00028 #include "iengine/sector.h"
    00029 #include "iengine/viscull.h"
    00030 #include "imesh/objmodel.h"
    00031
    00032 struct iGraphics3D;
    00033 struct iMeshWrapper;
    00034 struct iObjectRegistry;
    00035
    00036 #include "csutil/deprecated_warn_off.h"
    00037
    00038 namespace CS
    00039 {
    00040   namespace RenderManager
    00041   {
    00042     // Frustum culling visibility results.
    00043     enum NodeVisibility
    00044     {
    00045       NODE_INVISIBLE,
    00046       NODE_VISIBLE,
    00047       NODE_INSIDE
    00048     };
    00049
    00050     // Occlusion visibility results.
    00051     enum OcclusionVisibility
    00052     {
    00053       VISIBLE,
    00054       UNKNOWN,
    00055       INVISIBLE,
    00056       INVALID
    00057     };
    00058
    00059     typedef csArray<iVisibilityObject*, csArrayElementHandler<iVisibilityObject*>,
    00060     CS::Container::ArrayAllocDefault, csArrayCapacityFixedGrow<256> >
    00061     VistestObjectsArray;
    00062
    00063     struct IntersectSegmentFront2BackData
    00064     {
    00065       csSegment3 seg;
    00066       csVector3 isect;
    00067       float sqdist;             // Squared distance between seg.start and isect.
    00068       float r;
    00069       iMeshWrapper* mesh;
    00070       int polygon_idx;
    00071       VistestObjectsArray* vector;      // If not-null we need all objects.
    00072       bool accurate;
    00073     };
    00074
    00075     struct QueryData : public csRefCount
    00076     {
    00077       unsigned int uOQuery;
    00078       uint32 uQueryFrame;
    00079       uint32 uNextCheck;
    00080       OcclusionVisibility eResult;
    00081
    00082       QueryData ()
    00083         : uOQuery (0), uQueryFrame (0),
    00084           uNextCheck (0), eResult (INVALID)
    00085       {}
    00086     };
    00087
    00088     struct AABBTreeNodeVisibilityData
    00089     {
    00090       AABBTreeNodeVisibilityData ()
    00091       {
    00092         g3d = 0;
    00093       }
    00094
    00095       ~AABBTreeNodeVisibilityData ()
    00096       {
    00097         if (g3d)
    00098         {
    00099           FreeQueryData ();
    00100         }
    00101       }
    00102
    00103       void LeafAddObject (iVisibilityObject*)
    00104       {
    00105         RViewQueryHash::GlobalIterator itr = RViewQueries.GetIterator ();
    00106         while (itr.HasNext ())
    00107         {
    00108           itr.Next ()->eResult = INVALID;
    00109         }
    00110       }
    00111
    00112       void LeafUpdateObjects (iVisibilityObject**, uint)
    00113       {
    00114         RViewQueryHash::GlobalIterator itr = RViewQueries.GetIterator ();
    00115         while (itr.HasNext ())
    00116         {
    00117           itr.Next ()->eResult = INVALID;
    00118         }
    00119       }
    00120
    00121       void NodeUpdate (const AABBTreeNodeVisibilityData& child1,
    00122         const AABBTreeNodeVisibilityData& child2)
    00123       {
    00124         RViewQueryHash::GlobalIterator itr = RViewQueries.GetIterator ();
    00125         while (itr.HasNext ())
    00126         {
    00127           itr.Next ()->eResult = INVALID;
    00128         }
    00129       }
    00130
    00131       QueryData* GetQueryData (iGraphics3D* ig3d, iRenderView* rview)
    00132       {
    00133         csRef<QueryData> queryData = RViewQueries.Get (csPtrKey<iRenderView> (rview), csRef<QueryData> ());
    00134
    00135         if (!queryData.IsValid ())
    00136         {
    00137           g3d = ig3d;
    00138           queryData.AttachNew (new QueryData);
    00139           g3d->OQInitQueries (&queryData->uOQuery, 1);
    00140           RViewQueries.Put (csPtrKey<iRenderView> (rview), queryData);
    00141         }
    00142
    00143         return queryData;
    00144       }
    00145
    00146       void FreeQueryData ()
    00147       {
    00148         RViewQueryHash::GlobalIterator itr = RViewQueries.GetIterator ();
    00149         while (itr.HasNext ())
    00150         {
    00151           g3d->OQDelQueries (&itr.Next ()->uOQuery, 1);
    00152         }
    00153
    00154         RViewQueries.DeleteAll ();
    00155       }
    00156
    00157     private:
    00158       iGraphics3D* g3d;
    00159
    00160       typedef csHash<csRef<QueryData>, csPtrKey<iRenderView> > RViewQueryHash;
    00161       RViewQueryHash RViewQueries;
    00162     };
    00163
    00164     typedef CS::Geometry::AABBTree<iVisibilityObject, 1, AABBTreeNodeVisibilityData> AABBVisTree;
    00165     typedef AABBVisTree::Node AABBVisTreeNode;
    00166
    00167     class CS_CRYSTALSPACE_EXPORT csOccluvis : public AABBVisTree,
    00168       public scfImplementation1<csOccluvis, iVisibilityCuller>
    00169     {
    00170     private:
    00171       iObjectRegistry *object_reg;
    00172       csRef<iGraphics3D> g3d;
    00173       csRef<iEngine> engine;
    00174       csRef<iShaderManager> shaderMgr;
    00175       csRef<iStringSet> stringSet;
    00176       csRef<iShaderVarStringSet> svStrings;
    00177
    00178       // Structure of common f2b data.
    00179       struct Front2BackData
    00180       {
    00181         csVector3 pos;
    00182         iRenderView* rview;
    00183         csPlane3* frustum;
    00184         iVisibilityCullerListener* viscallback;
    00185       };
    00186
    00187       struct NodeMeshList : public csRefCount
    00188       {
    00189         NodeMeshList () : numMeshes (0), meshList (nullptr)
    00190         {
    00191         }
    00192
    00193         ~NodeMeshList ()
    00194         {
    00195           delete[] meshList;
    00196         }
    00197
    00198         int numMeshes;
    00199         uint framePassed;
    00200         csBitArray onlyTestZ;
    00201         bool alwaysVisible;
    00202         AABBVisTreeNode* node;
    00203         csSectorVisibleRenderMeshes* meshList;
    00204       };
    00205
    00206       class csVisibilityObjectWrapper
    00207         : public scfImplementation2<csVisibilityObjectWrapper, iMovableListener, iObjectModelListener>
    00208       {
    00209       public:
    00210         csVisibilityObjectWrapper (csOccluvis* culler, iVisibilityObject* vis_obj);
    00211
    00213         virtual void ObjectModelChanged (iObjectModel* model);
    00214
    00216         virtual void MovableChanged (iMovable* movable);
    00217
    00219         virtual void MovableDestroyed (iMovable*);
    00220
    00221         inline iVisibilityObject* GetVisObject () const
    00222         {
    00223           return vis_obj;
    00224         }
    00225
    00226       private:
    00227         csOccluvis* culler;
    00228         iVisibilityObject* vis_obj;
    00229         csBox3 oldBBox;
    00230       };
    00231
    00232       // Array of visibility objects.
    00233       csRefArray<csVisibilityObjectWrapper> visObjects;
    00234
    00235       // Set to true to pass all objects regardless of visibility next VisCull.
    00236       bool bAllVisible;
    00237
    00238       // Frame skip parameter
    00239       static const unsigned int visibilityFrameSkip = 10;
    00240
    00241       // Hash of mesh nodes for a render view.
    00242       csHash<csRefArray<NodeMeshList>*, csPtrKey<iRenderView> > nodeMeshHash;
    00243
    00244       // Hashes of MeshList objects for visibility objects.
    00245       typedef csHash<NodeMeshList*, csPtrKey<iVisibilityObject> > VisObjMeshHash;
    00246       typedef csHash<VisObjMeshHash, csPtrKey<iRenderView> > VisObjMeshHashes;
    00247       VisObjMeshHashes visobjMeshHashes;
    00248
    00249       // Vector of vistest objects (used in the box/sphere/etc. tests).
    00250       VistestObjectsArray vistest_objects;
    00251       bool vistest_objects_inuse;
    00252
    00253       // Depth test shader type ID.
    00254       csStringID depthTestID;
    00255
    00256       // Depth write shader type ID.
    00257       csStringID depthWriteID;
    00258
    00259       // Fallback depth write shader type ID.
    00260       csStringID fbDepthWriteID;
    00261
    00262       // Name of the default depth write/test shader.
    00263       csString defaultShader;
    00264
    00265       // Shader variable stack for depth rendering.
    00266       csShaderVariableStack shaderVarStack;
    00267
    00268       friend class F2BSorter;
    00269
    00270     protected:
    00274       template<bool bQueryVisibility>
    00275       void RenderMeshes (AABBVisTreeNode* node,
    00276                          iRenderView* rview,
    00277                          size_t& lastTicket,
    00278                          iShader*& lastShader,
    00279                          iShaderVariableContext* shadervars,
    00280                          NodeMeshList*& nodeMeshList);
    00281
    00285       template<bool bDoFrustumCulling>
    00286       void TraverseTreeF2B(AABBVisTreeNode* node, uint32 frustum_mask,
    00287         Front2BackData& f2bData, csRefArray<NodeMeshList>& meshList);
    00288
    00292       inline AABBTreeNodeVisibilityData& GetNodeVisData (AABBVisTreeNode* node)
    00293       {
    00294         return static_cast<AABBTreeNodeVisibilityData&> (*node);
    00295       }
    00296
    00300       OcclusionVisibility GetNodeVisibility (AABBVisTreeNode* node, iRenderView* rview);
    00301
    00305       bool CheckNodeVisibility (AABBVisTreeNode* node, iRenderView* rview);
    00306
    00310       void BeginNodeQuery (AABBVisTreeNode* node, iRenderView* rview);
    00311
    00315       void GetF2BChildren (AABBVisTreeNode* node, Front2BackData& data,
    00316         AABBVisTreeNode*& fChild, AABBVisTreeNode*& bChild);
    00317
    00321       NodeVisibility TestNodeVisibility (AABBVisTreeNode* node, Front2BackData& data, uint32& frustum_mask);
    00322
    00326       void MarkAllVisible (AABBVisTreeNode* node, Front2BackData& f2bData);
    00327
    00331       static int NodeMeshListCompare (NodeMeshList* const& object, AABBVisTreeNode* const& key);
    00332
    00336       void TraverseTreeBox(AABBVisTreeNode* node,
    00337         VistestObjectsArray* voArray, const csBox3& box);
    00338
    00342       void TraverseTreeSphere(AABBVisTreeNode* node,
    00343         VistestObjectsArray* voArray, const csVector3& centre,
    00344         const float sqradius);
    00345
    00349       void TraverseTreeSphere(AABBVisTreeNode* node,
    00350         iVisibilityCullerListener* viscallback,
    00351         const csVector3& centre, const float sqradius);
    00352
    00357       void TraverseTreePlanes (AABBVisTreeNode* node,
    00358         VistestObjectsArray* voArray, csPlane3* planes,
    00359         uint32 frustum_mask);
    00360
    00365       void TraverseTreePlanes (AABBVisTreeNode* node,
    00366         iVisibilityCullerListener* viscallback,
    00367         csPlane3* planes, uint32 frustum_mask);
    00368
    00369     public:
    00370       csOccluvis (iObjectRegistry *object_reg);
    00371       virtual ~csOccluvis ();
    00372
    00373       virtual void Setup (const char* defaultShaderName);
    00374
    00378       virtual void RegisterVisObject (iVisibilityObject* visobj);
    00379
    00383       virtual void UnregisterVisObject (iVisibilityObject* visobj);
    00384
    00388       virtual bool VisTest (iRenderView* rview, iVisibilityCullerListener* viscallback, int, int);
    00389
    00390       virtual csPtr<iVisibilityObjectIterator> VisTest (const csBox3& box);
    00391
    00392       virtual csPtr<iVisibilityObjectIterator> VisTest (const csSphere& sphere);
    00393
    00394       virtual void VisTest (const csSphere& sphere,
    00395         iVisibilityCullerListener* viscallback);
    00396
    00397       virtual csPtr<iVisibilityObjectIterator> VisTest (csPlane3* planes, int num_planes);
    00398
    00399       virtual void VisTest (csPlane3* planes,
    00400         int num_planes, iVisibilityCullerListener* viscallback);
    00401
    00402       virtual csPtr<iVisibilityObjectIterator> IntersectSegmentSloppy (
    00403         const csVector3& start, const csVector3& end);
    00404
    00405       virtual csPtr<iVisibilityObjectIterator> IntersectSegment (
    00406         const csVector3& start, const csVector3& end, bool accurate = false);
    00407
    00408       virtual bool IntersectSegment (const csVector3& start,
    00409         const csVector3& end, csVector3& isect, float* pr = 0,
    00410         iMeshWrapper** p_mesh = 0, int* poly_idx = 0,
    00411         bool accurate = true);
    00412
    00416       virtual void RenderViscull (iRenderView* rview, iShaderVariableContext* shadervars);
    00417
    00421       virtual void BeginPrecacheCulling ()
    00422       {
    00423         bAllVisible = true;
    00424       }
    00425
    00429       virtual void EndPrecacheCulling ()
    00430       {
    00431         bAllVisible = false;
    00432       }
    00433
    00434       virtual void PrecacheCulling () { CS_ASSERT ("Call (Begin/End)PrecacheCulling!\n"); }
    00435       virtual const char* ParseCullerParameters (iDocumentNode* node) { return 0; }
    00436     };
    00437
    00438     class F2BSorter
    00439     {
    00440     public:
    00441       F2BSorter (iEngine* engine, const csVector3& cameraOrigin)
    00442         : cameraOrigin (cameraOrigin)
    00443       {
    00444         portalPriority = engine->GetRenderPriority ("portal");
    00445       }
    00446
    00447       bool operator() (csOccluvis::NodeMeshList* const& m1,
    00448                        csOccluvis::NodeMeshList* const& m2);
    00449
    00450     private:
    00451       const csVector3& cameraOrigin;
    00452       CS::Graphics::RenderPriority portalPriority;
    00453     };
    00454
    00455     class csOccluvisObjIt :
    00456       public scfImplementation1<csOccluvisObjIt, iVisibilityObjectIterator>
    00457     {
    00458     private:
    00459       VistestObjectsArray* vector;
    00460       size_t position;
    00461       bool* vistest_objects_inuse;
    00462
    00463     public:
    00464       csOccluvisObjIt (VistestObjectsArray* vector,
    00465         bool* vistest_objects_inuse) :
    00466         scfImplementationType(this)
    00467       {
    00468         csOccluvisObjIt::vector = vector;
    00469         csOccluvisObjIt::vistest_objects_inuse = vistest_objects_inuse;
    00470         if (vistest_objects_inuse) *vistest_objects_inuse = true;
    00471         Reset ();
    00472       }
    00473       virtual ~csOccluvisObjIt ()
    00474       {
    00475         // If the vistest_objects_inuse pointer is not 0 we set the
    00476         // bool to false to indicate we're no longer using the base
    00477         // vector. Otherwise we delete the vector.
    00478         if (vistest_objects_inuse)
    00479           *vistest_objects_inuse = false;
    00480         else
    00481           delete vector;
    00482       }
    00483
    00484       virtual iVisibilityObject* Next()
    00485       {
    00486         if (position == (size_t)-1) return 0;
    00487         iVisibilityObject* vo = vector->Get (position);
    00488         position++;
    00489         if (position == vector->GetSize ())
    00490           position = (size_t)-1;
    00491         return vo;
    00492       }
    00493
    00494       virtual void Reset()
    00495       {
    00496         if (vector == 0 || vector->GetSize () < 1)
    00497           position = (size_t)-1;
    00498         else
    00499           position = 0;
    00500       }
    00501
    00502       virtual bool HasNext () const
    00503       {
    00504         return ((position != (size_t)-1) && position <= vector->GetSize ());
    00505       }
    00506     };
    00507   }
    00508 }
    00509
    00510 #include "csutil/deprecated_warn_on.h"
    00511
    00512 #endif // __CS_RENDERMANAGER_OCCLUVIS_H__