diff --git a/indra/newview/fsfloaterposer.cpp b/indra/newview/fsfloaterposer.cpp
index 327cf6945a..9145a618b1 100644
--- a/indra/newview/fsfloaterposer.cpp
+++ b/indra/newview/fsfloaterposer.cpp
@@ -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;
}
diff --git a/indra/newview/fsfloaterposer.h b/indra/newview/fsfloaterposer.h
index 1e4924a41a..f5574d1109 100644
--- a/indra/newview/fsfloaterposer.h
+++ b/indra/newview/fsfloaterposer.h
@@ -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();
diff --git a/indra/newview/fsposeranimator.cpp b/indra/newview/fsposeranimator.cpp
index 2112c666d2..7abe4abb99 100644
--- a/indra/newview/fsposeranimator.cpp
+++ b/indra/newview/fsposeranimator.cpp
@@ -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))
diff --git a/indra/newview/fsposeranimator.h b/indra/newview/fsposeranimator.h
index 7cf15c5169..ef04e7480a 100644
--- a/indra/newview/fsposeranimator.h
+++ b/indra/newview/fsposeranimator.h
@@ -263,6 +263,27 @@ public:
/// The joint with the rotation to undo.
void undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
+ ///
+ /// Undoes the last applied position to the supplied PoserJoint.
+ ///
+ /// The avatar having the joint to which we refer.
+ /// The joint with the position to undo.
+ void undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
+
+ ///
+ /// Resets the position of the supplied PoserJoint.
+ ///
+ /// The avatar having the joint to which we refer.
+ /// The joint with the position to reset.
+ void resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
+
+ ///
+ /// Resets the scale of the supplied joint to initial values.
+ ///
+ /// The avatar having the joint to which we refer.
+ /// The joint with the scale to reset.
+ void resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
+
///
/// Determines if a redo action is currently permitted for the supplied joint.
///
diff --git a/indra/newview/fsposingmotion.h b/indra/newview/fsposingmotion.h
index ad0b401e27..f9a940f4d9 100644
--- a/indra/newview/fsposingmotion.h
+++ b/indra/newview/fsposingmotion.h
@@ -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);
}
diff --git a/indra/newview/skins/default/xui/en/floater_poser.xml b/indra/newview/skins/default/xui/en/floater_poser.xml
index bbf980a6d9..230fa3310c 100644
--- a/indra/newview/skins/default/xui/en/floater_poser.xml
+++ b/indra/newview/skins/default/xui/en/floater_poser.xml
@@ -1111,14 +1111,14 @@ width="565">
function="Poser.Advanced.PositionSet"
parameter="2"/>
+
+
function="Poser.Advanced.ScaleSet"
parameter="2"/>
+