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 
00044 #include <queue>
00045 
00046 #define SG_STATE_INHERIT_MASK (CULLED | OCCLUDED)
00047 #define SG_INITIAL_STATE_MASK (OCCLUSION_DIRTY | DIRTY | GEOM_DIRTY)
00048 
00049 class LLSpatialPartition;
00050 class LLSpatialBridge;
00051 
00052 class LLDrawInfo : public LLRefCount 
00053 {
00054 protected:
00055         ~LLDrawInfo();  
00056         
00057 public:
00058         LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, 
00059                                 LLViewerImage* image, LLVertexBuffer* buffer, 
00060                                 BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
00061         
00062 
00063         LLPointer<LLVertexBuffer> mVertexBuffer;
00064         LLPointer<LLViewerImage> mTexture;
00065         LLPointer<LLCubeMap> mReflectionMap;
00066         LLColor4U mGlowColor;
00067         const LLMatrix4* mTextureMatrix;
00068         U32 mStart;
00069         U32 mEnd;
00070         U32 mCount;
00071         U32 mOffset;
00072         BOOL mFullbright;
00073         U8 mBump;
00074         BOOL mParticle;
00075         F32 mPartSize;
00076         F32 mVSize;
00077         
00078         struct CompareTexture
00079         {
00080                 bool operator()(const LLDrawInfo& lhs, const LLDrawInfo& rhs)
00081                 {
00082                         return lhs.mTexture > rhs.mTexture;
00083                 }
00084         };
00085 
00086         struct CompareTexturePtr
00087         {
00088                 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)     
00089                 {
00090                         // sort by pointer, sort NULL down to the end
00091                         return lhs.get() != rhs.get() 
00092                                                 && (lhs.isNull() || (rhs.notNull() && lhs->mTexture.get() > rhs->mTexture.get()));
00093                 }
00094         };
00095 
00096         struct CompareBump
00097         {
00098                 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) 
00099                 {
00100                         // sort by mBump value, sort NULL down to the end
00101                         return lhs.get() != rhs.get() 
00102                                                 && (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump));
00103                 }
00104         };
00105 };
00106 
00107 class LLSpatialGroup : public LLOctreeListener<LLDrawable>
00108 {
00109         friend class LLSpatialPartition;
00110 public:
00111 
00112         typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
00113         typedef std::set<LLPointer<LLSpatialGroup> > sg_set_t;
00114         typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
00115         typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t; 
00116         typedef std::map<U32, drawmap_elem_t > draw_map_t;      
00117         typedef std::map<LLPointer<LLViewerImage>, LLPointer<LLVertexBuffer> > buffer_map_t;
00118 
00119         typedef LLOctreeListener<LLDrawable>    BaseType;
00120         typedef LLOctreeListener<LLDrawable>    OctreeListener;
00121         typedef LLTreeNode<LLDrawable>                  TreeNode;
00122         typedef LLOctreeNode<LLDrawable>                OctreeNode;
00123         typedef LLOctreeRoot<LLDrawable>                OctreeRoot;
00124         typedef LLOctreeState<LLDrawable>               OctreeState;
00125         typedef LLOctreeTraveler<LLDrawable>    OctreeTraveler;
00126         typedef LLOctreeState<LLDrawable>::element_iter element_iter;
00127         typedef LLOctreeState<LLDrawable>::element_list element_list;
00128 
00129         struct CompareDistanceGreater
00130         {
00131                 bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
00132                 {
00133                         return lhs->mDistance > rhs->mDistance;
00134                 }
00135         };
00136 
00137         struct CompareDepthGreater
00138         {
00139                 bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
00140                 {
00141                         return lhs->mDepth > rhs->mDepth;
00142                 }
00143         };
00144 
00145         typedef enum
00146         {
00147                 IN_QUEUE                                = 0x00000001,
00148                 QUERY_PENDING                   = 0x00000002,
00149                 CULLED                                  = 0x00000004,
00150                 OCCLUDED                                = 0x00000008,
00151                 DEAD                                    = 0x00000010,
00152                 ACTIVE_OCCLUSION                = 0x00000020,
00153                 EARLY_FAIL                              = 0x00000040,
00154                 DEACTIVATE_OCCLUSION    = 0x00000080,
00155                 RESHADOW                                = 0x00000100,
00156                 RESHADOW_QUEUE                  = 0x00000200,
00157                 DIRTY                                   = 0x00000400,
00158                 OBJECT_DIRTY                    = 0x00000800,
00159                 GEOM_DIRTY                              = 0x00001000,
00160                 MATRIX_DIRTY                    = 0x00002000,
00161                 ALPHA_DIRTY                             = 0x00004000,
00162                 DISCARD_QUERY                   = 0x00008000,
00163                 QUERY_OUT                               = 0x00010000,
00164                 OCCLUDING                               = 0x00020000,
00165                 SKIP_FRUSTUM_CHECK              = 0x00040000,
00166                 OCCLUSION_DIRTY                 = 0x00080000,
00167                 BELOW_WATER                             = 0x00100000,
00168                 IN_IMAGE_QUEUE                  = 0x00200000,
00169                 IMAGE_DIRTY                             = 0x00400000,
00170         } eSpatialState;
00171 
00172         typedef enum
00173         {
00174                 STATE_MODE_SINGLE = 0,          //set one node
00175                 STATE_MODE_BRANCH,                      //set entire branch
00176                 STATE_MODE_DIFF                         //set entire branch as long as current state is different
00177         } eSetStateMode;
00178 
00179         LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
00180 
00181         BOOL isDead()                                                   { return isState(DEAD); }
00182         BOOL isState(U32 state) const                   { return mState & state ? TRUE : FALSE; }
00183         U32 getState()                                                  { return mState; }
00184         void setState(U32 state)                                { mState |= state; }
00185         void clearState(U32 state)                              { mState &= ~state; }
00186         
00187         void clearDrawMap();
00188         void validate();
00189         void validateDrawMap();
00190         
00191         void setState(U32 state, S32 mode);
00192 
00193         LLSpatialGroup* getParent();
00194 
00195         void clearState(U32 state, S32 mode);
00196         BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE);
00197         BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
00198         BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
00199         BOOL isVisible();
00200         void shift(const LLVector3 &offset);
00201         BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);
00202         void unbound();
00203         BOOL rebound();
00204         void destroyGL();
00205         
00206         void updateDistance(LLCamera& camera);
00207         BOOL changeLOD();
00208         void rebuildGeom();
00209         void makeStatic();
00210         
00211         void dirtyGeom() { setState(GEOM_DIRTY); }
00212         element_list& getData() { return mOctreeNode->getOctState()->getData(); }
00213 
00214          //LISTENER FUNCTIONS
00215         virtual void handleInsertion(const TreeNode* node, LLDrawable* face);
00216         virtual void handleRemoval(const TreeNode* node, LLDrawable* face);
00217         virtual void handleDestruction(const TreeNode* node);
00218         virtual void handleStateChange(const TreeNode* node);
00219         virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
00220         virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);
00221 
00222 protected:
00223         virtual ~LLSpatialGroup();
00224 
00225         U32 mState;
00226         S32 mLODHash;
00227         static S32 sLODSeed;
00228 
00229 public:
00230         bridge_list_t mBridgeList;
00231         buffer_map_t mBufferMap; //used by volume buffers to store unique buffers per texture
00232 
00233         F32 mBuilt;
00234         OctreeNode* mOctreeNode;
00235         LLSpatialPartition* mSpatialPartition;
00236         LLVector3 mBounds[2];
00237         LLVector3 mExtents[2];
00238         LLVector3 mObjectExtents[2];
00239         LLVector3 mObjectBounds[2];
00240 
00241         LLPointer<LLVertexBuffer> mVertexBuffer;
00242         LLPointer<LLVertexBuffer> mOcclusionVerts;
00243         LLPointer<LLCubeMap>    mReflectionMap;
00244 
00245         U32 mBufferUsage;
00246         draw_map_t mDrawMap;
00247         
00248         U32 mVertexCount;
00249         U32 mIndexCount;
00250         F32 mDistance;
00251         F32 mDepth;
00252         F32 mLastUpdateDistance;
00253         F32 mLastUpdateTime;
00254         F32 mLastAddTime;
00255         F32 mLastRenderTime;
00256         
00257         LLVector3 mViewAngle;
00258         LLVector3 mLastUpdateViewAngle;
00259         
00260         F32 mPixelArea;
00261         F32 mRadius;
00262 };
00263 
00264 class LLGeometryManager
00265 {
00266 public:
00267         std::vector<LLFace*> mFaceList;
00268         virtual ~LLGeometryManager() { }
00269         virtual void rebuildGeom(LLSpatialGroup* group) = 0;
00270         virtual void getGeometry(LLSpatialGroup* group) = 0;
00271         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count);
00272         virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
00273 };
00274 
00275 class LLSpatialPartition: public LLGeometryManager
00276 {
00277 public:
00278         LLSpatialPartition(U32 data_mask, BOOL is_volatile = FALSE, U32 mBufferUsage = GL_STATIC_DRAW_ARB);
00279         virtual ~LLSpatialPartition();
00280 
00281         LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
00282         BOOL remove(LLDrawable *drawablep, LLSpatialGroup *curp);
00283         
00284         LLDrawable*     pickDrawable(const LLVector3& start, const LLVector3& end, LLVector3& collision);
00285         
00286         // If the drawable moves, move it here.
00287         virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
00288         virtual void shift(const LLVector3 &offset);
00289 
00290         virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera);
00291         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00292 
00293         virtual void rebuildGeom(LLSpatialGroup* group);
00294 
00295         S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum
00296         BOOL checkOcclusion(LLSpatialGroup* group, LLCamera* camera);
00297         void markReimage(LLSpatialGroup* group);
00298         void processImagery(LLCamera* camera);
00299         void processOcclusion(LLCamera* camera);
00300         void buildOcclusion();
00301         void doOcclusion(LLCamera* camera);
00302         BOOL isVisible(const LLVector3& v);
00303         BOOL isVolatile() const { return mVolatile; }
00304 
00305         virtual LLSpatialBridge* asBridge() { return NULL; }
00306         virtual BOOL isBridge() { return asBridge() != NULL; }
00307 
00308         S32 getObjects(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results );
00309         S32 getLights(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results );
00310         
00311         void renderDebug();
00312         void restoreGL();
00313         void resetVertexBuffers();
00314         
00315 protected:
00316         S32 getDrawables(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results, BOOL get_lights );
00317         
00318         typedef std::set<LLPointer<LLSpatialGroup> > spatial_group_set_t;
00319         spatial_group_set_t mSpatialGroups;
00320 
00321         //things that might be occluded
00322         typedef std::queue<LLPointer<LLSpatialGroup> > spatial_group_queue_t;
00323         spatial_group_queue_t mOcclusionQueue;
00324 
00325         //things that need an image update
00326         spatial_group_queue_t mImageQueue;
00327 
00328         //things awaiting query
00329         spatial_group_queue_t mQueryQueue;
00330 
00331         std::vector<LLGLuint> mOcclusionQueries;        
00332 
00333 public:
00334         LLSpatialGroup::OctreeNode* mOctree;
00335 
00336         U32 mBufferUsage;
00337         BOOL mRenderByGroup;
00338         BOOL mImageEnabled;
00339         U32 mLODSeed;
00340         U32 mLODPeriod;
00341         U32 mVertexDataMask;
00342         F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
00343         BOOL mVolatile; //if TRUE, occlusion queries will be discarded when nodes change size
00344         BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
00345         U32 mDrawableType;
00346         U32 mPartitionType;
00347 
00348         //index buffer for occlusion verts
00349         LLPointer<LLVertexBuffer> mOcclusionIndices;
00350 
00351         //things that are occluded
00352         std::vector<LLPointer<LLSpatialGroup> > mOccludedList;
00353 };
00354 
00355 // class for creating bridges between spatial partitions
00356 class LLSpatialBridge : public LLDrawable, public LLSpatialPartition
00357 {
00358 protected:
00359         ~LLSpatialBridge();
00360 
00361 public:
00362         typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
00363         
00364         LLSpatialBridge(LLDrawable* root, U32 data_mask);
00365         
00366         virtual BOOL isSpatialBridge() const            { return TRUE; }
00367 
00368         virtual void updateSpatialExtents();
00369         virtual void updateBinRadius();
00370         virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
00371         virtual void updateDistance(LLCamera& camera_in);
00372         virtual void makeActive();
00373         virtual void makeStatic();
00374         virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE);
00375         virtual BOOL updateMove();
00376         virtual void shiftPos(const LLVector3& vec);
00377         virtual void cleanupReferences();
00378         virtual LLSpatialPartition* asPartition()               { return this; }
00379         virtual LLSpatialBridge* asBridge()                             { return this; }
00380         
00381         virtual LLCamera transformCamera(LLCamera& camera);
00382         
00383         LLDrawable* mDrawable;
00384 };
00385 
00386 //spatial partition for water (implemented in LLVOWater.cpp)
00387 class LLWaterPartition : public LLSpatialPartition
00388 {
00389 public:
00390         LLWaterPartition();
00391         virtual void getGeometry(LLSpatialGroup* group) {  }
00392         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
00393 };
00394 
00395 //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
00396 class LLTerrainPartition : public LLSpatialPartition
00397 {
00398 public:
00399         LLTerrainPartition();
00400         virtual void getGeometry(LLSpatialGroup* group);
00401         virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
00402 };
00403 
00404 //spatial partition for trees
00405 class LLTreePartition : public LLSpatialPartition
00406 {
00407 public:
00408         LLTreePartition();
00409         virtual void getGeometry(LLSpatialGroup* group) { }
00410         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
00411 
00412 };
00413 
00414 //spatial partition for particles (implemented in LLVOPartGroup.cpp)
00415 class LLParticlePartition : public LLSpatialPartition
00416 {
00417 public:
00418         LLParticlePartition();
00419         virtual void getGeometry(LLSpatialGroup* group);
00420         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
00421         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00422 protected:
00423         U32 mRenderPass;
00424 };
00425 
00426 //spatial partition for grass (implemented in LLVOGrass.cpp)
00427 class LLGrassPartition : public LLParticlePartition
00428 {
00429 public:
00430         LLGrassPartition();
00431 };
00432 
00433 //spatial partition for clouds (implemented in LLVOClouds.cpp)
00434 class LLCloudPartition : public LLParticlePartition
00435 {
00436 public:
00437         LLCloudPartition();
00438 };
00439 
00440 //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
00441 class LLVolumeGeometryManager: public LLGeometryManager
00442 {
00443 public:
00444         virtual ~LLVolumeGeometryManager() { }
00445         virtual void rebuildGeom(LLSpatialGroup* group);
00446         virtual void getGeometry(LLSpatialGroup* group);
00447         void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
00448 };
00449 
00450 //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
00451 class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
00452 {
00453 public:
00454         LLVolumePartition();
00455         virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
00456         virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
00457         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
00458 };
00459 
00460 //spatial bridge that uses volume geometry manager (implemented in LLVOVolume.cpp)
00461 class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
00462 {
00463 public:
00464         LLVolumeBridge(LLDrawable* drawable);
00465         virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
00466         virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
00467         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
00468 };
00469 
00470 class LLHUDBridge : public LLVolumeBridge
00471 {
00472 public:
00473         LLHUDBridge(LLDrawable* drawablep);
00474         virtual void shiftPos(const LLVector3& vec);
00475         virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
00476 };
00477 
00478 //spatial partition that holds nothing but spatial bridges
00479 class LLBridgePartition : public LLSpatialPartition
00480 {
00481 public:
00482         LLBridgePartition();
00483         virtual void getGeometry(LLSpatialGroup* group) { }
00484         virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) {  }
00485 };
00486 
00487 class LLHUDPartition : public LLBridgePartition
00488 {
00489 public:
00490         LLHUDPartition();
00491         virtual void shift(const LLVector3 &offset);
00492 };
00493 
00494 void validate_draw_info(LLDrawInfo& params);
00495 
00496 extern const F32 SG_BOX_SIDE;
00497 extern const F32 SG_BOX_OFFSET;
00498 extern const F32 SG_BOX_RAD;
00499 
00500 extern const F32 SG_OBJ_SIDE;
00501 extern const F32 SG_MAX_OBJ_RAD;
00502 
00503 #endif //LL_LLSPATIALPARTITION_H
00504 

Generated on Thu Jul 1 06:09:12 2010 for Second Life Viewer by  doxygen 1.4.7