From 620242477f6bd19fda2380e0a7d9aca673d889a5 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 29 Oct 2026 03:29:32 +0000 Subject: [PATCH 01/32] Add a pivot option to the mesh uploader The uploader always centres a model on its bounding box, so an object's origin, and the axis it turns about, sits at the box's centre. A door had to carry hidden geometry to put its hinge on an edge. The Upload options tab gets a pivot within the bounding box, -1 to 1 per axis. The uploader shifts every stored position domain, and the analyzed hulls' domain, so that the origin lands there; the quantized positions stay as they are. The sim keeps analyzed hulls where their domain puts them but fits any other physics shape to the box, so the pivot is held at the centre while a physics model is set but not analyzed, and a warning says the object will collide as its centred default hull when there is no physics model. It is held as well for rigged mesh, which its skeleton places, and for an upload of more than one model, whose pieces it would pull apart. The preview's display options get Origin, which draws the object's axes at the pivot, and Joint position overrides no longer wraps, to make room. Co-Authored-By: Claude Opus 5.5 --- indra/llprimitive/llmodel.cpp | 18 +++- indra/llprimitive/llmodel.h | 3 +- indra/newview/llfloatermodelpreview.cpp | 40 +++++++- indra/newview/llfloatermodelpreview.h | 1 + indra/newview/llmeshrepository.cpp | 13 ++- indra/newview/llmeshrepository.h | 7 +- indra/newview/llmodelpreview.cpp | 94 +++++++++++++++++++ indra/newview/llmodelpreview.h | 11 +++ .../default/xui/en/floater_model_preview.xml | 82 +++++++++++++++- 9 files changed, 254 insertions(+), 15 deletions(-) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 9521c82269e..c0ec5d69dd7 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -627,7 +627,8 @@ LLSD LLModel::writeModel( bool lock_scale_if_joint_position, EWriteModelMode write_mode, bool as_slm, - int submodel_id) + int submodel_id, + const LLVector3& position_offset) // Mesh uploader pivot { LLSD mdl; @@ -665,6 +666,15 @@ LLSD LLModel::writeModel( model[LLModel::LOD_PHYSICS] = NULL; } + // Mesh uploader pivot: the sim keeps analyzed hulls in their domain but fits the bounding hull to the box + if (!decomp.mHull.empty() && mdl.has("physics_convex")) + { + LLSD& convex = mdl["physics_convex"]; + convex["Min"] = (LLVector3(convex["Min"]) + position_offset).getValue(); + convex["Max"] = (LLVector3(convex["Max"]) + position_offset).getValue(); + } + // + if (as_slm) { //save material list names for (U32 i = 0; i < high->mMaterialList.size(); ++i) @@ -813,8 +823,10 @@ LLSD LLModel::writeModel( } //write out face data - mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); - mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); + // Mesh uploader pivot: the quantized positions stay, only their domain moves + mdl[model_names[idx]][i]["PositionDomain"]["Min"] = (min_pos + position_offset).getValue(); + mdl[model_names[idx]][i]["PositionDomain"]["Max"] = (max_pos + position_offset).getValue(); + // mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); mdl[model_names[idx]][i]["Position"] = verts; diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 55adbe7412b..99e6f93c60d 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -186,7 +186,8 @@ class alignas(16) LLModel : public LLVolume bool lock_scale_if_joint_position, EWriteModelMode write_mode = WRITE_BINARY, bool as_slm = false, - int submodel_id = 0); + int submodel_id = 0, + const LLVector3& position_offset = LLVector3::zero); // Mesh uploader pivot: shifts the stored domains off the prim's origin static LLSD writeModelToStream( std::ostream& ostr, diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 40578901136..73508358d6d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -191,6 +191,12 @@ bool LLFloaterModelPreview::postBuild() childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); + // Mesh uploader pivot + for (const char* axis : { "pivot_x", "pivot_y", "pivot_z" }) + { + getChild(axis)->setCommitCallback(boost::bind(&LLFloaterModelPreview::onPivotCommit, this)); + } + // getChild("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL); @@ -200,6 +206,7 @@ bool LLFloaterModelPreview::postBuild() getChild("show_skin_weight")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onShowSkinWeightChecked, this, _1)); getChild("show_joint_overrides")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild("show_joint_positions")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); + getChild("show_origin")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); // Mesh uploader pivot childDisable("upload_skin"); childDisable("upload_joints"); @@ -510,7 +517,8 @@ void LLFloaterModelPreview::onClickCalculateBtn() childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mUploadModelUrl, mDestinationFolderId, false, - getWholeModelFeeObserverHandle()); + getWholeModelFeeObserverHandle(), + LLHandle(), mModelPreview->getUploadPositionOffset()); // Mesh uploader pivot toggleCalculateButton(false); mUploadBtn->setEnabled(false); @@ -675,6 +683,24 @@ void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) fp->mModelPreview->refresh(); } + +// Mesh uploader pivot +void LLFloaterModelPreview::onPivotCommit() +{ + if (!mModelPreview) + { + return; + } + + mModelPreview->setUploadPivot(LLVector3((F32)childGetValue("pivot_x").asReal(), + (F32)childGetValue("pivot_y").asReal(), + (F32)childGetValue("pivot_z").asReal())); + mModelPreview->updateStatusMessages(); + toggleCalculateButton(true); + mModelPreview->refresh(); +} +// + //static void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata ) { @@ -1739,7 +1765,8 @@ void LLFloaterModelPreview::onUpload(void* user_data) mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mp->mUploadModelUrl, mp->mDestinationFolderId, - true, LLHandle(), mp->getWholeModelUploadObserverHandle()); + true, LLHandle(), mp->getWholeModelUploadObserverHandle(), + mp->mModelPreview->getUploadPositionOffset()); // Mesh uploader pivot } @@ -1873,6 +1900,15 @@ void LLFloaterModelPreview::resetDisplayOptions() void LLFloaterModelPreview::resetUploadOptions() { childSetValue("import_scale", 1); + // Mesh uploader pivot + childSetValue("pivot_x", 0); + childSetValue("pivot_y", 0); + childSetValue("pivot_z", 0); + if (mModelPreview) + { + mModelPreview->setUploadPivot(LLVector3::zero); + } + // childSetValue("pelvis_offset", 0); childSetValue("physics_explode", 0); childSetValue("physics_file", ""); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 39df7448f0d..1893be8cbe7 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -144,6 +144,7 @@ class LLFloaterModelPreview final : public LLFloaterModelUploadBase void onDescriptionKeystroke(LLUICtrl*); static void onImportScaleCommit(LLUICtrl*, void*); + void onPivotCommit(); // Mesh uploader pivot static void onPelvisOffsetCommit(LLUICtrl*, void*); static void onPreviewLODCommit(LLUICtrl*,void*); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e2620c6fc5d..a3afc5df1e3 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2699,7 +2699,8 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, const std::string & upload_url, LLUUID destination_folder_id, bool do_upload, LLHandle fee_observer, - LLHandle upload_observer) + LLHandle upload_observer, + const LLVector3& position_offset) // Mesh uploader pivot : LLThread("mesh upload"), LLCore::HttpHandler(), mDiscarded(false), @@ -2715,6 +2716,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data mUploadSkin = upload_skin; mUploadJoints = upload_joints; mLockScaleIfJointPosition = lock_scale_if_joint_position; + mPositionOffset = position_offset; // Mesh uploader pivot mMutex = new LLMutex(); mPendingUploads = 0; mFinished = false; @@ -2879,7 +2881,8 @@ void LLMeshUploadThread::packModelIntance( mLockScaleIfJointPosition, LLModel::WRITE_BINARY, false, - data.mBaseModel->mSubmodelID); + data.mBaseModel->mSubmodelID, + mPositionOffset); // Mesh uploader pivot data.mAssetData = ostr.str(); std::string str = ostr.str(); @@ -5556,11 +5559,13 @@ void LLMeshRepository::uploadModel(std::vector& data, const std LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, std::string upload_url, const LLUUID& destination_folder_id, bool do_upload, - LLHandle fee_observer, LLHandle upload_observer) + LLHandle fee_observer, LLHandle upload_observer, + const LLVector3& position_offset) // Mesh uploader pivot { LLMeshUploadThread* thread = new LLMeshUploadThread(data, lod_sources, scale, upload_textures, upload_skin, upload_joints, lock_scale_if_joint_position, - upload_url, destination_folder_id, do_upload, fee_observer, upload_observer); + upload_url, destination_folder_id, do_upload, fee_observer, upload_observer, + position_offset); // Mesh uploader pivot mUploadWaitList.push_back(thread); } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 5060e55d051..516a2283de6 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -801,6 +801,7 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler bool mUploadSkin; bool mUploadJoints; bool mLockScaleIfJointPosition; + LLVector3 mPositionOffset; // Mesh uploader pivot: added to every stored domain volatile bool mDiscarded; LLHost mHost; @@ -815,7 +816,8 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler const LLUUID destination_folder_id = LLUUID::null, bool do_upload = true, LLHandle fee_observer = (LLHandle()), - LLHandle upload_observer = (LLHandle())); + LLHandle upload_observer = (LLHandle()), + const LLVector3& position_offset = LLVector3::zero); // Mesh uploader pivot ~LLMeshUploadThread(); bool finished() const { return mFinished; } @@ -1008,7 +1010,8 @@ class LLMeshRepository const LLUUID& destination_folder_id = LLUUID::null, bool do_upload = true, LLHandle fee_observer= (LLHandle()), - LLHandle upload_observer = (LLHandle())); + LLHandle upload_observer = (LLHandle()), + const LLVector3& position_offset = LLVector3::zero); // Mesh uploader pivot S32 getMeshSize(const LLUUID& mesh_id, S32 lod) const; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 374821d3e4f..0376164f322 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2182,6 +2182,53 @@ void LLModelPreview::updateStatusMessages() } } + // Mesh uploader pivot: the sim keeps analyzed hulls where the pivot puts them but fits + // any other physics shape to the box, so a pivot needs analyzed physics or none at all. + { + bool has_physics = false; + bool analyzed = true; + bool rigged = false; + for (const LLModelInstance& instance : mUploadData) + { + rigged |= instance.mModel && !instance.mModel->mSkinWeights.empty(); + const LLModel* physics = instance.mLOD[LLModel::LOD_PHYSICS]; + if (physics && physics->getNumVolumeFaces() > 0) + { + has_physics = true; + analyzed &= !physics->mPhysics.mHull.empty(); + } + } + + std::string pivot_status; + mUploadPivotAllowed = true; + if (rigged) + { + pivot_status = mFMP->getString("pivot_status_rigged"); + mUploadPivotAllowed = false; + } + else if (mUploadData.size() > 1) + { + pivot_status = mFMP->getString("pivot_status_multiple"); + mUploadPivotAllowed = false; + } + else if (has_physics && !analyzed) + { + pivot_status = mFMP->getString("pivot_status_analyze"); + mUploadPivotAllowed = false; + } + else if (!has_physics && !mUploadPivot.isExactlyZero()) + { + pivot_status = mFMP->getString("pivot_status_no_physics"); + } + + for (const char* axis : { "pivot_x", "pivot_y", "pivot_z" }) + { + mFMP->childSetEnabled(axis, mUploadPivotAllowed); + } + mFMP->childSetValue("pivot_status", pivot_status); + } + // + if (!mModelNoErrors || mHasDegenerate) { mFMP->childDisable("ok_btn"); @@ -3641,6 +3688,53 @@ bool LLModelPreview::render() } } + // Mesh uploader pivot: the object's origin, drawn through the model + if (mViewOption["show_origin"]) + { + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + gDebugProgram.bind(); + gGL.getTextureSlot(0)->unbind(); + LLGLDepthTest gls_depth(GL_FALSE); + gGL.setLineWidth(2.f); + + const LLVector3 pivot = getEffectiveUploadPivot() * 0.5f; + for (const LLModelInstance& instance : mUploadData) + { + const LLMatrix4& mat = instance.mTransform; + const LLVector3 origin = pivot * mat; + + LLVector3 axes[3]; + F32 reach = 0.f; + for (S32 i = 0; i < 3; ++i) + { + axes[i].set(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]); + reach = llmax(reach, axes[i].normalize()); + } + reach *= 0.6f; + + static const LLColor4 colors[3] = { LLColor4::red, LLColor4::green, LLColor4::blue }; + gGL.begin(LLRender::LINES); + for (S32 i = 0; i < 3; ++i) + { + gGL.color4f(colors[i].mV[VRED] * 0.5f, colors[i].mV[VGREEN] * 0.5f, colors[i].mV[VBLUE] * 0.5f, 1.f); + gGL.vertex3fv((origin - axes[i] * reach).mV); + gGL.vertex3fv(origin.mV); + gGL.color4fv(colors[i].mV); + gGL.vertex3fv(origin.mV); + gGL.vertex3fv((origin + axes[i] * reach).mV); + } + gGL.end(); + } + gGL.flush(); + gGL.setLineWidth(1.f); + + if (shader) + { + shader->bind(); + } + } + // + gObjectPreviewProgram.unbind(); gGL.popMatrix(); diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index b62030a349c..f5a09606208 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -172,6 +172,15 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH void setHasPivot(bool val) { mHasPivot = val; } void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; } + // Mesh uploader pivot: the object's origin within its bounding box, -1 to 1 per axis + void setUploadPivot(const LLVector3& pivot) { mUploadPivot = pivot; } + const LLVector3& getUploadPivot() const { return mUploadPivot; } + // The pivot in effect: centred while the physics or the model count rules it out. + LLVector3 getEffectiveUploadPivot() const { return mUploadPivotAllowed ? mUploadPivot : LLVector3::zero; } + // What the stored domains are shifted by so that the origin lands on the pivot. + LLVector3 getUploadPositionOffset() const { return getEffectiveUploadPivot() * -0.5f; } + // + //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions //Accessors for joint position upload friendly rigs const bool isRigValidForJointPositionUpload(void) const { return mRigValidJointUpload; } @@ -271,6 +280,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH bool mResetJoints; bool mModelNoErrors; bool mLookUpLodFiles; + LLVector3 mUploadPivot; // Mesh uploader pivot + bool mUploadPivotAllowed{true}; // Mesh uploader pivot std::map mViewOption; diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index dee158eaa9e..c8f14716c77 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -35,6 +35,10 @@ LOD materials are not a subset of reference model. Some physical hulls exceed vertex limitations. The physics mesh is too dense or contains degenerate triangles. Use Analyze/Simplify to resolve. + A pivot is for unrigged mesh; rigged mesh is placed by its skeleton. + A pivot can be set only when uploading a single model. + Analyze the physics to set a pivot: unanalyzed physics stays centred on the object. + No physics shape is defined, so the object collides with its default hull, centred on itself. Fine for a phantom piece or physics type None. All Analyzing... Simplifying... @@ -1365,6 +1369,70 @@ label_text.text_color="White" left="20" top_pad="20"/> + + + Pivot: + + + + + + @@ -1934,8 +2000,18 @@ Analysed: label_text.text_color="White" layout="topleft" name="show_joint_positions" - top_pad="21"> + top_pad="10"> + + + + Date: Thu, 29 Oct 2026 03:31:56 +0000 Subject: [PATCH 02/32] Show the uploader pivot in percent or metres Percent of the half-extent suits snapping to a face; metres from the centre suit a hinge at a known distance. The pivot is kept as a fraction of the box, so metres follow the scale and the model's size. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 66 +++++++++++++++++-- indra/newview/llfloatermodelpreview.h | 7 +- indra/newview/llmodelpreview.cpp | 7 ++ .../default/xui/en/floater_model_preview.xml | 42 +++++++----- 4 files changed, 99 insertions(+), 23 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 73508358d6d..9a27e98a22c 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -196,6 +196,8 @@ bool LLFloaterModelPreview::postBuild() { getChild(axis)->setCommitCallback(boost::bind(&LLFloaterModelPreview::onPivotCommit, this)); } + childSetValue("pivot_units", "percent"); + getChild("pivot_units")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onPivotUnitsCommit, this)); // getChild("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL); @@ -685,6 +687,17 @@ void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) } // Mesh uploader pivot +static const char* const PIVOT_AXES[3] = { "pivot_x", "pivot_y", "pivot_z" }; + +LLVector3 LLFloaterModelPreview::getPivotHalfExtents() const +{ + if (!mModelPreview) + { + return LLVector3::zero; + } + return mModelPreview->mPreviewScale * (F32)childGetValue("import_scale").asReal(); +} + void LLFloaterModelPreview::onPivotCommit() { if (!mModelPreview) @@ -692,13 +705,55 @@ void LLFloaterModelPreview::onPivotCommit() return; } - mModelPreview->setUploadPivot(LLVector3((F32)childGetValue("pivot_x").asReal(), - (F32)childGetValue("pivot_y").asReal(), - (F32)childGetValue("pivot_z").asReal())); + const bool metres = childGetValue("pivot_units").asString() == "metres"; + const LLVector3 half = getPivotHalfExtents(); + LLVector3 pivot; + for (S32 i = 0; i < 3; ++i) + { + const F32 shown = (F32)childGetValue(PIVOT_AXES[i]).asReal(); + if (metres) + { + pivot.mV[i] = half.mV[i] > 0.f ? shown / half.mV[i] : 0.f; + } + else + { + pivot.mV[i] = shown / 100.f; + } + pivot.mV[i] = llclamp(pivot.mV[i], -1.f, 1.f); + } + + mModelPreview->setUploadPivot(pivot); mModelPreview->updateStatusMessages(); toggleCalculateButton(true); mModelPreview->refresh(); } + +void LLFloaterModelPreview::onPivotUnitsCommit() +{ + updatePivotControls(); +} + +void LLFloaterModelPreview::updatePivotControls() +{ + if (!mModelPreview) + { + return; + } + + const bool metres = childGetValue("pivot_units").asString() == "metres"; + const LLVector3 half = getPivotHalfExtents(); + const LLVector3& pivot = mModelPreview->getUploadPivot(); + for (S32 i = 0; i < 3; ++i) + { + LLSpinCtrl* spinner = getChild(PIVOT_AXES[i]); + const F32 range = metres ? half.mV[i] : 100.f; + spinner->setMinValue(-range); + spinner->setMaxValue(range); + spinner->setIncrement(metres ? 0.01f : 50.f); + spinner->setPrecision(metres ? 3 : 1); + spinner->setValue(pivot.mV[i] * range); + } +} // //static @@ -1901,13 +1956,12 @@ void LLFloaterModelPreview::resetUploadOptions() { childSetValue("import_scale", 1); // Mesh uploader pivot - childSetValue("pivot_x", 0); - childSetValue("pivot_y", 0); - childSetValue("pivot_z", 0); + childSetValue("pivot_units", "percent"); if (mModelPreview) { mModelPreview->setUploadPivot(LLVector3::zero); } + updatePivotControls(); // childSetValue("pelvis_offset", 0); childSetValue("physics_explode", 0); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 1893be8cbe7..902f9c63d4e 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -144,7 +144,12 @@ class LLFloaterModelPreview final : public LLFloaterModelUploadBase void onDescriptionKeystroke(LLUICtrl*); static void onImportScaleCommit(LLUICtrl*, void*); - void onPivotCommit(); // Mesh uploader pivot + // Mesh uploader pivot: shown in percent of the half-extent or in metres from the centre + void onPivotCommit(); + void onPivotUnitsCommit(); + void updatePivotControls(); + LLVector3 getPivotHalfExtents() const; + // static void onPelvisOffsetCommit(LLUICtrl*, void*); static void onPreviewLODCommit(LLUICtrl*,void*); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 0376164f322..9b582477967 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -279,6 +279,13 @@ void LLModelPreview::updateDimentionsAndOffsets() mDetailsSignal((F32)(mPreviewScale[0] * scale), (F32)(mPreviewScale[1] * scale), (F32)(mPreviewScale[2] * scale)); + // Mesh uploader pivot: metres follow the model's size + if (LLFloaterModelPreview::sInstance && LLFloaterModelPreview::sInstance->mModelPreview == this) + { + LLFloaterModelPreview::sInstance->updatePivotControls(); + } + // + updateStatusMessages(); } diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index c8f14716c77..28f79f1a4e9 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1378,51 +1378,61 @@ text_color="White" top_pad="20" width="50" - tool_tip="Where the object's origin, and so its rotation, sits within its bounding box: -1 and 1 are its faces, 0 its centre."> + tool_tip="Where the object's origin, and so its rotation, sits within its bounding box: in percent, -100 and 100 are its faces and 0 its centre; in metres, the distance from its centre."> Pivot: + width="80"/> + width="80"/> + width="80"/> + + % + m + Date: Mon, 2 Nov 2026 05:03:36 +0000 Subject: [PATCH 03/32] Fit the uploader's display options inside their panel The right panel was 140 tall, so the Origin check box, and part of Joints, lay below it where clicks never reached them; the preview gives up the height. Co-Authored-By: Claude Opus 5.5 --- indra/newview/skins/default/xui/en/floater_model_preview.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 28f79f1a4e9..83af7d78667 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1932,10 +1932,10 @@ Analysed: name="preview_panel" top_pad="4" width="325" - height="408"/> + height="340"/> Date: Mon, 2 Nov 2026 05:05:24 +0000 Subject: [PATCH 04/32] Give the pivot units their values back A combo item's text is its value, so the metres item reported "m" and the pivot stayed in percent; the labels are attributes now, as the file's other combos have them. Co-Authored-By: Claude Opus 5.5 --- indra/newview/skins/default/xui/en/floater_model_preview.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 83af7d78667..c4396eb5f1b 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1430,8 +1430,8 @@ name="pivot_units" top_delta="0" width="50"> - % - m + + Date: Mon, 2 Nov 2026 05:08:32 +0000 Subject: [PATCH 05/32] Draw the uploader origin as the translate gizmo's arrows Each axis is a shaft and a solid cone in the gizmo's colours, red X forward, so the origin reads as the object's frame rather than three crossing lines. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 37 ++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 9b582477967..450a0aac416 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3719,16 +3719,45 @@ bool LLModelPreview::render() } reach *= 0.6f; + // Arrows as the translate gizmo draws them: a shaft and a solid cone per axis. static const LLColor4 colors[3] = { LLColor4::red, LLColor4::green, LLColor4::blue }; + const F32 head_length = reach * 0.2f; + const F32 head_radius = reach * 0.06f; + constexpr S32 HEAD_SEGMENTS = 12; + gGL.begin(LLRender::LINES); for (S32 i = 0; i < 3; ++i) { - gGL.color4f(colors[i].mV[VRED] * 0.5f, colors[i].mV[VGREEN] * 0.5f, colors[i].mV[VBLUE] * 0.5f, 1.f); - gGL.vertex3fv((origin - axes[i] * reach).mV); - gGL.vertex3fv(origin.mV); gGL.color4fv(colors[i].mV); gGL.vertex3fv(origin.mV); - gGL.vertex3fv((origin + axes[i] * reach).mV); + gGL.vertex3fv((origin + axes[i] * (reach - head_length)).mV); + } + gGL.end(); + + gGL.begin(LLRender::TRIANGLES); + for (S32 i = 0; i < 3; ++i) + { + const LLVector3 tip = origin + axes[i] * reach; + const LLVector3 base = origin + axes[i] * (reach - head_length); + const LLVector3 u = axes[(i + 1) % 3] * head_radius; + const LLVector3 v = axes[(i + 2) % 3] * head_radius; + for (S32 s = 0; s < HEAD_SEGMENTS; ++s) + { + const F32 a0 = F_TWO_PI * s / HEAD_SEGMENTS; + const F32 a1 = F_TWO_PI * (s + 1) / HEAD_SEGMENTS; + const LLVector3 r0 = base + u * cosf(a0) + v * sinf(a0); + const LLVector3 r1 = base + u * cosf(a1) + v * sinf(a1); + // Shade the side by its angle so the cone reads as solid. + const F32 shade = 0.65f + 0.35f * cosf(a0); + gGL.color4f(colors[i].mV[VRED] * shade, colors[i].mV[VGREEN] * shade, colors[i].mV[VBLUE] * shade, 1.f); + gGL.vertex3fv(tip.mV); + gGL.vertex3fv(r0.mV); + gGL.vertex3fv(r1.mV); + gGL.color4f(colors[i].mV[VRED] * 0.5f, colors[i].mV[VGREEN] * 0.5f, colors[i].mV[VBLUE] * 0.5f, 1.f); + gGL.vertex3fv(base.mV); + gGL.vertex3fv(r1.mV); + gGL.vertex3fv(r0.mV); + } } gGL.end(); } From ded3ab2ea25b623fc1880c238ae54acc57b6c89d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 2 Nov 2026 07:19:43 +0000 Subject: [PATCH 06/32] Colour the uploader origin's arrows per axis gDebugProgram draws one uniform colour, so every arrow took the last one set, blue; gUIProgram takes the vertex colours. Culling is off so the cones show from any side. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 450a0aac416..6e2598bb78c 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3699,9 +3699,10 @@ bool LLModelPreview::render() if (mViewOption["show_origin"]) { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - gDebugProgram.bind(); + gUIProgram.bind(); // takes the vertex colours, which gDebugProgram replaces with one uniform gGL.getTextureSlot(0)->unbind(); LLGLDepthTest gls_depth(GL_FALSE); + LLGLDisable no_cull(GL_CULL_FACE); gGL.setLineWidth(2.f); const LLVector3 pivot = getEffectiveUploadPivot() * 0.5f; From 23f68546595736c8a4af54ca680246748926a221 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 2 Nov 2026 08:33:19 +0000 Subject: [PATCH 07/32] Measure the uploader pivot along the mesh's own axes Metres divided by the scene's bounding box, so a rotated instance moved by the wrong amount; they now use the instance's local half-extents, as the pivot and the Origin arrows do. A flat axis keeps its pivot at zero in percent too, and an analyzed hull on the base model, which the upload sends when there is no physics model, counts as physics. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 20 ++++++++++++++++---- indra/newview/llmodelpreview.cpp | 5 +++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9a27e98a22c..1af60b238d1 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -695,7 +695,19 @@ LLVector3 LLFloaterModelPreview::getPivotHalfExtents() const { return LLVector3::zero; } - return mModelPreview->mPreviewScale * (F32)childGetValue("import_scale").asReal(); + const F32 scale = (F32)childGetValue("import_scale").asReal(); + if (mModelPreview->mUploadData.size() == 1) + { + // The pivot moves along the mesh's own axes, so a rotated instance measures along them. + const LLMatrix4& mat = mModelPreview->mUploadData[0].mTransform; + LLVector3 half; + for (S32 i = 0; i < 3; ++i) + { + half.mV[i] = LLVector3(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]).length() * 0.5f * scale; + } + return half; + } + return mModelPreview->mPreviewScale * scale; } void LLFloaterModelPreview::onPivotCommit() @@ -711,13 +723,13 @@ void LLFloaterModelPreview::onPivotCommit() for (S32 i = 0; i < 3; ++i) { const F32 shown = (F32)childGetValue(PIVOT_AXES[i]).asReal(); - if (metres) + if (half.mV[i] <= 0.f) { - pivot.mV[i] = half.mV[i] > 0.f ? shown / half.mV[i] : 0.f; + pivot.mV[i] = 0.f; // a flat axis has nowhere to put it } else { - pivot.mV[i] = shown / 100.f; + pivot.mV[i] = metres ? shown / half.mV[i] : shown / 100.f; } pivot.mV[i] = llclamp(pivot.mV[i], -1.f, 1.f); } diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 6e2598bb78c..5b9b374debe 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2198,12 +2198,17 @@ void LLModelPreview::updateStatusMessages() for (const LLModelInstance& instance : mUploadData) { rigged |= instance.mModel && !instance.mModel->mSkinWeights.empty(); + // The hulls uploaded are the physics model's, or the base model's without one. const LLModel* physics = instance.mLOD[LLModel::LOD_PHYSICS]; if (physics && physics->getNumVolumeFaces() > 0) { has_physics = true; analyzed &= !physics->mPhysics.mHull.empty(); } + else if (!physics && instance.mModel && !instance.mModel->mPhysics.mHull.empty()) + { + has_physics = true; + } } std::string pivot_status; From e0db0c770391ed2fb09b47b97ac34b3d58f29064 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 00:17:58 +0000 Subject: [PATCH 08/32] Take the uploader pivot from the file by default The file already says where each model's origin is, such as its object origin in Blender: the loader centres the model on its box and records where it moved the centre from. The pivot now has three modes: - From file, the default: each model's origin as the file gives it, for uploads of one model or several. A model whose origin lies outside its box keeps its centre, since that origin is a scene's. - Centre: as uploads were before. - Custom: the spinners, for a single model, starting from the pivot last shown. Each model's offset now travels with it to the upload, and each instance stands on its own pivot, so a linkset's parts stay where the file placed them. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 44 +++++++++-- indra/newview/llfloatermodelpreview.h | 1 + indra/newview/llmeshrepository.cpp | 21 ++++-- indra/newview/llmeshrepository.h | 10 ++- indra/newview/llmodelpreview.cpp | 73 ++++++++++++++++--- indra/newview/llmodelpreview.h | 27 ++++--- .../default/xui/en/floater_model_preview.xml | 40 +++++++++- 7 files changed, 182 insertions(+), 34 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 1af60b238d1..91c1d551470 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -31,6 +31,8 @@ #include "llfloatermodelpreview.h" +#include "llradiogroup.h" // Mesh uploader pivot + #include "llfilepicker.h" #include "llimagebmp.h" #include "llimagetga.h" @@ -198,6 +200,8 @@ bool LLFloaterModelPreview::postBuild() } childSetValue("pivot_units", "percent"); getChild("pivot_units")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onPivotUnitsCommit, this)); + childSetValue("pivot_mode", "file"); + getChild("pivot_mode")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onPivotModeCommit, this)); // getChild("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL); @@ -520,7 +524,7 @@ void LLFloaterModelPreview::onClickCalculateBtn() upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mUploadModelUrl, mDestinationFolderId, false, getWholeModelFeeObserverHandle(), - LLHandle(), mModelPreview->getUploadPositionOffset()); // Mesh uploader pivot + LLHandle(), mModelPreview->getUploadPositionOffsets()); // Mesh uploader pivot toggleCalculateButton(false); mUploadBtn->setEnabled(false); @@ -734,7 +738,7 @@ void LLFloaterModelPreview::onPivotCommit() pivot.mV[i] = llclamp(pivot.mV[i], -1.f, 1.f); } - mModelPreview->setUploadPivot(pivot); + mModelPreview->setCustomPivot(pivot); mModelPreview->updateStatusMessages(); toggleCalculateButton(true); mModelPreview->refresh(); @@ -745,6 +749,22 @@ void LLFloaterModelPreview::onPivotUnitsCommit() updatePivotControls(); } +void LLFloaterModelPreview::onPivotModeCommit() +{ + if (!mModelPreview) + { + return; + } + const std::string mode = childGetValue("pivot_mode").asString(); + mModelPreview->setPivotMode(mode == "custom" ? LLModelPreview::PIVOT_CUSTOM + : mode == "centre" ? LLModelPreview::PIVOT_CENTRE + : LLModelPreview::PIVOT_FILE); + updatePivotControls(); + mModelPreview->updateStatusMessages(); + toggleCalculateButton(true); + mModelPreview->refresh(); +} + void LLFloaterModelPreview::updatePivotControls() { if (!mModelPreview) @@ -752,9 +772,22 @@ void LLFloaterModelPreview::updatePivotControls() return; } + // Custom is for one model: several each take their own origin from the file, or the centre. + const bool single = mModelPreview->mUploadData.size() == 1; + if (LLRadioGroup* modes = getChild("pivot_mode")) + { + if (!single && mModelPreview->getPivotMode() == LLModelPreview::PIVOT_CUSTOM) + { + mModelPreview->setPivotMode(LLModelPreview::PIVOT_FILE); + } + modes->setIndexEnabled(2, single); + const LLModelPreview::EPivotMode mode = mModelPreview->getPivotMode(); + modes->setValue(mode == LLModelPreview::PIVOT_CUSTOM ? "custom" : mode == LLModelPreview::PIVOT_CENTRE ? "centre" : "file"); + } + const bool metres = childGetValue("pivot_units").asString() == "metres"; const LLVector3 half = getPivotHalfExtents(); - const LLVector3& pivot = mModelPreview->getUploadPivot(); + const LLVector3 pivot = single ? mModelPreview->getWantedPivot(mModelPreview->mUploadData[0].mModel) : LLVector3::zero; for (S32 i = 0; i < 3; ++i) { LLSpinCtrl* spinner = getChild(PIVOT_AXES[i]); @@ -1833,7 +1866,7 @@ void LLFloaterModelPreview::onUpload(void* user_data) upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mp->mUploadModelUrl, mp->mDestinationFolderId, true, LLHandle(), mp->getWholeModelUploadObserverHandle(), - mp->mModelPreview->getUploadPositionOffset()); // Mesh uploader pivot + mp->mModelPreview->getUploadPositionOffsets()); // Mesh uploader pivot } @@ -1971,7 +2004,8 @@ void LLFloaterModelPreview::resetUploadOptions() childSetValue("pivot_units", "percent"); if (mModelPreview) { - mModelPreview->setUploadPivot(LLVector3::zero); + mModelPreview->setPivotMode(LLModelPreview::PIVOT_FILE); + mModelPreview->setCustomPivot(LLVector3::zero); } updatePivotControls(); // diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 902f9c63d4e..347d215a9ee 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -147,6 +147,7 @@ class LLFloaterModelPreview final : public LLFloaterModelUploadBase // Mesh uploader pivot: shown in percent of the half-extent or in metres from the centre void onPivotCommit(); void onPivotUnitsCommit(); + void onPivotModeCommit(); void updatePivotControls(); LLVector3 getPivotHalfExtents() const; // diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a3afc5df1e3..e2329accc3b 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2700,7 +2700,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data const std::string & upload_url, LLUUID destination_folder_id, bool do_upload, LLHandle fee_observer, LLHandle upload_observer, - const LLVector3& position_offset) // Mesh uploader pivot + const position_offsets_t& position_offsets) // Mesh uploader pivot : LLThread("mesh upload"), LLCore::HttpHandler(), mDiscarded(false), @@ -2716,7 +2716,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data mUploadSkin = upload_skin; mUploadJoints = upload_joints; mLockScaleIfJointPosition = lock_scale_if_joint_position; - mPositionOffset = position_offset; // Mesh uploader pivot + mPositionOffsets = position_offsets; // Mesh uploader pivot mMutex = new LLMutex(); mPendingUploads = 0; mFinished = false; @@ -2827,6 +2827,14 @@ LLSD llsd_from_file(std::string filename) return result; } +// Mesh uploader pivot +LLVector3 LLMeshUploadThread::getPositionOffset(const LLModel* model) const +{ + auto it = mPositionOffsets.find(model); + return it != mPositionOffsets.end() ? it->second : LLVector3::zero; +} +// + void LLMeshUploadThread::packModelIntance( LLModel* model, LLMeshUploadThread::instance_list_t& instance_list, @@ -2882,7 +2890,7 @@ void LLMeshUploadThread::packModelIntance( LLModel::WRITE_BINARY, false, data.mBaseModel->mSubmodelID, - mPositionOffset); // Mesh uploader pivot + getPositionOffset(data.mBaseModel)); // Mesh uploader pivot data.mAssetData = ostr.str(); std::string str = ostr.str(); @@ -2910,6 +2918,9 @@ void LLMeshUploadThread::packModelIntance( LLQuaternion rot; LLMatrix4 transformation = instance.mTransform; decomposeMeshMatrix(transformation, pos, rot, scale); + // Mesh uploader pivot: the prim stands on its pivot, so the mesh stays where it was placed + pos = (-getPositionOffset(data.mBaseModel)) * transformation; + // instance_entry["position"] = ll_sd_from_vector3(pos); instance_entry["rotation"] = ll_sd_from_quaternion(rot); instance_entry["scale"] = ll_sd_from_vector3(scale); @@ -5560,12 +5571,12 @@ void LLMeshRepository::uploadModel(std::vector& data, const std bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, std::string upload_url, const LLUUID& destination_folder_id, bool do_upload, LLHandle fee_observer, LLHandle upload_observer, - const LLVector3& position_offset) // Mesh uploader pivot + const LLMeshUploadThread::position_offsets_t& position_offsets) // Mesh uploader pivot { LLMeshUploadThread* thread = new LLMeshUploadThread(data, lod_sources, scale, upload_textures, upload_skin, upload_joints, lock_scale_if_joint_position, upload_url, destination_folder_id, do_upload, fee_observer, upload_observer, - position_offset); // Mesh uploader pivot + position_offsets); // Mesh uploader pivot mUploadWaitList.push_back(thread); } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 516a2283de6..5e5ebc7993e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -801,7 +801,11 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler bool mUploadSkin; bool mUploadJoints; bool mLockScaleIfJointPosition; - LLVector3 mPositionOffset; // Mesh uploader pivot: added to every stored domain + // Mesh uploader pivot: added to each base model's stored domains + typedef boost::unordered_map position_offsets_t; + position_offsets_t mPositionOffsets; + LLVector3 getPositionOffset(const LLModel* model) const; + // volatile bool mDiscarded; LLHost mHost; @@ -817,7 +821,7 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler bool do_upload = true, LLHandle fee_observer = (LLHandle()), LLHandle upload_observer = (LLHandle()), - const LLVector3& position_offset = LLVector3::zero); // Mesh uploader pivot + const position_offsets_t& position_offsets = position_offsets_t()); // Mesh uploader pivot ~LLMeshUploadThread(); bool finished() const { return mFinished; } @@ -1011,7 +1015,7 @@ class LLMeshRepository bool do_upload = true, LLHandle fee_observer= (LLHandle()), LLHandle upload_observer = (LLHandle()), - const LLVector3& position_offset = LLVector3::zero); // Mesh uploader pivot + const LLMeshUploadThread::position_offsets_t& position_offsets = LLMeshUploadThread::position_offsets_t()); // Mesh uploader pivot S32 getMeshSize(const LLUUID& mesh_id, S32 lod) const; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 5b9b374debe..4e675d9cb67 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1846,6 +1846,64 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d << ", failures: " << meshes_fail_count << LL_ENDL; } +// Mesh uploader pivot +void LLModelPreview::setPivotMode(EPivotMode mode) +{ + if (mode == PIVOT_CUSTOM && mPivotMode != PIVOT_CUSTOM && mUploadData.size() == 1) + { + mCustomPivot = getWantedPivot(mUploadData[0].mModel); + } + mPivotMode = mode; +} + +// static +LLVector3 LLModelPreview::getFileOriginPivot(const LLModel* model) +{ + if (!model) + { + return LLVector3::zero; + } + // The loader centred the model on its box; the file's origin is where it moved the centre from. + LLVector3 size, centre; + model->getNormalizedScaleTranslation(size, centre); + LLVector3 pivot; + for (S32 i = 0; i < 3; ++i) + { + pivot.mV[i] = size.mV[i] > 0.f ? -2.f * centre.mV[i] / size.mV[i] : 0.f; + // An origin outside the box is a scene's, from a file that placed its vertices in the scene: centre it. + if (fabsf(pivot.mV[i]) > 1.001f) + { + return LLVector3::zero; + } + pivot.mV[i] = llclamp(pivot.mV[i], -1.f, 1.f); + } + return pivot; +} + +LLVector3 LLModelPreview::getWantedPivot(const LLModel* model) const +{ + switch (mPivotMode) + { + case PIVOT_FILE: + return getFileOriginPivot(model); + case PIVOT_CUSTOM: + return mUploadData.size() == 1 ? mCustomPivot : LLVector3::zero; + default: + return LLVector3::zero; + } +} + +LLMeshUploadThread::position_offsets_t LLModelPreview::getUploadPositionOffsets() const +{ + LLMeshUploadThread::position_offsets_t offsets; + for (const LLModelInstance& instance : mUploadData) + { + offsets[instance.mModel.get()] = getUploadPivot(instance.mModel) * -0.5f; + } + return offsets; +} +// + void LLModelPreview::updateStatusMessages() { // bit mask values for physics errors. used to prevent overwrite of single line status @@ -2218,25 +2276,23 @@ void LLModelPreview::updateStatusMessages() pivot_status = mFMP->getString("pivot_status_rigged"); mUploadPivotAllowed = false; } - else if (mUploadData.size() > 1) - { - pivot_status = mFMP->getString("pivot_status_multiple"); - mUploadPivotAllowed = false; - } else if (has_physics && !analyzed) { pivot_status = mFMP->getString("pivot_status_analyze"); mUploadPivotAllowed = false; } - else if (!has_physics && !mUploadPivot.isExactlyZero()) + else if (!has_physics && std::any_of(mUploadData.begin(), mUploadData.end(), [this](const LLModelInstance& instance) + { return !getWantedPivot(instance.mModel).isExactlyZero(); })) { pivot_status = mFMP->getString("pivot_status_no_physics"); } + const bool custom = mFMP->childGetValue("pivot_mode").asString() == "custom"; for (const char* axis : { "pivot_x", "pivot_y", "pivot_z" }) { - mFMP->childSetEnabled(axis, mUploadPivotAllowed); + mFMP->childSetEnabled(axis, mUploadPivotAllowed && custom); } + mFMP->childSetEnabled("pivot_mode", mUploadPivotAllowed); mFMP->childSetValue("pivot_status", pivot_status); } // @@ -3710,11 +3766,10 @@ bool LLModelPreview::render() LLGLDisable no_cull(GL_CULL_FACE); gGL.setLineWidth(2.f); - const LLVector3 pivot = getEffectiveUploadPivot() * 0.5f; for (const LLModelInstance& instance : mUploadData) { const LLMatrix4& mat = instance.mTransform; - const LLVector3 origin = pivot * mat; + const LLVector3 origin = (getUploadPivot(instance.mModel) * 0.5f) * mat; LLVector3 axes[3]; F32 reach = 0.f; diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index f5a09606208..6c363e79faa 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -172,13 +172,19 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH void setHasPivot(bool val) { mHasPivot = val; } void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; } - // Mesh uploader pivot: the object's origin within its bounding box, -1 to 1 per axis - void setUploadPivot(const LLVector3& pivot) { mUploadPivot = pivot; } - const LLVector3& getUploadPivot() const { return mUploadPivot; } - // The pivot in effect: centred while the physics or the model count rules it out. - LLVector3 getEffectiveUploadPivot() const { return mUploadPivotAllowed ? mUploadPivot : LLVector3::zero; } - // What the stored domains are shifted by so that the origin lands on the pivot. - LLVector3 getUploadPositionOffset() const { return getEffectiveUploadPivot() * -0.5f; } + // Mesh uploader pivot: each model's origin within its bounding box, -1 to 1 per axis + enum EPivotMode { PIVOT_FILE, PIVOT_CENTRE, PIVOT_CUSTOM }; + // Custom starts from the pivot the last mode gave a single model. + void setPivotMode(EPivotMode mode); + EPivotMode getPivotMode() const { return mPivotMode; } + void setCustomPivot(const LLVector3& pivot) { mCustomPivot = pivot; } + // The origin the file gave the model, where its vertices' origin sits in its box. + static LLVector3 getFileOriginPivot(const LLModel* model); + // The pivot the mode asks for, and the one in effect: centred while the physics or rigging rules it out. + LLVector3 getWantedPivot(const LLModel* model) const; + LLVector3 getUploadPivot(const LLModel* model) const { return mUploadPivotAllowed ? getWantedPivot(model) : LLVector3::zero; } + // What each model's stored domains are shifted by so that its origin lands on its pivot. + LLMeshUploadThread::position_offsets_t getUploadPositionOffsets() const; // //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions @@ -280,8 +286,11 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH bool mResetJoints; bool mModelNoErrors; bool mLookUpLodFiles; - LLVector3 mUploadPivot; // Mesh uploader pivot - bool mUploadPivotAllowed{true}; // Mesh uploader pivot + // Mesh uploader pivot + EPivotMode mPivotMode{PIVOT_FILE}; + LLVector3 mCustomPivot; + bool mUploadPivotAllowed{true}; + // std::map mViewOption; diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index c4396eb5f1b..df00392e25a 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -36,7 +36,6 @@ Some physical hulls exceed vertex limitations. The physics mesh is too dense or contains degenerate triangles. Use Analyze/Simplify to resolve. A pivot is for unrigged mesh; rigged mesh is placed by its skeleton. - A pivot can be set only when uploading a single model. Analyze the physics to set a pivot: unanalyzed physics stays centred on the object. No physics shape is defined, so the object collides with its default hull, centred on itself. Fine for a phantom piece or physics type None. All @@ -1381,6 +1380,41 @@ tool_tip="Where the object's origin, and so its rotation, sits within its bounding box: in percent, -100 and 100 are its faces and 0 its centre; in metres, the distance from its centre."> Pivot: + + + + + Date: Tue, 3 Nov 2026 00:30:25 +0000 Subject: [PATCH 09/32] Lay the pivot modes out in a row The radio items took their default layout, so they stacked under the label and over the spinners. Co-Authored-By: Claude Opus 5.5 --- indra/newview/skins/default/xui/en/floater_model_preview.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index df00392e25a..d0e5775de1c 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1381,6 +1381,7 @@ Pivot: Date: Tue, 3 Nov 2026 00:30:56 +0000 Subject: [PATCH 10/32] Set the pivot spinners beside its modes The modes stack in a column after the label, with the spinners and the status to their right. Co-Authored-By: Claude Opus 5.5 --- .../default/xui/en/floater_model_preview.xml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index d0e5775de1c..82172309f07 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1383,11 +1383,11 @@ + width="90"> @@ -1426,11 +1426,11 @@ increment="50" label="X" label_width="12" - left="70" + left_pad="10" max_val="100" min_val="-100" name="pivot_x" - top_pad="6" + top_delta="-2" value="0" width="80"/> From e19466f3ff1d0986f636104d24d4b89c4616b709 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 01:39:33 +0000 Subject: [PATCH 11/32] Place uploaded meshes from the region's origin again The pivot override of each instance's position dropped the upload origin that decomposeMeshMatrix adds, so pivoted uploads landed at the region's corner. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmeshrepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e2329accc3b..7f81db1e7cc 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2919,7 +2919,7 @@ void LLMeshUploadThread::packModelIntance( LLMatrix4 transformation = instance.mTransform; decomposeMeshMatrix(transformation, pos, rot, scale); // Mesh uploader pivot: the prim stands on its pivot, so the mesh stays where it was placed - pos = (-getPositionOffset(data.mBaseModel)) * transformation; + pos = (-getPositionOffset(data.mBaseModel)) * transformation + mOrigin; // instance_entry["position"] = ll_sd_from_vector3(pos); instance_entry["rotation"] = ll_sd_from_quaternion(rot); From e25b56a6a82c3d9a206a9bd36cd61ac151f6c2cc Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 01:39:33 +0000 Subject: [PATCH 12/32] Measure the pivot's metres without scaling twice The instance transform already carries the import scale, so multiplying by it again doubled the half extents a pivot in metres was read against. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 91c1d551470..3c000533654 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -699,19 +699,19 @@ LLVector3 LLFloaterModelPreview::getPivotHalfExtents() const { return LLVector3::zero; } - const F32 scale = (F32)childGetValue("import_scale").asReal(); if (mModelPreview->mUploadData.size() == 1) { // The pivot moves along the mesh's own axes, so a rotated instance measures along them. + // The transform carries the import scale already. const LLMatrix4& mat = mModelPreview->mUploadData[0].mTransform; LLVector3 half; for (S32 i = 0; i < 3; ++i) { - half.mV[i] = LLVector3(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]).length() * 0.5f * scale; + half.mV[i] = LLVector3(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]).length() * 0.5f; } return half; } - return mModelPreview->mPreviewScale * scale; + return mModelPreview->mPreviewScale * (F32)childGetValue("import_scale").asReal(); } void LLFloaterModelPreview::onPivotCommit() From dbf1c7d8dae22b7402e2bcd286d80477e188ab81 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 01:42:30 +0000 Subject: [PATCH 13/32] Take the LOD and physics models a single file names into their slots A file holding NAME, NAME_LOD2, NAME_LOD1, NAME_LOD0 and NAME_PHYS uploaded every one of them as a model of its own: the loaders cut the suffixes off, so each became a copy of NAME, and LOD slots filled only from separate files. A high LOD file now keeps its names whole, and the preview moves each suffixed model whose base the file has into that LOD's slot, where the matching by name that separate LOD files use finds it. Those LODs are not generated over; a LOD only some models have is generated instead. Submodels move with their root, a later high file releases what an earlier one filled, and physics taken this way warns of models without one as an explicit physics file does. A suffixed model with no base is named without its suffix, as before. Co-Authored-By: Claude Opus 5.5 --- indra/llprimitive/lldaeloader.cpp | 5 +- indra/newview/gltf/llgltfloader.cpp | 3 +- indra/newview/llmodelpreview.cpp | 228 +++++++++++++++++++++++++++- indra/newview/llmodelpreview.h | 5 + 4 files changed, 237 insertions(+), 4 deletions(-) diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 2bb02c6c130..a14fad1ff74 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2131,7 +2131,7 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da if (model->mLabel.empty()) { - label = getLodlessLabel(instance_geo); + label = mLod == LLModel::LOD_HIGH ? getElementLabel(instance_geo) : getLodlessLabel(instance_geo); // Mesh uploader LODs by name llassert(!label.empty()); @@ -2512,7 +2512,8 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo LLModel* ret = new LLModel(volume_params, 0.f); - std::string model_name = getLodlessLabel(mesh); + // Mesh uploader LODs by name: the high LOD's file keeps its suffixes for the preview to sort out + std::string model_name = mLod == LLModel::LOD_HIGH ? getElementLabel(mesh) : getLodlessLabel(mesh); ret->mLabel = model_name + lod_suffix[mLod]; llassert(!ret->mLabel.empty()); diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index cb5d97ae9dd..304d89b8b46 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -431,7 +431,8 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map // Potentially multiple nodes can reuse the same mesh and Collada used // node name instead of mesh name, so for consistency use node name if // avaliable, node index otherwise. - std::string base_name = getLodlessLabel(node); + // Mesh uploader LODs by name: the high LOD's file keeps its suffixes for the preview to sort out + std::string base_name = mLod == LLModel::LOD_HIGH ? node.mName : getLodlessLabel(node); if (base_name.empty()) { base_name = "node_" + std::to_string(node_idx); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 374821d3e4f..fab3e2cb777 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1007,6 +1007,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (loaded_lod == -1) { //populate all LoDs from model loader scene mSimplifiers.clear(); + std::fill(std::begin(mLODFromHighFile), std::end(mLODFromHighFile), false); // Mesh uploader LODs by name mBaseModel.clear(); mBaseScene.clear(); @@ -1113,6 +1114,18 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { //only replace given LoD mModel[loaded_lod] = mModelLoader->mModelList; mScene[loaded_lod] = mModelLoader->mScene; + // Mesh uploader LODs by name: a file of its own replaces what the high file gave + if (loaded_lod != LLModel::LOD_HIGH) + { + mLODFromHighFile[loaded_lod] = false; + } + // + // Mesh uploader LODs by name + if (loaded_lod == LLModel::LOD_HIGH) + { + splitSuffixedModels(mModelLoader->mFilename); + } + // // Duplicate the model if it is an internal bounding box model if (loaded_lod == LLModel::LOD_PHYSICS && @@ -1839,6 +1852,216 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d << ", failures: " << meshes_fail_count << LL_ENDL; } +// Mesh uploader LODs by name +void LLModelPreview::splitSuffixedModels(const std::string& filename) +{ + bool was_from_file[LLModel::NUM_LODS]; + std::copy(std::begin(mLODFromHighFile), std::end(mLODFromHighFile), was_from_file); + for (bool& from_file : mLODFromHighFile) + { + from_file = false; + } + // A submodel is named after its root with a letter added, after any suffix: NAME_LOD2b. + auto core_of = [](const LLModel* model) -> std::string + { + return model->mSubmodelID > 0 && !model->mLabel.empty() ? model->mLabel.substr(0, model->mLabel.size() - 1) : model->mLabel; + }; + auto letter_of = [](const LLModel* model) -> std::string + { + return model->mSubmodelID > 0 && !model->mLabel.empty() ? model->mLabel.substr(model->mLabel.size() - 1) : std::string(); + }; + auto suffix_lod = [](const std::string& label) -> S32 + { + for (S32 lod : { (S32)LLModel::LOD_IMPOSTOR, (S32)LLModel::LOD_LOW, (S32)LLModel::LOD_MEDIUM, (S32)LLModel::LOD_PHYSICS }) + { + const std::string suffix = getLodSuffix(lod); + if (label.size() > suffix.size() && label.compare(label.size() - suffix.size(), suffix.size(), suffix) == 0) + { + return lod; + } + } + return -1; + }; + + const bool legacy = gSavedSettings.getBOOL("ImporterLegacyMatching"); + // Only a suffixed model whose base the file also has is a LOD; any other is a model of its own. + std::set bases; + for (const LLPointer& model : mModel[LLModel::LOD_HIGH]) + { + if (model && !model->mSubmodelID && suffix_lod(model->mLabel) < 0) + { + bases.insert(model->mLabel); + } + } + auto lod_of = [&](const LLModel* model) -> S32 + { + if (!model) + { + return -1; + } + const std::string core = core_of(model); + const S32 lod = suffix_lod(core); + return lod >= 0 && bases.count(stripSuffix(core)) && !legacy ? lod : -1; + }; + + // LODs an earlier file filled and this one does not are generated again. + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + auto release = [&](S32 lod) + { + mModel[lod].clear(); + mScene[lod].clear(); + mLODFile[lod].clear(); + mVertexBuffer[lod].clear(); + if (fmp && lod != LLModel::LOD_PHYSICS) + { + fmp->mLODMode[lod] = MESH_OPTIMIZER_AUTO; + if (LLComboBox* lod_combo = fmp->findChild("lod_source_" + lod_name[lod])) + { + lod_combo->setCurrentByIndex(MESH_OPTIMIZER_AUTO); + } + fmp->childSetValue("lod_file_" + lod_name[lod], ""); + } + else if (fmp) + { + fmp->childSetValue("physics_file", ""); + } + }; + + // A suffixed model with no base is named as the loader always named it, without its suffix. + for (auto& scene_pair : mScene[LLModel::LOD_HIGH]) + { + for (LLModelInstance& instance : scene_pair.second) + { + LLModel* model = instance.mModel; + if (model && suffix_lod(core_of(model)) >= 0 && lod_of(model) < 0) + { + instance.mLabel = stripSuffix(instance.mLabel); + model->mLabel = stripSuffix(core_of(model)) + letter_of(model); + } + } + } + + // Each model's LOD is settled once, before any is renamed. + std::map moved; + for (const LLPointer& model : mModel[LLModel::LOD_HIGH]) + { + const S32 lod = lod_of(model); + if (lod >= 0) + { + moved[model.get()] = lod; + } + } + auto moved_to = [&](const LLModel* model) -> S32 + { + auto it = moved.find(model); + return it != moved.end() ? it->second : -1; + }; + + bool split[LLModel::NUM_LODS] = {}; + for (const LLPointer& model : mModel[LLModel::LOD_HIGH]) + { + const S32 lod = moved_to(model); + if (lod >= 0 && !split[lod]) + { + split[lod] = true; + mModel[lod].clear(); + mScene[lod].clear(); + } + } + LLModelLoader::model_list kept; + for (const LLPointer& model : mModel[LLModel::LOD_HIGH]) + { + const S32 lod = moved_to(model); + if (lod < 0) + { + kept.push_back(model); + } + else + { + // Named as a separate LOD file would name it, so the matching finds a submodel too. + model->mLabel = stripSuffix(core_of(model)) + letter_of(model) + getLodSuffix(lod); + mModel[lod].push_back(model); + } + } + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + if (was_from_file[lod] && !split[lod]) + { + release(lod); + } + } + if (kept.size() == mModel[LLModel::LOD_HIGH].size()) + { + return; + } + mModel[LLModel::LOD_HIGH] = kept; + + for (auto scene_it = mScene[LLModel::LOD_HIGH].begin(); scene_it != mScene[LLModel::LOD_HIGH].end();) + { + LLModelLoader::model_instance_list& list = scene_it->second; + for (auto it = list.begin(); it != list.end();) + { + const S32 lod = moved_to(it->mModel); + if (lod < 0) + { + ++it; + continue; + } + mScene[lod][scene_it->first].push_back(*it); + it = list.erase(it); + } + scene_it = list.empty() ? mScene[LLModel::LOD_HIGH].erase(scene_it) : std::next(scene_it); + } + + if (split[LLModel::LOD_PHYSICS]) + { + // As an explicit physics file does: the parts with no _PHYS are logged and may use a default shape. + mPhysicsSearchLOD = LLModel::LOD_PHYSICS; + LLMatrix4 ignored_transform; + LLModel* default_shape = nullptr; + FindModel(mScene[LLModel::LOD_PHYSICS], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(LLModel::LOD_PHYSICS), default_shape, ignored_transform); + mDefaultPhysicsShapeP = default_shape; + mWarnOfUnmatchedPhyicsMeshes = true; + } + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + if (!split[lod]) + { + continue; + } + if (lod != LLModel::LOD_PHYSICS && countRootModels(mModel[lod]) != countRootModels(kept)) + { + // A LOD needs every model; the file's partial set is dropped and the LOD generated. + release(lod); + std::ostringstream out; + out << "Only some models have a " << getLodSuffix(lod) << " model in the file; generating that LOD instead"; + LLFloaterModelPreview::addStringToLog(out, true); + continue; + } + mLODFromHighFile[lod] = true; + mLODFile[lod] = filename; + mVertexBuffer[lod].clear(); + if (fmp) + { + fmp->setCtrlLoadFromFile(lod); + if (lod == LLModel::LOD_PHYSICS) + { + fmp->childSetValue("physics_file", filename); + } + else + { + fmp->mLODMode[lod] = LOD_FROM_FILE; + fmp->childSetValue("lod_file_" + lod_name[lod], filename); + } + } + std::ostringstream out; + out << "Took " << mModel[lod].size() << " model(s) named " << getLodSuffix(lod) << " from the file for that slot"; + LLFloaterModelPreview::addStringToLog(out, false); + } +} +// + void LLModelPreview::updateStatusMessages() { // bit mask values for physics errors. used to prevent overwrite of single line status @@ -2699,7 +2922,10 @@ void LLModelPreview::update() for (S32 lod = LLModel::LOD_HIGH; lod >= 0; --lod) { // adding all lods into query for generation - mLodsQuery.push_back(lod); + if (!mLODFromHighFile[lod]) // Mesh uploader LODs by name: the file gave this one + { + mLodsQuery.push_back(lod); + } } if (subscribe_for_generation) diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index b62030a349c..14c46d97f66 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -172,6 +172,10 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH void setHasPivot(bool val) { mHasPivot = val; } void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; } + // Mesh uploader LODs by name: a file's NAME_LOD0-2 and NAME_PHYS models fill those slots of NAME + void splitSuffixedModels(const std::string& filename); + // + //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions //Accessors for joint position upload friendly rigs const bool isRigValidForJointPositionUpload(void) const { return mRigValidJointUpload; } @@ -271,6 +275,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH bool mResetJoints; bool mModelNoErrors; bool mLookUpLodFiles; + bool mLODFromHighFile[LLModel::NUM_LODS]{}; // Mesh uploader LODs by name std::map mViewOption; From 94aea1d1ebf2cc7b494b877ba0a2a2059dacac0d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 01:59:58 +0000 Subject: [PATCH 14/32] Hide the uploader origin while skin weights are shown With skin weights shown, the mesh is drawn on the preview avatar, away from the instance transform the origin is drawn from. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 4e675d9cb67..5a0bc823eac 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3757,7 +3757,7 @@ bool LLModelPreview::render() } // Mesh uploader pivot: the object's origin, drawn through the model - if (mViewOption["show_origin"]) + if (mViewOption["show_origin"] && !mViewOption["show_skin_weight"]) // rigged mesh is drawn on the avatar { LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; gUIProgram.bind(); // takes the vertex colours, which gDebugProgram replaces with one uniform From d41e240f3efeeb452db555ddd74932cbe00ebf8d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 01:59:58 +0000 Subject: [PATCH 15/32] Settle the pivot against the data an upload sends Whether a pivot is allowed was last worked out before the upload data was rebuilt, so a physics file loaded since could still be sent unanalyzed under a pivot the sim would not follow. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 3c000533654..7ca22b3336b 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -508,6 +508,7 @@ void LLFloaterModelPreview::onClickCalculateBtn() clearLogTab(); addStringToLog("Calculating model data.", false); mModelPreview->rebuildUploadData(); + mModelPreview->updateStatusMessages(); // Mesh uploader pivot: whether a pivot is allowed follows the rebuilt data bool upload_skinweights = childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); @@ -1848,6 +1849,7 @@ void LLFloaterModelPreview::onUpload(void* user_data) mp->mUploadBtn->setEnabled(false); mp->mModelPreview->rebuildUploadData(); + mp->mModelPreview->updateStatusMessages(); // Mesh uploader pivot: whether a pivot is allowed follows the rebuilt data bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); From e9201bdaa525b94abffb322280a21d1ecd87c781 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 02:01:38 +0000 Subject: [PATCH 16/32] Keep the physics and default shape a high file's LODs feed Physics copied from a LOD the high file then replaced kept the old file's models, physics copied from a LOD no longer counted as the high file's, and the default physics shape was cleared by every rebuild before parts without a _PHYS could use it. A LOD set whose submodels differ from the high LOD's is now generated rather than kept. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 36 +++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index fab3e2cb777..188d678d630 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -287,6 +287,15 @@ void LLModelPreview::rebuildUploadData() assert_main_thread(); mDefaultPhysicsShapeP = NULL; + // Mesh uploader LODs by name: physics from the high file names its default shape as a physics file does + if (mLODFromHighFile[LLModel::LOD_PHYSICS]) + { + LLMatrix4 ignored_transform; + LLModel* default_shape = nullptr; + FindModel(mScene[LLModel::LOD_PHYSICS], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(LLModel::LOD_PHYSICS), default_shape, ignored_transform); + mDefaultPhysicsShapeP = default_shape; + } + // mUploadData.clear(); mTextureSet.clear(); @@ -885,6 +894,7 @@ void LLModelPreview::setPhysicsFromLOD(S32 lod) if (lod >= 0 && lod <= 3) { mPhysicsSearchLOD = lod; + mLODFromHighFile[LLModel::LOD_PHYSICS] = false; // Mesh uploader LODs by name mModel[LLModel::LOD_PHYSICS] = mModel[lod]; mScene[LLModel::LOD_PHYSICS] = mScene[lod]; mLODFile[LLModel::LOD_PHYSICS].clear(); @@ -1990,8 +2000,20 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) release(lod); } } + // Physics copied from a LOD follows that LOD when this file replaces it. + const S32 physics_from = mPhysicsSearchLOD; + auto follow_physics = [&]() + { + if (physics_from >= LLModel::LOD_IMPOSTOR && physics_from <= LLModel::LOD_HIGH && (split[physics_from] || was_from_file[physics_from])) + { + mModel[LLModel::LOD_PHYSICS] = mModel[physics_from]; + mScene[LLModel::LOD_PHYSICS] = mScene[physics_from]; + mVertexBuffer[LLModel::LOD_PHYSICS].clear(); + } + }; if (kept.size() == mModel[LLModel::LOD_HIGH].size()) { + follow_physics(); return; } mModel[LLModel::LOD_HIGH] = kept; @@ -2015,12 +2037,8 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) if (split[LLModel::LOD_PHYSICS]) { - // As an explicit physics file does: the parts with no _PHYS are logged and may use a default shape. + // As an explicit physics file does: the parts with no _PHYS are logged, and may use a default shape. mPhysicsSearchLOD = LLModel::LOD_PHYSICS; - LLMatrix4 ignored_transform; - LLModel* default_shape = nullptr; - FindModel(mScene[LLModel::LOD_PHYSICS], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(LLModel::LOD_PHYSICS), default_shape, ignored_transform); - mDefaultPhysicsShapeP = default_shape; mWarnOfUnmatchedPhyicsMeshes = true; } @@ -2030,9 +2048,9 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) { continue; } - if (lod != LLModel::LOD_PHYSICS && countRootModels(mModel[lod]) != countRootModels(kept)) + if (lod != LLModel::LOD_PHYSICS && mModel[lod].size() != kept.size()) { - // A LOD needs every model; the file's partial set is dropped and the LOD generated. + // A LOD needs every model and submodel; the file's partial set is dropped and the LOD generated. release(lod); std::ostringstream out; out << "Only some models have a " << getLodSuffix(lod) << " model in the file; generating that LOD instead"; @@ -2059,6 +2077,10 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) out << "Took " << mModel[lod].size() << " model(s) named " << getLodSuffix(lod) << " from the file for that slot"; LLFloaterModelPreview::addStringToLog(out, false); } + if (!split[LLModel::LOD_PHYSICS]) + { + follow_physics(); + } } // From cd5ed5a2ea1a54417776c58518ef1dd64c57aa02 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 02:16:54 +0000 Subject: [PATCH 17/32] Guide setting object origins for the uploader's pivot How to place an origin on a hinge or joint in Blender, what the Pivot modes and status lines mean, and the usual mistakes. Co-Authored-By: Claude Opus 5.5 --- doc/mesh/object-origins.md | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 doc/mesh/object-origins.md diff --git a/doc/mesh/object-origins.md b/doc/mesh/object-origins.md new file mode 100644 index 00000000000..6d37e07bcfe --- /dev/null +++ b/doc/mesh/object-origins.md @@ -0,0 +1,59 @@ +# Object Origins for Prim-Animated Doors, Hinges and Joints + +## Why the origin matters + +A prim in Second Life turns about its own position, and a mesh prim's position is the object origin it was uploaded with. Put the origin on the hinge, and a script that turns the door with `llSetLocalRot` swings it on its hinge. Leave it in the middle, and the door spins about its centre. + +Until now the uploader always moved the origin to the middle of the object's bounding box. Doors were built with an invisible extra half, or a script had to move the prim as it turned it. The uploader's **Pivot** option keeps the origin you set in Blender instead. + +## Setting the origin in Blender + +1. Apply rotation and scale first: select the object, **Ctrl+A > Rotation & Scale**. +2. Put the 3D cursor on the hinge or joint: in Edit Mode select the vertices along the hinge line, then **Shift+S > Cursor to Selected**. +3. Back in Object Mode, **Object > Set Origin > Origin to 3D Cursor**. +4. Check it: rotate the object (R, then an axis key). It should turn about the hinge, and the orange dot should sit on it. + +- **The origin must lie inside or on the object's bounding box.** The uploader stores it as a point within the box, so an origin outside is moved back to the centre. +- **Turn about a local axis.** Model the part so the hinge runs along X, Y or Z, so a script needs only one angle. +- Each part of a linkset has its own origin. An arm needs one per joint: the turret on its vertical axis, each limb on its elbow. + +## The uploader's Pivot + +The **Pivot** row is on the **Upload options** tab. It has three modes, X/Y/Z spinners beside them, and a status line under the spinners. + +| Mode | The origin goes | Works for | +| --- | --- | --- | +| From file (default) | where Blender's origin was, for each object | one object or many | +| Centre | to the middle of the bounding box, as uploads always did | one object or many | +| Custom | where you type it in the spinners | a single object only | + +- The spinners show the pivot along the object's own axes, in **percent** of its half size (−100 to 100, 0 = centre) or in **metres**; the dropdown beside them switches the unit. +- They are editable only in Custom, which starts from the pivot shown when you switch to it. +- Tick **Origin** under the preview to see the pivot: coloured arrows (X red, Y green, Z blue) drawn at each object's pivot. +- In a multi-object upload each part keeps its own origin, and its position in the linkset moves with it, so every part lands where it sat in Blender. + +The status line says when the pivot is held at the centre, or when the collision stays centred: + +| Status | Why | Fix | +| --- | --- | --- | +| Rigged mesh | rigged mesh is placed by its skeleton | none needed | +| Physics not analyzed | the sim fits a mesh physics shape to the box until it's analyzed | click **Analyze** on the Physics tab | +| No physics shape | the part moves to its pivot, but collides with a default hull centred on itself | fine for phantom parts or physics type None; otherwise add a physics shape and analyze it | + +## Examples and common mistakes + +| Part | Where the origin goes | Turns about | +| --- | --- | --- | +| Door | on the hinge edge, halfway up | its vertical axis | +| Chest lid | on the back edge, along the hinge | the hinge's axis | +| Arm turret | on the base's centre line | its vertical axis | +| Arm limb | in the joint at the limb's near end | the joint's axis | + +A limb's joint is often at the very end of the part. That's fine: the origin may sit on the box's edge, just not outside it. + +| You see | Likely cause | +| --- | --- | +| The part spins about its middle | the pivot is on Centre, the origin lies outside the box, or the physics isn't analyzed | +| The spinners read 0 0 0 on From file | Blender's origin was at the middle, or outside the box | +| The part rotates about the wrong axis | rotation wasn't applied before export | +| Custom is greyed out | the upload has several objects; Custom is for a single one | From 6ecbd443532380a02f26c97b28d59abf84da887d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 02:16:55 +0000 Subject: [PATCH 18/32] Guide exporting a multi-object file with its own LODs How to name and lay out parts and their _LOD and _PHYS objects in Blender for a single-file upload, with the glTF export settings it needs. Co-Authored-By: Claude Opus 5.5 --- doc/mesh/images/blender-gltf-export.png | Bin 0 -> 56665 bytes doc/mesh/images/blender-outliner.png | Bin 0 -> 118124 bytes doc/mesh/multi-object-single-file.md | 81 ++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 doc/mesh/images/blender-gltf-export.png create mode 100644 doc/mesh/images/blender-outliner.png create mode 100644 doc/mesh/multi-object-single-file.md diff --git a/doc/mesh/images/blender-gltf-export.png b/doc/mesh/images/blender-gltf-export.png new file mode 100644 index 0000000000000000000000000000000000000000..60fdb53aec6571a6b9d685ba971ee7f6f388db61 GIT binary patch literal 56665 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

4v*?~WLj8#%Mt-Lsp<#jS5-ymmp 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�W5_XpaX;A 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 literal 0 HcmV?d00001 diff --git a/doc/mesh/images/blender-outliner.png b/doc/mesh/images/blender-outliner.png new file mode 100644 index 0000000000000000000000000000000000000000..7a57cea153cde8a908aaff43b41c02e0d8384620 GIT binary patch literal 118124 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 Z8ODYi$PV!Gk)*=^cB^PArz;*h_g|d{7ZU&g literal 0 HcmV?d00001 diff --git a/doc/mesh/multi-object-single-file.md b/doc/mesh/multi-object-single-file.md new file mode 100644 index 00000000000..fcf92d86760 --- /dev/null +++ b/doc/mesh/multi-object-single-file.md @@ -0,0 +1,81 @@ +# Multi-Object Single-File Blender Exports + +The example throughout is a robot arm built as a linkset of ten parts: a base, a turret, an upper arm, a forearm, two wrist joints, a flange and three fingers. Each part has its own levels of detail (LOD) and a physics shape, and the whole arm uploads from one file. + +## How the uploader reads names + +Second Life draws each part with up to four levels of detail (LOD): High up close, then Medium, Low and Lowest further away, plus a physics shape for collisions. The uploader matches each part to its LOD models and physics shape by name: the part's name plus a suffix that says which slot it fills. + +| Slot in the uploader | Suffix | Example | +| --- | --- | --- | +| High (LOD3) | none | `A1_turret` | +| Medium (LOD2) | `_LOD2` | `A1_turret_LOD2` | +| Low (LOD1) | `_LOD1` | `A1_turret_LOD1` | +| Lowest (LOD0) | `_LOD0` | `A1_turret_LOD0` | +| Physics | `_PHYS` | `A1_turret_PHYS` | + +Every part and all its LOD models go in one `.glb`. You pick that one file, and the uploader puts each LOD model and physics shape into its part's slot. Any LOD you leave out is generated from the part. + +- Suffixes are upper case and go at the very end of the name. +- Don't use `_LOD` or `_PHYS` anywhere else in a name. +- No two parts may share a name. + +## Setting up the file + +Keep every part and its LOD models in one `.blend`, export the whole scene to one `.glb`, and pick that file in the uploader. Only the parts are uploaded; their `_LOD2`, `_LOD1`, `_LOD0` and `_PHYS` objects fill the parts' slots. + +The arm's Blender file keeps them in two collections: + +| Collection | Objects | +| --- | --- | +| `TelvanniArm` | the 10 parts: `A0_base`, `A1_turret` … `A7_finger_2` | +| `LODs` (hidden) | each part's LOD models and physics shape: `A1_turret_LOD2`, `A1_turret_LOD1`, `A1_turret_LOD0`, `A1_turret_PHYS`, and the same for every part | + +### Object names, not mesh names + +Each row in the Outliner is two things: the **object** (orange triangle, such as `A1_turret_LOD1`) and, under it, its **mesh data** (green triangle). The uploader reads only the object name. The mesh data is never read, so give it a plain label that can't be mistaken for one. The arm's are `Arm Turret`, `Arm Turret medium`, `Arm Turret low`, `Arm Turret lowest` and `Arm Turret collision`. + +In the screenshot below, the parts are parented in a chain under `TelvanniArm`, each holding its mesh (`Arm Base`, `Arm Turret`, `Upper Arm` …). The hidden `LODs` collection holds every LOD object; `A1_turret_LOD1` holds the mesh `Arm Turret low`. + +![The arm in Blender's Outliner: objects (orange) holding mesh data (green), the LOD models in the hidden LODs collection](images/blender-outliner.png) + +1. Name each part's object plainly (`A1_turret`), and each of its LOD objects with the suffix at the very end (`A1_turret_LOD1`). Delete Blender's `.001` endings. +2. Place each LOD model exactly over its part, with the same bounding box. +3. Export the whole scene with **Limit to** off, so the hidden LOD objects go in too. +4. Pick the `.glb` in **Build > Upload > Model**. The LOD dropdowns read **Load from file**, and the **Log** tab lists the LOD models taken from the file. + +- **Each LOD needs every part.** If only some parts have a `_LOD1`, the Low LOD is generated for all of them, and the log says so. +- **Physics may be partial.** A part with no `_PHYS` gets the uploader's usual physics. +- **A suffixed object needs its part.** `A1_turret_LOD1` with no `A1_turret` in the file uploads as a part of its own. +- Each LOD model needs the same material slots as its part. + +## glTF export settings + +Use **File > Export > glTF 2.0** with these settings; anything not listed can stay at its default. + +| Panel | Setting | Value | +| --- | --- | --- | +| Format | Format | glTF Binary (`.glb`) | +| Include > Limit to | all four | off, so the hidden LOD objects go in too | +| Include > Data | Cameras, Punctual Lights | off | +| Transform | +Y Up | on | +| Data > Mesh | Apply Modifiers | on | +| Data > Mesh | UVs, Normals | on | +| Data > Material | Materials | Export | +| Data > Compression | Draco Compression, Meshopt Compression | off | +| Animation | Animation | off | + +![Blender's glTF 2.0 export settings for a single-file upload](images/blender-gltf-export.png) + +Apply rotation and scale first (Ctrl+A), so the exported shape matches what you see. + +## Common mistakes + +Where each part turns in-world is set by its origin; that has [a guide of its own](object-origins.md). + +| You see | Likely cause | +| --- | --- | +| `A1_turret_LOD2` uploads as a separate part | its part is missing or misspelt, or the name ends in `.001` | +| An LOD you made is generated anyway | not every part has that LOD | +| An LOD looks stretched in-world | its bounding box differs from its part's | +| An LOD is missing from the upload | Limit to was on when exporting, so the hidden LOD objects were left out | From 5c751f8eb88158f25caff73159b7cf307f78cdcf Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 02:21:32 +0000 Subject: [PATCH 19/32] Show the uploader's Pivot row in the origins guide Co-Authored-By: Claude Opus 5.5 --- doc/mesh/images/uploader-pivot.png | Bin 0 -> 89058 bytes doc/mesh/object-origins.md | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 doc/mesh/images/uploader-pivot.png diff --git a/doc/mesh/images/uploader-pivot.png b/doc/mesh/images/uploader-pivot.png new file mode 100644 index 0000000000000000000000000000000000000000..a609c185af6783a2f231d213659f9f2ab9f1c103 GIT binary patch literal 89058 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

okt{{ZB;;n7a+ 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%0A%)(8!UTj{w?bKt@DFhh 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 Date: Tue, 3 Nov 2026 02:41:35 +0000 Subject: [PATCH 20/32] Leave a local mesh's named LOD and physics models out of its parts A file holding NAME beside NAME_LOD2, NAME_LOD1, NAME_LOD0 and NAME_PHYS rezzed every one of them as a part of the preview linkset. Those are NAME's lower LODs and physics shape, as the uploader reads the file, so the preview now builds only the parts. A suffixed model with no NAME beside it is still a part. Co-Authored-By: Claude Opus 5.5 --- indra/newview/lllocalmesh.cpp | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/indra/newview/lllocalmesh.cpp b/indra/newview/lllocalmesh.cpp index f156ab0cf2f..9f2ca7d59b1 100644 --- a/indra/newview/lllocalmesh.cpp +++ b/indra/newview/lllocalmesh.cpp @@ -27,6 +27,9 @@ #include "lllocalmesh.h" #include // std::sort (stable rez-order listing of spawned copies) +#include +#include +#include #include // mSpawnedCopies: instance id -> copy (O(1) per-copy lookup/erase) #include // dedup avatars when rebuilding overrides across copies @@ -516,6 +519,39 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) importGLTFMaterials(gltf_mat_by_name, new_owned_materials); } + // A model named NAME_LOD0-2 or NAME_PHYS beside a NAME is one of NAME's + // lower LODs or its physics shape, as the uploader reads the file, not a + // part of its own. A submodel's letter follows the suffix: NAME_LOD2b. + static const std::array lod_suffixes{ "_LOD0", "_LOD1", "_LOD2", "_PHYS" }; + auto core_label = [](const LLModel* mdl) -> std::string_view + { + std::string_view label(mdl->mLabel); + return mdl->mSubmodelID > 0 && !label.empty() ? label.substr(0, label.size() - 1) : label; + }; + auto base_of = [&](std::string_view label) -> std::string_view + { + for (std::string_view suffix : lod_suffixes) + { + if (label.size() > suffix.size() && label.substr(label.size() - suffix.size()) == suffix) + { + return label.substr(0, label.size() - suffix.size()); + } + } + return {}; + }; + std::set> bases; + for (auto iter = scene.begin(); iter != scene.end(); ++iter) + { + for (const LLModelInstance& instance : iter->second) + { + const LLModel* mdl = instance.mModel.notNull() ? instance.mModel.get() : instance.mLOD[LLModel::LOD_HIGH].get(); + if (mdl && !mdl->mSubmodelID && base_of(mdl->mLabel).empty()) + { + bases.emplace(mdl->mLabel); + } + } + } + for (auto iter = scene.begin(); iter != scene.end(); ++iter) { for (LLModelInstance& instance : iter->second) @@ -525,6 +561,11 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) { continue; } + const std::string_view base = base_of(core_label(mdl)); + if (!base.empty() && bases.find(base) != bases.end()) + { + continue; + } std::vector faces; faces.reserve(mdl->getNumVolumeFaces()); From 82ce9ca4b5cb0ff2bbba181d9e37a11f17294adf Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 02:48:57 +0000 Subject: [PATCH 21/32] Show a local mesh's own LODs and physics as a mesh asset would A local mesh showed its High model at every distance and had no physics shape. Each part now keeps the file's NAME_LOD0-2 models as volumes the repository serves for those LODs, falling back to the High model where the file has none, and its NAME_PHYS model as the physics mesh the physics display draws. Nothing is generated or decomposed, so a reload stays as quick as before. Co-Authored-By: Claude Opus 5.5 --- indra/newview/lllocalmesh.cpp | 106 ++++++++++++++++++++++++++++- indra/newview/lllocalmesh.h | 7 +- indra/newview/llmeshrepository.cpp | 8 +-- 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/indra/newview/lllocalmesh.cpp b/indra/newview/lllocalmesh.cpp index 9f2ca7d59b1..40ffd293de3 100644 --- a/indra/newview/lllocalmesh.cpp +++ b/indra/newview/lllocalmesh.cpp @@ -551,6 +551,78 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) } } } + // Each part's own LOD and physics models, by the part's label (NAME, or NAMEb for a submodel): + // slots 0-2 are LOD0-2, slot 3 the physics shape. + std::map, std::less<>> lods_of; + for (auto iter = scene.begin(); iter != scene.end(); ++iter) + { + for (const LLModelInstance& instance : iter->second) + { + LLModel* mdl = instance.mModel.notNull() ? instance.mModel.get() : instance.mLOD[LLModel::LOD_HIGH].get(); + if (!mdl || mdl->getNumVolumeFaces() <= 0) + { + continue; + } + const std::string_view core = core_label(mdl); + const std::string_view base = base_of(core); + if (base.empty() || bases.find(base) == bases.end()) + { + continue; + } + const std::string_view suffix = core.substr(base.size()); + const size_t slot = suffix == "_PHYS" ? 3 : (size_t)(suffix.back() - '0'); + std::string key(base); + if (mdl->mSubmodelID > 0) + { + key += mdl->mLabel.back(); + } + lods_of[key][slot] = mdl; // value-initialised to nulls on first use + } + } + // A LOD or physics model's faces as a volume the repository can serve, built as the part's own is. + auto make_volume = [&](LLModel* mdl) -> LLPointer + { + std::vector lod_faces; + lod_faces.reserve(mdl->getNumVolumeFaces()); + const LLModel::JointWeightCache lod_weights(*mdl); + for (S32 fi = 0; fi < mdl->getNumVolumeFaces(); ++fi) + { + LLVolumeFace face = mdl->getVolumeFace(fi); + if (unit_rigged) + { + populateFaceWeights(face, *mdl, lod_weights); + } + lod_faces.push_back(face); + } + LLVolumeParams lod_params; + lod_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + LLPointer volume = new LLVolume(lod_params, 1.f); + volume->copyFacesFrom(lod_faces); + volume->cacheOptimize(true); + volume->setMeshAssetLoaded(true); + return volume; + }; + // A physics model as the triangle list the physics display draws, as a downloaded physics mesh is. + auto make_physics = [](const LLModel* mdl) -> std::shared_ptr + { + auto decomp = std::make_shared(); + std::vector& pos = decomp->mPhysicsShapeMesh.mPositions; + std::vector& norm = decomp->mPhysicsShapeMesh.mNormals; + for (S32 fi = 0; fi < mdl->getNumVolumeFaces(); ++fi) + { + const LLVolumeFace& face = mdl->getVolumeFace(fi); + for (S32 i = 0; i < face.mNumIndices; ++i) + { + const U16 idx = face.mIndices[i]; + if (idx < face.mNumVertices) + { + pos.emplace_back(face.mPositions[idx].getF32ptr()); + norm.emplace_back(face.mNormals[idx].getF32ptr()); + } + } + } + return decomp->mPhysicsShapeMesh.mPositions.empty() ? nullptr : decomp; + }; for (auto iter = scene.begin(); iter != scene.end(); ++iter) { @@ -697,6 +769,22 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) } part.mVolume->setMeshAssetLoaded(true); + auto own = lods_of.find(mdl->mLabel); + if (own != lods_of.end()) + { + for (S32 lod = LLModel::LOD_IMPOSTOR; lod < LLModel::LOD_HIGH; ++lod) + { + if (LLModel* lod_mdl = own->second[lod]) + { + part.mLODVolumes[lod] = make_volume(lod_mdl); + } + } + if (LLModel* physics_mdl = own->second[3]) + { + part.mPhysics = make_physics(physics_mdl); + } + } + if (!mdl->mSkinInfo.mJointNames.empty()) { // Owned copy bound to this part's world id. By default include_joints @@ -1156,10 +1244,24 @@ bool LLLocalMeshMgr::isLocal(const LLUUID& world_id) const return findPart(world_id) != nullptr; } -LLVolume* LLLocalMeshMgr::getVolumeForWorldID(const LLUUID& world_id) const +LLVolume* LLLocalMeshMgr::getVolumeForWorldID(const LLUUID& world_id, S32 lod) const +{ + const LLLocalMeshPart* part = findPart(world_id); + if (!part) + { + return nullptr; + } + if (lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::LOD_HIGH && part->mLODVolumes[lod].notNull()) + { + return part->mLODVolumes[lod].get(); + } + return part->mVolume.get(); +} + +LLModel::Decomposition* LLLocalMeshMgr::getDecompositionForWorldID(const LLUUID& world_id) const { const LLLocalMeshPart* part = findPart(world_id); - return part ? part->mVolume.get() : nullptr; + return part ? part->mPhysics.get() : nullptr; } const LLMeshSkinInfo* LLLocalMeshMgr::getSkinInfoForWorldID(const LLUUID& world_id) const diff --git a/indra/newview/lllocalmesh.h b/indra/newview/lllocalmesh.h index 09adb58999f..a4828d493ad 100644 --- a/indra/newview/lllocalmesh.h +++ b/indra/newview/lllocalmesh.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,8 @@ struct LLLocalMeshPart std::string mName; // sub-mesh (model/instance) name, for build-floater display LLUUID mWorldID; // unique mesh id objects/repository reference LLPointer mVolume; // normalized geometry (<= 8 faces) + LLPointer mLODVolumes[LLModel::LOD_HIGH]; // the file's NAME_LOD0-2, null where it has none + std::shared_ptr mPhysics; // the file's NAME_PHYS as a physics mesh, null where it has none LLPointer mSkinInfo; // null if not rigged LLVector3 mScale; // object scale (decomposed instance scale; rigged: authored size) LLQuaternion mRotation; // object rotation (decomposed instance rotation; rigged: identity) @@ -236,7 +239,9 @@ class LLLocalMeshMgr : public LLSingleton // Mesh repository injection: resolve a part's world id to its decoded data. bool isLocal(const LLUUID& world_id) const; - LLVolume* getVolumeForWorldID(const LLUUID& world_id) const; + // The part's geometry for a LOD: the file's own model for it, else the High one. + LLVolume* getVolumeForWorldID(const LLUUID& world_id, S32 lod = LLModel::LOD_HIGH) const; + LLModel::Decomposition* getDecompositionForWorldID(const LLUUID& world_id) const; const LLMeshSkinInfo* getSkinInfoForWorldID(const LLUUID& world_id) const; // Despawn in-world preview copies but KEEP the loaded unit so it can be re-spawned diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e2620c6fc5d..58800664985 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4620,7 +4620,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } // Local mesh: serve the decoded geometry directly from the registry instead - // of issuing an asset fetch. The same geometry is served for every LOD. + // of issuing an asset fetch. Each LOD gets the file's own model for it, or the High one. // Local mesh LODs // Local mesh: decide locality by registry membership, not by whether a decoded // volume happens to exist right now. A local-only world id must never fall through // to the simulator-backed fetch below -- not even during the brief window of a @@ -4628,7 +4628,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para if (LLLocalMeshMgr::instanceExists() && LLLocalMeshMgr::getInstance()->isLocal(mesh_params.getSculptID())) { - LLVolume* local_volume = LLLocalMeshMgr::getInstance()->getVolumeForWorldID(mesh_params.getSculptID()); + LLVolume* local_volume = LLLocalMeshMgr::getInstance()->getVolumeForWorldID(mesh_params.getSculptID(), new_lod); // Local mesh LODs: the file's own model for this LOD if (local_volume) { LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, new_lod); @@ -5421,7 +5421,7 @@ LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id // forever, retrying). if (LLLocalMeshMgr::instanceExists() && LLLocalMeshMgr::getInstance()->isLocal(mesh_id)) { - return ret; + return LLLocalMeshMgr::getInstance()->getDecompositionForWorldID(mesh_id); // Local mesh LODs: the file's physics model } if (mesh_id.notNull()) @@ -5475,7 +5475,7 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) // decomposition fetch below). if (LLLocalMeshMgr::instanceExists() && LLLocalMeshMgr::getInstance()->isLocal(mesh_id)) { - return false; + return LLLocalMeshMgr::getInstance()->getDecompositionForWorldID(mesh_id) != nullptr; // Local mesh LODs: the file's physics model } if (const LLMeshHeader* header = mHeaderCache.findValid(mesh_id)) From d4cb621cde6d0cb0fa4cb229a6a50534d1765391 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 03:00:59 +0000 Subject: [PATCH 22/32] Stand each local mesh part on the origin its file gives A local mesh centred every part on its bounding box, so a door or joint turned about its middle in the preview though the uploader keeps its file origin. Each static part now takes the uploader's From file pivot: its geometry, LOD models and physics shape move by the same offset the uploader writes into the position domain, and the part is placed at its pivot, so the linkset sits where the file placed it. Rigged parts stay as they were. Co-Authored-By: Claude Opus 5.5 --- indra/newview/lllocalmesh.cpp | 38 +++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/indra/newview/lllocalmesh.cpp b/indra/newview/lllocalmesh.cpp index 40ffd293de3..32213794554 100644 --- a/indra/newview/lllocalmesh.cpp +++ b/indra/newview/lllocalmesh.cpp @@ -56,6 +56,7 @@ #include "lllocalgltfmaterials.h" // import a glTF mesh's materials as mesh-owned local materials #include "llprimitive.h" // LL_PCODE_VOLUME #include "object_flags.h" // FLAGS_OBJECT_* for owner permissions +#include "llmodelpreview.h" // LLModelPreview::getFileOriginPivot, the uploader's origin rule #include "llnotificationsutil.h" // warn when a loaded mesh has no UVs #include "llscrolllistctrl.h" #include "llselectmgr.h" // deselect before re-parenting onto the avatar @@ -579,8 +580,27 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) lods_of[key][slot] = mdl; // value-initialised to nulls on first use } } + // A static part stands on the origin its file gives, as the uploader's From file pivot places it: + // its geometry moves by the offset that brings that origin to the prim's, and the part moves back. + auto shift_face = [](LLVolumeFace& face, const LLVector4a& offset) + { + for (S32 v = 0; v < face.mNumVertices; ++v) + { + face.mPositions[v].add(offset); + } + if (face.mExtents) + { + face.mExtents[0].add(offset); + face.mExtents[1].add(offset); + } + if (face.mCenter) + { + face.mCenter->add(offset); + } + }; + // A LOD or physics model's faces as a volume the repository can serve, built as the part's own is. - auto make_volume = [&](LLModel* mdl) -> LLPointer + auto make_volume = [&](LLModel* mdl, const LLVector4a& offset) -> LLPointer { std::vector lod_faces; lod_faces.reserve(mdl->getNumVolumeFaces()); @@ -592,6 +612,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) { populateFaceWeights(face, *mdl, lod_weights); } + shift_face(face, offset); lod_faces.push_back(face); } LLVolumeParams lod_params; @@ -603,7 +624,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) return volume; }; // A physics model as the triangle list the physics display draws, as a downloaded physics mesh is. - auto make_physics = [](const LLModel* mdl) -> std::shared_ptr + auto make_physics = [](const LLModel* mdl, const LLVector3& offset) -> std::shared_ptr { auto decomp = std::make_shared(); std::vector& pos = decomp->mPhysicsShapeMesh.mPositions; @@ -616,7 +637,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) const U16 idx = face.mIndices[i]; if (idx < face.mNumVertices) { - pos.emplace_back(face.mPositions[idx].getF32ptr()); + pos.emplace_back(LLVector3(face.mPositions[idx].getF32ptr()) + offset); norm.emplace_back(face.mNormals[idx].getF32ptr()); } } @@ -638,6 +659,10 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) { continue; } + // Rigged parts are placed by their skeleton, so only a static part takes its file's origin. + const LLVector3 pivot_offset = unit_rigged ? LLVector3::zero : LLModelPreview::getFileOriginPivot(mdl) * -0.5f; + LLVector4a pivot_offset4; + pivot_offset4.load3(pivot_offset.mV); std::vector faces; faces.reserve(mdl->getNumVolumeFaces()); @@ -647,6 +672,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) for (S32 fi = 0; fi < mdl->getNumVolumeFaces(); ++fi) { LLVolumeFace face = mdl->getVolumeFace(fi); // deep copy + shift_face(face, pivot_offset4); // Keep the loader's model-local geometry for both rigged and static // units; the instance transform is applied as the object transform // below (mirroring the upload), so geometry/normals/tangents stay in @@ -753,7 +779,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) decomposeInstanceMatrix(instance.mTransform, pos, rot, scl); part.mScale = scl; part.mRotation = rot; - part.mOffset = pos; // scene-space; spawn uses per-part differences + part.mOffset = (-pivot_offset) * instance.mTransform; // scene-space at the pivot; spawn uses per-part differences } LLVolumeParams vparams; @@ -776,12 +802,12 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) { if (LLModel* lod_mdl = own->second[lod]) { - part.mLODVolumes[lod] = make_volume(lod_mdl); + part.mLODVolumes[lod] = make_volume(lod_mdl, pivot_offset4); } } if (LLModel* physics_mdl = own->second[3]) { - part.mPhysics = make_physics(physics_mdl); + part.mPhysics = make_physics(physics_mdl, pivot_offset); } } From 52f899e635907b97e04d8f0c6082bd83ae18b025 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 04:11:04 +0000 Subject: [PATCH 23/32] Serve a local mesh's own LOD only where it can stand in for High A LOD split into a different set of submodels left faces out, one with its materials in another order took High's by face index onto the wrong faces, and on rigged mesh one without skin weights drew unskinned; each now falls back to High. A physics model without normals no longer reads through a null pointer. Co-Authored-By: Claude Opus 5.5 --- indra/newview/lllocalmesh.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/indra/newview/lllocalmesh.cpp b/indra/newview/lllocalmesh.cpp index 32213794554..c0399470104 100644 --- a/indra/newview/lllocalmesh.cpp +++ b/indra/newview/lllocalmesh.cpp @@ -555,6 +555,10 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) // Each part's own LOD and physics models, by the part's label (NAME, or NAMEb for a submodel): // slots 0-2 are LOD0-2, slot 3 the physics shape. std::map, std::less<>> lods_of; + // How many models (root and submodels) each part has at High, and at each of its own LOD slots: + // a LOD split differently from High would leave faces out, so it isn't served. + std::map> high_count; + std::map, std::less<>> lod_count; for (auto iter = scene.begin(); iter != scene.end(); ++iter) { for (const LLModelInstance& instance : iter->second) @@ -568,6 +572,10 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) const std::string_view base = base_of(core); if (base.empty() || bases.find(base) == bases.end()) { + if (base.empty()) + { + ++high_count[std::string(core)]; + } continue; } const std::string_view suffix = core.substr(base.size()); @@ -578,6 +586,7 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) key += mdl->mLabel.back(); } lods_of[key][slot] = mdl; // value-initialised to nulls on first use + ++lod_count[std::string(base)][slot]; } } // A static part stands on the origin its file gives, as the uploader's From file pivot places it: @@ -638,7 +647,8 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) if (idx < face.mNumVertices) { pos.emplace_back(LLVector3(face.mPositions[idx].getF32ptr()) + offset); - norm.emplace_back(face.mNormals[idx].getF32ptr()); + // A Collada model without normals has none; the physics display draws positions alone. + norm.emplace_back(face.mNormals ? LLVector3(face.mNormals[idx].getF32ptr()) : LLVector3::z_axis); } } } @@ -798,9 +808,19 @@ bool LLLocalMesh::ingestScene(LLModelLoader::scene& scene) auto own = lods_of.find(mdl->mLabel); if (own != lods_of.end()) { + const std::string_view own_base = core_label(mdl); + const auto high_it = high_count.find(own_base); + const auto lod_it = lod_count.find(own_base); for (S32 lod = LLModel::LOD_IMPOSTOR; lod < LLModel::LOD_HIGH; ++lod) { - if (LLModel* lod_mdl = own->second[lod]) + LLModel* lod_mdl = own->second[lod]; + // Served only where it can stand in for High: split the same way, with its + // materials in the same order (faces take High's materials by index), and + // skinned where High is, or it would draw unskinned at that distance. + if (lod_mdl + && high_it != high_count.end() && lod_it != lod_count.end() && lod_it->second[lod] == high_it->second + && lod_mdl->mMaterialList == mdl->mMaterialList + && (!unit_rigged || !lod_mdl->mSkinWeights.empty())) { part.mLODVolumes[lod] = make_volume(lod_mdl, pivot_offset4); } From adadad0bf85c4abd94bf7f7b100d90bc3cae6468 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 04:11:43 +0000 Subject: [PATCH 24/32] Keep a leftover submodel's letter and a chosen LOD source A suffixed submodel with no base kept its root's instance label once its suffix was stripped, so the upload resolved it to the root and dropped its geometry. A LOD the next high file no longer supplies went back to generation even where it was set to use the LOD above. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 188d678d630..79e95a13bce 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1924,10 +1924,15 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) mVertexBuffer[lod].clear(); if (fmp && lod != LLModel::LOD_PHYSICS) { - fmp->mLODMode[lod] = MESH_OPTIMIZER_AUTO; - if (LLComboBox* lod_combo = fmp->findChild("lod_source_" + lod_name[lod])) + // Only a LOD still set to come from the file goes back to generation; another source stays. + LLComboBox* lod_combo = fmp->findChild("lod_source_" + lod_name[lod]); + if (!lod_combo || lod_combo->getCurrentIndex() == LOD_FROM_FILE) { - lod_combo->setCurrentByIndex(MESH_OPTIMIZER_AUTO); + fmp->mLODMode[lod] = MESH_OPTIMIZER_AUTO; + if (lod_combo) + { + lod_combo->setCurrentByIndex(MESH_OPTIMIZER_AUTO); + } } fmp->childSetValue("lod_file_" + lod_name[lod], ""); } @@ -1945,8 +1950,8 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) LLModel* model = instance.mModel; if (model && suffix_lod(core_of(model)) >= 0 && lod_of(model) < 0) { - instance.mLabel = stripSuffix(instance.mLabel); model->mLabel = stripSuffix(core_of(model)) + letter_of(model); + instance.mLabel = model->mLabel; // a submodel keeps its letter, so it isn't taken for its root } } } From 23ec9059d1c4a5f036482d7ad2aee609fca57eac Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 05:37:10 +0000 Subject: [PATCH 25/32] Count submodels with their root for the pivot, and warn per part A model with more than eight materials uploads as a root and submodels, so Custom and metres were refused for what is one model. The warning that a pivoted part collides with a centred default hull was also hidden whenever any other part of the linkset had physics. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 4 ++-- indra/newview/llmodelpreview.cpp | 22 ++++++++++++++++------ indra/newview/llmodelpreview.h | 2 ++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 7ca22b3336b..bdaad3c1e06 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -700,7 +700,7 @@ LLVector3 LLFloaterModelPreview::getPivotHalfExtents() const { return LLVector3::zero; } - if (mModelPreview->mUploadData.size() == 1) + if (mModelPreview->isSingleModel()) { // The pivot moves along the mesh's own axes, so a rotated instance measures along them. // The transform carries the import scale already. @@ -774,7 +774,7 @@ void LLFloaterModelPreview::updatePivotControls() } // Custom is for one model: several each take their own origin from the file, or the centre. - const bool single = mModelPreview->mUploadData.size() == 1; + const bool single = mModelPreview->isSingleModel(); if (LLRadioGroup* modes = getChild("pivot_mode")) { if (!single && mModelPreview->getPivotMode() == LLModelPreview::PIVOT_CUSTOM) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 5a0bc823eac..69656842abf 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1849,7 +1849,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d // Mesh uploader pivot void LLModelPreview::setPivotMode(EPivotMode mode) { - if (mode == PIVOT_CUSTOM && mPivotMode != PIVOT_CUSTOM && mUploadData.size() == 1) + if (mode == PIVOT_CUSTOM && mPivotMode != PIVOT_CUSTOM && isSingleModel()) { mCustomPivot = getWantedPivot(mUploadData[0].mModel); } @@ -1887,12 +1887,19 @@ LLVector3 LLModelPreview::getWantedPivot(const LLModel* model) const case PIVOT_FILE: return getFileOriginPivot(model); case PIVOT_CUSTOM: - return mUploadData.size() == 1 ? mCustomPivot : LLVector3::zero; + return isSingleModel() ? mCustomPivot : LLVector3::zero; default: return LLVector3::zero; } } +bool LLModelPreview::isSingleModel() const +{ + // A model with more than eight materials uploads as a root and its submodels, sharing one transform. + return std::count_if(mUploadData.begin(), mUploadData.end(), + [](const LLModelInstance& instance) { return instance.mModel && !instance.mModel->mSubmodelID; }) == 1; +} + LLMeshUploadThread::position_offsets_t LLModelPreview::getUploadPositionOffsets() const { LLMeshUploadThread::position_offsets_t offsets; @@ -2253,20 +2260,24 @@ void LLModelPreview::updateStatusMessages() bool has_physics = false; bool analyzed = true; bool rigged = false; + bool pivot_without_physics = false; // a pivoted part that collides with a default hull centred on itself for (const LLModelInstance& instance : mUploadData) { rigged |= instance.mModel && !instance.mModel->mSkinWeights.empty(); // The hulls uploaded are the physics model's, or the base model's without one. const LLModel* physics = instance.mLOD[LLModel::LOD_PHYSICS]; + bool instance_physics = false; if (physics && physics->getNumVolumeFaces() > 0) { - has_physics = true; + instance_physics = true; analyzed &= !physics->mPhysics.mHull.empty(); } else if (!physics && instance.mModel && !instance.mModel->mPhysics.mHull.empty()) { - has_physics = true; + instance_physics = true; } + has_physics |= instance_physics; + pivot_without_physics |= !instance_physics && !getWantedPivot(instance.mModel).isExactlyZero(); } std::string pivot_status; @@ -2281,8 +2292,7 @@ void LLModelPreview::updateStatusMessages() pivot_status = mFMP->getString("pivot_status_analyze"); mUploadPivotAllowed = false; } - else if (!has_physics && std::any_of(mUploadData.begin(), mUploadData.end(), [this](const LLModelInstance& instance) - { return !getWantedPivot(instance.mModel).isExactlyZero(); })) + else if (pivot_without_physics) { pivot_status = mFMP->getString("pivot_status_no_physics"); } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 6c363e79faa..663a68ba9cb 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -185,6 +185,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH LLVector3 getUploadPivot(const LLModel* model) const { return mUploadPivotAllowed ? getWantedPivot(model) : LLVector3::zero; } // What each model's stored domains are shifted by so that its origin lands on its pivot. LLMeshUploadThread::position_offsets_t getUploadPositionOffsets() const; + // One model to upload, counting a root and its submodels once: what Custom and metres are for. + bool isSingleModel() const; // //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions From 9b41eabac1fbb219bc20e34280e13c4be5490f0d Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 05:38:24 +0000 Subject: [PATCH 26/32] Match a file's LODs by name and keep its default physics shape Collada instances of a high file were still cut at any _LOD or _PHYS in their names, so a part such as Wall_LODGE found no High model. A LOD set was judged complete by its count, so a part without its own LOD could take another's submodel; it now needs each part's model by name. default_physics_shape_PHYS goes to physics without a part of that name, as the separate physics file it stands for would. Physics loaded from a file of its own no longer follows a LOD it was once copied from, and the LOD controls show each slot's source once the file has set it. Co-Authored-By: Claude Opus 5.5 --- indra/llprimitive/lldaeloader.cpp | 6 ++++- indra/newview/llmodelpreview.cpp | 44 ++++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index a14fad1ff74..f978a955f82 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2146,7 +2146,11 @@ void LLDAELoader::processElement( daeElement* element, bool& badElement, DAE* da { // Don't change model's name if possible, it will play havoc with scenes that already use said model. size_t ext_pos = getSuffixPosition(model->mLabel); - if (ext_pos != std::string::npos) + if (mLod == LLModel::LOD_HIGH) + { + label = model->mLabel; // Mesh uploader LODs by name: the instance is named as its model is + } + else if (ext_pos != std::string::npos) { label = model->mLabel.substr(0, ext_pos); } diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 79e95a13bce..31bcd967c42 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1129,9 +1129,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { mLODFromHighFile[loaded_lod] = false; } - // - // Mesh uploader LODs by name - if (loaded_lod == LLModel::LOD_HIGH) + else { splitSuffixedModels(mModelLoader->mFilename); } @@ -1910,8 +1908,17 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) return -1; } const std::string core = core_of(model); + if (legacy) + { + return -1; + } + // The shape for parts with no _PHYS of their own goes to physics whether or not a part shares its name. + if (core == DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(LLModel::LOD_PHYSICS)) + { + return LLModel::LOD_PHYSICS; + } const S32 lod = suffix_lod(core); - return lod >= 0 && bases.count(stripSuffix(core)) && !legacy ? lod : -1; + return lod >= 0 && bases.count(stripSuffix(core)) ? lod : -1; }; // LODs an earlier file filled and this one does not are generated again. @@ -2003,13 +2010,20 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) if (was_from_file[lod] && !split[lod]) { release(lod); + if (lod != LLModel::LOD_PHYSICS) + { + updateLodControls(lod); + } } } // Physics copied from a LOD follows that LOD when this file replaces it. const S32 physics_from = mPhysicsSearchLOD; auto follow_physics = [&]() { - if (physics_from >= LLModel::LOD_IMPOSTOR && physics_from <= LLModel::LOD_HIGH && (split[physics_from] || was_from_file[physics_from])) + // A physics file of its own is left alone; only physics copied from that LOD follows it. + const bool own_physics_file = !mLODFile[LLModel::LOD_PHYSICS].empty() && !was_from_file[LLModel::LOD_PHYSICS]; + if (!own_physics_file && physics_from >= LLModel::LOD_IMPOSTOR && physics_from <= LLModel::LOD_HIGH + && (split[physics_from] || was_from_file[physics_from])) { mModel[LLModel::LOD_PHYSICS] = mModel[physics_from]; mScene[LLModel::LOD_PHYSICS] = mScene[physics_from]; @@ -2053,10 +2067,25 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) { continue; } - if (lod != LLModel::LOD_PHYSICS && mModel[lod].size() != kept.size()) + // A LOD needs every model and submodel, each by its own name: a partial set is dropped and the LOD generated. + auto complete = [&]() + { + if (mModel[lod].size() != kept.size()) + { + return false; + } + std::set names; + for (const LLPointer& model : mModel[lod]) + { + names.insert(model->mLabel); + } + return std::all_of(kept.begin(), kept.end(), [&](const LLPointer& model) + { return names.count(model->mLabel + getLodSuffix(lod)) > 0; }); + }; + if (lod != LLModel::LOD_PHYSICS && !complete()) { - // A LOD needs every model and submodel; the file's partial set is dropped and the LOD generated. release(lod); + updateLodControls(lod); std::ostringstream out; out << "Only some models have a " << getLodSuffix(lod) << " model in the file; generating that LOD instead"; LLFloaterModelPreview::addStringToLog(out, true); @@ -2076,6 +2105,7 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) { fmp->mLODMode[lod] = LOD_FROM_FILE; fmp->childSetValue("lod_file_" + lod_name[lod], filename); + updateLodControls(lod); } } std::ostringstream out; From 82b3dbe59cb5060e637971b1bef9f34a2da76f12 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 09:42:06 +0000 Subject: [PATCH 27/32] Hold only the parts that cannot take a pivot One rigged part, or one with physics not yet analyzed, held every part of the upload at its centre; now only that part is held. Skin weights left out of the upload no longer count as rigged, and a metre pivot reads the import scale as it is now rather than as the upload data was last built. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llfloatermodelpreview.cpp | 6 ++-- indra/newview/llmodelpreview.cpp | 39 ++++++++++++++++--------- indra/newview/llmodelpreview.h | 6 ++-- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index bdaad3c1e06..ef5d78cab45 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -703,12 +703,14 @@ LLVector3 LLFloaterModelPreview::getPivotHalfExtents() const if (mModelPreview->isSingleModel()) { // The pivot moves along the mesh's own axes, so a rotated instance measures along them. - // The transform carries the import scale already. + // The transform carries the import scale it was built with; a scale changed since is applied here. const LLMatrix4& mat = mModelPreview->mUploadData[0].mTransform; + const F32 built = mModelPreview->mPivotScale; + const F32 rescale = built > 0.f ? (F32)childGetValue("import_scale").asReal() / built : 1.f; LLVector3 half; for (S32 i = 0; i < 3; ++i) { - half.mV[i] = LLVector3(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]).length() * 0.5f; + half.mV[i] = LLVector3(mat.mMatrix[i][0], mat.mMatrix[i][1], mat.mMatrix[i][2]).length() * 0.5f * rescale; } return half; } diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 69656842abf..281f5794bdb 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -304,6 +304,7 @@ void LLModelPreview::rebuildUploadData() LLSpinCtrl* scale_spinner = mFMP->getChild("import_scale"); F32 scale = (F32)scale_spinner->getValue().asReal(); + mPivotScale = scale; // Mesh uploader pivot: the scale the transforms below carry LLMatrix4 scale_mat; scale_mat.initScale(LLVector3(scale, scale, scale)); @@ -2257,40 +2258,52 @@ void LLModelPreview::updateStatusMessages() // Mesh uploader pivot: the sim keeps analyzed hulls where the pivot puts them but fits // any other physics shape to the box, so a pivot needs analyzed physics or none at all. { - bool has_physics = false; - bool analyzed = true; - bool rigged = false; + // Each part is judged on its own, so one rigged or unanalyzed part holds only itself at the centre. + const bool uploading_skin = mFMP->childGetValue("upload_skin").asBoolean(); + bool any_rigged = false; + bool any_unanalyzed = false; bool pivot_without_physics = false; // a pivoted part that collides with a default hull centred on itself + mPivotHeld.clear(); for (const LLModelInstance& instance : mUploadData) { - rigged |= instance.mModel && !instance.mModel->mSkinWeights.empty(); + const LLModel* model = instance.mModel; + if (!model) + { + continue; + } + // Skin weights left out of the upload make a static mesh, which can take a pivot. + const bool rigged = uploading_skin && !model->mSkinWeights.empty(); // The hulls uploaded are the physics model's, or the base model's without one. const LLModel* physics = instance.mLOD[LLModel::LOD_PHYSICS]; bool instance_physics = false; + bool unanalyzed = false; if (physics && physics->getNumVolumeFaces() > 0) { instance_physics = true; - analyzed &= !physics->mPhysics.mHull.empty(); + unanalyzed = physics->mPhysics.mHull.empty(); } - else if (!physics && instance.mModel && !instance.mModel->mPhysics.mHull.empty()) + else if (!physics && !model->mPhysics.mHull.empty()) { instance_physics = true; } - has_physics |= instance_physics; - pivot_without_physics |= !instance_physics && !getWantedPivot(instance.mModel).isExactlyZero(); + if (rigged || unanalyzed) + { + mPivotHeld.insert(model); + } + any_rigged |= rigged; + any_unanalyzed |= unanalyzed && !rigged; + pivot_without_physics |= !rigged && !instance_physics && !getWantedPivot(model).isExactlyZero(); } std::string pivot_status; - mUploadPivotAllowed = true; - if (rigged) + mUploadPivotAllowed = mPivotHeld.size() < mUploadData.size(); + if (any_rigged) { pivot_status = mFMP->getString("pivot_status_rigged"); - mUploadPivotAllowed = false; } - else if (has_physics && !analyzed) + else if (any_unanalyzed) { pivot_status = mFMP->getString("pivot_status_analyze"); - mUploadPivotAllowed = false; } else if (pivot_without_physics) { diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 663a68ba9cb..094561c11dd 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -182,7 +182,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH static LLVector3 getFileOriginPivot(const LLModel* model); // The pivot the mode asks for, and the one in effect: centred while the physics or rigging rules it out. LLVector3 getWantedPivot(const LLModel* model) const; - LLVector3 getUploadPivot(const LLModel* model) const { return mUploadPivotAllowed ? getWantedPivot(model) : LLVector3::zero; } + LLVector3 getUploadPivot(const LLModel* model) const { return mPivotHeld.count(model) ? LLVector3::zero : getWantedPivot(model); } // What each model's stored domains are shifted by so that its origin lands on its pivot. LLMeshUploadThread::position_offsets_t getUploadPositionOffsets() const; // One model to upload, counting a root and its submodels once: what Custom and metres are for. @@ -291,7 +291,9 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH // Mesh uploader pivot EPivotMode mPivotMode{PIVOT_FILE}; LLVector3 mCustomPivot; - bool mUploadPivotAllowed{true}; + bool mUploadPivotAllowed{true}; // some part may take a pivot + std::set mPivotHeld; // parts held at the centre: rigged, or with physics not yet analyzed + F32 mPivotScale{1.f}; // the import scale the upload data was last built with // std::map mViewOption; From 99c75a28c616803a4dfe302a686a5d39181edaef Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 09:42:59 +0000 Subject: [PATCH 28/32] Copy physics from its LOD once that LOD is generated Physics set to use a LOD was copied from it while it was released for generation, so it stayed empty and the upload fell back to the High model's own hulls. It is now copied when the LOD it uses is generated. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 31bcd967c42..cd02b45c15e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1852,6 +1852,17 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d } } + // Mesh uploader LODs by name: physics copied from a LOD follows it once it is generated again + if (mPhysicsSearchLOD >= LLModel::LOD_IMPOSTOR && mPhysicsSearchLOD <= LLModel::LOD_HIGH + && mLODFile[LLModel::LOD_PHYSICS].empty() && !mLODFromHighFile[LLModel::LOD_PHYSICS] + && (which_lod == -1 || which_lod == mPhysicsSearchLOD)) + { + mModel[LLModel::LOD_PHYSICS] = mModel[mPhysicsSearchLOD]; + mScene[LLModel::LOD_PHYSICS] = mScene[mPhysicsSearchLOD]; + mVertexBuffer[LLModel::LOD_PHYSICS].clear(); + } + // + dropFacesCopiesOfLostModels(); LL_INFOS("Upload") << "LOD " << which_lod << ", Mesh optimizer processed meshes : " << meshes_processed @@ -2020,10 +2031,11 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) const S32 physics_from = mPhysicsSearchLOD; auto follow_physics = [&]() { - // A physics file of its own is left alone; only physics copied from that LOD follows it. + // A physics file of its own is left alone; only physics copied from that LOD follows it. A LOD + // released for generation is copied once generated (genMeshOptimizerLODs), not while empty here. const bool own_physics_file = !mLODFile[LLModel::LOD_PHYSICS].empty() && !was_from_file[LLModel::LOD_PHYSICS]; if (!own_physics_file && physics_from >= LLModel::LOD_IMPOSTOR && physics_from <= LLModel::LOD_HIGH - && (split[physics_from] || was_from_file[physics_from])) + && split[physics_from]) { mModel[LLModel::LOD_PHYSICS] = mModel[physics_from]; mScene[LLModel::LOD_PHYSICS] = mScene[physics_from]; From b83cdc5eb637abacad466d0f118648c70f9cc0d0 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 3 Nov 2026 10:01:37 +0000 Subject: [PATCH 29/32] Enable the pivot by instance and show every reason it is held Two instances of one rigged model left the pivot controls enabled though both were held at the centre, and a rigged part hid the warning that a pivoted static part without physics collides with a centred hull. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 19 +++++++++++++------ .../default/xui/en/floater_model_preview.xml | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 281f5794bdb..775d7854e4f 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2295,19 +2295,26 @@ void LLModelPreview::updateStatusMessages() pivot_without_physics |= !rigged && !instance_physics && !getWantedPivot(model).isExactlyZero(); } + // Some instance must be free of the hold: several instances of one held model are all held. + mUploadPivotAllowed = std::any_of(mUploadData.begin(), mUploadData.end(), [this](const LLModelInstance& instance) + { return instance.mModel && !mPivotHeld.count(instance.mModel); }); + // Every reason that applies is shown, since each concerns different parts. std::string pivot_status; - mUploadPivotAllowed = mPivotHeld.size() < mUploadData.size(); + auto add_status = [&](const char* name) + { + pivot_status += (pivot_status.empty() ? "" : " ") + mFMP->getString(name); + }; if (any_rigged) { - pivot_status = mFMP->getString("pivot_status_rigged"); + add_status("pivot_status_rigged"); } - else if (any_unanalyzed) + if (any_unanalyzed) { - pivot_status = mFMP->getString("pivot_status_analyze"); + add_status("pivot_status_analyze"); } - else if (pivot_without_physics) + if (pivot_without_physics) { - pivot_status = mFMP->getString("pivot_status_no_physics"); + add_status("pivot_status_no_physics"); } const bool custom = mFMP->childGetValue("pivot_mode").asString() == "custom"; diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 82172309f07..ac7527fdb22 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1473,7 +1473,7 @@ Date: Wed, 4 Nov 2026 13:05:13 +0000 Subject: [PATCH 30/32] Keep rigged mesh on the default position domain The upload takes its skin from the High model, which can carry weights its base does not, so such a mesh escaped the rigged check and had its domain shifted. Rigged mesh is now judged from both models, and its upload offset is zero whatever the pivot mode says. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 17 ++++++++++++++--- indra/newview/llmodelpreview.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 775d7854e4f..242bd99e840 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1894,6 +1894,17 @@ LLVector3 LLModelPreview::getWantedPivot(const LLModel* model) const } } +bool LLModelPreview::uploadsRigged(const LLModelInstance& instance) const +{ + // The upload takes its skin from the High model, which may carry weights its base does not. + if (!mFMP || !mFMP->childGetValue("upload_skin").asBoolean()) + { + return false; + } + const LLModel* high = instance.mLOD[LLModel::LOD_HIGH]; + return (instance.mModel && !instance.mModel->mSkinWeights.empty()) || (high && !high->mSkinWeights.empty()); +} + bool LLModelPreview::isSingleModel() const { // A model with more than eight materials uploads as a root and its submodels, sharing one transform. @@ -1906,7 +1917,8 @@ LLMeshUploadThread::position_offsets_t LLModelPreview::getUploadPositionOffsets( LLMeshUploadThread::position_offsets_t offsets; for (const LLModelInstance& instance : mUploadData) { - offsets[instance.mModel.get()] = getUploadPivot(instance.mModel) * -0.5f; + // Rigged mesh is placed by its skeleton and keeps the default position domain, whatever the pivot. + offsets[instance.mModel.get()] = uploadsRigged(instance) ? LLVector3::zero : getUploadPivot(instance.mModel) * -0.5f; } return offsets; } @@ -2259,7 +2271,6 @@ void LLModelPreview::updateStatusMessages() // any other physics shape to the box, so a pivot needs analyzed physics or none at all. { // Each part is judged on its own, so one rigged or unanalyzed part holds only itself at the centre. - const bool uploading_skin = mFMP->childGetValue("upload_skin").asBoolean(); bool any_rigged = false; bool any_unanalyzed = false; bool pivot_without_physics = false; // a pivoted part that collides with a default hull centred on itself @@ -2272,7 +2283,7 @@ void LLModelPreview::updateStatusMessages() continue; } // Skin weights left out of the upload make a static mesh, which can take a pivot. - const bool rigged = uploading_skin && !model->mSkinWeights.empty(); + const bool rigged = uploadsRigged(instance); // The hulls uploaded are the physics model's, or the base model's without one. const LLModel* physics = instance.mLOD[LLModel::LOD_PHYSICS]; bool instance_physics = false; diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 094561c11dd..10a465845bb 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -187,6 +187,8 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH LLMeshUploadThread::position_offsets_t getUploadPositionOffsets() const; // One model to upload, counting a root and its submodels once: what Custom and metres are for. bool isSingleModel() const; + // Whether this instance uploads skinned, from its base or its High model: such mesh takes no pivot. + bool uploadsRigged(const LLModelInstance& instance) const; // //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions From 6d4ecf05899b6fd388ed41360f713348c6719397 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Wed, 4 Nov 2026 14:48:45 +0000 Subject: [PATCH 31/32] Keep physics set to use a LOD equal to that LOD Physics chosen as a copy of a LOD was copied once and went stale when the LOD changed: a new high file, the file's own LODs, generation or a LOD file loaded later all left the old copy. Rebuilding the upload data now copies that LOD again wherever it differs, which replaces the copies the split and generation made at their own points. Every instance of a shared leftover suffixed model now takes its stripped name. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 63 +++++++++++++++----------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index cd02b45c15e..c20dd520280 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -287,6 +287,17 @@ void LLModelPreview::rebuildUploadData() assert_main_thread(); mDefaultPhysicsShapeP = NULL; + // Mesh uploader LODs by name: physics set to use a LOD is that LOD as it stands now, however + // it changed since (a new high file, the file's own LODs, generation, a LOD file of its own) + if (mPhysicsSearchLOD >= LLModel::LOD_IMPOSTOR && mPhysicsSearchLOD <= LLModel::LOD_HIGH + && mLODFile[LLModel::LOD_PHYSICS].empty() && !mLODFromHighFile[LLModel::LOD_PHYSICS] + && mModel[LLModel::LOD_PHYSICS] != mModel[mPhysicsSearchLOD]) + { + mModel[LLModel::LOD_PHYSICS] = mModel[mPhysicsSearchLOD]; + mScene[LLModel::LOD_PHYSICS] = mScene[mPhysicsSearchLOD]; + mVertexBuffer[LLModel::LOD_PHYSICS].clear(); + } + // // Mesh uploader LODs by name: physics from the high file names its default shape as a physics file does if (mLODFromHighFile[LLModel::LOD_PHYSICS]) { @@ -1852,17 +1863,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d } } - // Mesh uploader LODs by name: physics copied from a LOD follows it once it is generated again - if (mPhysicsSearchLOD >= LLModel::LOD_IMPOSTOR && mPhysicsSearchLOD <= LLModel::LOD_HIGH - && mLODFile[LLModel::LOD_PHYSICS].empty() && !mLODFromHighFile[LLModel::LOD_PHYSICS] - && (which_lod == -1 || which_lod == mPhysicsSearchLOD)) - { - mModel[LLModel::LOD_PHYSICS] = mModel[mPhysicsSearchLOD]; - mScene[LLModel::LOD_PHYSICS] = mScene[mPhysicsSearchLOD]; - mVertexBuffer[LLModel::LOD_PHYSICS].clear(); - } - // - dropFacesCopiesOfLostModels(); LL_INFOS("Upload") << "LOD " << which_lod << ", Mesh optimizer processed meshes : " << meshes_processed @@ -1960,7 +1960,9 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) } }; - // A suffixed model with no base is named as the loader always named it, without its suffix. + // A suffixed model with no base is named as the loader always named it, without its suffix. Models + // are found first, so every instance of one shared model takes the new name, not only the first. + std::set leftovers; for (auto& scene_pair : mScene[LLModel::LOD_HIGH]) { for (LLModelInstance& instance : scene_pair.second) @@ -1968,8 +1970,21 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) LLModel* model = instance.mModel; if (model && suffix_lod(core_of(model)) >= 0 && lod_of(model) < 0) { - model->mLabel = stripSuffix(core_of(model)) + letter_of(model); - instance.mLabel = model->mLabel; // a submodel keeps its letter, so it isn't taken for its root + leftovers.insert(model); + } + } + } + for (LLModel* model : leftovers) + { + model->mLabel = stripSuffix(core_of(model)) + letter_of(model); + } + for (auto& scene_pair : mScene[LLModel::LOD_HIGH]) + { + for (LLModelInstance& instance : scene_pair.second) + { + if (leftovers.count(instance.mModel)) + { + instance.mLabel = instance.mModel->mLabel; // a submodel keeps its letter, so it isn't taken for its root } } } @@ -2027,24 +2042,8 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) } } } - // Physics copied from a LOD follows that LOD when this file replaces it. - const S32 physics_from = mPhysicsSearchLOD; - auto follow_physics = [&]() - { - // A physics file of its own is left alone; only physics copied from that LOD follows it. A LOD - // released for generation is copied once generated (genMeshOptimizerLODs), not while empty here. - const bool own_physics_file = !mLODFile[LLModel::LOD_PHYSICS].empty() && !was_from_file[LLModel::LOD_PHYSICS]; - if (!own_physics_file && physics_from >= LLModel::LOD_IMPOSTOR && physics_from <= LLModel::LOD_HIGH - && split[physics_from]) - { - mModel[LLModel::LOD_PHYSICS] = mModel[physics_from]; - mScene[LLModel::LOD_PHYSICS] = mScene[physics_from]; - mVertexBuffer[LLModel::LOD_PHYSICS].clear(); - } - }; if (kept.size() == mModel[LLModel::LOD_HIGH].size()) { - follow_physics(); return; } mModel[LLModel::LOD_HIGH] = kept; @@ -2124,10 +2123,6 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) out << "Took " << mModel[lod].size() << " model(s) named " << getLodSuffix(lod) << " from the file for that slot"; LLFloaterModelPreview::addStringToLog(out, false); } - if (!split[LLModel::LOD_PHYSICS]) - { - follow_physics(); - } } // From abebcfcd395f8da25dafc32dd01b6b37711aa8b1 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 5 Nov 2026 04:57:11 +0000 Subject: [PATCH 32/32] Set the physics source to none when the high file stops supplying it A reloaded high file without _PHYS models emptied the physics slot but left the physics source on 'file', its file controls enabled. Co-Authored-By: Claude Opus 5.5 --- indra/newview/llmodelpreview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index c20dd520280..15e8467af0f 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1956,7 +1956,9 @@ void LLModelPreview::splitSuffixedModels(const std::string& filename) } else if (fmp) { + // Physics the high file no longer supplies is no longer from a file: back to none, as a reset leaves it. fmp->childSetValue("physics_file", ""); + fmp->childSetValue("physics_lod_combo", "none"); } };