summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmath/llvolume.cpp161
-rw-r--r--indra/llmath/llvolume.h11
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llfloaterimagepreview.cpp3
-rw-r--r--indra/newview/llpanelcontents.cpp37
-rw-r--r--indra/newview/llpanelcontents.h4
-rw-r--r--indra/newview/llpanelprofilepicks.cpp15
-rw-r--r--indra/newview/llpreviewscript.cpp2
-rw-r--r--indra/newview/llsidepanelinventory.cpp20
-rw-r--r--indra/newview/llvovolume.cpp3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml16
11 files changed, 73 insertions, 210 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index a029fea992..e2407860b3 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -1972,8 +1972,6 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const bool ge
mNumHullIndices = 0;
// set defaults
- mSculptValidationCache.fill(LLSculptValidationState::Unvalidated);
-
if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
{
mPathp = new LLDynamicPath();
@@ -2001,13 +1999,6 @@ void LLVolume::resizePath(S32 length)
setDirty();
}
-void LLVolume::setDirty()
-{
- mPathp->setDirty();
- mProfilep->setDirty();
- mSculptValidationCache.fill(LLSculptValidationState::Unvalidated);
-}
-
void LLVolume::regen()
{
generate();
@@ -3289,100 +3280,10 @@ S32 sculpt_sides(F32 detail)
}
}
-static bool validate_sculpt_geometry(const LLVolume* volume, bool validate_area)
-{
- if (!volume || volume->getNumVolumeFaces() == 0)
- {
- return true;
- }
-
- // Validate each face in the sculpt
- for (S32 face_idx = 0; face_idx < volume->getNumVolumeFaces(); ++face_idx)
- {
- const LLVolumeFace& face = volume->getVolumeFace(face_idx);
-
- // Skip validation for degenerate faces
- if (face.mNumVertices < 3 || face.mNumIndices < 3)
- {
- continue;
- }
-
- // Calculate 'bounding' surface
- LLVector4a extent_size;
- extent_size.setSub(face.mExtents[1], face.mExtents[0]);
-
- F32 width = extent_size[0];
- F32 height = extent_size[1];
- F32 depth = extent_size[2];
-
- F32 bounding_surface = width * height + width * depth + height * depth;
- bounding_surface *= 2;
-
- if (!llfinite(bounding_surface) || bounding_surface <= FLT_EPSILON)
- {
- return false;
- }
-
- // Calculate total surface area of all triangles
- F32 total_triangle_area = 0.0f;
- S32 num_triangles = face.mNumIndices / 3;
-
- for (S32 i = 0; i < num_triangles; ++i)
- {
- S32 idx_base = i * 3;
- U16 idx0 = face.mIndices[idx_base];
- U16 idx1 = face.mIndices[idx_base + 1];
- U16 idx2 = face.mIndices[idx_base + 2];
-
- // Validate indices
- if (idx0 >= face.mNumVertices || idx1 >= face.mNumVertices || idx2 >= face.mNumVertices)
- {
- continue;
- }
-
- const LLVector4a& v0 = face.mPositions[idx0];
- const LLVector4a& v1 = face.mPositions[idx1];
- const LLVector4a& v2 = face.mPositions[idx2];
-
- // Calculate triangle area
- LLVector4a edge1, edge2, cross;
- edge1.setSub(v1, v0);
- edge2.setSub(v2, v0);
- cross.setCross3(edge1, edge2);
-
- F32 triangle_area = cross.getLength3().getF32() * 0.5f;
- total_triangle_area += triangle_area;
- }
-
- if (!llfinite(total_triangle_area))
- {
- return false;
- }
-
- // The idea here is that the total area of a sculpt is normally comparable
- // to the area of a bounding box. But a random overlapping collection of
- // triangles has a significantly larger area than a sculpt normally has.
- F32 area_ratio = total_triangle_area / bounding_surface;
- constexpr F32 MAX_AREA_TO_AREA_RATIO = 16.0f;
- if (validate_area && area_ratio > MAX_AREA_TO_AREA_RATIO)
- {
- LL_DEBUGS("LLVOLUME") << "Sculpt rejected: excessive triangle area."
- << " Face index: " << face_idx
- << " Total triangle area: " << total_triangle_area << " sq m"
- << " Bounding surface area: " << bounding_surface << " sq m"
- << " Ratio: " << area_ratio
- << " Triangle count: " << num_triangles
- << " Bounds: [" << width << " x " << height << " x " << depth << "]" << LL_ENDL;
- return false;
- }
- }
-
- return true;
-}
// determine the number of vertices in both s and t direction for this sculpt
-static void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t)
+void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 detail, S32& s, S32& t)
{
// this code has the following properties:
// 1) the aspect ratio of the mesh is as close as possible to the ratio of the map
@@ -3417,7 +3318,7 @@ static void sculpt_calc_mesh_resolution(U16 width, U16 height, U8 type, F32 deta
}
// sculpt replaces generate() for sculpted surfaces
-void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder, bool validate_area)
+void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder)
{
U8 sculpt_type = mParams.getSculptType();
@@ -3492,62 +3393,10 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
mSculptLevel = sculpt_level;
- LLSculptValidationState cached_state = LLSculptValidationState::Valid;
- if (!data_is_empty && (sculpt_level >= 0) && sculpt_level < SCULPT_CACHE_SIZE)
- {
- // validation might be expensive, so we do it only once per lod.
- cached_state = mSculptValidationCache[sculpt_level];
- }
-
- switch (cached_state)
- {
- case LLSculptValidationState::Valid:
- {
- // Delete any existing faces, then regenerate
- mVolumeFaces.clear();
- createVolumeFaces();
- break;
- }
- case LLSculptValidationState::Invalid:
- {
- // Invalid geometry
- // Regenerate mesh with an empty placeholder
- mVolumeFaces.clear();
- sculptGenerateEmptyPlaceholder();
- createVolumeFaces();
- break;
- }
- case LLSculptValidationState::Unvalidated:
- {
- // First time at this LOD
- mVolumeFaces.clear();
- createVolumeFaces();
-
- bool valid_geometry = true;
-
- // Todo: can this be backed into createVolumeFaces?
- // Or calculated without having to call createVolumeFaces first?
- // Todo 2: should the same be done for meshes?
- valid_geometry = validate_sculpt_geometry(this, validate_area);
- mSculptValidationCache[sculpt_level] = valid_geometry ? LLSculptValidationState::Valid : LLSculptValidationState::Invalid;
-
- if (!valid_geometry)
- {
- LL_WARNS("LLVOLUME") << "Sculpt failed geometry validation - either invalid image or malicious. "
- << "Replacing with placeholder. Image: " << mParams.getSculptID() << LL_ENDL;
-
- // Clear the malicious faces
- mVolumeFaces.clear();
-
- // Regenerate mesh with empty placeholder
- sculptGenerateEmptyPlaceholder();
+ // Delete any existing faces so that they get regenerated
+ mVolumeFaces.clear();
- // Recreate faces with placeholder geometry
- createVolumeFaces();
- }
- break;
- }
- } //switch (cached_state)
+ createVolumeFaces();
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 40e6f8e220..3496928f7b 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -60,8 +60,6 @@ class LLVolumeOctree;
#include "llalignedarray.h"
#include "llrigginginfo.h"
-#include <array>
-
//============================================================================
constexpr S32 MIN_DETAIL_FACES = 6;
@@ -1042,7 +1040,7 @@ public:
const LLVector4a& getMeshPt(const U32 i) const { return mMesh[i]; }
- void setDirty();
+ void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
void regen();
void genTangents(S32 face);
@@ -1095,7 +1093,7 @@ public:
U32 mFaceMask; // bit array of which faces exist in this volume
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
- void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder, bool validate_area);
+ void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level, bool visible_placeholder);
void copyVolumeFaces(const LLVolume* volume);
void copyFacesTo(std::vector<LLVolumeFace> &faces) const;
void copyFacesFrom(const std::vector<LLVolumeFace> &faces);
@@ -1133,11 +1131,6 @@ public:
bool mIsMeshAssetLoaded;
bool mIsMeshAssetUnavaliable;
- // Cache for sculpt geometry validation results
- static constexpr S32 SCULPT_CACHE_SIZE = 6; // 0 to 5 inclusive
- enum class LLSculptValidationState : S8 { Unvalidated, Valid, Invalid };
- std::array<LLSculptValidationState, SCULPT_CACHE_SIZE> mSculptValidationCache;
-
const LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 12da2c67a7..c3868469f2 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16822,17 +16822,6 @@
<key>Value</key>
<integer>1000</integer>
</map>
- <key>ValidateSculptyAreaRatio</key>
- <map>
- <key>Comment</key>
- <string>Version information generated by running the viewer</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>VersionChannelName</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 116286c872..bbff3e4c86 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -926,9 +926,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
if (imagep)
{
- static LLCachedControl<bool> validate_area(gSavedSettings, "ValidateSculptyAreaRatio", true);
LLImageDataSharedLock lock(imagep);
- mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false, validate_area());
+ mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0, false);
}
const LLVolumeFace &vf = mVolume->getVolumeFace(0);
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 43dd1bfe40..d9301d60f8 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -111,6 +111,7 @@ LLPanelContents::LLPanelContents()
LLPanelContents::~LLPanelContents()
{
+ mSimulatorFeaturesConnection.disconnect();
// Children all cleaned up by default view destructor.
}
@@ -119,6 +120,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
{
if( !objectp )
{
+ mSimulatorFeaturesConnection.disconnect();
mLastScriptObjectID.setNull();
getChildView("button new script")->setEnabled(false);
getChildView("button new notecard")->setEnabled(false);
@@ -154,11 +156,18 @@ void LLPanelContents::getState(LLViewerObject *objectp )
region->getSimulatorFeatures(simulatorFeatures);
lua_region = simulatorFeatures["LuaScriptsEnabled"].asBoolean();
}
+ mSimulatorFeaturesConnection.disconnect();
+ if (region && !region->simulatorFeaturesReceived())
+ {
+ mSimulatorFeaturesConnection = region->setSimulatorFeaturesReceivedCallback(
+ boost::bind(&LLPanelContents::onSimulatorFeaturesReceived, this, _1));
+ }
LLComboBox* new_script = getChild<LLComboBox>("button new script");
new_script->setEnabledByValue("lua", lua_region);
if (mLastScriptObjectID != objectp->getID() || mLastLuaRegion != lua_region)
{
- new_script->setValue(lua_region ? "lua" : "lsl");
+ mNewScriptIsLua = lua_region;
+ new_script->setValue(mNewScriptIsLua ? "lua" : "lsl");
}
mLastScriptObjectID = objectp->getID();
mLastLuaRegion = lua_region;
@@ -187,6 +196,11 @@ void LLPanelContents::getState(LLViewerObject *objectp )
}
}
+void LLPanelContents::onSimulatorFeaturesReceived(const LLUUID&)
+{
+ refresh();
+}
+
void LLPanelContents::onFilterEdit()
{
const std::string& filter_substring = mFilterEditor->getText();
@@ -277,31 +291,18 @@ void LLPanelContents::onNewScriptFlyoutCommit(LLUICtrl* ctrl)
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok);
if (!object) return;
- U8 script_language;
const std::string value = ctrl->getValue().asString();
if (value == "lsl")
{
- script_language = SST_LSL;
+ mNewScriptIsLua = false;
}
else if (value == "lua")
{
- script_language = SST_LUA;
- }
- else
- {
- script_language = SST_LSL;
- LLViewerRegion* region = object->getRegion();
- if (region && region->simulatorFeaturesReceived())
- {
- LLSD simulatorFeatures;
- region->getSimulatorFeatures(simulatorFeatures);
- if (simulatorFeatures["LuaScriptsEnabled"].asBoolean())
- {
- script_language = SST_LUA;
- }
- }
+ mNewScriptIsLua = true;
}
+ ctrl->setValue(mNewScriptIsLua ? "lua" : "lsl");
+ const U8 script_language = mNewScriptIsLua ? SST_LUA : SST_LSL;
std::string vm = (script_language == SST_LUA) ? "luau" : "mono";
LLSD params;
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index d576b72353..e2909d21fc 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -35,6 +35,7 @@
#include "llvoinventorylistener.h"
#include "llscripteditorws.h"
#include "v3math.h"
+#include <boost/signals2/connection.hpp>
class LLButton;
class LLPanelObjectInventory;
@@ -79,10 +80,13 @@ public:
protected:
void getState(LLViewerObject *object);
void onFilterEdit();
+ void onSimulatorFeaturesReceived(const LLUUID& region_id);
bool mDirtyFilter { false };
LLUUID mLastScriptObjectID;
bool mLastLuaRegion { false };
+ bool mNewScriptIsLua { false };
+ boost::signals2::connection mSimulatorFeaturesConnection;
public:
class LLFilterEditor* mFilterEditor;
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
index 6870d719af..ca1dd1b786 100644
--- a/indra/newview/llpanelprofilepicks.cpp
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -41,6 +41,7 @@
#include "llpanelavatar.h"
#include "llpanelprofile.h"
#include "llparcel.h"
+#include "llregionhandle.h"
#include "llstartup.h"
#include "lltabcontainer.h"
#include "lltextbox.h"
@@ -915,7 +916,19 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
{
// Region might have moved since the pick was saved; refresh the stored global position
// using the parcel info so map/teleport use the current location.
- setPosGlobal(LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z));
+ LLVector3d parcel_pos(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z);
+ U64 old_region_handle = to_region_handle(getPosGlobal());
+ U64 new_region_handle = to_region_handle(parcel_pos);
+ if (old_region_handle != new_region_handle)
+ {
+ F32 old_origin_x, old_origin_y;
+ from_region_handle(old_region_handle, &old_origin_x, &old_origin_y);
+ LLVector3d local_offset = getPosGlobal() - LLVector3d(old_origin_x, old_origin_y, 0.0);
+
+ F32 new_origin_x, new_origin_y;
+ from_region_handle(new_region_handle, &new_origin_x, &new_origin_y);
+ setPosGlobal(LLVector3d(new_origin_x, new_origin_y, 0.0) + local_offset);
+ }
setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index fbe6fc3e40..9e209f3914 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -2045,6 +2045,7 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
mPendingUploads = 0;
mScriptEd->mErrorList->deleteAllItems();
+ mScriptEd->enableSave(false);
mScriptEd->mEditor->makePristine();
if (sync)
@@ -2081,6 +2082,7 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
void LLPreviewLSL::onCompileTargetChanged()
{
+ mScriptEd->enableSave(true);
bool is_lua = (mScriptEd->mCompileTarget->getValue().asString() == "luau");
mScriptEd->mEditor->setLuauLanguage(is_lua);
mScriptEd->processKeywords(is_lua);
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 623db82939..ddb60b15db 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -313,6 +313,13 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel();
mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();
+
+ // Collapsing/expanding the inbox layout panel doesn't toggle actual view visibility, so if the
+ // inbox is already expanded at this point, build the views right away.
+ if (mInboxLayoutPanel && !mInboxLayoutPanel->isCollapsed())
+ {
+ inventory_panel->initializeViewBuilding();
+ }
}
void LLSidepanelInventory::enableInbox(bool enabled)
@@ -373,10 +380,17 @@ void LLSidepanelInventory::onToggleInboxBtn()
{
mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
if (mInboxLayoutPanel->isInVisibleChain())
- {
- gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", (U32)time_corrected());
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", (U32)time_corrected());
+ }
+
+ // Build the views when expanding the inbox if that hasn't happened yet.
+ LLInventoryPanel* inventory_panel = mInventoryPanelInbox.get();
+ if (inventory_panel)
+ {
+ inventory_panel->initializeViewBuilding();
+ }
}
-}
else
{
gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->getTargetDim());
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3ec2843fed..13707b1889 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1444,8 +1444,7 @@ void LLVOVolume::sculpt()
}
}
- static LLCachedControl<bool> validate_area(gSavedSettings, "ValidateSculptyAreaRatio", true);
- getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset(), validate_area());
+ getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset());
}
}
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index cf8f7be7b5..6cb36abe17 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1412,7 +1412,7 @@ function="World.EnvPreset"
parameter="script_debug" />
</menu_item_check>
<menu_item_call
- label="Recompile Scripts (Mono)"
+ label="Recompile LSL Scripts (Mono)"
name="Mono">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
@@ -1421,7 +1421,7 @@ function="World.EnvPreset"
function="EditableSelectedMono" />
</menu_item_call>
<menu_item_call
- label="Recompile Scripts (LSL)"
+ label="Recompile LSL Scripts (Legacy LSL)"
name="LSL">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
@@ -1430,20 +1430,20 @@ function="World.EnvPreset"
function="EditableSelected" />
</menu_item_call>
<menu_item_call
- label="Recompile Scripts (Lua)"
- name="Lua">
+ label="Recompile LSL Scripts (LSL on Luau)"
+ name="LSL on Luau">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
- parameter="compile lua" />
+ parameter="compile lsl-luau" />
<menu_item_call.on_enable
function="EditableSelectedLua" />
</menu_item_call>
<menu_item_call
- label="Recompile Scripts (LSL on Luau)"
- name="LSL on Luau">
+ label="Recompile Lua Scripts"
+ name="Lua">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
- parameter="compile lsl-luau" />
+ parameter="compile lua" />
<menu_item_call.on_enable
function="EditableSelectedLua" />
</menu_item_call>