FIRE-30873: Add undo/reset buttons to advanced areas

master
Angeldark Raymaker 2024-10-07 23:20:25 +01:00
parent 76657a75aa
commit d0465c9e6e
6 changed files with 241 additions and 8 deletions

View File

@ -129,6 +129,9 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key)
mCommitCallbackRegistrar.add("Poser.Advanced.PositionSet", boost::bind(&FSFloaterPoser::onAdvancedPositionSet, this));
mCommitCallbackRegistrar.add("Poser.Advanced.RotationSet", boost::bind(&FSFloaterPoser::onAdvancedRotationSet, this));
mCommitCallbackRegistrar.add("Poser.Advanced.ScaleSet", boost::bind(&FSFloaterPoser::onAdvancedScaleSet, this));
mCommitCallbackRegistrar.add("Poser.UndoLastPosition", boost::bind(&FSFloaterPoser::onUndoLastPosition, this));
mCommitCallbackRegistrar.add("Poser.ResetPosition", boost::bind(&FSFloaterPoser::onResetPosition, this));
mCommitCallbackRegistrar.add("Poser.ResetScale", boost::bind(&FSFloaterPoser::onResetScale, this));
mCommitCallbackRegistrar.add("Poser.Save", boost::bind(&FSFloaterPoser::onClickPoseSave, this));
mCommitCallbackRegistrar.add("Pose.Menu", boost::bind(&FSFloaterPoser::onPoseMenuAction, this, _2));
@ -991,6 +994,78 @@ void FSFloaterPoser::onUndoLastRotation()
refreshTrackpadCursor();
}
void FSFloaterPoser::onUndoLastPosition()
{
LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar)
return;
if (!_poserAnimator.isPosingAvatar(avatar))
return;
auto selectedJoints = getUiSelectedPoserJoints();
if (selectedJoints.size() < 1)
return;
bool shouldEnableRedoButton = false;
for (auto item : selectedJoints)
{
bool currentlyPosing = _poserAnimator.isPosingAvatarJoint(avatar, *item);
if (currentlyPosing)
_poserAnimator.undoLastJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
refreshAdvancedPositionSliders();
}
void FSFloaterPoser::onResetPosition()
{
LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar)
return;
if (!_poserAnimator.isPosingAvatar(avatar))
return;
auto selectedJoints = getUiSelectedPoserJoints();
if (selectedJoints.size() < 1)
return;
bool shouldEnableRedoButton = false;
for (auto item : selectedJoints)
{
bool currentlyPosing = _poserAnimator.isPosingAvatarJoint(avatar, *item);
if (currentlyPosing)
_poserAnimator.resetJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
refreshAdvancedPositionSliders();
}
void FSFloaterPoser::onResetScale()
{
LLVOAvatar* avatar = getUiSelectedAvatar();
if (!avatar)
return;
if (!_poserAnimator.isPosingAvatar(avatar))
return;
auto selectedJoints = getUiSelectedPoserJoints();
if (selectedJoints.size() < 1)
return;
bool shouldEnableRedoButton = false;
for (auto item : selectedJoints)
{
bool currentlyPosing = _poserAnimator.isPosingAvatarJoint(avatar, *item);
if (currentlyPosing)
_poserAnimator.resetJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle());
}
refreshAdvancedScaleSliders();
}
void FSFloaterPoser::onRedoLastRotation()
{
LLVOAvatar* avatar = getUiSelectedAvatar();
@ -1284,6 +1359,7 @@ void FSFloaterPoser::onAvatarPositionSet()
F32 posZ = (F32) zposSlider->getValue().asReal();
setSelectedJointsPosition(posX, posY, posZ);
refreshAdvancedPositionSliders();
}
void FSFloaterPoser::onLimbTrackballChanged()
@ -1599,7 +1675,7 @@ LLVector3 FSFloaterPoser::getPositionOfFirstSelectedJoint()
if (!_poserAnimator.isPosingAvatar(avatar))
return position;
position = _poserAnimator.getJointPosition(avatar, *selectedJoints.front()); // TODO: inject translations like rotation does?
position = _poserAnimator.getJointPosition(avatar, *selectedJoints.front());
return position;
}
@ -1617,7 +1693,7 @@ LLVector3 FSFloaterPoser::getScaleOfFirstSelectedJoint()
if (!_poserAnimator.isPosingAvatar(avatar))
return scale;
scale = _poserAnimator.getJointScale(avatar, *selectedJoints.front()); // TODO: inject translations like rotation does?
scale = _poserAnimator.getJointScale(avatar, *selectedJoints.front());
return scale;
}

View File

@ -214,6 +214,9 @@ class FSFloaterPoser : public LLFloater
void setRotationChangeButtons(bool mirror, bool sympathetic);
void onUndoLastRotation();
void onRedoLastRotation();
void onUndoLastPosition();
void onResetPosition();
void onResetScale();
void enableOrDisableRedoButton();
void onPoseStartStop();
void onLimbTrackballChanged();

View File

@ -126,6 +126,90 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->undoLastRotationSet();
}
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
FSPosingMotion* posingMotion = getPosingMotion(avatar);
if (!posingMotion)
return;
if (posingMotion->isStopped())
return;
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
if (!jointPose)
return;
jointPose->undoLastPositionSet();
if (style == NONE)
return;
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
if (!oppositeJointPose)
return;
oppositeJointPose->undoLastPositionSet();
}
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
FSPosingMotion* posingMotion = getPosingMotion(avatar);
if (!posingMotion)
return;
if (posingMotion->isStopped())
return;
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
if (!jointPose)
return;
jointPose->setTargetPosition(jointPose->getBeginningPosition());
if (style == NONE)
return;
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
if (!oppositeJointPose)
return;
oppositeJointPose->setTargetPosition(oppositeJointPose->getBeginningPosition());
}
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
FSPosingMotion* posingMotion = getPosingMotion(avatar);
if (!posingMotion)
return;
if (posingMotion->isStopped())
return;
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
if (!jointPose)
return;
jointPose->revertJointScale();
if (style == NONE)
return;
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
if (!oppositeJointPose)
return;
oppositeJointPose->revertJointScale();
}
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint joint)
{
if (!isAvatarSafeToUse(avatar))

View File

@ -263,6 +263,27 @@ public:
/// <param name="joint">The joint with the rotation to undo.</param>
void undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
/// <summary>
/// Undoes the last applied position to the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the position to undo.</param>
void undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the position of the supplied PoserJoint.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the position to reset.</param>
void resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the scale of the supplied joint to initial values.
/// </summary>
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint with the scale to reset.</param>
void resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
/// <summary>
/// Determines if a redo action is currently permitted for the supplied joint.
/// </summary>

View File

@ -273,7 +273,7 @@ public:
joint->setScale(_beginningScale);
}
LLVector3 getJointScale() { return _targetScale; }
LLVector3 getJointScale() const { return _targetScale; }
void setJointScale(LLVector3 scale)
{
_targetScale.set(scale);
@ -293,6 +293,7 @@ public:
if (!joint)
return;
_targetScale = _beginningScale;
joint->setScale(_beginningScale);
}

View File

@ -1111,14 +1111,14 @@ width="565">
<layout_panel
follows="top|left|right"
layout="topleft"
height="75"
height="97"
visible="true"
auto_resize="false"
name="advanced_controls_layout"
width="607">
<panel
follows="top|left|right"
height="75"
height="97"
left="0"
layout="all"
enabled="false"
@ -1130,7 +1130,7 @@ width="565">
<tab_container
follows="all"
halign="center"
height="75"
height="97"
layout="topleft"
name="modifier_tabs"
enabled="true"
@ -1142,7 +1142,7 @@ width="565">
<panel
follows="all"
background_visible="false"
height="75"
height="97"
layout="topleft"
left="0"
title="Body Part Position"
@ -1209,11 +1209,43 @@ width="565">
function="Poser.Advanced.PositionSet"
parameter="2"/>
</slider>
<button
height="21"
follows="left|top"
layout="topleft"
label="Undo Position Change"
image_overlay="Script_Undo"
image_overlay_alignment="left"
image_unselected="Toolbar_Middle_Off"
name="undo_position_change"
tool_tip="Undo the last position change"
width="150"
top_pad="2"
left_delta="0">
<button.commit_callback
function="Poser.UndoLastPosition"/>
</button>
<button
height="21"
follows="left|top"
layout="topleft"
label="Reset Position"
image_overlay="Inv_TrashOpen"
image_overlay_alignment="left"
image_unselected="Toolbar_Middle_Off"
name="undo_position_change"
tool_tip="Reset position back to original"
width="110"
top_delta="0"
left_pad="4">
<button.commit_callback
function="Poser.ResetPosition"/>
</button>
</panel>
<panel
follows="all"
background_visible="false"
height="75"
height="97"
layout="topleft"
left="0"
title="Body Part Scale"
@ -1280,6 +1312,22 @@ width="565">
function="Poser.Advanced.ScaleSet"
parameter="2"/>
</slider>
<button
height="21"
follows="left|top"
layout="topleft"
label="Reset Scale Change"
image_overlay="Inv_TrashOpen"
image_overlay_alignment="left"
image_unselected="Toolbar_Middle_Off"
name="reset_scale_change"
tool_tip="Reset the scale of the selected body part(s) to normal"
width="150"
top_pad="2"
left_delta="0">
<button.commit_callback
function="Poser.ResetScale"/>
</button>
</panel>
</tab_container>
</panel>