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 {
00095 bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
00096 {
00097
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
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,
00187 STATE_MODE_BRANCH,
00188 STATE_MODE_DIFF
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);
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();
00219 void checkOcclusion();
00220 void doOcclusion(LLCamera* camera);
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
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;
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;
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
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);
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
00336 spatial_group_queue_t mImageQueue;
00337
00338 public:
00339 LLSpatialGroup::OctreeNode* mOctree;
00340 BOOL mOcclusionEnabled;
00341 BOOL mInfiniteFarClip;
00342 U32 mBufferUsage;
00343 BOOL mRenderByGroup;
00344 BOOL mImageEnabled;
00345 U32 mLODSeed;
00346 U32 mLODPeriod;
00347 U32 mVertexDataMask;
00348 F32 mSlopRatio;
00349 BOOL mDepthMask;
00350 U32 mDrawableType;
00351 U32 mPartitionType;
00352 };
00353
00354
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
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
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
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
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
00491 class LLGrassPartition : public LLParticlePartition
00492 {
00493 public:
00494 LLGrassPartition();
00495 };
00496
00497
00498 class LLCloudPartition : public LLParticlePartition
00499 {
00500 public:
00501 LLCloudPartition();
00502 };
00503
00504
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
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
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
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