summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-28 03:15:43 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-28 18:16:43 +0300
commit0be27809566c1378fa613aa7c42bfd2406a9f764 (patch)
treec2fea1e46237c991a26d8aa763272ea60704865d
parenta1b68fb8ed6c2589dd13bd9ba1fab7050ba38226 (diff)
#5855 Added a way to check triangles for all lods
-rw-r--r--indra/newview/llfloaterobjectweights.cpp228
-rw-r--r--indra/newview/llfloaterobjectweights.h21
-rw-r--r--indra/newview/llselectmgr.cpp1
-rw-r--r--indra/newview/llselectmgr.h1
-rw-r--r--indra/newview/llviewerobject.cpp26
-rw-r--r--indra/newview/llviewerobject.h2
-rw-r--r--indra/newview/llvovolume.cpp13
-rw-r--r--indra/newview/llvovolume.h1
-rw-r--r--indra/newview/skins/default/xui/en/floater_object_weights.xml172
9 files changed, 416 insertions, 49 deletions
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index bd8530abd7..cf89518c03 100644
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -33,8 +33,10 @@
#include "lltextbox.h"
#include "llagent.h"
+#include "llcallbacklist.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
+#include "llmeshrepository.h"
static const std::string lod_strings[4] =
{
@@ -74,6 +76,14 @@ bool LLCrossParcelFunctor::apply(LLViewerObject* obj)
LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
: LLFloater(key),
+ mWeightsDirty(false),
+ mSelectionDirty(true),
+ mSelectionMeshDirty(true),
+ mSelectionLastLOD(-1),
+ mSelectionLastTris(0),
+ mSelectionLastArea(0),
+ mLastActiveLODRequests(0),
+ mSelectionRefreshTime(0.),
mSelectedObjects(NULL),
mSelectedPrims(NULL),
mSelectedDownloadWeight(NULL),
@@ -88,6 +98,13 @@ LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key)
mTrianglesShown(nullptr),
mPixelArea(nullptr)
{
+ mSelectionConnection = LLSelectMgr::getInstance()->mUpdateSignal.connect(
+ [this]()
+ {
+ mSelectionDirty = true;
+ mSelectionMeshDirty = true; // assume that mesh data will arrive with a delay.
+ }
+ );
}
LLFloaterObjectWeights::~LLFloaterObjectWeights()
@@ -114,6 +131,11 @@ bool LLFloaterObjectWeights::postBuild()
mTrianglesShown = getChild<LLTextBox>("triangles_shown");
mPixelArea = getChild<LLTextBox>("pixel_area");
+ mHighLodTris = getChild<LLTextBox>("high_lod_tris");
+ mMediumLodTris = getChild<LLTextBox>("medium_lod_tris");
+ mLowLodTris = getChild<LLTextBox>("low_lod_tris");
+ mLowestLodTris = getChild<LLTextBox>("lowest_lod_tris");
+
return true;
}
@@ -122,6 +144,14 @@ void LLFloaterObjectWeights::onOpen(const LLSD& key)
{
refresh();
updateLandImpacts(LLViewerParcelMgr::getInstance()->getFloatingParcelSelection()->getParcel());
+
+ onIdleRefresh(this);
+ gIdleCallbacks.addFunction(onIdleRefresh, this);
+}
+
+void LLFloaterObjectWeights::onClose(bool app_quitting)
+{
+ gIdleCallbacks.deleteFunction(onIdleRefresh, this);
}
// virtual
@@ -131,8 +161,9 @@ void LLFloaterObjectWeights::onWeightsUpdate(const SelectionCost& selection_cost
mSelectedPhysicsWeight->setText(llformat("%.1f", selection_cost.mPhysicsCost));
mSelectedServerWeight->setText(llformat("%.1f", selection_cost.mSimulationCost));
- S32 render_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectRenderCost();
- mSelectedDisplayWeight->setText(llformat("%d", render_cost));
+ // onWeightsUpdate comes from a coroutine.
+ // Postpone LLSelectMgr operations as getSelectedObjectRenderCost is not coroutine-safe
+ mWeightsDirty = true;
toggleWeightsLoadingIndicators(false);
}
@@ -152,20 +183,13 @@ void LLFloaterObjectWeights::setErrorStatus(S32 status, const std::string& reaso
void LLFloaterObjectWeights::draw()
{
- // Normally it's a bad idea to set text and visibility inside draw
- // since it can cause rect updates go to different, already drawn elements,
- // but floater is very simple and these elements are supposed to be isolated
+ // This logic might be a bit too expensive for draw(),
+ // but this floater needs to react fast, even if it's
+ // detrimental to performance. Having callbacks like
+ // 'tris changed' in every selected object might be
+ // more impactful on performance.
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- if (selection->isEmpty())
- {
- const std::string text = getString("nothing_selected");
- mLodLevel->setText(text);
- mTrianglesShown->setText(text);
- mPixelArea->setText(text);
-
- toggleRenderLoadingIndicators(false);
- }
- else
+ if (!selection->isEmpty() && !mSelectionDirty)
{
S32 object_lod = -1;
bool multiple_lods = false;
@@ -192,27 +216,71 @@ void LLFloaterObjectWeights::draw()
}
}
- if (multiple_lods)
+ if (mSelectionLastTris != total_tris)
{
- mLodLevel->setText(getString("multiple_lods"));
- toggleRenderLoadingIndicators(false);
+ mSelectionDirty = true;
}
- else if (object_lod < 0)
+ else if (mSelectionLastArea != pixel_area)
{
- // nodes are waiting for data
- toggleRenderLoadingIndicators(true);
+ mSelectionDirty = true;
}
- else
+ else if (multiple_lods)
{
- mLodLevel->setText(getString(lod_strings[object_lod]));
- toggleRenderLoadingIndicators(false);
+ mSelectionDirty |= mSelectionLastLOD != -1;
+ }
+ else if (mSelectionLastLOD != object_lod)
+ {
+ mSelectionDirty = true;
}
- mTrianglesShown->setText(llformat("%d", total_tris));
- mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
}
LLFloater::draw();
}
+void LLFloaterObjectWeights::onIdleRefresh(void* user_data)
+{
+ LLFloaterObjectWeights* self = (LLFloaterObjectWeights*)user_data;
+
+ F64 current_time = LLTimer::getTotalSeconds();
+ S32 current_lod_requests = LLMeshRepoThread::sActiveLODRequests.load();
+ // Can't look for a specific mesh (no callback mechanics and we
+ // need multiple ones), so just update periodically if something loads
+ self->mSelectionMeshDirty |= (self->mLastActiveLODRequests > current_lod_requests);
+ bool throttle_elapsed = (current_time - self->mSelectionRefreshTime) >= 2.0;
+
+ if (self->mLastActiveLODRequests < current_lod_requests)
+ {
+ // we are interested in finished downloads,
+ // so don't refresh if more requests are getting added.
+ self->mLastActiveLODRequests = current_lod_requests;
+ }
+
+ if (self->mSelectionDirty)
+ {
+ // Always refresh on selection changes
+ self->refreshDataFromSelection();
+ self->mSelectionDirty = false;
+ self->mSelectionRefreshTime = current_time;
+ // refreshDataFromSelection could have indirectly initiated more requests
+ self->mLastActiveLODRequests = LLMeshRepoThread::sActiveLODRequests.load();
+ }
+ else if (self->mSelectionMeshDirty && throttle_elapsed)
+ {
+ // LOD requests count changed or mesh needs lod data reload
+ self->refreshDataFromSelection();
+ self->mSelectionRefreshTime = current_time;
+ self->mSelectionMeshDirty = false;
+ // refreshDataFromSelection could have indirectly initiated more requests
+ self->mLastActiveLODRequests = LLMeshRepoThread::sActiveLODRequests.load();
+ }
+ else if (self->mWeightsDirty) // also done in refreshDataFromSelection
+ {
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ S32 render_cost = selection->getSelectedObjectRenderCost();
+ self->mSelectedDisplayWeight->setText(llformat("%d", render_cost));
+ self->mWeightsDirty = false;
+ }
+}
+
void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel)
{
if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty())
@@ -240,6 +308,101 @@ void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel)
}
}
+void LLFloaterObjectWeights::refreshDataFromSelection()
+{
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (selection->isEmpty())
+ {
+ const std::string text = getString("nothing_selected");
+ mLodLevel->setText(text);
+ mTrianglesShown->setText(text);
+ mPixelArea->setText(text);
+
+ mHighLodTris->setText(text);
+ mMediumLodTris->setText(text);
+ mLowLodTris->setText(text);
+ mLowestLodTris->setText(text);
+
+ toggleRenderLoadingIndicators(false);
+ toggleLODLoadingIndicators(false);
+ }
+ else
+ {
+ S32 object_lod = -1;
+ bool multiple_lods = false;
+ S32 total_tris = 0;
+ F32 pixel_area = 0;
+ S32 high_tris = 0;
+ S32 medium_tris = 0;
+ S32 low_tris = 0;
+ S32 lowest_tris = 0;
+ for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
+ iter != selection->valid_root_end(); ++iter)
+ {
+ LLViewerObject* object = (*iter)->getObject();
+ S32 lod = object->getLOD();
+ if (object_lod < 0)
+ {
+ object_lod = lod;
+ }
+ else if (object_lod != lod)
+ {
+ multiple_lods = true;
+ }
+
+ if (object->isRootEdit())
+ {
+ total_tris += object->recursiveGetTriangleCount();
+ pixel_area += object->getPixelArea();
+ object->recursiveGetLODTriangleCount(high_tris, medium_tris, low_tris, lowest_tris);
+ }
+ }
+
+ mSelectionLastTris = total_tris;
+ mSelectionLastArea = pixel_area;
+ if (multiple_lods)
+ {
+ mSelectionLastLOD = -1;
+ }
+ else
+ {
+ mSelectionLastLOD = object_lod;
+ }
+
+ if (multiple_lods)
+ {
+ mLodLevel->setText(getString("multiple_lods"));
+ toggleRenderLoadingIndicators(false);
+ toggleLODLoadingIndicators(false);
+ }
+ else if (object_lod < 0)
+ {
+ // nodes are waiting for data
+ toggleRenderLoadingIndicators(true);
+ toggleLODLoadingIndicators(true);
+ }
+ else
+ {
+ mLodLevel->setText(getString(lod_strings[object_lod]));
+ toggleRenderLoadingIndicators(false);
+ toggleLODLoadingIndicators(false);
+ }
+ mTrianglesShown->setText(llformat("%d", total_tris));
+ mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
+ mHighLodTris->setText(llformat("%d", high_tris));
+ mMediumLodTris->setText(llformat("%d", medium_tris));
+ mLowLodTris->setText(llformat("%d", low_tris));
+ mLowestLodTris->setText(llformat("%d", lowest_tris));
+ }
+
+ if (mWeightsDirty)
+ {
+ S32 render_cost = selection->getSelectedObjectRenderCost();
+ mSelectedDisplayWeight->setText(llformat("%d", render_cost));
+ mWeightsDirty = false;
+ }
+}
+
void LLFloaterObjectWeights::refresh()
{
LLSelectMgr* sel_mgr = LLSelectMgr::getInstance();
@@ -341,6 +504,19 @@ void LLFloaterObjectWeights::toggleRenderLoadingIndicators(bool visible)
mPixelArea->setVisible(!visible);
}
+void LLFloaterObjectWeights::toggleLODLoadingIndicators(bool visible)
+{
+ childSetVisible("high_lod_tris_loading_indicator", visible);
+ childSetVisible("medium_lod_tris_loading_indicator", visible);
+ childSetVisible("low_lod_tris_loading_indicator", visible);
+ childSetVisible("lowest_lod_tris_loading_indicator", visible);
+
+ mHighLodTris->setVisible(!visible);
+ mMediumLodTris->setVisible(!visible);
+ mLowLodTris->setVisible(!visible);
+ mLowestLodTris->setVisible(!visible);
+}
+
void LLFloaterObjectWeights::updateIfNothingSelected()
{
const std::string text = getString("nothing_selected");
diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h
index bda625564b..dac87d2a10 100644
--- a/indra/newview/llfloaterobjectweights.h
+++ b/indra/newview/llfloaterobjectweights.h
@@ -61,13 +61,17 @@ public:
bool postBuild() override;
void onOpen(const LLSD& key) override;
+ void onClose(bool app_quitting) override;
void onWeightsUpdate(const SelectionCost& selection_cost) override;
void setErrorStatus(S32 status, const std::string& reason) override;
void draw() override;
+ static void onIdleRefresh(void* user_data);
+
void updateLandImpacts(const LLParcel* parcel);
+ void refreshDataFromSelection();
void refresh() override;
private:
@@ -76,9 +80,19 @@ private:
void toggleWeightsLoadingIndicators(bool visible);
void toggleLandImpactsLoadingIndicators(bool visible);
void toggleRenderLoadingIndicators(bool visible);
+ void toggleLODLoadingIndicators(bool visible);
void updateIfNothingSelected();
+ bool mWeightsDirty;
+ bool mSelectionDirty;
+ bool mSelectionMeshDirty;
+ F64 mSelectionRefreshTime;
+ S32 mSelectionLastLOD;
+ S32 mSelectionLastTris;
+ F32 mSelectionLastArea;
+ S32 mLastActiveLODRequests;
+
LLTextBox *mSelectedObjects;
LLTextBox *mSelectedPrims;
@@ -95,6 +109,13 @@ private:
LLTextBox *mLodLevel;
LLTextBox *mTrianglesShown;
LLTextBox *mPixelArea;
+
+ LLTextBox *mHighLodTris;
+ LLTextBox *mMediumLodTris;
+ LLTextBox *mLowLodTris;
+ LLTextBox *mLowestLodTris;
+
+ boost::signals2::scoped_connection mSelectionConnection;
};
#endif //LL_LLFLOATEROBJECTWEIGHTS_H
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 1b64eab3c0..72f92785fc 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -252,7 +252,6 @@ LLSelectMgr::LLSelectMgr()
LLSelectMgr::~LLSelectMgr()
{
clearSelections();
- mSlectionLodModChangedConnection.disconnect();
}
void LLSelectMgr::clearSelections()
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 11aad3b806..792a37297f 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -943,7 +943,6 @@ private:
bool mForceSelection;
std::vector<LLAnimPauseRequest> mPauseRequests;
- boost::signals2::connection mSlectionLodModChangedConnection;
};
// *DEPRECATED: For callbacks or observers, use
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 7c26cb3c9f..57915cca85 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4034,6 +4034,11 @@ U32 LLViewerObject::getTriangleCount(S32* vcount) const
return 0;
}
+U32 LLViewerObject::getLODTriangleCount(S32 lod)
+{
+ return 0;
+}
+
U32 LLViewerObject::getHighLODTriangleCount()
{
return 0;
@@ -4055,6 +4060,27 @@ U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const
return total_tris;
}
+void LLViewerObject::recursiveGetLODTriangleCount(S32& high_lod, S32& medium_lod, S32& low_lod, S32& lowest_lod)
+{
+ high_lod = (S32)getLODTriangleCount(LLModel::LOD_HIGH);
+ medium_lod = (S32)getLODTriangleCount(LLModel::LOD_MEDIUM);
+ low_lod = (S32)getLODTriangleCount(LLModel::LOD_LOW);
+ lowest_lod = (S32)getLODTriangleCount(LLModel::LOD_IMPOSTOR);
+ LLViewerObject::const_child_list_t& child_list = getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* childp = *iter;
+ if (childp)
+ {
+ high_lod += (S32)childp->getLODTriangleCount(LLModel::LOD_HIGH);
+ medium_lod += (S32)childp->getLODTriangleCount(LLModel::LOD_MEDIUM);
+ low_lod += (S32)childp->getLODTriangleCount(LLModel::LOD_LOW);
+ lowest_lod += (S32)childp->getLODTriangleCount(LLModel::LOD_IMPOSTOR);
+ }
+ }
+}
+
// This is using the stored surface area for each volume (which
// defaults to 1.0 for the case of everything except a sculpt) and
// then scaling it linearly based on the largest dimension in the
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 465e221ae4..54cdf046c7 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -427,10 +427,12 @@ public:
virtual F32 getStreamingCost() const;
virtual bool getCostData(LLMeshCostData& costs) const;
virtual U32 getTriangleCount(S32* vcount = NULL) const;
+ virtual U32 getLODTriangleCount(S32 lod);
virtual U32 getHighLODTriangleCount();
F32 recursiveGetScaledSurfaceArea() const;
U32 recursiveGetTriangleCount(S32* vcount = NULL) const;
+ void recursiveGetLODTriangleCount(S32 &high_lod, S32 &medium_lod, S32 &low_lod, S32 &lowest_lod);
void setObjectCost(F32 cost);
F32 getObjectCost();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3b41ccb6fc..076e5eb22e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4445,7 +4445,7 @@ U32 LLVOVolume::getTriangleCount(S32* vcount) const
return count;
}
-U32 LLVOVolume::getHighLODTriangleCount()
+U32 LLVOVolume::getLODTriangleCount(S32 lod)
{
U32 ret = 0;
@@ -4453,16 +4453,16 @@ U32 LLVOVolume::getHighLODTriangleCount()
if (!isSculpted())
{
- LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
+ LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), lod);
ret = ref->getNumTriangles();
LLPrimitive::getVolumeManager()->unrefVolume(ref);
}
else if (isMesh())
{
- LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
+ LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), lod);
if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
{
- gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
+ gMeshRepo.loadMesh(this, volume->getParams(), lod);
}
ret = ref->getNumTriangles();
LLPrimitive::getVolumeManager()->unrefVolume(ref);
@@ -4475,6 +4475,11 @@ U32 LLVOVolume::getHighLODTriangleCount()
return ret;
}
+U32 LLVOVolume::getHighLODTriangleCount()
+{
+ return getLODTriangleCount(LLModel::LOD_HIGH);
+}
+
//static
void LLVOVolume::preUpdateGeom()
{
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index b6044bc319..00d6138512 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -155,6 +155,7 @@ public:
/*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
/*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
+ /*virtual*/ U32 getLODTriangleCount(S32 lod) override;
/*virtual*/ U32 getHighLODTriangleCount() override;
/*virtual*/ bool lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml
index 709fbdd27e..e68c00a8d4 100644
--- a/indra/newview/skins/default/xui/en/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml
@@ -2,14 +2,14 @@
<floater
can_close="true"
can_tear_off="false"
- height="372"
+ height="479"
help_topic="object_weights"
layout="topleft"
name="object_weights"
save_rect="true"
single_instance="true"
title="ADVANCED"
- width="200">
+ width="205">
<floater.string
name="nothing_selected"
value="--"/>
@@ -48,7 +48,7 @@
name="objects"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<text
follows="left|top"
height="16"
@@ -67,7 +67,7 @@
name="prims"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<text
follows="left|top"
height="16"
@@ -85,7 +85,7 @@
left="10"
name="selected_text_border"
top_pad="5"
- width="180"/>
+ width="185"/>
<text
@@ -107,7 +107,7 @@
name="download"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -134,7 +134,7 @@
name="physics"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -161,7 +161,7 @@
name="server"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -188,7 +188,7 @@
name="display"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -214,7 +214,7 @@
left="10"
name="weights_text_border"
top_pad="5"
- width="180"/>
+ width="185"/>
<text
@@ -236,7 +236,7 @@
name="selected"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -263,7 +263,7 @@
name="rezzed_on_land"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -290,7 +290,7 @@
name="remaining_capacity"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -317,7 +317,7 @@
name="total_capacity"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -336,6 +336,15 @@
value="Total capacity"
width="130" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="rendering_text_border"
+ top_pad="5"
+ width="185"/>
<text
follows="left|top"
@@ -356,7 +365,7 @@
name="lod_level"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -383,7 +392,7 @@
name="triangles_shown"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -410,7 +419,7 @@
name="pixel_area"
top_pad="3"
value="--"
- width="40" />
+ width="45" />
<loading_indicator
follows="left|top"
height="16"
@@ -428,4 +437,133 @@
top_delta="0"
value="Pixel Area"
width="130" />
+
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="10"
+ name="lods_text_border"
+ top_pad="5"
+ width="185"/>
+
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lod_info_text"
+ text_color="EmphasisColor"
+ top_pad="10"
+ value="LOD INFO"
+ width="180" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="high_lod_tris"
+ top_pad="3"
+ value="--"
+ width="45" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="high_lod_tris_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="high_lod_tris_label"
+ top_delta="0"
+ value="High triangles"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="medium_lod_tris"
+ top_pad="3"
+ value="--"
+ width="45" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="medium_lod_tris_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="medium_lod_tris_label"
+ top_delta="0"
+ value="Medium triangles"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="low_lod_tris"
+ top_pad="3"
+ value="--"
+ width="45" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="low_lod_tris_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="low_lod_tris_label"
+ top_delta="0"
+ value="Low triangles"
+ width="130" />
+ <text
+ follows="left|top"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="lowest_lod_tris"
+ top_pad="3"
+ value="--"
+ width="45" />
+ <loading_indicator
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="34"
+ name="lowest_lod_tris_loading_indicator"
+ top_delta="0"
+ width="16" />
+ <text
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left_pad="10"
+ name="lowest_lod_tris_label"
+ top_delta="0"
+ value="Lowest triangles"
+ width="130" />
</floater>