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
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
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,
00175 STATE_MODE_BRANCH,
00176 STATE_MODE_DIFF
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);
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
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;
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
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);
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
00322 typedef std::queue<LLPointer<LLSpatialGroup> > spatial_group_queue_t;
00323 spatial_group_queue_t mOcclusionQueue;
00324
00325
00326 spatial_group_queue_t mImageQueue;
00327
00328
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;
00343 BOOL mVolatile;
00344 BOOL mDepthMask;
00345 U32 mDrawableType;
00346 U32 mPartitionType;
00347
00348
00349 LLPointer<LLVertexBuffer> mOcclusionIndices;
00350
00351
00352 std::vector<LLPointer<LLSpatialGroup> > mOccludedList;
00353 };
00354
00355
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
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
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
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
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
00427 class LLGrassPartition : public LLParticlePartition
00428 {
00429 public:
00430 LLGrassPartition();
00431 };
00432
00433
00434 class LLCloudPartition : public LLParticlePartition
00435 {
00436 public:
00437 LLCloudPartition();
00438 };
00439
00440
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
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
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
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