diff --git a/.github/workflows/deploy_only.yml b/.github/workflows/deploy_only.yml
index 0923484f1d..47243942f8 100644
--- a/.github/workflows/deploy_only.yml
+++ b/.github/workflows/deploy_only.yml
@@ -45,7 +45,7 @@ jobs:
run: pip install discord-webhook
- name: Download Build Artifacts
- uses: dawidd6/action-download-artifact@v7
+ uses: dawidd6/action-download-artifact@v8
id: download
with:
workflow: build_viewer.yml
diff --git a/.github/workflows/sign.yml b/.github/workflows/sign.yml
index 6d98335165..6cf2b30f3f 100644
--- a/.github/workflows/sign.yml
+++ b/.github/workflows/sign.yml
@@ -41,7 +41,7 @@ jobs:
setup_files: ${{ steps.get-files.outputs.setup_files }}
steps:
- name: Download Build Artifacts
- uses: dawidd6/action-download-artifact@v7
+ uses: dawidd6/action-download-artifact@v8
id: download
with:
workflow: build_viewer.yml
diff --git a/.github/workflows/tag-fs-build.yml b/.github/workflows/tag-fs-build.yml
index 3a3c6a0f5c..2760619cba 100644
--- a/.github/workflows/tag-fs-build.yml
+++ b/.github/workflows/tag-fs-build.yml
@@ -71,7 +71,7 @@ jobs:
echo "build_run_number=${{ github.event.inputs.build_run_number }}" >> "$GITHUB_OUTPUT"
fi
- name: Download Build Artifacts
- uses: dawidd6/action-download-artifact@v7
+ uses: dawidd6/action-download-artifact@v8
id: download_build_info
with:
workflow: build_viewer.yml
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 9ae5dd1ceb..a32537357f 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1509,6 +1509,14 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("areaTex");
mReservedUniforms.push_back("searchTex");
mReservedUniforms.push_back("blendTex");
+ // reserved uniforms for snapshot frame
+ mReservedUniforms.push_back("border_color");
+ mReservedUniforms.push_back("border_thickness");
+ mReservedUniforms.push_back("guide_color");
+ mReservedUniforms.push_back("guide_thickness");
+ mReservedUniforms.push_back("guide_style");
+ mReservedUniforms.push_back("frame_rect");
+ //
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 0fb67ff3df..e672b07068 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -351,6 +351,14 @@ public:
SMAA_SEARCH_TEX, // "searchTex"
SMAA_BLEND_TEX, // "blendTex"
+ // Uniforms for snapshot frame
+ SNAPSHOT_BORDER_COLOR, // "border_color"
+ SNAPSHOT_BORDER_THICKNESS, // "border_thickness"
+ SNAPSHOT_GUIDE_COLOR, // "guide_color"
+ SNAPSHOT_GUIDE_THICKNESS, // "guide_thickness"
+ SNAPSHOT_GUIDE_STYLE, // "guide_style"
+ SNAPSHOT_FRAME_RECT, // "frame_rect"
+ //
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// clang-format on
diff --git a/indra/newview/ao.cpp b/indra/newview/ao.cpp
index 92c9c813e7..f0fb99875f 100644
--- a/indra/newview/ao.cpp
+++ b/indra/newview/ao.cpp
@@ -282,6 +282,10 @@ bool FloaterAO::postBuild()
mPreviousButtonSmall->setCommitCallback(boost::bind(&FloaterAO::onClickPrevious, this));
mNextButtonSmall->setCommitCallback(boost::bind(&FloaterAO::onClickNext, this));
+// Double click on animation in AO
+ mAnimationList->setDoubleClickCallback(boost::bind(&FloaterAO::onDoubleClick, this));
+//
+
updateSmart();
AOEngine::instance().setReloadCallback(boost::bind(&FloaterAO::updateList, this));
@@ -780,6 +784,40 @@ void FloaterAO::onClickNext()
AOEngine::instance().cycle(AOEngine::CycleNext);
}
+// Double click on animation in AO
+void FloaterAO::onDoubleClick()
+{
+ LLScrollListItem* item = mAnimationList->getFirstSelected();
+ if (!item)
+ {
+ return;
+ }
+ LLUUID* animUUID = (LLUUID*)item->getUserdata();
+ if (!animUUID)
+ {
+ return;
+ }
+
+ // do nothing if animation is for a different state than the active state
+ if (mSelectedState != AOEngine::instance().getCurrentState())
+ {
+ return;
+ }
+
+ // activate AO set if necessary
+ if (AOEngine::instance().getCurrentSet() != mSelectedSet)
+ {
+ // sync small set selector with main set selector
+ mSetSelectorSmall->selectNthItem(mSetSelector->getCurrentIndex());
+
+ LL_DEBUGS("AOEngine") << "Set activated: " << mSetSelector->getSelectedItemLabel() << LL_ENDL;
+ AOEngine::instance().selectSet(mSelectedSet);
+ }
+
+ AOEngine::instance().playAnimation(*animUUID);
+}
+//
+
void FloaterAO::onClickMore()
{
LLRect fullSize = gSavedPerAccountSettings.getRect("floater_rect_animation_overrider_full");
diff --git a/indra/newview/ao.h b/indra/newview/ao.h
index 1ef283d9c0..cadde5088c 100644
--- a/indra/newview/ao.h
+++ b/indra/newview/ao.h
@@ -91,6 +91,10 @@ class FloaterAO
void onClickMore();
void onClickLess();
+// Double click on animation in AO
+ void onDoubleClick();
+//
+
void onAnimationChanged(const LLUUID& animation);
void reloading(bool reload);
diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp
index 62141ef422..33f91d556a 100644
--- a/indra/newview/aoengine.cpp
+++ b/indra/newview/aoengine.cpp
@@ -960,6 +960,115 @@ void AOEngine::cycle(eCycleMode cycleMode)
}
}
+// Double click on animation in AO
+void AOEngine::playAnimation(const LLUUID& animation)
+{
+ if (!mEnabled)
+ {
+ return;
+ }
+
+ if (!mCurrentSet)
+ {
+ LL_DEBUGS("AOEngine") << "cycle without set." << LL_ENDL;
+ return;
+ }
+
+ // do not cycle if we're sitting and sit-override is off
+ if (mLastMotion == ANIM_AGENT_SIT && !mCurrentSet->getSitOverride())
+ {
+ return;
+ }
+ // do not cycle if we're standing and mouselook stand override is disabled while being in mouselook
+ else if (mLastMotion == ANIM_AGENT_STAND && mCurrentSet->getMouselookStandDisable() && mInMouselook)
+ {
+ return;
+ }
+
+ AOSet::AOState* state = mCurrentSet->getStateByRemapID(mLastMotion);
+ if (!state)
+ {
+ LL_DEBUGS("AOEngine") << "cycle without state." << LL_ENDL;
+ return;
+ }
+
+ if (!state->mAnimations.size())
+ {
+ LL_DEBUGS("AOEngine") << "cycle without animations in state." << LL_ENDL;
+ return;
+ }
+
+ LLViewerInventoryItem* item = gInventory.getItem(animation);
+ AOSet::AOAnimation anim;
+ anim.mName = item->LLInventoryItem::getName();
+ anim.mInventoryUUID = item->getUUID();
+ anim.mOriginalUUID = item->getLinkedUUID();
+ anim.mAssetUUID = LLUUID::null;
+
+ // if we can find the original animation already right here, save its asset ID, otherwise this will
+ // be tried again in AOSet::getAnimationForState() and/or AOEngine::cycle()
+ if (item->getLinkedItem())
+ {
+ anim.mAssetUUID = item->getAssetUUID();
+ }
+
+ LLUUID newAnimation = anim.mAssetUUID;
+ LLUUID oldAnimation = state->mCurrentAnimationID;
+
+ // don't do anything if the animation didn't change
+ if (newAnimation == oldAnimation)
+ {
+ return;
+ }
+
+ mAnimationChangedSignal(LLUUID::null);
+
+ // Searches for the index of the animation
+ U32 idx = -1;
+ for (U32 i = 0; i < state->mAnimations.size(); i++)
+ {
+ if (state->mAnimations[i].mAssetUUID == newAnimation)
+ {
+ idx = i;
+ break;
+ }
+ }
+ if (idx < 0)
+ {
+ idx = 0;
+ }
+
+ state->mCurrentAnimation = idx;
+ state->mCurrentAnimationID = newAnimation;
+ if (newAnimation.notNull())
+ {
+ LL_DEBUGS("AOEngine") << "requesting animation start for motion " << gAnimLibrary.animationName(mLastMotion) << ": " << newAnimation << LL_ENDL;
+ gAgent.sendAnimationRequest(newAnimation, ANIM_REQUEST_START);
+ mAnimationChangedSignal(state->mAnimations[state->mCurrentAnimation].mInventoryUUID);
+ }
+ else
+ {
+ LL_DEBUGS("AOEngine") << "overrider came back with NULL animation for motion " << gAnimLibrary.animationName(mLastMotion) << "." << LL_ENDL;
+ }
+
+ if (oldAnimation.notNull())
+ {
+ LL_DEBUGS("AOEngine") << "Cycling state " << state->mName << " - stopping animation " << oldAnimation << LL_ENDL;
+ gAgent.sendAnimationRequest(oldAnimation, ANIM_REQUEST_STOP);
+ gAgentAvatarp->LLCharacter::stopMotion(oldAnimation);
+ }
+}
+
+const AOSet* AOEngine::getCurrentSet() const
+{
+ return mCurrentSet;
+}
+const AOSet::AOState* AOEngine::getCurrentState() const
+{
+ return mCurrentSet->getStateByRemapID(mLastMotion);
+}
+//
+
void AOEngine::updateSortOrder(AOSet::AOState* state)
{
for (U32 index = 0; index < state->mAnimations.size(); ++index)
diff --git a/indra/newview/aoengine.h b/indra/newview/aoengine.h
index a381d00dd3..438fe217b9 100644
--- a/indra/newview/aoengine.h
+++ b/indra/newview/aoengine.h
@@ -123,6 +123,12 @@ class AOEngine
void cycleTimeout(const AOSet* set);
void cycle(eCycleMode cycleMode);
+// Double click on animation in AO
+ void playAnimation(const LLUUID& animation);
+ const AOSet* getCurrentSet() const;
+ const AOSet::AOState* getCurrentState() const;
+//
+
void inMouselook(bool mouselook);
void selectSet(AOSet* set);
AOSet* selectSetByName(const std::string& name);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 71b5918270..fb7f6a124b 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -26124,5 +26124,68 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
0
+ FSSnapshotShowCaptureFrame
+
+ FSSnapshotFrameBorderColor
+
+ FSSnapshotFrameGuideColor
+
+ FSSnapshotFrameBorderWidth
+
+ FSSnapshotFrameGuideWidth
+
diff --git a/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl b/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl
new file mode 100644
index 0000000000..3f76193610
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl
@@ -0,0 +1,78 @@
+#extension GL_ARB_texture_rectangle : enable
+
+out vec4 frag_color;
+
+uniform sampler2D diffuseRect;
+uniform vec2 screen_res;
+uniform vec4 frame_rect; // x, y, width, height (normalized 0->1)
+uniform vec3 border_color;
+uniform float border_thickness; // in pixels
+uniform vec3 guide_color;
+uniform float guide_thickness; // in pixels
+uniform float guide_style; // 0: no guide, 1: rule of thirds, 2: golden spiral
+
+in vec2 vary_fragcoord;
+
+void main()
+{
+ vec4 diff = texture(diffuseRect, vary_fragcoord);
+ vec2 tc = vary_fragcoord * screen_res;
+
+ // Convert normalized frame_rect to pixel values
+ vec4 frame_rect_px = vec4(frame_rect.x * screen_res.x, frame_rect.y * screen_res.y, frame_rect.z * screen_res.x, frame_rect.w * screen_res.y);
+ vec4 border_rect_px = vec4(
+ (frame_rect.x * screen_res.x) - border_thickness,
+ (frame_rect.y * screen_res.y) - border_thickness,
+ (frame_rect.z * screen_res.x) + border_thickness,
+ (frame_rect.w * screen_res.y) + border_thickness);
+
+ // Desaturate fragments outside the snapshot frame
+ if (tc.x < border_rect_px.x || tc.x > border_rect_px.z ||
+ tc.y < border_rect_px.y || tc.y > border_rect_px.w)
+ {
+ // Simple box blur
+ vec3 blur_color = vec3(0.0);
+ float blur_size = 2;
+ int blur_samples = 9;
+
+ for (int x = -1; x <= 1; ++x)
+ {
+ for (int y = -1; y <= 1; ++y)
+ {
+ vec2 offset = vec2(x, y) * blur_size / screen_res;
+ blur_color += texture(diffuseRect, vary_fragcoord + offset).rgb;
+ }
+ }
+
+ blur_color /= float(blur_samples);
+ float gray = dot(blur_color, vec3(0.299, 0.587, 0.114));
+ diff.rgb = vec3(gray);
+ }
+ else
+ {
+ // Draw border around the snapshot frame
+ if ((tc.x >= border_rect_px.x && tc.x < frame_rect_px.x) ||
+ (tc.x <= border_rect_px.z && tc.x > frame_rect_px.z) ||
+ (tc.y >= border_rect_px.y && tc.y < frame_rect_px.y) ||
+ (tc.y <= border_rect_px.w && tc.y > frame_rect_px.w))
+ {
+ diff.rgb = mix(diff.rgb, border_color, 0.5);
+ }
+
+ // Draw guide based on guide_style
+ if (guide_style == 1)
+ {
+ // Draw rule of thirds guide
+ float third_x = (frame_rect_px.z - frame_rect_px.x) / 3.0;
+ float third_y = (frame_rect_px.w - frame_rect_px.y) / 3.0;
+ if ((tc.x > frame_rect_px.x + third_x - guide_thickness && tc.x < frame_rect_px.x + third_x + guide_thickness) ||
+ (tc.x > frame_rect_px.x + 2.0 * third_x - guide_thickness && tc.x < frame_rect_px.x + 2.0 * third_x + guide_thickness) ||
+ (tc.y > frame_rect_px.y + third_y - guide_thickness && tc.y < frame_rect_px.y + third_y + guide_thickness) ||
+ (tc.y > frame_rect_px.y + 2.0 * third_y - guide_thickness && tc.y < frame_rect_px.y + 2.0 * third_y + guide_thickness))
+ {
+ diff.rgb = mix(diff.rgb, guide_color, 0.05);
+ }
+ }
+ }
+ frag_color = diff;
+}
\ No newline at end of file
diff --git a/indra/newview/fsfloaterposer.cpp b/indra/newview/fsfloaterposer.cpp
index b90705a31d..eba653938d 100644
--- a/indra/newview/fsfloaterposer.cpp
+++ b/indra/newview/fsfloaterposer.cpp
@@ -105,6 +105,9 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
mCommitCallbackRegistrar.add("Poser.RecaptureSelectedBones", [this](LLUICtrl*, const LLSD&) { onClickRecaptureSelectedBones(); });
mCommitCallbackRegistrar.add("Poser.TogglePosingSelectedBones", [this](LLUICtrl*, const LLSD&) { onClickToggleSelectedBoneEnabled(); });
mCommitCallbackRegistrar.add("Poser.PoseJointsReset", [this](LLUICtrl*, const LLSD&) { onPoseJointsReset(); });
+
+ //mCommitCallbackRegistrar.add("Poser.CommitSpinner", [this](LLUICtrl* spinnerControl, const LLSD&) { onCommitSpinner(spinnerControl); });
+ mCommitCallbackRegistrar.add("Poser.CommitSpinner", boost::bind(&FSFloaterPoser::onCommitSpinner, this, _1, _2));
}
bool FSFloaterPoser::postBuild()
@@ -164,7 +167,6 @@ bool FSFloaterPoser::postBuild()
mToggleAdvancedPanelBtn->setValue(true);
mTrackpadSensitivitySlider = getChild("trackpad_sensitivity_slider");
- mTrackpadSensitivitySlider->setValue(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY));
mPoseSaveNameEditor = getChild("pose_save_name");
mPoseSaveNameEditor->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe);
@@ -216,6 +218,20 @@ bool FSFloaterPoser::postBuild()
mResetBaseRotCbx = getChild("reset_base_rotation_on_edit_checkbox");
mResetBaseRotCbx->setCommitCallback([this](LLUICtrl*, const LLSD&) { onClickSetBaseRotZero(); });
+ mTrackpadSensitivitySpnr = getChild("trackpad_sensitivity_spinner");
+ mYawSpnr = getChild("limb_yaw_spinner");
+ mPitchSpnr = getChild("limb_pitch_spinner");
+ mRollSpnr = getChild("limb_roll_spinner");
+ mUpDownSpnr = getChild("av_position_updown_spinner");
+ mLeftRightSpnr = getChild("av_position_leftright_spinner");
+ mInOutSpnr = getChild("av_position_inout_spinner");
+ mAdvPosXSpnr = getChild("adv_posx_spinner");
+ mAdvPosYSpnr = getChild("adv_posy_spinner");
+ mAdvPosZSpnr = getChild("adv_posz_spinner");
+ mScaleXSpnr = getChild("adv_scalex_spinner");
+ mScaleYSpnr = getChild("adv_scaley_spinner");
+ mScaleZSpnr = getChild("adv_scalez_spinner");
+
return true;
}
@@ -238,7 +254,7 @@ void FSFloaterPoser::onClose(bool app_quitting)
gSavedSettings.setBOOL(POSER_ADVANCEDWINDOWSTATE_SAVE_KEY, mToggleAdvancedPanelBtn->getValue().asBoolean());
if (gSavedSettings.getBOOL(POSER_STOPPOSINGWHENCLOSED_SAVE_KEY))
- stopPosingSelf();
+ stopPosingAllAvatars();
LLFloater::onClose(app_quitting);
}
@@ -467,7 +483,7 @@ void FSFloaterPoser::onClickToggleSelectedBoneEnabled()
mPoserAnimator.setPosingAvatarJoint(avatar, *item, !currentlyPosing);
}
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
refreshTextHighlightingOnJointScrollLists();
}
@@ -511,7 +527,7 @@ void FSFloaterPoser::onClickFlipSelectedJoints()
mPoserAnimator.reflectJoint(avatar, item);
}
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
}
@@ -526,7 +542,7 @@ void FSFloaterPoser::onClickFlipPose()
mPoserAnimator.flipEntirePose(avatar);
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
}
@@ -553,7 +569,7 @@ void FSFloaterPoser::onClickRecaptureSelectedBones()
}
setSavePosesButtonText(true);
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
refreshTextHighlightingOnJointScrollLists();
}
@@ -566,6 +582,114 @@ void FSFloaterPoser::onClickBrowsePoseCache()
gViewerWindow->getWindow()->openFile(pathname);
}
+//void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner)
+// Pass in an ID as a parameter, so you can use a switch statement
+void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id)
+{
+ if (!spinner)
+ return;
+
+ auto activeTab = mJointsTabs->getCurrentPanel();
+ if (!activeTab)
+ return;
+
+ bool changingBodyPosition = activeTab == mPositionRotationPnl;
+
+ F32 value = (F32)spinner->getValue().asReal();
+
+ // Use the ID passed in to perform a switch statment
+ // which should make each action take the same amount of time.
+ switch (id)
+ {
+ case 0: // av_position_updown_spinner
+ {
+ mPosZSlider->setValue(value);
+ onAvatarPositionSet();
+ break;
+ }
+ case 1: // av_position_leftright
+ {
+ mPosYSlider->setValue(value);
+ onAvatarPositionSet();
+ break;
+ }
+ case 2: // av_position_inout_spinner
+ {
+ mPosXSlider->setValue(value);
+ onAvatarPositionSet();
+ break;
+ }
+ case 3: // trackpad_sensitivity_spinner
+ {
+ onAdjustTrackpadSensitivity();
+ break;
+ }
+ case 4: // limb_pitch_spinner
+ {
+ mLimbPitchSlider->setValue(value);
+ onYawPitchRollSliderChanged();
+ break;
+ }
+ case 5: // limb_yaw_spinner
+ {
+ mLimbYawSlider->setValue(value);
+ onYawPitchRollSliderChanged();
+ break;
+ }
+ case 6: // limb_roll_spinner
+ {
+ mLimbRollSlider->setValue(value);
+ onYawPitchRollSliderChanged();
+ break;
+ }
+ case 7: // adv_posx_spinner
+ {
+ if (changingBodyPosition)
+ mPosXSlider->setValue(value);
+
+ mAdvPosXSlider->setValue(value);
+ onAdvancedPositionSet();
+ break;
+ }
+ case 8: // adv_posy_spinner
+ {
+ if (changingBodyPosition)
+ mPosYSlider->setValue(value);
+
+ mAdvPosYSlider->setValue(value);
+ onAdvancedPositionSet();
+ break;
+ }
+ case 9: // adv_posz_spinner
+ {
+ if (changingBodyPosition)
+ mPosZSlider->setValue(value);
+
+ mAdvPosZSlider->setValue(value);
+ onAdvancedPositionSet();
+ break;
+ }
+ case 10: // adv_scalex_spinner
+ {
+ mAdvScaleXSlider->setValue(value);
+ onAdvancedScaleSet();
+ break;
+ }
+ case 11: // adv_scaley_spinner
+ {
+ mAdvScaleYSlider->setValue(value);
+ onAdvancedScaleSet();
+ break;
+ }
+ case 12: // adv_scalez_spinner
+ {
+ mAdvScaleZSlider->setValue(value);
+ onAdvancedScaleSet();
+ break;
+ }
+ }
+}
+
void FSFloaterPoser::onPoseJointsReset()
{
if (notDoubleClicked())
@@ -589,9 +713,9 @@ void FSFloaterPoser::onPoseJointsReset()
mPoserAnimator.resetAvatarJoint(avatar, *item);
}
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
- refreshAvatarPositionSliders();
+ refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onPoseMenuAction(const LLSD& param)
@@ -892,20 +1016,24 @@ void FSFloaterPoser::startPosingSelf()
onAvatarSelect();
}
-void FSFloaterPoser::stopPosingSelf()
+void FSFloaterPoser::stopPosingAllAvatars()
{
if (!gAgentAvatarp || gAgentAvatarp.isNull())
return;
- LLVOAvatar* avatar = getAvatarByUuid(gAgentAvatarp->getID());
- if (!avatar)
- return;
+ for (auto listItem : mAvatarSelectionScrollList->getAllData())
+ {
+ LLScrollListCell* cell = listItem->getColumn(COL_UUID);
+ if (!cell)
+ continue;
- bool arePosingSelected = mPoserAnimator.isPosingAvatar(avatar);
- if (!arePosingSelected)
- return;
+ LLUUID selectedAvatarId = cell->getValue().asUUID();
+ LLVOAvatar* listAvatar = getAvatarByUuid(selectedAvatarId);
+
+ if (mPoserAnimator.isPosingAvatar(listAvatar))
+ mPoserAnimator.stopPosingAvatar(listAvatar);
+ }
- mPoserAnimator.stopPosingAvatar(avatar);
onAvatarSelect();
}
@@ -1145,7 +1273,7 @@ void FSFloaterPoser::onUndoLastRotation()
}
enableOrDisableRedoButton();
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
}
@@ -1169,8 +1297,8 @@ void FSFloaterPoser::onUndoLastPosition()
mPoserAnimator.undoLastJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedPositionSliders();
- refreshAvatarPositionSliders();
+ refreshAdvancedPositionSlidersAndSpinners();
+ refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onUndoLastScale()
@@ -1193,7 +1321,7 @@ void FSFloaterPoser::onUndoLastScale()
mPoserAnimator.undoLastJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedScaleSliders();
+ refreshAdvancedScaleSlidersAndSpinners();
}
void FSFloaterPoser::onSetAvatarToTpose()
@@ -1233,8 +1361,8 @@ void FSFloaterPoser::onResetPosition()
mPoserAnimator.resetJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedPositionSliders();
- refreshAvatarPositionSliders();
+ refreshAdvancedPositionSlidersAndSpinners();
+ refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onResetScale()
@@ -1260,7 +1388,7 @@ void FSFloaterPoser::onResetScale()
mPoserAnimator.resetJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedScaleSliders();
+ refreshAdvancedScaleSlidersAndSpinners();
}
void FSFloaterPoser::onRedoLastRotation()
@@ -1284,7 +1412,7 @@ void FSFloaterPoser::onRedoLastRotation()
}
enableOrDisableRedoButton();
- refreshRotationSliders();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
}
@@ -1308,8 +1436,8 @@ void FSFloaterPoser::onRedoLastPosition()
mPoserAnimator.redoLastJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedPositionSliders();
- refreshAvatarPositionSliders();
+ refreshAdvancedPositionSlidersAndSpinners();
+ refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onRedoLastScale()
@@ -1332,7 +1460,7 @@ void FSFloaterPoser::onRedoLastScale()
mPoserAnimator.redoLastJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
- refreshAdvancedScaleSliders();
+ refreshAdvancedScaleSlidersAndSpinners();
}
void FSFloaterPoser::enableOrDisableRedoButton()
@@ -1565,8 +1693,15 @@ void FSFloaterPoser::onAdvancedPositionSet()
F32 posY = mAdvPosYSlider->getValueF32();
F32 posZ = mAdvPosZSlider->getValueF32();
+ mAdvPosXSpnr->setValue(posX);
+ mInOutSpnr->setValue(posX);
+ mAdvPosYSpnr->setValue(posY);
+ mLeftRightSpnr->setValue(posY);
+ mAdvPosZSpnr->setValue(posZ);
+ mUpDownSpnr->setValue(posZ);
+
setSelectedJointsPosition(posX, posY, posZ);
- refreshAvatarPositionSliders();
+ refreshAvatarPositionSlidersAndSpinners();
}
void FSFloaterPoser::onAdvancedScaleSet()
@@ -1575,6 +1710,10 @@ void FSFloaterPoser::onAdvancedScaleSet()
F32 scY = mAdvScaleYSlider->getValueF32();
F32 scZ = mAdvScaleZSlider->getValueF32();
+ mScaleXSpnr->setValue(scX);
+ mScaleYSpnr->setValue(scY);
+ mScaleZSpnr->setValue(scZ);
+
setSelectedJointsScale(scX, scY, scZ);
}
@@ -1584,8 +1723,15 @@ void FSFloaterPoser::onAvatarPositionSet()
F32 posY = mPosYSlider->getValueF32();
F32 posZ = mPosZSlider->getValueF32();
+ mAdvPosXSpnr->setValue(posX);
+ mInOutSpnr->setValue(posX);
+ mAdvPosYSpnr->setValue(posY);
+ mLeftRightSpnr->setValue(posY);
+ mAdvPosZSpnr->setValue(posZ);
+ mUpDownSpnr->setValue(posZ);
+
setSelectedJointsPosition(posX, posY, posZ);
- refreshAdvancedPositionSliders();
+ refreshAdvancedPositionSlidersAndSpinners();
}
void FSFloaterPoser::onLimbTrackballChanged()
@@ -1624,6 +1770,10 @@ void FSFloaterPoser::onLimbTrackballChanged()
mLimbYawSlider->setValue(trackPadPos.mV[VX] *= RAD_TO_DEG);
mLimbPitchSlider->setValue(trackPadPos.mV[VY] *= RAD_TO_DEG);
mLimbRollSlider->setValue(trackPadPos.mV[VZ] *= RAD_TO_DEG);
+
+ mYawSpnr->setValue(mLimbYawSlider->getValueF32());
+ mPitchSpnr->setValue(mLimbPitchSlider->getValueF32());
+ mRollSpnr->setValue(mLimbRollSlider->getValueF32());
}
F32 FSFloaterPoser::unWrapScale(F32 scale)
@@ -1665,11 +1815,14 @@ void FSFloaterPoser::onYawPitchRollSliderChanged()
absoluteRotation.mV[VZ] /= NormalTrackpadRangeInRads;
mAvatarTrackball->setValue(absoluteRotation.getValue());
+
+ mYawSpnr->setValue(mLimbYawSlider->getValueF32());
+ mPitchSpnr->setValue(mLimbPitchSlider->getValueF32());
+ mRollSpnr->setValue(mLimbRollSlider->getValueF32());
}
void FSFloaterPoser::onAdjustTrackpadSensitivity()
{
- gSavedSettings.setF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY, mTrackpadSensitivitySlider->getValueF32());
refreshTrackpadCursor();
}
@@ -1689,7 +1842,7 @@ void FSFloaterPoser::refreshTrackpadCursor()
///
/// This only sets the position sliders of the 'basic' view (not the advanced sliders).
///
-void FSFloaterPoser::refreshAvatarPositionSliders()
+void FSFloaterPoser::refreshAvatarPositionSlidersAndSpinners()
{
auto activeTab = mJointsTabs->getCurrentPanel();
if (!activeTab)
@@ -1700,36 +1853,48 @@ void FSFloaterPoser::refreshAvatarPositionSliders()
LLVector3 position = getPositionOfFirstSelectedJoint();
mPosXSlider->setValue(position.mV[VX]);
+ mInOutSpnr->setValue(position.mV[VX]);
mPosYSlider->setValue(position.mV[VY]);
+ mLeftRightSpnr->setValue(position.mV[VY]);
mPosZSlider->setValue(position.mV[VZ]);
+ mUpDownSpnr->setValue(position.mV[VZ]);
}
-void FSFloaterPoser::refreshRotationSliders()
+void FSFloaterPoser::refreshRotationSlidersAndSpinners()
{
LLVector3 rotation = getRotationOfFirstSelectedJoint();
mLastSliderRotation = rotation;
mLimbYawSlider->setValue(rotation.mV[VX] *= RAD_TO_DEG);
+ mYawSpnr->setValue(rotation.mV[VX]);
mLimbPitchSlider->setValue(rotation.mV[VY] *= RAD_TO_DEG);
+ mPitchSpnr->setValue(rotation.mV[VY]);
mLimbRollSlider->setValue(rotation.mV[VZ] *= RAD_TO_DEG);
+ mRollSpnr->setValue(rotation.mV[VZ]);
}
-void FSFloaterPoser::refreshAdvancedPositionSliders()
+void FSFloaterPoser::refreshAdvancedPositionSlidersAndSpinners()
{
LLVector3 position = getPositionOfFirstSelectedJoint();
mAdvPosXSlider->setValue(position.mV[VX]);
+ mAdvPosXSpnr->setValue(position.mV[VX]);
mAdvPosYSlider->setValue(position.mV[VY]);
+ mAdvPosYSpnr->setValue(position.mV[VY]);
mAdvPosZSlider->setValue(position.mV[VZ]);
+ mAdvPosZSpnr->setValue(position.mV[VZ]);
}
-void FSFloaterPoser::refreshAdvancedScaleSliders()
+void FSFloaterPoser::refreshAdvancedScaleSlidersAndSpinners()
{
LLVector3 rotation = getScaleOfFirstSelectedJoint();
mAdvScaleXSlider->setValue(rotation.mV[VX]);
+ mScaleXSpnr->setValue(rotation.mV[VX]);
mAdvScaleYSlider->setValue(rotation.mV[VY]);
+ mScaleYSpnr->setValue(rotation.mV[VY]);
mAdvScaleZSlider->setValue(rotation.mV[VZ]);
+ mScaleZSpnr->setValue(rotation.mV[VZ]);
}
void FSFloaterPoser::setSelectedJointsPosition(F32 x, F32 y, F32 z)
@@ -1873,16 +2038,16 @@ LLVector3 FSFloaterPoser::getScaleOfFirstSelectedJoint() const
void FSFloaterPoser::onJointTabSelect()
{
- refreshAvatarPositionSliders();
- refreshRotationSliders();
+ refreshAvatarPositionSlidersAndSpinners();
+ refreshRotationSlidersAndSpinners();
refreshTrackpadCursor();
enableOrDisableRedoButton();
onClickSetBaseRotZero();
if (mToggleAdvancedPanelBtn->getValue().asBoolean())
{
- refreshAdvancedPositionSliders();
- refreshAdvancedScaleSliders();
+ refreshAdvancedPositionSlidersAndSpinners();
+ refreshAdvancedScaleSlidersAndSpinners();
}
}
@@ -2074,7 +2239,7 @@ void FSFloaterPoser::onAvatarsRefresh()
LLAvatarName av_name;
std::string animeshName = getControlAvatarName(avatar);
if (animeshName.empty())
- animeshName = avatar->getFullname();
+ continue;
LLSD row;
row["columns"][COL_ICON]["column"] = "icon";
@@ -2109,6 +2274,9 @@ std::string FSFloaterPoser::getControlAvatarName(const LLControlAvatar* avatar)
if (attachedItem)
return attachedItem->getName();
+ if (rootEditObject->permYouOwner())
+ return avatar->getFullname();
+
return "";
}
@@ -2146,24 +2314,6 @@ void FSFloaterPoser::setSavePosesButtonText(bool setAsSaveDiff)
setAsSaveDiff ? mSavePosesBtn->setLabel("Save Diff") : mSavePosesBtn->setLabel("Save Pose");
}
-bool FSFloaterPoser::posingAnyoneOnScrollList()
-{
- for (auto listItem : mAvatarSelectionScrollList->getAllData())
- {
- LLScrollListCell* cell = listItem->getColumn(COL_UUID);
- if (!cell)
- continue;
-
- LLUUID selectedAvatarId = cell->getValue().asUUID();
- LLVOAvatar* listAvatar = getAvatarByUuid(selectedAvatarId);
-
- if (mPoserAnimator.isPosingAvatar(listAvatar))
- return true;
- }
-
- return false;
-}
-
void FSFloaterPoser::addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar)
{
if (!avatar)
diff --git a/indra/newview/fsfloaterposer.h b/indra/newview/fsfloaterposer.h
index f847fb587a..bd8e4c09db 100644
--- a/indra/newview/fsfloaterposer.h
+++ b/indra/newview/fsfloaterposer.h
@@ -236,7 +236,7 @@ class FSFloaterPoser : public LLFloater
void enableOrDisableRedoButton();
void onPoseStartStop();
void startPosingSelf();
- void stopPosingSelf();
+ void stopPosingAllAvatars();
void onLimbTrackballChanged();
void onYawPitchRollSliderChanged();
void onAvatarPositionSet();
@@ -253,13 +253,15 @@ class FSFloaterPoser : public LLFloater
void onClickLoadRightHandPose();
void onClickLoadHandPose(bool isRightHand);
void onClickSetBaseRotZero();
+ //void onCommitSpinner(LLUICtrl* spinner);
+ void onCommitSpinner(LLUICtrl* spinner, S32 ID);
// UI Refreshments
- void refreshRotationSliders();
- void refreshAvatarPositionSliders();
+ void refreshRotationSlidersAndSpinners();
+ void refreshAvatarPositionSlidersAndSpinners();
void refreshTrackpadCursor();
- void refreshAdvancedPositionSliders();
- void refreshAdvancedScaleSliders();
+ void refreshAdvancedPositionSlidersAndSpinners();
+ void refreshAdvancedScaleSlidersAndSpinners();
///
/// Determines if we have permission to animate the supplied avatar.
@@ -328,11 +330,6 @@ class FSFloaterPoser : public LLFloater
/// Whether to indicate a diff will be saved, instead of a pose.
void setSavePosesButtonText(bool setAsSaveDiff);
- ///
- /// Gets whether any avatar know by the UI is being posed.
- ///
- bool posingAnyoneOnScrollList();
-
///
/// Applies the appropriate font-face (such as bold) to the text of the supplied list, to indicate use.
///
@@ -501,6 +498,20 @@ class FSFloaterPoser : public LLFloater
LLCheckBoxCtrl* mResetBaseRotCbx{ nullptr };
LLCheckBoxCtrl* mAlsoSaveBvhCbx{ nullptr };
+
+ LLUICtrl* mTrackpadSensitivitySpnr{ nullptr };
+ LLUICtrl* mYawSpnr{ nullptr };
+ LLUICtrl* mPitchSpnr{ nullptr };
+ LLUICtrl* mRollSpnr{ nullptr };
+ LLUICtrl* mUpDownSpnr{ nullptr };
+ LLUICtrl* mLeftRightSpnr{ nullptr };
+ LLUICtrl* mInOutSpnr{ nullptr };
+ LLUICtrl* mAdvPosXSpnr{ nullptr };
+ LLUICtrl* mAdvPosYSpnr{ nullptr };
+ LLUICtrl* mAdvPosZSpnr{ nullptr };
+ LLUICtrl* mScaleXSpnr{ nullptr };
+ LLUICtrl* mScaleYSpnr{ nullptr };
+ LLUICtrl* mScaleZSpnr{ nullptr };
};
#endif
diff --git a/indra/newview/installers/darwin/apple-notarize.sh b/indra/newview/installers/darwin/apple-notarize.sh
index c8ff10df5c..edaeb95896 100755
--- a/indra/newview/installers/darwin/apple-notarize.sh
+++ b/indra/newview/installers/darwin/apple-notarize.sh
@@ -28,11 +28,35 @@ if [[ -f "$CONFIG_FILE" ]]; then
echo "Notarized with id: [$match]"
else
echo "No match found"
+ exit 1
fi
- # if [[ ! $match -eq 0 ]]; then
- echo "Running Stapler"
- xcrun stapler staple "$app_file"
+ # --- WAIT / RETRY LOGIC FOR STAPLER ---
+ # Try stapler up to 5 times with a 5-second delay in between attempts
+ max_attempts=5
+ sleep_seconds=5
+ attempt=1
+
+ while [[ $attempt -le $max_attempts ]]; do
+ echo "Running stapler (attempt $attempt of $max_attempts)..."
+ xcrun stapler staple "$app_file"
+ ret=$?
+
+ if [[ $ret -eq 0 ]]; then
+ echo "Stapling succeeded on attempt $attempt"
+ break
+ else
+ if [[ $attempt -lt $max_attempts ]]; then
+ echo "Stapling failed (Error $ret). Waiting $sleep_seconds seconds before retry..."
+ sleep $sleep_seconds
+ else
+ echo "Stapling failed after $max_attempts attempts, giving up."
+ exit 65
+ fi
+ fi
+ attempt=$((attempt + 1))
+ done
+
# Delete the zip file to stop it being packed in the dmg
rm -f "$zip_file"
if [[ $? -eq 0 ]]; then
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index f514a937eb..332c1c689c 100755
Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index eb3f7c3109..39e5ea7af3 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -103,6 +103,10 @@ echo "LIBGL_DRIVERS_PATH is ${LIBGL_DRIVERS_PATH}"
if [ "$GTK_IM_MODULE" = "scim" ]; then
export GTK_IM_MODULE=xim
fi
+if [ "$XMODIFIERS" = "" ]; then
+ ## IME is valid only for fcitx, not when using ibus
+ export XMODIFIERS="@im=fcitx"
+fi
## - Automatically work around the ATI mouse cursor crash bug:
## (this workaround is disabled as most fglrx users do not see the bug)
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index a9c740eec5..3feb484135 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1098,15 +1098,20 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
const LLWearableType::EType type = new_wearable->getType();
// BOM fallback legacy opensim
- if(!gAgent.getRegion()->bakesOnMeshEnabled())
+ #ifdef OPENSIM
+ if (!LLGridManager::getInstance()->isInSecondLife())
{
- if(type == LLWearableType::WT_UNIVERSAL)
+ if(!gAgent.getRegion()->bakesOnMeshEnabled())
{
- LL_DEBUGS("Avatar") << "Universal wearable not supported on this region - ignoring." << LL_ENDL;
- mismatched++;
- continue;
+ if(type == LLWearableType::WT_UNIVERSAL)
+ {
+ LL_DEBUGS("Avatar") << "Universal wearable not supported on this region - ignoring." << LL_ENDL;
+ mismatched++;
+ continue;
+ }
}
}
+ #endif
//
if (type < 0 || type>=LLWearableType::WT_COUNT)
{
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
index 2c6cca1a68..64d0c9c935 100644
--- a/indra/newview/llfloaterflickr.cpp
+++ b/indra/newview/llfloaterflickr.cpp
@@ -966,3 +966,13 @@ void LLFloaterFlickr::onOpen(const LLSD& key)
mFlickrPhotoPanel->onOpen(key);
}
//
+// Add snapshot frame support to flickr
+LLSnapshotLivePreview* LLFloaterFlickr::getPreviewView()
+{
+ if(mFlickrPhotoPanel)
+ {
+ return mFlickrPhotoPanel->getPreviewView();
+ }
+ return nullptr;
+}
+//
\ No newline at end of file
diff --git a/indra/newview/llfloaterflickr.h b/indra/newview/llfloaterflickr.h
index 400674f390..e0579ba870 100644
--- a/indra/newview/llfloaterflickr.h
+++ b/indra/newview/llfloaterflickr.h
@@ -134,6 +134,7 @@ public:
// Exodus' flickr upload
void onOpen(const LLSD& key);
+ LLSnapshotLivePreview* getPreviewView(); // Required for snapshot frame rendering
private:
LLFlickrPhotoPanel* mFlickrPhotoPanel;
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 0354021776..752a19b7c7 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1480,12 +1480,14 @@ bool LLFloaterSnapshot::isWaitingState()
return (impl->getStatus() == ImplBase::STATUS_WORKING);
}
-bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
+// FIRE-35002 - Post to flickr broken, improved solution
+// bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
+bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized, bool have_flickr)
+//
{
// Share to Flickr
//if (!initialized)
- LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance("flickr");
- if (!initialized && !floater_flickr)
+ if (!initialized && !have_flickr)
//
return false;
@@ -1504,8 +1506,11 @@ void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
{
// don't update preview for hidden floater
// FIRE-35002 - Post to flickr broken
- // if (mFloater && mFloater->isInVisibleChain() && ImplBase::updatePreviewList(true))
- if (ImplBase::updatePreviewList(true) && mFloater)
+ LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance("flickr");
+ auto have_flickr = floater_flickr != nullptr;
+ if ( ((mFloater && mFloater->isInVisibleChain()) ||
+ have_flickr) &&
+ ImplBase::updatePreviewList(true, have_flickr))
//
{
LL_DEBUGS() << "changed" << LL_ENDL;
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index c90f9a3e3c..1fc101848c 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -122,7 +122,7 @@ public:
virtual EStatus getStatus() const { return mStatus; }
virtual void setNeedRefresh(bool need);
- static bool updatePreviewList(bool initialized);
+ static bool updatePreviewList(bool initialized, bool have_flickr = false); // FIRE-35002 - Post to flickr broken, improved solution
void setAdvanced(bool advanced) { mAdvanced = advanced; }
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index ddd3893bc4..fa1f800952 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -129,16 +129,12 @@ void LLHUDText::render()
// If the current text object is highighed and the use hover highlight feature is enabled, then
// disable writing to the depth buffer
static LLCachedControl mbUseHoverHighlight(gSavedSettings, "FSHudTextUseHoverHighlight");
- if (mbUseHoverHighlight && mbIsHighlighted)
- {
- LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
- }
- //Else, use the standard method of writing to the depth buffer for all other non-highlighted text objects
- else
- {
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- }
- // [FIRE-35019]
+ // [FIRE-35102] - Hover text appearing through walls in Beta 7.1.12.7737
+ // So it turns out when the LLGLDepthTest object goes out of scope, it reverts back
+ // to the previous state. So by having the LLGLDepthTest in the if statements, they were
+ // never applied.
+ LLGLDepthTest gls_depth(mbUseHoverHighlight && mbIsHighlighted ? GL_FALSE : GL_TRUE, GL_FALSE);
+ // [FIRE-35019] [FIRE-35102]
//LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText();
}
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index bec3cd181b..be87303f36 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -3978,7 +3978,7 @@ bool LLViewerRegion::meshUploadEnabled() const
bool LLViewerRegion::bakesOnMeshEnabled() const
{
- return (mSimulatorFeatures.has("BakesOnMeshEnabled") &&
+ return (mSimulatorFeaturesReceived && mSimulatorFeatures.has("BakesOnMeshEnabled") && // FIRE-35111 (bugsplat) checking bakes on mesh feature before features received.
mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 9b845cc6a1..983ae58df1 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -137,6 +137,7 @@ LLGLSLShader gGlowProgram;
LLGLSLShader gGlowExtractProgram;
LLGLSLShader gPostScreenSpaceReflectionProgram;
LLGLSLShader gPostVignetteProgram; // Import Vignette from Exodus
+LLGLSLShader gPostSnapshotFrameProgram; // Add Snapshot frame guide
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram;
@@ -1033,6 +1034,7 @@ bool LLViewerShaderMgr::loadShadersEffects()
gGlowProgram.unload();
gGlowExtractProgram.unload();
gPostVignetteProgram.unload(); // Import Vignette from Exodus
+ gPostSnapshotFrameProgram.unload(); // Add Snapshot framing shader
return true;
}
@@ -1084,6 +1086,17 @@ bool LLViewerShaderMgr::loadShadersEffects()
success = gPostVignetteProgram.createShader();
}
//
+// Add Snapshot framing shader
+ if (success)
+ {
+ gPostSnapshotFrameProgram.mName = "Snapshot Frame Post";
+ gPostSnapshotFrameProgram.mShaderFiles.clear();
+ gPostSnapshotFrameProgram.mShaderFiles.push_back(make_pair("post/exoPostBaseV.glsl", GL_VERTEX_SHADER));
+ gPostSnapshotFrameProgram.mShaderFiles.push_back(make_pair("post/snapshotFrameF.glsl", GL_FRAGMENT_SHADER));
+ gPostSnapshotFrameProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+ success = gPostSnapshotFrameProgram.createShader();
+ }
+//
return success;
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 8dca7c7622..f10fd9b3c1 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -214,6 +214,7 @@ extern LLGLSLShader gImpostorProgram;
// Post Process Shaders
extern LLGLSLShader gPostScreenSpaceReflectionProgram;
extern LLGLSLShader gPostVignetteProgram; // Import Vignette from Exodus
+extern LLGLSLShader gPostSnapshotFrameProgram; // Snapshot Frame overlay
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2e0db84afd..1b938944b4 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -109,6 +109,9 @@
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloatertools.h"
+#include "llfloatersnapshot.h" // for snapshotFrame
+#include "llfloaterflickr.h" // for snapshotFrame
+#include "llsnapshotlivepreview.h" // for snapshotFrame
// #include "llpanelface.h" // switchable edit texture/materials panel - include not needed
#include "llpathfindingpathtool.h"
#include "llscenemonitor.h"
@@ -7872,7 +7875,7 @@ void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst)
}
// updated Vignette code (based on original Exo Vignette)
-void LLPipeline::renderVignette(LLRenderTarget* src, LLRenderTarget* dst)
+bool LLPipeline::renderVignette(LLRenderTarget* src, LLRenderTarget* dst)
{
if (RenderVignette.mV[0] > 0.f)
{
@@ -7909,14 +7912,166 @@ void LLPipeline::renderVignette(LLRenderTarget* src, LLRenderTarget* dst)
shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
shader->unbind();
dst->flush();
+ return true;
}
else
{
- copyRenderTarget(src, dst);
+ return false;
}
}
//
+// Render Snapshot frame oerlay
+bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ static LLCachedControl show_frame(gSavedSettings, "FSSnapshotShowCaptureFrame", false);
+ static LLCachedControl show_guides(gSavedSettings, "FSSnapshotShowGuides", false);
+
+ float left = 0.f;
+ float top = 0.f;
+ float right = 1.f;
+ float bottom = 1.f;
+
+ // TODO - add debug settings to control the appearance of the snapshot frameand guides
+ static LLCachedControl border_color(gSavedSettings, "FSSnapshotFrameBorderColor", LLColor3(1.f, 0.f, 0.f));
+ static LLCachedControl guide_color(gSavedSettings, "FSSnapshotFrameGuideColor", LLColor3(1.f, 1.f, 0.f));
+ static LLCachedControl border_thickness(gSavedSettings, "FSSnapshotFrameBorderWidth", 2.0f);
+ static LLCachedControl guide_thickness(gSavedSettings, "FSSnapshotFrameGuideWidth", 2.0f);
+
+ F32 guide_style = 1.f; // 0:off, 1:rule_of_thirds, others maybe in the future
+ if (!show_guides)
+ {
+ guide_style = 0.f;
+ }
+ const bool simple_snapshot_visible = LLFloaterReg::instanceVisible("simple_snapshot");
+ const bool flickr_snapshot_visible = LLFloaterReg::instanceVisible("flickr");
+ const bool snapshot_visible = LLFloaterReg::instanceVisible("snapshot");
+ const bool any_snapshot_visible = simple_snapshot_visible || flickr_snapshot_visible || snapshot_visible;
+ if (!show_frame || !any_snapshot_visible || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ return false;
+
+ }
+ LLSnapshotLivePreview * previewView = nullptr;
+ if (snapshot_visible)
+ {
+ auto * floater =dynamic_cast(LLFloaterReg::findInstance("snapshot"));
+ previewView = floater->impl->getPreviewView();
+ }
+ // Note: simple_snapshot not supported as there can be more than one active and more complex selection is required
+ if (flickr_snapshot_visible && !previewView)
+ {
+ auto * floater = dynamic_cast(LLFloaterReg::findInstance("flickr"));
+ previewView = floater->getPreviewView();
+ }
+ if(!previewView)
+ {
+ return false;
+ }
+
+ static LLCachedControl keep_aspect(gSavedSettings, "KeepAspectForSnapshot", false);
+
+ S32 snapshot_width;
+ S32 snapshot_height;
+ previewView->getSize(snapshot_width, snapshot_height);
+ F32 screen_aspect = float(gViewerWindow->getWindowWidthRaw()) / float(gViewerWindow->getWindowHeightRaw());
+ F32 snapshot_aspect = float(snapshot_width) / float(snapshot_height);
+
+ if (keep_aspect || (std::fabs(screen_aspect - snapshot_aspect) < 1e-6f) )
+ {
+ top = 0.0f;
+ left = 0.0f;
+ bottom = 1.0f;
+ right = 1.0f;
+ }
+
+ float w = screen_aspect;
+ float h = 1.0;
+ if (snapshot_aspect > screen_aspect)
+ {
+ float frame_width = w;
+ float frame_height = frame_width / snapshot_aspect;
+ // Centre this box in [0..1]×[0..1]
+ float y_offset = 0.5f * (h - frame_height);
+ left = 0.f;
+ top = y_offset / h;
+ right = 1.f;
+ bottom = (y_offset + frame_height) / h;
+ }
+ else
+ {
+ float frame_height = h;
+ float frame_width = h * snapshot_aspect;
+ // Centre this box in [0..1]×[0..1]
+ float x_offset = 0.5f * (w - frame_width);
+ left = x_offset / w;
+ top = 0.f;
+ right = (x_offset + frame_width) / w;
+ bottom = 1.f;
+
+ }
+ LL_PROFILE_GPU_ZONE("Snapshot Frame");
+ dst->bindTarget();
+ LLGLSLShader *shader = &gPostSnapshotFrameProgram;
+
+ // bind the program and output to screentriangle VBO
+ shader->bind();
+
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+ else
+ {
+ LL_ERRS("snapshot_frame") << "Failed to bind diffuse texture" << LL_ENDL;
+ }
+
+ shader->uniform2f(
+ LLShaderMgr::DEFERRED_SCREEN_RES,
+ (GLfloat)dst->getWidth(),
+ (GLfloat)dst->getHeight());
+
+ // Assuming frame_rect is a static or accessible variable containing the frame dimensions
+ shader->uniform4f(
+ LLShaderMgr::SNAPSHOT_FRAME_RECT,
+ (GLfloat)left,
+ (GLfloat)top,
+ (GLfloat)right,
+ (GLfloat)bottom);
+
+ shader->uniform3fv(
+ LLShaderMgr::SNAPSHOT_BORDER_COLOR,
+ 1,
+ border_color().mV);
+
+ shader->uniform1f(
+ LLShaderMgr::SNAPSHOT_BORDER_THICKNESS,
+ (GLfloat)border_thickness);
+
+ shader->uniform3fv(
+ LLShaderMgr::SNAPSHOT_GUIDE_COLOR,
+ 1,
+ guide_color().mV);
+
+ shader->uniform1f(
+ LLShaderMgr::SNAPSHOT_GUIDE_THICKNESS,
+ (GLfloat)guide_thickness);
+ shader->uniform1f(
+ LLShaderMgr::SNAPSHOT_GUIDE_STYLE,
+ (GLfloat)guide_style);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ shader->unbind();
+ dst->flush();
+ return true;
+}
+//
+
void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
{
{
@@ -8217,8 +8372,23 @@ void LLPipeline::renderFinalize()
targetBuffer = params.m_pSrcBuffer;
}
// [/RLVa:KB]
- renderVignette(activeBuffer, targetBuffer);
- finalBuffer = targetBuffer;
+
+ if (renderVignette(activeBuffer, targetBuffer))
+ {
+ auto prevActiveBuffer = activeBuffer;
+ activeBuffer = targetBuffer;
+ targetBuffer = prevActiveBuffer;
+ };
+ //
+ // new shader for snapshot frame helper
+ if (renderSnapshotFrame(targetBuffer, activeBuffer))
+ {
+ auto prevActiveBuffer = activeBuffer;
+ activeBuffer = targetBuffer;
+ targetBuffer = prevActiveBuffer;
+ };
+
+ finalBuffer = activeBuffer;
//
if (RenderBufferVisualization > -1)
{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3b50453c40..5343dccfba 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -348,7 +348,8 @@ public:
void renderShadow(const glm::mat4& view, const glm::mat4& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp);
void renderSelectedFaces(const LLColor4& color);
void renderHighlights();
- void renderVignette(LLRenderTarget* src, LLRenderTarget* dst);
+ bool renderVignette(LLRenderTarget* src, LLRenderTarget* dst);
+ bool renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst); // Add snapshot frame rendering
void renderDebug();
void renderPhysicsDisplay();
diff --git a/indra/newview/skins/default/xui/de/floater_fs_poser.xml b/indra/newview/skins/default/xui/de/floater_fs_poser.xml
index 2119dfb5a5..4d2b073034 100644
--- a/indra/newview/skins/default/xui/de/floater_fs_poser.xml
+++ b/indra/newview/skins/default/xui/de/floater_fs_poser.xml
@@ -235,7 +235,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index 1400c69b4b..76e7d93710 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -59,6 +59,8 @@
+
+
diff --git a/indra/newview/skins/default/xui/de/panel_flickr_photo.xml b/indra/newview/skins/default/xui/de/panel_flickr_photo.xml
index fb1d9c2cc8..f72250cf35 100644
--- a/indra/newview/skins/default/xui/de/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/de/panel_flickr_photo.xml
@@ -11,6 +11,8 @@
Aktualisiere...
+
+
diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
index 2d2d817944..89b0045e53 100644
--- a/indra/newview/skins/default/xui/en/floater_flickr.xml
+++ b/indra/newview/skins/default/xui/en/floater_flickr.xml
@@ -10,7 +10,7 @@
single_instance="true"
reuse_instance="true"
title="Share to Flickr"
- height="590"
+ height="600"
width="272">
max_val="1.5"
name="av_position_updown"
top_pad="5"
- width="172"
+ width="122"
tool_tip="Move the selected avatar up or down"
can_edit_text="true">
+
+
+
Left/Right:
@@ -380,6 +396,7 @@ width="403">
max_val="1.5"
name="av_position_leftright"
top_pad="5"
- width="172"
+ width="122"
tool_tip="Move the selected avatar left or right"
can_edit_text="true">
+
+
+
In/Out:
@@ -408,6 +440,7 @@ width="403">
max_val="1.5"
name="av_position_inout"
top_pad="5"
- width="172"
+ width="122"
tool_tip="Move the selected avatar in or out"
can_edit_text="true">
-
+
+
+
+
left_delta="0"
max_val="2"
min_val="0.01"
+ show_text="false"
name="trackpad_sensitivity_slider"
tool_tip="Adjusts the sensitivity of the trackball"
top_pad="3"
- width="170" >
+ width="120" >
+
+
+
follows="left|top"
left="5"
tool_tip="Not stopping your pose can be helpful if you do a lot of work, and don't want to accidentally lose it."
- top_pad="5"
+ top_pad="10"
width="134" />
enabled="false"
label="Write BVH when saving**"
follows="left|top"
- left="5"
+ left="15"
tool_tip="When you save your pose, also write a BVH file, which can be uploaded via the 'Build > Upload > Animation' to pose yourself or others in-world. This needs joints to reset their 'base' to zero, because BVH requires original work."
- top_pad="5"
+ top_pad="2"
width="134" />
@@ -923,7 +989,7 @@ width="403">
layout="topleft"
image_overlay="Inv_TrashOpen"
image_unselected="Toolbar_Middle_Off"
- name="refresh_avatars"
+ name="poser_joint_reset"
tool_tip="Double click to reset all selected body parts to when you first started posing"
width="18"
top_delta="0"
@@ -992,7 +1058,7 @@ width="403">
name="limb_pitch_label"
height="10"
layout="topleft"
- left_delta="0"
+ left="0"
top_pad="2"
width="200">
Up/Down:
@@ -1008,16 +1074,31 @@ width="403">
min_val="-180"
max_val="180"
name="limb_pitch"
+ show_text="false"
top_pad="2"
- width="150"
- can_edit_text="true"/>
+ width="98"/>
+
+
+
Left/Right:
@@ -1032,16 +1113,32 @@ width="403">
min_val="-180"
max_val="180"
name="limb_yaw"
+ show_text="false"
top_pad="0"
- width="150"
+ width="98"
can_edit_text="true"/>
+
+
+
Roll:
@@ -1052,13 +1149,29 @@ width="403">
increment="0.1"
initial_value="0"
layout="topleft"
+ show_text="false"
left_delta="5"
min_val="-180"
max_val="180"
name="limb_roll"
top_pad="-1"
- width="150"
+ width="98"
can_edit_text="true"/>
+
+
+
top="0"
width="555">
+ top_pad="2"
+ width="342" >
-
+
+
+
-
-
-
+ max_val="1.5"
+ min_val="-1.5"
+ name="Advanced_Position_Y"
+ left="3"
+ width="342" >
+
+
+
+
+
+
+
+
+
@@ -1419,7 +1574,7 @@ width="403">
image_unselected="Toolbar_Middle_Off"
name="redo_position_change"
tool_tip="Redo the last position change"
- width="110"
+ width="108"
top_delta="0"
left_pad="4">
image_unselected="Toolbar_Middle_Off"
name="reset_positions"
tool_tip="Double click to reset position back to original"
- width="110"
+ width="109"
top_delta="0"
left_pad="4">
+ top_pad="2"
+ width="342" >
+
+
+
+ width="342" >
+
+
+
+ width="342" >
+
+
+
@@ -1535,7 +1738,7 @@ width="403">
image_unselected="Toolbar_Middle_Off"
name="redo_scale_change"
tool_tip="Redo the last scale change"
- width="110"
+ width="108"
top_delta="0"
left_pad="4">
image_unselected="Toolbar_Middle_Off"
name="reset_scales"
tool_tip="Double click to reset scale back to original"
- width="110"
+ width="109"
top_delta="0"
left_pad="4">
+
+
Refreshing...
+
+
-
+
diff --git a/indra/newview/skins/default/xui/it/floater_fs_poser.xml b/indra/newview/skins/default/xui/it/floater_fs_poser.xml
index 714b61e7e6..27d90fe643 100644
--- a/indra/newview/skins/default/xui/it/floater_fs_poser.xml
+++ b/indra/newview/skins/default/xui/it/floater_fs_poser.xml
@@ -226,7 +226,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/pl/floater_fs_poser.xml b/indra/newview/skins/default/xui/pl/floater_fs_poser.xml
index 54b0bb5a47..8912a19a82 100644
--- a/indra/newview/skins/default/xui/pl/floater_fs_poser.xml
+++ b/indra/newview/skins/default/xui/pl/floater_fs_poser.xml
@@ -227,7 +227,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/ru/floater_fs_poser.xml b/indra/newview/skins/default/xui/ru/floater_fs_poser.xml
index 334bf5ab34..e54577f5d3 100644
--- a/indra/newview/skins/default/xui/ru/floater_fs_poser.xml
+++ b/indra/newview/skins/default/xui/ru/floater_fs_poser.xml
@@ -221,7 +221,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/ru/floater_stats.xml b/indra/newview/skins/default/xui/ru/floater_stats.xml
index 5a60e6af4e..f7b2c0eea9 100644
--- a/indra/newview/skins/default/xui/ru/floater_stats.xml
+++ b/indra/newview/skins/default/xui/ru/floater_stats.xml
@@ -16,8 +16,12 @@
+
+
+
+
@@ -29,15 +33,18 @@
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index 9f25fc498d..7c11d04636 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -107,6 +107,7 @@
+
diff --git a/indra/newview/skins/default/xui/zh/floater_fs_poser.xml b/indra/newview/skins/default/xui/zh/floater_fs_poser.xml
index 144b311812..91b5454616 100644
--- a/indra/newview/skins/default/xui/zh/floater_fs_poser.xml
+++ b/indra/newview/skins/default/xui/zh/floater_fs_poser.xml
@@ -234,7 +234,7 @@
-
+
@@ -261,7 +261,7 @@
-
+
diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml
index 8a41b6a762..fc80ed4198 100644
--- a/indra/newview/skins/default/xui/zh/floater_tools.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tools.xml
@@ -46,7 +46,7 @@
剩餘容納量 [LAND_CAPACITY]。
- 聯結數:
+ 聯結序號:
面: