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"/> +