summaryrefslogtreecommitdiff
path: root/indra/newview/llspatialpartition.h
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llspatialpartition.h
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/newview/llspatialpartition.h')
-rw-r--r--indra/newview/llspatialpartition.h1558
1 files changed, 779 insertions, 779 deletions
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 42ad0e423c..f73e32294a 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -1,779 +1,779 @@
-/**
- * @file llspatialpartition.h
- * @brief LLSpatialGroup header file including definitions for supporting functions
- *
- * $LicenseInfo:firstyear=2003&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSPATIALPARTITION_H
-#define LL_LLSPATIALPARTITION_H
-
-#define SG_MIN_DIST_RATIO 0.00001f
-
-#include "lldrawable.h"
-#include "lloctree.h"
-#include "llpointer.h"
-#include "llrefcount.h"
-#include "llvertexbuffer.h"
-#include "llgltypes.h"
-#include "llcubemap.h"
-#include "lldrawpool.h"
-#include "llface.h"
-#include "llviewercamera.h"
-#include "llvector4a.h"
-#include "llvoavatar.h"
-#include "llfetchedgltfmaterial.h"
-
-#include <queue>
-#include <unordered_map>
-
-#define SG_STATE_INHERIT_MASK (OCCLUDED)
-#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
-
-class LLViewerOctreePartition;
-class LLSpatialPartition;
-class LLSpatialBridge;
-class LLSpatialGroup;
-class LLViewerRegion;
-class LLReflectionMap;
-
-void pushVerts(LLFace* face);
-
-/*
- Class that represents a single Draw Call
-
- Make every effort to keep size minimal.
- Member ordering is important for cache coherency
-*/
-class LLDrawInfo final : public LLRefCount
-{
- LL_ALIGN_NEW;
-protected:
- ~LLDrawInfo();
-
-public:
- LLDrawInfo(const LLDrawInfo& rhs)
- {
- *this = rhs;
- }
-
- const LLDrawInfo& operator=(const LLDrawInfo& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
-
- // return a hash of this LLDrawInfo as a debug color
- LLColor4U getDebugColor() const;
-
- LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
- LLViewerTexture* image, LLVertexBuffer* buffer,
- bool fullbright = false, U8 bump = 0);
-
-
- void validate();
-
- // return mSkinHash->mHash, or 0 if mSkinHash is null
- U64 getSkinHash();
-
- LLPointer<LLVertexBuffer> mVertexBuffer;
- U16 mStart = 0;
- U16 mEnd = 0;
- U32 mCount = 0;
- U32 mOffset = 0;
-
- LLPointer<LLViewerTexture> mTexture;
- LLPointer<LLViewerTexture> mSpecularMap;
- LLPointer<LLViewerTexture> mNormalMap;
-
- const LLMatrix4* mSpecularMapMatrix = nullptr;
- const LLMatrix4* mNormalMapMatrix = nullptr;
- const LLMatrix4* mTextureMatrix = nullptr;
- const LLMatrix4* mModelMatrix = nullptr;
-
- LLPointer<LLVOAvatar> mAvatar = nullptr;
- LLMeshSkinInfo* mSkinInfo = nullptr;
-
- // Material pointer here is likely for debugging only and are immaterial (zing!)
- LLPointer<LLMaterial> mMaterial;
-
- // PBR material parameters
- LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
-
- LLVector4 mSpecColor = LLVector4(1.f, 1.f, 1.f, 0.5f); // XYZ = Specular RGB, W = Specular Exponent
-
- std::vector<LLPointer<LLViewerTexture> > mTextureList;
-
- LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
-
- U32 mShaderMask = 0;
- F32 mEnvIntensity = 0.f;
- F32 mAlphaMaskCutoff = 0.5f;
-
- LLRender::eBlendFactor mBlendFuncSrc = LLRender::BF_SOURCE_ALPHA;
- LLRender::eBlendFactor mBlendFuncDst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
- U8 mDiffuseAlphaMode = 0;
- U8 mBump = 0;
- U8 mShiny = 0;
- bool mFullbright = false;
- bool mHasGlow = false;
-
- struct CompareTexture
- {
- bool operator()(const LLDrawInfo& lhs, const LLDrawInfo& rhs)
- {
- return lhs.mTexture > rhs.mTexture;
- }
- };
-
- struct CompareTexturePtr
- { //sort by texture
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- // sort by pointer, sort NULL down to the end
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && lhs->mTexture.get() > rhs->mTexture.get()));
- }
- };
-
- struct CompareVertexBuffer
- { //sort by texture
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- // sort by pointer, sort NULL down to the end
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && lhs->mVertexBuffer.get() > rhs->mVertexBuffer.get()));
- }
- };
-
- struct CompareTexturePtrMatrix
- {
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && (lhs->mTexture.get() > rhs->mTexture.get() ||
- (lhs->mTexture.get() == rhs->mTexture.get() && lhs->mModelMatrix > rhs->mModelMatrix))));
- }
-
- };
-
- struct CompareMatrixTexturePtr
- {
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && (lhs->mModelMatrix > rhs->mModelMatrix ||
- (lhs->mModelMatrix == rhs->mModelMatrix && lhs->mTexture.get() > rhs->mTexture.get()))));
- }
-
- };
-
- struct CompareBump
- {
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- // sort by mBump value, sort NULL down to the end
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump));
- }
- };
-};
-
-LL_ALIGN_PREFIX(16)
-class LLSpatialGroup : public LLOcclusionCullingGroup
-{
- using super = LLOcclusionCullingGroup;
- friend class LLSpatialPartition;
- friend class LLOctreeStateCheck;
-public:
-
- LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)
- {
- *this = rhs;
- }
-
- const LLSpatialGroup& operator=(const LLSpatialGroup& rhs)
- {
- LL_ERRS() << "Illegal operation!" << LL_ENDL;
- return *this;
- }
-
- static U32 sNodeCount;
- static bool sNoDelete; //deletion of spatial groups and draw info not allowed if true
-
- typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
- typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
- typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
- typedef std::unordered_map<U32, drawmap_elem_t > draw_map_t;
- typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
- typedef std::unordered_map<LLFace*, buffer_list_t> buffer_texture_map_t;
- typedef std::unordered_map<U32, buffer_texture_map_t> buffer_map_t;
-
- struct CompareDistanceGreater
- {
- bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
- {
- return lhs->mDistance > rhs->mDistance;
- }
- };
-
- struct CompareUpdateUrgency
- {
- bool operator()(const LLPointer<LLSpatialGroup> lhs, const LLPointer<LLSpatialGroup> rhs)
- {
- return lhs->getUpdateUrgency() > rhs->getUpdateUrgency();
- }
- };
-
- struct CompareDepthGreater
- {
- bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
- {
- return lhs->mDepth > rhs->mDepth;
- }
- };
-
- struct CompareRenderOrder
- {
- bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
- {
- if (lhs->mAvatarp != rhs->mAvatarp)
- {
- return lhs->mAvatarp < rhs->mAvatarp;
- }
-
- return lhs->mRenderOrder > rhs->mRenderOrder;
- }
- };
-
- typedef enum
- {
- GEOM_DIRTY = LLViewerOctreeGroup::INVALID_STATE,
- ALPHA_DIRTY = (GEOM_DIRTY << 1),
- IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1),
- IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1),
- MESH_DIRTY = (IMAGE_DIRTY << 1),
- NEW_DRAWINFO = (MESH_DIRTY << 1),
- IN_BUILD_Q1 = (NEW_DRAWINFO << 1),
- IN_BUILD_Q2 = (IN_BUILD_Q1 << 1),
- STATE_MASK = 0x0000FFFF,
- } eSpatialState;
-
- LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
-
- bool isHUDGroup() ;
-
- void clearDrawMap();
- void validate();
- void validateDrawMap();
-
- void setState(U32 state, S32 mode);
- void clearState(U32 state, S32 mode);
- void clearState(U32 state) {mState &= ~state;}
-
- LLSpatialGroup* getParent();
-
- bool addObject(LLDrawable *drawablep);
- bool removeObject(LLDrawable *drawablep, bool from_octree = false);
- bool updateInGroup(LLDrawable *drawablep, bool immediate = false); // Update position if it's in the group
- void expandExtents(const LLVector4a* addingExtents, const LLXformMatrix& currentTransform);
- void shift(const LLVector4a &offset);
-
- // TODO: this no longer appears to be called, figure out if it's important and if not remove it
- void destroyGLState(bool keep_occlusion = false);
-
- void updateDistance(LLCamera& camera);
- F32 getUpdateUrgency() const;
- bool changeLOD();
- void rebuildGeom();
- void rebuildMesh();
-
- void setState(U32 state) {mState |= state;}
- void dirtyGeom() { setState(GEOM_DIRTY); }
- void dirtyMesh() { setState(MESH_DIRTY); }
-
- void drawObjectBox(LLColor4 col);
-
- LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- bool pick_rigged,
- bool pick_unselectable,
- bool pick_reflection_probe,
- S32* face_hit, // return the face hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
-
-
- LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
-
- //LISTENER FUNCTIONS
- virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face);
- virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
- virtual void handleDestruction(const TreeNode* node);
- virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
-
- // LLViewerOctreeGroup
- virtual void rebound();
-
-public:
- LL_ALIGN_16(LLVector4a mViewAngle);
- LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
-
-protected:
- virtual ~LLSpatialGroup();
-
-public:
- LLPointer<LLVertexBuffer> mVertexBuffer;
- draw_map_t mDrawMap;
-
- bridge_list_t mBridgeList;
- buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
-
- F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
- U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node
- F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
- F32 mBuilt;
-
- F32 mDistance;
- F32 mDepth;
- F32 mLastUpdateDistance;
- F32 mLastUpdateTime;
-
- F32 mPixelArea;
- F32 mRadius;
-
- //used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior
- LLVOAvatar* mAvatarp = nullptr;
- U32 mRenderOrder = 0;
- // Reflection Probe associated with this node (if any)
- LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
-} LL_ALIGN_POSTFIX(16);
-
-class LLGeometryManager
-{
-public:
- std::vector<LLFace*> mFaceList;
- virtual ~LLGeometryManager() { }
- virtual void rebuildGeom(LLSpatialGroup* group) = 0;
- virtual void rebuildMesh(LLSpatialGroup* group) = 0;
- virtual void getGeometry(LLSpatialGroup* group) = 0;
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count);
-};
-
-class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
-{
-public:
- LLSpatialPartition(U32 data_mask, bool render_by_group, LLViewerRegion* regionp);
- virtual ~LLSpatialPartition();
-
- LLSpatialGroup *put(LLDrawable *drawablep, bool was_visible = false);
- bool remove(LLDrawable *drawablep, LLSpatialGroup *curp);
-
- LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
- bool pick_transparent,
- bool pick_rigged,
- bool pick_unselectable,
- bool pick_reflection_probe,
- S32* face_hit, // return the face hit
- LLVector4a* intersection = NULL, // return the intersection point
- LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
- LLVector4a* normal = NULL, // return the surface normal at the intersection point
- LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
-
-
- // If the drawable moves, move it here.
- virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, bool immediate = false);
- virtual void shift(const LLVector4a &offset);
-
- virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera);
- virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
-
- virtual void rebuildGeom(LLSpatialGroup* group);
- virtual void rebuildMesh(LLSpatialGroup* group);
-
- bool visibleObjectsInFrustum(LLCamera& camera);
- /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion=false); // Cull on arbitrary frustum
- S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, bool for_select); // Cull on arbitrary frustum
-
- bool isVisible(const LLVector3& v);
- bool isHUDPartition() ;
-
- LLSpatialBridge* asBridge() { return mBridge; }
- bool isBridge() { return asBridge() != NULL; }
-
- void renderPhysicsShapes(bool depth_only);
- void renderDebug();
- void renderIntersectingBBoxes(LLCamera* camera);
- void restoreGL();
-
- bool getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
-
-public:
- LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
- // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
- // to call asBridge() from the destructor
-
- bool mInfiniteFarClip; // if true, frustum culling ignores far clip plane
- const bool mRenderByGroup;
- U32 mVertexDataMask;
- F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
- bool mDepthMask; //if true, objects in this partition will be written to depth during alpha rendering
-};
-
-// class for creating bridges between spatial partitions
-class LLSpatialBridge : public LLDrawable, public LLSpatialPartition
-{
-protected:
- ~LLSpatialBridge();
-
-public:
- typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
-
- LLSpatialBridge(LLDrawable* root, bool render_by_group, U32 data_mask, LLViewerRegion* regionp);
-
- void destroyTree();
-
- virtual bool isSpatialBridge() const { return true; }
- virtual void updateSpatialExtents();
- virtual void updateBinRadius();
- virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, bool for_select = false);
- virtual void updateDistance(LLCamera& camera_in, bool force_update);
- virtual void makeActive();
- virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, bool immediate = false);
- virtual bool updateMove();
- virtual void shiftPos(const LLVector4a& vec);
- virtual void cleanupReferences();
- virtual LLSpatialPartition* asPartition() { return this; }
-
- //transform agent space camera into this Spatial Bridge's coordinate frame
- virtual LLCamera transformCamera(LLCamera& camera);
-
- //transform agent space bounding box into this Spatial Bridge's coordinate frame
- void transformExtents(const LLVector4a* src, LLVector4a* dst);
- LLDrawable* mDrawable;
-};
-
-class LLCullResult
-{
-public:
- LLCullResult();
-
- typedef std::vector<LLSpatialGroup*> sg_list_t;
- typedef std::vector<LLDrawable*> drawable_list_t;
- typedef std::vector<LLSpatialBridge*> bridge_list_t;
- typedef std::vector<LLDrawInfo*> drawinfo_list_t;
-
- typedef LLSpatialGroup** sg_iterator;
- typedef LLSpatialBridge** bridge_iterator;
- typedef LLDrawInfo** drawinfo_iterator;
- typedef LLDrawable** drawable_iterator;
-
- // Helper function for taking advantage of _mm_prefetch when iterating over cull results
- static inline void increment_iterator(LLCullResult::drawinfo_iterator& i, const LLCullResult::drawinfo_iterator& end)
- {
- ++i;
-
- if (i != end)
- {
- _mm_prefetch((char*)(*i)->mVertexBuffer.get(), _MM_HINT_NTA);
-
- auto* ni = i + 1;
- if (ni != end)
- {
- _mm_prefetch((char*)*ni, _MM_HINT_NTA);
- }
- }
- }
-
- void clear();
-
- sg_iterator beginVisibleGroups();
- sg_iterator endVisibleGroups();
-
- sg_iterator beginAlphaGroups();
- sg_iterator endAlphaGroups();
-
- sg_iterator beginRiggedAlphaGroups();
- sg_iterator endRiggedAlphaGroups();
-
- bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
- sg_iterator beginOcclusionGroups();
- sg_iterator endOcclusionGroups();
-
- sg_iterator beginDrawableGroups();
- sg_iterator endDrawableGroups();
-
- drawable_iterator beginVisibleList();
- drawable_iterator endVisibleList();
-
- bridge_iterator beginVisibleBridge();
- bridge_iterator endVisibleBridge();
-
- drawinfo_iterator beginRenderMap(U32 type);
- drawinfo_iterator endRenderMap(U32 type);
-
- void pushVisibleGroup(LLSpatialGroup* group);
- void pushAlphaGroup(LLSpatialGroup* group);
- void pushRiggedAlphaGroup(LLSpatialGroup* group);
- void pushOcclusionGroup(LLSpatialGroup* group);
- void pushDrawableGroup(LLSpatialGroup* group);
- void pushDrawable(LLDrawable* drawable);
- void pushBridge(LLSpatialBridge* bridge);
- void pushDrawInfo(U32 type, LLDrawInfo* draw_info);
-
- U32 getVisibleGroupsSize() { return mVisibleGroupsSize; }
- U32 getAlphaGroupsSize() { return mAlphaGroupsSize; }
- U32 getRiggedAlphaGroupsSize() { return mRiggedAlphaGroupsSize; }
- U32 getDrawableGroupsSize() { return mDrawableGroupsSize; }
- U32 getVisibleListSize() { return mVisibleListSize; }
- U32 getVisibleBridgeSize() { return mVisibleBridgeSize; }
- U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; }
-
- void assertDrawMapsEmpty();
-
-private:
-
- template <class T, class V> void pushBack(T &head, U32& count, V* val);
-
- U32 mVisibleGroupsSize;
- U32 mAlphaGroupsSize;
- U32 mRiggedAlphaGroupsSize;
- U32 mOcclusionGroupsSize;
- U32 mDrawableGroupsSize;
- U32 mVisibleListSize;
- U32 mVisibleBridgeSize;
-
- U32 mVisibleGroupsAllocated;
- U32 mAlphaGroupsAllocated;
- U32 mRiggedAlphaGroupsAllocated;
- U32 mOcclusionGroupsAllocated;
- U32 mDrawableGroupsAllocated;
- U32 mVisibleListAllocated;
- U32 mVisibleBridgeAllocated;
-
- U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
-
- sg_list_t mVisibleGroups;
- sg_iterator mVisibleGroupsEnd;
- sg_list_t mAlphaGroups;
- sg_iterator mAlphaGroupsEnd;
- sg_list_t mRiggedAlphaGroups;
- sg_iterator mRiggedAlphaGroupsEnd;
- sg_list_t mOcclusionGroups;
- sg_iterator mOcclusionGroupsEnd;
- sg_list_t mDrawableGroups;
- sg_iterator mDrawableGroupsEnd;
- drawable_list_t mVisibleList;
- drawable_iterator mVisibleListEnd;
- bridge_list_t mVisibleBridge;
- bridge_iterator mVisibleBridgeEnd;
- drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
- U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES];
- drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
-
-};
-
-
-//spatial partition for water (implemented in LLVOWater.cpp)
-class LLWaterPartition : public LLSpatialPartition
-{
-public:
- LLWaterPartition(LLViewerRegion* regionp);
- virtual void getGeometry(LLSpatialGroup* group) { }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
-};
-
-//spatial partition for hole and edge water (implemented in LLVOWater.cpp)
-class LLVoidWaterPartition : public LLWaterPartition
-{
-public:
- LLVoidWaterPartition(LLViewerRegion* regionp);
-};
-
-//spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
-class LLTerrainPartition : public LLSpatialPartition
-{
-public:
- LLTerrainPartition(LLViewerRegion* regionp);
- virtual void getGeometry(LLSpatialGroup* group);
-};
-
-//spatial partition for trees
-class LLTreePartition : public LLSpatialPartition
-{
-public:
- LLTreePartition(LLViewerRegion* regionp);
- virtual void getGeometry(LLSpatialGroup* group) { }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
-
-};
-
-//spatial partition for particles (implemented in LLVOPartGroup.cpp)
-class LLParticlePartition : public LLSpatialPartition
-{
-public:
- LLParticlePartition(LLViewerRegion* regionp);
- virtual void rebuildGeom(LLSpatialGroup* group);
- virtual void getGeometry(LLSpatialGroup* group);
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
- virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
-protected:
- U32 mRenderPass;
-};
-
-class LLHUDParticlePartition : public LLParticlePartition
-{
-public:
- LLHUDParticlePartition(LLViewerRegion* regionp);
-};
-
-//spatial partition for grass (implemented in LLVOGrass.cpp)
-class LLGrassPartition : public LLSpatialPartition
-{
-public:
- LLGrassPartition(LLViewerRegion* regionp);
- virtual void getGeometry(LLSpatialGroup* group);
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
-protected:
- U32 mRenderPass;
-};
-
-//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
-class LLVolumeGeometryManager: public LLGeometryManager
-{
- public:
- typedef enum
- {
- NONE = 0,
- BATCH_SORT,
- DISTANCE_SORT
- } eSortType;
-
- LLVolumeGeometryManager();
- virtual ~LLVolumeGeometryManager();
- virtual void rebuildGeom(LLSpatialGroup* group);
- virtual void rebuildMesh(LLSpatialGroup* group);
- virtual void getGeometry(LLSpatialGroup* group);
- virtual void addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count);
- U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, bool distance_sort = false, bool batch_textures = false, bool rigged = false);
- void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
-
-private:
- void allocateFaces(U32 pMaxFaceCount);
- void freeFaces();
-
- static int32_t sInstanceCount;
- static LLFace** sFullbrightFaces[2];
- static LLFace** sBumpFaces[2];
- static LLFace** sSimpleFaces[2];
- static LLFace** sNormFaces[2];
- static LLFace** sSpecFaces[2];
- static LLFace** sNormSpecFaces[2];
- static LLFace** sPbrFaces[2];
- static LLFace** sAlphaFaces[2];
-};
-
-//spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
-class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
-{
-public:
- LLVolumePartition(LLViewerRegion* regionp);
- virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
- virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
- virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
-};
-
-//spatial bridge that uses volume geometry manager (implemented in LLVOVolume.cpp)
-class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
-{
-public:
- LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp);
- virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
- virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
- virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
-};
-
-class LLAvatarBridge : public LLVolumeBridge
-{
-public:
- LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
-};
-
-class LLControlAVBridge : public LLVolumeBridge
-{
- using super = LLVolumeBridge;
-public:
- LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
-};
-
-class LLHUDBridge : public LLVolumeBridge
-{
-public:
- LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
- virtual void shiftPos(const LLVector4a& vec);
- virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
-};
-
-//spatial partition that holds nothing but spatial bridges
-class LLBridgePartition : public LLSpatialPartition
-{
-public:
- LLBridgePartition(LLViewerRegion* regionp);
- virtual void getGeometry(LLSpatialGroup* group) { }
- virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
-};
-
-class LLAvatarPartition : public LLBridgePartition
-{
-public:
- LLAvatarPartition(LLViewerRegion* regionp);
-};
-
-class LLControlAVPartition : public LLBridgePartition
-{
-public:
- LLControlAVPartition(LLViewerRegion* regionp);
-};
-
-class LLHUDPartition : public LLBridgePartition
-{
-public:
- LLHUDPartition(LLViewerRegion* regionp);
- virtual void shift(const LLVector4a &offset);
-};
-
-extern const F32 SG_BOX_SIDE;
-extern const F32 SG_BOX_OFFSET;
-extern const F32 SG_BOX_RAD;
-
-extern const F32 SG_OBJ_SIDE;
-extern const F32 SG_MAX_OBJ_RAD;
-
-
-#endif //LL_LLSPATIALPARTITION_H
-
+/**
+ * @file llspatialpartition.h
+ * @brief LLSpatialGroup header file including definitions for supporting functions
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSPATIALPARTITION_H
+#define LL_LLSPATIALPARTITION_H
+
+#define SG_MIN_DIST_RATIO 0.00001f
+
+#include "lldrawable.h"
+#include "lloctree.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llvertexbuffer.h"
+#include "llgltypes.h"
+#include "llcubemap.h"
+#include "lldrawpool.h"
+#include "llface.h"
+#include "llviewercamera.h"
+#include "llvector4a.h"
+#include "llvoavatar.h"
+#include "llfetchedgltfmaterial.h"
+
+#include <queue>
+#include <unordered_map>
+
+#define SG_STATE_INHERIT_MASK (OCCLUDED)
+#define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY)
+
+class LLViewerOctreePartition;
+class LLSpatialPartition;
+class LLSpatialBridge;
+class LLSpatialGroup;
+class LLViewerRegion;
+class LLReflectionMap;
+
+void pushVerts(LLFace* face);
+
+/*
+ Class that represents a single Draw Call
+
+ Make every effort to keep size minimal.
+ Member ordering is important for cache coherency
+*/
+class LLDrawInfo final : public LLRefCount
+{
+ LL_ALIGN_NEW;
+protected:
+ ~LLDrawInfo();
+
+public:
+ LLDrawInfo(const LLDrawInfo& rhs)
+ {
+ *this = rhs;
+ }
+
+ const LLDrawInfo& operator=(const LLDrawInfo& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ // return a hash of this LLDrawInfo as a debug color
+ LLColor4U getDebugColor() const;
+
+ LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
+ LLViewerTexture* image, LLVertexBuffer* buffer,
+ bool fullbright = false, U8 bump = 0);
+
+
+ void validate();
+
+ // return mSkinHash->mHash, or 0 if mSkinHash is null
+ U64 getSkinHash();
+
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+ U16 mStart = 0;
+ U16 mEnd = 0;
+ U32 mCount = 0;
+ U32 mOffset = 0;
+
+ LLPointer<LLViewerTexture> mTexture;
+ LLPointer<LLViewerTexture> mSpecularMap;
+ LLPointer<LLViewerTexture> mNormalMap;
+
+ const LLMatrix4* mSpecularMapMatrix = nullptr;
+ const LLMatrix4* mNormalMapMatrix = nullptr;
+ const LLMatrix4* mTextureMatrix = nullptr;
+ const LLMatrix4* mModelMatrix = nullptr;
+
+ LLPointer<LLVOAvatar> mAvatar = nullptr;
+ LLMeshSkinInfo* mSkinInfo = nullptr;
+
+ // Material pointer here is likely for debugging only and are immaterial (zing!)
+ LLPointer<LLMaterial> mMaterial;
+
+ // PBR material parameters
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+
+ LLVector4 mSpecColor = LLVector4(1.f, 1.f, 1.f, 0.5f); // XYZ = Specular RGB, W = Specular Exponent
+
+ std::vector<LLPointer<LLViewerTexture> > mTextureList;
+
+ LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
+
+ U32 mShaderMask = 0;
+ F32 mEnvIntensity = 0.f;
+ F32 mAlphaMaskCutoff = 0.5f;
+
+ LLRender::eBlendFactor mBlendFuncSrc = LLRender::BF_SOURCE_ALPHA;
+ LLRender::eBlendFactor mBlendFuncDst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ U8 mDiffuseAlphaMode = 0;
+ U8 mBump = 0;
+ U8 mShiny = 0;
+ bool mFullbright = false;
+ bool mHasGlow = false;
+
+ struct CompareTexture
+ {
+ bool operator()(const LLDrawInfo& lhs, const LLDrawInfo& rhs)
+ {
+ return lhs.mTexture > rhs.mTexture;
+ }
+ };
+
+ struct CompareTexturePtr
+ { //sort by texture
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
+ {
+ // sort by pointer, sort NULL down to the end
+ return lhs.get() != rhs.get()
+ && (lhs.isNull() || (rhs.notNull() && lhs->mTexture.get() > rhs->mTexture.get()));
+ }
+ };
+
+ struct CompareVertexBuffer
+ { //sort by texture
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
+ {
+ // sort by pointer, sort NULL down to the end
+ return lhs.get() != rhs.get()
+ && (lhs.isNull() || (rhs.notNull() && lhs->mVertexBuffer.get() > rhs->mVertexBuffer.get()));
+ }
+ };
+
+ struct CompareTexturePtrMatrix
+ {
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
+ {
+ return lhs.get() != rhs.get()
+ && (lhs.isNull() || (rhs.notNull() && (lhs->mTexture.get() > rhs->mTexture.get() ||
+ (lhs->mTexture.get() == rhs->mTexture.get() && lhs->mModelMatrix > rhs->mModelMatrix))));
+ }
+
+ };
+
+ struct CompareMatrixTexturePtr
+ {
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
+ {
+ return lhs.get() != rhs.get()
+ && (lhs.isNull() || (rhs.notNull() && (lhs->mModelMatrix > rhs->mModelMatrix ||
+ (lhs->mModelMatrix == rhs->mModelMatrix && lhs->mTexture.get() > rhs->mTexture.get()))));
+ }
+
+ };
+
+ struct CompareBump
+ {
+ bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
+ {
+ // sort by mBump value, sort NULL down to the end
+ return lhs.get() != rhs.get()
+ && (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump));
+ }
+ };
+};
+
+LL_ALIGN_PREFIX(16)
+class LLSpatialGroup : public LLOcclusionCullingGroup
+{
+ using super = LLOcclusionCullingGroup;
+ friend class LLSpatialPartition;
+ friend class LLOctreeStateCheck;
+public:
+
+ LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)
+ {
+ *this = rhs;
+ }
+
+ const LLSpatialGroup& operator=(const LLSpatialGroup& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ static U32 sNodeCount;
+ static bool sNoDelete; //deletion of spatial groups and draw info not allowed if true
+
+ typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
+ typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
+ typedef std::vector<LLPointer<LLDrawInfo> > drawmap_elem_t;
+ typedef std::unordered_map<U32, drawmap_elem_t > draw_map_t;
+ typedef std::vector<LLPointer<LLVertexBuffer> > buffer_list_t;
+ typedef std::unordered_map<LLFace*, buffer_list_t> buffer_texture_map_t;
+ typedef std::unordered_map<U32, buffer_texture_map_t> buffer_map_t;
+
+ struct CompareDistanceGreater
+ {
+ bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
+ {
+ return lhs->mDistance > rhs->mDistance;
+ }
+ };
+
+ struct CompareUpdateUrgency
+ {
+ bool operator()(const LLPointer<LLSpatialGroup> lhs, const LLPointer<LLSpatialGroup> rhs)
+ {
+ return lhs->getUpdateUrgency() > rhs->getUpdateUrgency();
+ }
+ };
+
+ struct CompareDepthGreater
+ {
+ bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
+ {
+ return lhs->mDepth > rhs->mDepth;
+ }
+ };
+
+ struct CompareRenderOrder
+ {
+ bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs)
+ {
+ if (lhs->mAvatarp != rhs->mAvatarp)
+ {
+ return lhs->mAvatarp < rhs->mAvatarp;
+ }
+
+ return lhs->mRenderOrder > rhs->mRenderOrder;
+ }
+ };
+
+ typedef enum
+ {
+ GEOM_DIRTY = LLViewerOctreeGroup::INVALID_STATE,
+ ALPHA_DIRTY = (GEOM_DIRTY << 1),
+ IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1),
+ IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1),
+ MESH_DIRTY = (IMAGE_DIRTY << 1),
+ NEW_DRAWINFO = (MESH_DIRTY << 1),
+ IN_BUILD_Q1 = (NEW_DRAWINFO << 1),
+ IN_BUILD_Q2 = (IN_BUILD_Q1 << 1),
+ STATE_MASK = 0x0000FFFF,
+ } eSpatialState;
+
+ LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
+
+ bool isHUDGroup() ;
+
+ void clearDrawMap();
+ void validate();
+ void validateDrawMap();
+
+ void setState(U32 state, S32 mode);
+ void clearState(U32 state, S32 mode);
+ void clearState(U32 state) {mState &= ~state;}
+
+ LLSpatialGroup* getParent();
+
+ bool addObject(LLDrawable *drawablep);
+ bool removeObject(LLDrawable *drawablep, bool from_octree = false);
+ bool updateInGroup(LLDrawable *drawablep, bool immediate = false); // Update position if it's in the group
+ void expandExtents(const LLVector4a* addingExtents, const LLXformMatrix& currentTransform);
+ void shift(const LLVector4a &offset);
+
+ // TODO: this no longer appears to be called, figure out if it's important and if not remove it
+ void destroyGLState(bool keep_occlusion = false);
+
+ void updateDistance(LLCamera& camera);
+ F32 getUpdateUrgency() const;
+ bool changeLOD();
+ void rebuildGeom();
+ void rebuildMesh();
+
+ void setState(U32 state) {mState |= state;}
+ void dirtyGeom() { setState(GEOM_DIRTY); }
+ void dirtyMesh() { setState(MESH_DIRTY); }
+
+ void drawObjectBox(LLColor4 col);
+
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ bool pick_transparent,
+ bool pick_rigged,
+ bool pick_unselectable,
+ bool pick_reflection_probe,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+
+ LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
+
+ //LISTENER FUNCTIONS
+ virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face);
+ virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);
+ virtual void handleDestruction(const TreeNode* node);
+ virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
+
+ // LLViewerOctreeGroup
+ virtual void rebound();
+
+public:
+ LL_ALIGN_16(LLVector4a mViewAngle);
+ LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
+
+protected:
+ virtual ~LLSpatialGroup();
+
+public:
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+ draw_map_t mDrawMap;
+
+ bridge_list_t mBridgeList;
+ buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
+
+ F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
+ U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node
+ F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
+ F32 mBuilt;
+
+ F32 mDistance;
+ F32 mDepth;
+ F32 mLastUpdateDistance;
+ F32 mLastUpdateTime;
+
+ F32 mPixelArea;
+ F32 mRadius;
+
+ //used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior
+ LLVOAvatar* mAvatarp = nullptr;
+ U32 mRenderOrder = 0;
+ // Reflection Probe associated with this node (if any)
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
+} LL_ALIGN_POSTFIX(16);
+
+class LLGeometryManager
+{
+public:
+ std::vector<LLFace*> mFaceList;
+ virtual ~LLGeometryManager() { }
+ virtual void rebuildGeom(LLSpatialGroup* group) = 0;
+ virtual void rebuildMesh(LLSpatialGroup* group) = 0;
+ virtual void getGeometry(LLSpatialGroup* group) = 0;
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count);
+};
+
+class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
+{
+public:
+ LLSpatialPartition(U32 data_mask, bool render_by_group, LLViewerRegion* regionp);
+ virtual ~LLSpatialPartition();
+
+ LLSpatialGroup *put(LLDrawable *drawablep, bool was_visible = false);
+ bool remove(LLDrawable *drawablep, LLSpatialGroup *curp);
+
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ bool pick_transparent,
+ bool pick_rigged,
+ bool pick_unselectable,
+ bool pick_reflection_probe,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+
+ // If the drawable moves, move it here.
+ virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, bool immediate = false);
+ virtual void shift(const LLVector4a &offset);
+
+ virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera);
+ virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
+
+ virtual void rebuildGeom(LLSpatialGroup* group);
+ virtual void rebuildMesh(LLSpatialGroup* group);
+
+ bool visibleObjectsInFrustum(LLCamera& camera);
+ /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion=false); // Cull on arbitrary frustum
+ S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, bool for_select); // Cull on arbitrary frustum
+
+ bool isVisible(const LLVector3& v);
+ bool isHUDPartition() ;
+
+ LLSpatialBridge* asBridge() { return mBridge; }
+ bool isBridge() { return asBridge() != NULL; }
+
+ void renderPhysicsShapes(bool depth_only);
+ void renderDebug();
+ void renderIntersectingBBoxes(LLCamera* camera);
+ void restoreGL();
+
+ bool getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
+
+public:
+ LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
+ // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
+ // to call asBridge() from the destructor
+
+ bool mInfiniteFarClip; // if true, frustum culling ignores far clip plane
+ const bool mRenderByGroup;
+ U32 mVertexDataMask;
+ F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
+ bool mDepthMask; //if true, objects in this partition will be written to depth during alpha rendering
+};
+
+// class for creating bridges between spatial partitions
+class LLSpatialBridge : public LLDrawable, public LLSpatialPartition
+{
+protected:
+ ~LLSpatialBridge();
+
+public:
+ typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t;
+
+ LLSpatialBridge(LLDrawable* root, bool render_by_group, U32 data_mask, LLViewerRegion* regionp);
+
+ void destroyTree();
+
+ virtual bool isSpatialBridge() const { return true; }
+ virtual void updateSpatialExtents();
+ virtual void updateBinRadius();
+ virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, bool for_select = false);
+ virtual void updateDistance(LLCamera& camera_in, bool force_update);
+ virtual void makeActive();
+ virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, bool immediate = false);
+ virtual bool updateMove();
+ virtual void shiftPos(const LLVector4a& vec);
+ virtual void cleanupReferences();
+ virtual LLSpatialPartition* asPartition() { return this; }
+
+ //transform agent space camera into this Spatial Bridge's coordinate frame
+ virtual LLCamera transformCamera(LLCamera& camera);
+
+ //transform agent space bounding box into this Spatial Bridge's coordinate frame
+ void transformExtents(const LLVector4a* src, LLVector4a* dst);
+ LLDrawable* mDrawable;
+};
+
+class LLCullResult
+{
+public:
+ LLCullResult();
+
+ typedef std::vector<LLSpatialGroup*> sg_list_t;
+ typedef std::vector<LLDrawable*> drawable_list_t;
+ typedef std::vector<LLSpatialBridge*> bridge_list_t;
+ typedef std::vector<LLDrawInfo*> drawinfo_list_t;
+
+ typedef LLSpatialGroup** sg_iterator;
+ typedef LLSpatialBridge** bridge_iterator;
+ typedef LLDrawInfo** drawinfo_iterator;
+ typedef LLDrawable** drawable_iterator;
+
+ // Helper function for taking advantage of _mm_prefetch when iterating over cull results
+ static inline void increment_iterator(LLCullResult::drawinfo_iterator& i, const LLCullResult::drawinfo_iterator& end)
+ {
+ ++i;
+
+ if (i != end)
+ {
+ _mm_prefetch((char*)(*i)->mVertexBuffer.get(), _MM_HINT_NTA);
+
+ auto* ni = i + 1;
+ if (ni != end)
+ {
+ _mm_prefetch((char*)*ni, _MM_HINT_NTA);
+ }
+ }
+ }
+
+ void clear();
+
+ sg_iterator beginVisibleGroups();
+ sg_iterator endVisibleGroups();
+
+ sg_iterator beginAlphaGroups();
+ sg_iterator endAlphaGroups();
+
+ sg_iterator beginRiggedAlphaGroups();
+ sg_iterator endRiggedAlphaGroups();
+
+ bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
+ sg_iterator beginOcclusionGroups();
+ sg_iterator endOcclusionGroups();
+
+ sg_iterator beginDrawableGroups();
+ sg_iterator endDrawableGroups();
+
+ drawable_iterator beginVisibleList();
+ drawable_iterator endVisibleList();
+
+ bridge_iterator beginVisibleBridge();
+ bridge_iterator endVisibleBridge();
+
+ drawinfo_iterator beginRenderMap(U32 type);
+ drawinfo_iterator endRenderMap(U32 type);
+
+ void pushVisibleGroup(LLSpatialGroup* group);
+ void pushAlphaGroup(LLSpatialGroup* group);
+ void pushRiggedAlphaGroup(LLSpatialGroup* group);
+ void pushOcclusionGroup(LLSpatialGroup* group);
+ void pushDrawableGroup(LLSpatialGroup* group);
+ void pushDrawable(LLDrawable* drawable);
+ void pushBridge(LLSpatialBridge* bridge);
+ void pushDrawInfo(U32 type, LLDrawInfo* draw_info);
+
+ U32 getVisibleGroupsSize() { return mVisibleGroupsSize; }
+ U32 getAlphaGroupsSize() { return mAlphaGroupsSize; }
+ U32 getRiggedAlphaGroupsSize() { return mRiggedAlphaGroupsSize; }
+ U32 getDrawableGroupsSize() { return mDrawableGroupsSize; }
+ U32 getVisibleListSize() { return mVisibleListSize; }
+ U32 getVisibleBridgeSize() { return mVisibleBridgeSize; }
+ U32 getRenderMapSize(U32 type) { return mRenderMapSize[type]; }
+
+ void assertDrawMapsEmpty();
+
+private:
+
+ template <class T, class V> void pushBack(T &head, U32& count, V* val);
+
+ U32 mVisibleGroupsSize;
+ U32 mAlphaGroupsSize;
+ U32 mRiggedAlphaGroupsSize;
+ U32 mOcclusionGroupsSize;
+ U32 mDrawableGroupsSize;
+ U32 mVisibleListSize;
+ U32 mVisibleBridgeSize;
+
+ U32 mVisibleGroupsAllocated;
+ U32 mAlphaGroupsAllocated;
+ U32 mRiggedAlphaGroupsAllocated;
+ U32 mOcclusionGroupsAllocated;
+ U32 mDrawableGroupsAllocated;
+ U32 mVisibleListAllocated;
+ U32 mVisibleBridgeAllocated;
+
+ U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
+
+ sg_list_t mVisibleGroups;
+ sg_iterator mVisibleGroupsEnd;
+ sg_list_t mAlphaGroups;
+ sg_iterator mAlphaGroupsEnd;
+ sg_list_t mRiggedAlphaGroups;
+ sg_iterator mRiggedAlphaGroupsEnd;
+ sg_list_t mOcclusionGroups;
+ sg_iterator mOcclusionGroupsEnd;
+ sg_list_t mDrawableGroups;
+ sg_iterator mDrawableGroupsEnd;
+ drawable_list_t mVisibleList;
+ drawable_iterator mVisibleListEnd;
+ bridge_list_t mVisibleBridge;
+ bridge_iterator mVisibleBridgeEnd;
+ drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
+ U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES];
+ drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
+
+};
+
+
+//spatial partition for water (implemented in LLVOWater.cpp)
+class LLWaterPartition : public LLSpatialPartition
+{
+public:
+ LLWaterPartition(LLViewerRegion* regionp);
+ virtual void getGeometry(LLSpatialGroup* group) { }
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
+};
+
+//spatial partition for hole and edge water (implemented in LLVOWater.cpp)
+class LLVoidWaterPartition : public LLWaterPartition
+{
+public:
+ LLVoidWaterPartition(LLViewerRegion* regionp);
+};
+
+//spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)
+class LLTerrainPartition : public LLSpatialPartition
+{
+public:
+ LLTerrainPartition(LLViewerRegion* regionp);
+ virtual void getGeometry(LLSpatialGroup* group);
+};
+
+//spatial partition for trees
+class LLTreePartition : public LLSpatialPartition
+{
+public:
+ LLTreePartition(LLViewerRegion* regionp);
+ virtual void getGeometry(LLSpatialGroup* group) { }
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
+
+};
+
+//spatial partition for particles (implemented in LLVOPartGroup.cpp)
+class LLParticlePartition : public LLSpatialPartition
+{
+public:
+ LLParticlePartition(LLViewerRegion* regionp);
+ virtual void rebuildGeom(LLSpatialGroup* group);
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+ virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
+protected:
+ U32 mRenderPass;
+};
+
+class LLHUDParticlePartition : public LLParticlePartition
+{
+public:
+ LLHUDParticlePartition(LLViewerRegion* regionp);
+};
+
+//spatial partition for grass (implemented in LLVOGrass.cpp)
+class LLGrassPartition : public LLSpatialPartition
+{
+public:
+ LLGrassPartition(LLViewerRegion* regionp);
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+protected:
+ U32 mRenderPass;
+};
+
+//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
+class LLVolumeGeometryManager: public LLGeometryManager
+{
+ public:
+ typedef enum
+ {
+ NONE = 0,
+ BATCH_SORT,
+ DISTANCE_SORT
+ } eSortType;
+
+ LLVolumeGeometryManager();
+ virtual ~LLVolumeGeometryManager();
+ virtual void rebuildGeom(LLSpatialGroup* group);
+ virtual void rebuildMesh(LLSpatialGroup* group);
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count);
+ U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, bool distance_sort = false, bool batch_textures = false, bool rigged = false);
+ void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
+
+private:
+ void allocateFaces(U32 pMaxFaceCount);
+ void freeFaces();
+
+ static int32_t sInstanceCount;
+ static LLFace** sFullbrightFaces[2];
+ static LLFace** sBumpFaces[2];
+ static LLFace** sSimpleFaces[2];
+ static LLFace** sNormFaces[2];
+ static LLFace** sSpecFaces[2];
+ static LLFace** sNormSpecFaces[2];
+ static LLFace** sPbrFaces[2];
+ static LLFace** sAlphaFaces[2];
+};
+
+//spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
+class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager
+{
+public:
+ LLVolumePartition(LLViewerRegion* regionp);
+ virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
+ virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
+ virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
+};
+
+//spatial bridge that uses volume geometry manager (implemented in LLVOVolume.cpp)
+class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager
+{
+public:
+ LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp);
+ virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }
+ virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }
+ virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); }
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { LLVolumeGeometryManager::addGeometryCount(group, vertex_count, index_count); }
+};
+
+class LLAvatarBridge : public LLVolumeBridge
+{
+public:
+ LLAvatarBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
+class LLControlAVBridge : public LLVolumeBridge
+{
+ using super = LLVolumeBridge;
+public:
+ LLControlAVBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+};
+
+class LLHUDBridge : public LLVolumeBridge
+{
+public:
+ LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp);
+ virtual void shiftPos(const LLVector4a& vec);
+ virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
+};
+
+//spatial partition that holds nothing but spatial bridges
+class LLBridgePartition : public LLSpatialPartition
+{
+public:
+ LLBridgePartition(LLViewerRegion* regionp);
+ virtual void getGeometry(LLSpatialGroup* group) { }
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }
+};
+
+class LLAvatarPartition : public LLBridgePartition
+{
+public:
+ LLAvatarPartition(LLViewerRegion* regionp);
+};
+
+class LLControlAVPartition : public LLBridgePartition
+{
+public:
+ LLControlAVPartition(LLViewerRegion* regionp);
+};
+
+class LLHUDPartition : public LLBridgePartition
+{
+public:
+ LLHUDPartition(LLViewerRegion* regionp);
+ virtual void shift(const LLVector4a &offset);
+};
+
+extern const F32 SG_BOX_SIDE;
+extern const F32 SG_BOX_OFFSET;
+extern const F32 SG_BOX_RAD;
+
+extern const F32 SG_OBJ_SIDE;
+extern const F32 SG_MAX_OBJ_RAD;
+
+
+#endif //LL_LLSPATIALPARTITION_H
+