llspatialpartition.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLSPATIALPARTITION_H
00033 #define LL_LLSPATIALPARTITION_H
00034 
00035 #define SG_MIN_DIST_RATIO 0.00001f
00036 
00037 #include "llmemory.h"
00038 #include "lldrawable.h"
00039 #include "lloctree.h"
00040 #include "llvertexbuffer.h"
00041 #include "llgltypes.h"
00042 #include "llcubemap.h"
00043 #include "lldrawpool.h"
00044 
00045 #include <queue>
00046 
00047 #define SG_STATE_INHERIT_MASK (OCCLUDED)
00048 #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
00049 
00050 class LLSpatialPartition;
00051 class LLSpatialBridge;
00052 class LLSpatialGroup;
00053 
00054 S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);
00055 
00056 class LLDrawInfo : public LLRefCount 
00057 {
00058 protected:
00059         ~LLDrawInfo();  
00060         
00061 public:
00062         LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, 
00063                                 LLViewerImage* image, LLVertexBuffer* buffer, 
00064                                 BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
00065         
00066 
00067         LLPointer<LLVertexBuffer> mVertexBuffer;
00068         LLPointer<LLViewerImage> mTexture;
00069         LLPointer<LLCubeMap> mReflectionMap;
00070         LLColor4U mGlowColor;
00071         S32 mDebugColor;
00072         const LLMatrix4* mTextureMatrix;
00073         const LLMatrix4* mModelMatrix;
00074         U16 mStart;
00075         U16 mEnd;
00076         U32 mCount;
00077         U32 mOffset;
00078         BOOL mFullbright;
00079         U8 mBump;
00080         BOOL mParticle;
00081         F32 mPartSize;
00082         F32 mVSize;
00083         LLSpatialGroup* mGroup;
00084 
00085         struct CompareTexture
00086         {
00087                 bool operator()(const LLDrawInfo& lhs, const LLDrawInfo& rhs)
00088                 {
00089                         return lhs.mTexture > rhs.mTexture;
00090                 }
00091         };
00092 
00093         struct CompareTexturePtr
00094         { //sort by texture
00095                 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)     
00096                 {
00097                         // sort by pointer, sort NULL down to the end
00098                         return lhs.get() != rhs.get() 
00099                                                 && (lhs.isNull() || (rhs.notNull() && lhs->mTexture.get() > rhs->mTexture.get()));
00100                 }
00101         };
00102 
00103         struct CompareTexturePtrMatrix
00104         {
00105                 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)     
00106                 {
00107                         return lhs.get() != rhs.get() 
00108                                                 && (lhs.isNull() || (rhs.notNull() && (lhs->mTexture.get() > rhs->mTexture.get() ||
00109                                                                                                                            (lhs->mTexture.get() == rhs->mTexture.get() && lhs->mModelMatrix > rhs->mModelMatrix))));
00110                 }
00111 
00112         };
00113 
00114         struct CompareBump
00115         {
00116                 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) 
00117                 {
00118                         // sort by mBump value, sort NULL down to the end
00119                         return lhs.get() != rhs.get() 
00120                                                 && (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump));
00121                 }
00122         };
00123 };
00124 
00125 class LLSpatialGroup : public LLOctreeListener<LLDrawable>
00126 {
00127         friend class LLSpatialPartition;
00128 public:
00129         static U32 sNodeCount;
00130 
00131         typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
00132         typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t;
00133         typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
00134         typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; 
00135         typedef std::map<U32, drawmap_elem_t > draw_map_t;      
00136         typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
00137         typedef std::map<LLPointer<LLViewerImage>, buffer_list_t> buffer_map_t;
00138 
00139         typedef LLOctreeListener<LLDrawable>    BaseType;
00140         typedef LLOctreeListener<LLDrawable>    OctreeListener;
00141         typedef LLTreeNode<LLDrawable>                  TreeNode;
00142         typedef LLOctreeNode<LLDrawable>                OctreeNode;
00143         typedef LLOctreeRoot<LLDrawable>                OctreeRoot;
00144         typedef LLOctreeTraveler<LLDrawable>    OctreeTraveler;
00145         typedef LLOctreeNode<LLDrawable>::element_iter element_iter;
00146         typedef LLOctreeNode<LLDrawable>::element_list element_list;
00147 
00148         struct CompareDistanceGreater
00149         {
00150                 bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
00151                 {
00152                         return lhs->mDistance > rhs->mDistance;
00153                 }
00154         };
00155 
00156         struct CompareDepthGreater
00157         {
00158                 bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
00159                 {
00160                         return lhs->mDepth > rhs->mDepth;
00161                 }
00162         };
00163 
00164         typedef enum
00165         {
00166                 OCCLUDED                                = 0x00000001,
00167                 IN_QUEUE                                = 0x00000002,
00168                 QUERY_PENDING                   = 0x00000004,
00169                 ACTIVE_OCCLUSION                = 0x00000008,
00170                 DISCARD_QUERY                   = 0x00000010,
00171                 DEAD                                    = 0x00000020,
00172                 EARLY_FAIL                              = 0x00000040,
00173                 DIRTY                                   = 0x00000080,
00174                 OBJECT_DIRTY                    = 0x00000100,
00175                 GEOM_DIRTY                              = 0x00000200,
00176                 ALPHA_DIRTY                             = 0x00000800,
00177                 SKIP_FRUSTUM_CHECK              = 0x00001000,
00178                 IN_IMAGE_QUEUE                  = 0x00002000,
00179                 IMAGE_DIRTY                             = 0x00004000,
00180                 OCCLUSION_DIRTY                 = 0x00008000,
00181                 MESH_DIRTY                              = 0x00010000,
00182         } eSpatialState;
00183 
00184         typedef enum
00185         {
00186                 STATE_MODE_SINGLE = 0,          //set one node
00187                 STATE_MODE_BRANCH,                      //set entire branch
00188                 STATE_MODE_DIFF                         //set entire branch as long as current state is different
00189         } eSetStateMode;
00190 
00191         LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
00192 
00193         BOOL isDead()                                                   { return isState(DEAD); }
00194         BOOL isState(U32 state) const                   { return mState & state ? TRUE : FALSE; }
00195         U32 getState()                                                  { return mState; }
00196         void setState(U32 state);       
00197         void clearState(U32 state);     
00198         
00199         void clearDrawMap();
00200         void validate();
00201         void checkStates();
00202         void validateDrawMap();
00203         
00204         void setState(U32 state, S32 mode);
00205 
00206         LLSpatialGroup* getParent();
00207 
00208         void clearState(U32 state, S32 mode);
00209         BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
00210         BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
00211         BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
00212         BOOL isVisible() const;
00213         void setVisible();
00214         void shift(const LLVector3 &offset);
00215         BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
00216         void unbound();
00217         BOOL rebound();
00218         void buildOcclusion(); //rebuild mOcclusionVerts
00219         void checkOcclusion(); //read back last occlusion query (if any)
00220         void doOcclusion(LLCamera* camera); //issue occlusion query
00221         void destroyGL();
00222         
00223         void updateDistance(LLCamera& camera);
00224         BOOL needsUpdate();
00225         BOOL changeLOD();
00226         void rebuildGeom();
00227 
00228         void dirtyGeom() { setState(GEOM_DIRTY); }
00229         void dirtyMesh() { setState(MESH_DIRTY); }
00230         element_list& getData() { return mOctreeNode->getData(); }
00231         U32 getElementCount() const { return mOctreeNode->getElementCount(); }
00232 
00233          //LISTENER FUNCTIONS
00234         virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
00235         virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
00236         virtual void handleDestruction(const TreeNode* node);
00237         virtual void handleStateChange(const TreeNode* node);
00238         virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
00239         virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
00240 
00241 protected:
00242         virtual ~LLSpatialGroup();
00243 
00244         U32 mState;
00245         S32 mLODHash;
00246         static S32 sLODSeed;
00247 
00248 public:
00249         bridge_list_t mBridgeList;
00250         buffer_map_t mBufferMap; //used by volume buffers to store unique buffers per texture
00251 
00252         F32 mBuilt;
00253         OctreeNode* mOctreeNode;
00254         LLSpatialPartition* mSpatialPartition;
00255         LLVector3 mBounds[2];
00256         LLVector3 mExtents[2];
00257         
00258         LLVector3 mObjectExtents[2];
00259         LLVector3 mObjectBounds[2];
00260 
00261         LLPointer<LLVertexBuffer> mVertexBuffer;
00262         F32*                                    mOcclusionVerts;
00263         GLuint                                  mOcclusionQuery;
00264         LLPointer<LLCubeMap>    mReflectionMap;
00265 
00266         U32 mBufferUsage;
00267         draw_map_t mDrawMap;
00268         
00269         S32 mVisible;
00270         F32 mDistance;
00271         F32 mDepth;
00272         F32 mLastUpdateDistance;
00273         F32 mLastUpdateTime;
00274                         
00275         LLVector3 mViewAngle;
00276         LLVector3 mLastUpdateViewAngle;
00277         
00278         F32 mPixelArea;
00279         F32 mRadius;
00280 };
00281 
00282 class LLGeometryManager
00283 {
00284 public:
00285         std::vector<LLFace*> mFaceList;
00286         virtual ~LLGeometryManager() { }
00287         virtual void rebuildGeom(LLSpatialGroup* group) = 0;
00288         virtual void getGeometry(LLSpatialGroup* group) = 0;
00289         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count);
00290         virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
00291 };
00292 
00293 class LLSpatialPartition: public LLGeometryManager
00294 {
00295 public:
00296         static BOOL sFreezeState; //if true, no spatialgroup state updates will be made
00297 
00298         LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB);
00299         virtual ~LLSpatialPartition();
00300 
00301         LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
00302         BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
00303         
00304         LLDrawable*     pickDrawable(const LLVector3& start, const LLVector3& end, LLVector3& collision);
00305         
00306         // If the drawable moves, move it here.
00307         virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
00308         virtual void shift(const LLVector3 &offset);
00309 
00310         virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera);
00311         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00312 
00313         virtual void rebuildGeom(LLSpatialGroup* group);
00314 
00315         S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
00316         void markReimage(LLSpatialGroup* group);
00317         void processImagery(LLCamera* camera);
00318         
00319         BOOL isVisible(const LLVector3& v);
00320         
00321         virtual LLSpatialBridge* asBridge() { return NULL; }
00322         virtual BOOL isBridge() { return asBridge() != NULL; }
00323 
00324         void renderDebug();
00325         void restoreGL();
00326         void resetVertexBuffers();
00327         
00328 protected:
00329         
00330         typedef std::set<LLPointer<LLSpatialGroup> > spatial_group_set_t;
00331         spatial_group_set_t mSpatialGroups;
00332 
00333         typedef std::queue<LLPointer<LLSpatialGroup> > spatial_group_queue_t;
00334         
00335         //things that need an image update
00336         spatial_group_queue_t mImageQueue;
00337 
00338 public:
00339         LLSpatialGroup::OctreeNode* mOctree;
00340         BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
00341         BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
00342         U32 mBufferUsage;
00343         BOOL mRenderByGroup;
00344         BOOL mImageEnabled;
00345         U32 mLODSeed;
00346         U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed)
00347         U32 mVertexDataMask;
00348         F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
00349         BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
00350         U32 mDrawableType;
00351         U32 mPartitionType;
00352 };
00353 
00354 // class for creating bridges between spatial partitions
00355 class LLSpatialBridge : public LLDrawable, public LLSpatialPartition
00356 {
00357 protected:
00358         ~LLSpatialBridge();
00359 
00360 public:
00361         typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
00362         
00363         LLSpatialBridge(LLDrawable* root, U32 data_mask);
00364         
00365         virtual BOOL isSpatialBridge() const            { return TRUE; }
00366 
00367         virtual void updateSpatialExtents();
00368         virtual void updateBinRadius();
00369         virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
00370         virtual void updateDistance(LLCamera& camera_in);
00371         virtual void makeActive();
00372         virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
00373         virtual BOOL updateMove();
00374         virtual void shiftPos(const LLVector3& vec);
00375         virtual void cleanupReferences();
00376         virtual LLSpatialPartition* asPartition()               { return this; }
00377         virtual LLSpatialBridge* asBridge()                             { return this; }
00378         
00379         virtual LLCamera transformCamera(LLCamera& camera);
00380         
00381         LLDrawable* mDrawable;
00382 };
00383 
00384 class LLCullResult 
00385 {
00386 public:
00387         LLCullResult();
00388 
00389         typedef std::vector<LLSpatialGroup*> sg_list_t;
00390         typedef std::vector<LLDrawable*> drawable_list_t;
00391         typedef std::vector<LLSpatialBridge*> bridge_list_t;
00392         typedef std::vector<LLDrawInfo*> drawinfo_list_t;
00393 
00394         void clear();
00395         
00396         sg_list_t::iterator beginVisibleGroups();
00397         sg_list_t::iterator endVisibleGroups();
00398 
00399         sg_list_t::iterator beginAlphaGroups();
00400         sg_list_t::iterator endAlphaGroups();
00401 
00402         sg_list_t::iterator beginOcclusionGroups();
00403         sg_list_t::iterator endOcclusionGroups();
00404 
00405         sg_list_t::iterator beginDrawableGroups();
00406         sg_list_t::iterator endDrawableGroups();
00407 
00408         drawable_list_t::iterator beginVisibleList();
00409         drawable_list_t::iterator endVisibleList();
00410 
00411         bridge_list_t::iterator beginVisibleBridge();
00412         bridge_list_t::iterator endVisibleBridge();
00413 
00414         drawinfo_list_t::iterator beginRenderMap(U32 type);
00415         drawinfo_list_t::iterator endRenderMap(U32 type);
00416 
00417         void pushVisibleGroup(LLSpatialGroup* group);
00418         void pushAlphaGroup(LLSpatialGroup* group);
00419         void pushOcclusionGroup(LLSpatialGroup* group);
00420         void pushDrawableGroup(LLSpatialGroup* group);
00421         void pushDrawable(LLDrawable* drawable);
00422         void pushBridge(LLSpatialBridge* bridge);
00423         void pushDrawInfo(U32 type, LLDrawInfo* draw_info);
00424 
00425         U32 getVisibleGroupsSize()              { return mVisibleGroupsSize; }
00426         U32     getAlphaGroupsSize()            { return mAlphaGroupsSize; }
00427         U32     getDrawableGroupsSize()         { return mDrawableGroupsSize; }
00428         U32     getVisibleListSize()            { return mVisibleListSize; }
00429         U32     getVisibleBridgeSize()          { return mVisibleBridgeSize; }
00430         U32     getRenderMapSize(U32 type)      { return mRenderMapSize[type]; }
00431 
00432 private:
00433         U32                                     mVisibleGroupsSize;
00434         U32                                     mAlphaGroupsSize;
00435         U32                                     mOcclusionGroupsSize;
00436         U32                                     mDrawableGroupsSize;
00437         U32                                     mVisibleListSize;
00438         U32                                     mVisibleBridgeSize;
00439         U32                                     mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
00440 
00441         sg_list_t                       mVisibleGroups;
00442         sg_list_t                       mAlphaGroups;
00443         sg_list_t                       mOcclusionGroups;
00444         sg_list_t                       mDrawableGroups;
00445         drawable_list_t         mVisibleList;
00446         bridge_list_t           mVisibleBridge;
00447         drawinfo_list_t         mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
00448 };
00449 
00450 //spatial partition for water (implemented in LLVOWater.cpp)
00451 class LLWaterPartition : public LLSpatialPartition
00452 {
00453 public:
00454         LLWaterPartition();
00455         virtual void getGeometry(LLSpatialGroup* group) {  }
00456         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
00457 };
00458 
00459 //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
00460 class LLTerrainPartition : public LLSpatialPartition
00461 {
00462 public:
00463         LLTerrainPartition();
00464         virtual void getGeometry(LLSpatialGroup* group);
00465         virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
00466 };
00467 
00468 //spatial partition for trees
00469 class LLTreePartition : public LLSpatialPartition
00470 {
00471 public:
00472         LLTreePartition();
00473         virtual void getGeometry(LLSpatialGroup* group) { }
00474         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
00475 
00476 };
00477 
00478 //spatial partition for particles (implemented in LLVOPartGroup.cpp)
00479 class LLParticlePartition : public LLSpatialPartition
00480 {
00481 public:
00482         LLParticlePartition();
00483         virtual void getGeometry(LLSpatialGroup* group);
00484         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
00485         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00486 protected:
00487         U32 mRenderPass;
00488 };
00489 
00490 //spatial partition for grass (implemented in LLVOGrass.cpp)
00491 class LLGrassPartition : public LLParticlePartition
00492 {
00493 public:
00494         LLGrassPartition();
00495 };
00496 
00497 //spatial partition for clouds (implemented in LLVOClouds.cpp)
00498 class LLCloudPartition : public LLParticlePartition
00499 {
00500 public:
00501         LLCloudPartition();
00502 };
00503 
00504 //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
00505 class LLVolumeGeometryManager: public LLGeometryManager
00506 {
00507 public:
00508         virtual ~LLVolumeGeometryManager() { }
00509         virtual void rebuildGeom(LLSpatialGroup* group);
00510         virtual void getGeometry(LLSpatialGroup* group);
00511         void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
00512 };
00513 
00514 //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
00515 class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
00516 {
00517 public:
00518         LLVolumePartition();
00519         virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
00520         virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
00521         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
00522 };
00523 
00524 //spatial bridge that uses volume geometry manager (implemented in LLVOVolume.cpp)
00525 class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
00526 {
00527 public:
00528         LLVolumeBridge(LLDrawable* drawable);
00529         virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
00530         virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
00531         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
00532 };
00533 
00534 class LLHUDBridge : public LLVolumeBridge
00535 {
00536 public:
00537         LLHUDBridge(LLDrawable* drawablep);
00538         virtual void shiftPos(const LLVector3& vec);
00539         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00540 };
00541 
00542 //spatial partition that holds nothing but spatial bridges
00543 class LLBridgePartition : public LLSpatialPartition
00544 {
00545 public:
00546         LLBridgePartition();
00547         virtual void getGeometry(LLSpatialGroup* group) { }
00548         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) {  }
00549 };
00550 
00551 class LLHUDPartition : public LLBridgePartition
00552 {
00553 public:
00554         LLHUDPartition();
00555         virtual void shift(const LLVector3 &offset);
00556 };
00557 
00558 void validate_draw_info(LLDrawInfo& params);
00559 
00560 extern const F32 SG_BOX_SIDE;
00561 extern const F32 SG_BOX_OFFSET;
00562 extern const F32 SG_BOX_RAD;
00563 
00564 extern const F32 SG_OBJ_SIDE;
00565 extern const F32 SG_MAX_OBJ_RAD;
00566 
00567 
00568 #endif //LL_LLSPATIALPARTITION_H
00569 

Generated on Fri May 16 08:34:01 2008 for SecondLife by  doxygen 1.5.5