From 47a2a780897fc3560e8acc22152006120e66a729 Mon Sep 17 00:00:00 2001 From: Angeldark Raymaker Date: Sun, 9 Mar 2025 23:22:28 +0000 Subject: [PATCH] Poser: Refactor undo to one stack Rework UI: removed 'advanced' panel. Remove yaw/pitch/roll sliders. Added Symmetrize L/R. --- indra/newview/fsfloaterposer.cpp | 344 +---- indra/newview/fsfloaterposer.h | 27 +- indra/newview/fsjointpose.cpp | 132 +- indra/newview/fsjointpose.h | 163 ++- indra/newview/fsposeranimator.cpp | 279 ++-- indra/newview/fsposeranimator.h | 66 +- indra/newview/fsposingmotion.cpp | 2 +- .../skins/default/xui/en/floater_fs_poser.xml | 1132 ++++++++--------- 8 files changed, 833 insertions(+), 1312 deletions(-) diff --git a/indra/newview/fsfloaterposer.cpp b/indra/newview/fsfloaterposer.cpp index 9b0d95ab55..1812a85bdb 100644 --- a/indra/newview/fsfloaterposer.cpp +++ b/indra/newview/fsfloaterposer.cpp @@ -55,7 +55,6 @@ constexpr char XML_LIST_TITLE_STRING_PREFIX[] = "title_"; constexpr char XML_JOINT_TRANSFORM_STRING_PREFIX[] = "joint_transform_"; constexpr char XML_JOINT_DELTAROT_STRING_PREFIX[] = "joint_delta_rotate_"; constexpr char BVH_JOINT_TRANSFORM_STRING_PREFIX[] = "bvh_joint_transform_"; -constexpr std::string_view POSER_ADVANCEDWINDOWSTATE_SAVE_KEY = "FSPoserAdvancedWindowState"; constexpr std::string_view POSER_TRACKPAD_SENSITIVITY_SAVE_KEY = "FSPoserTrackpadSensitivity"; constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed"; constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit"; @@ -74,10 +73,9 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key) mCommitCallbackRegistrar.add("Poser.RefreshAvatars", [this](LLUICtrl*, const LLSD&) { onAvatarsRefresh(); }); mCommitCallbackRegistrar.add("Poser.StartStopAnimating", [this](LLUICtrl*, const LLSD&) { onPoseStartStop(); }); mCommitCallbackRegistrar.add("Poser.ToggleLoadSavePanel", [this](LLUICtrl*, const LLSD&) { onToggleLoadSavePanel(); }); - mCommitCallbackRegistrar.add("Poser.ToggleAdvancedPanel", [this](LLUICtrl*, const LLSD&) { onToggleAdvancedPanel(); }); - mCommitCallbackRegistrar.add("Poser.UndoLastRotation", [this](LLUICtrl*, const LLSD&) { onUndoLastRotation(); }); - mCommitCallbackRegistrar.add("Poser.RedoLastRotation", [this](LLUICtrl*, const LLSD&) { onRedoLastRotation(); }); + mCommitCallbackRegistrar.add("Poser.UndoLastRotation", [this](LLUICtrl*, const LLSD&) { onUndoLastChange(); }); + mCommitCallbackRegistrar.add("Poser.RedoLastRotation", [this](LLUICtrl*, const LLSD&) { onRedoLastChange(); }); mCommitCallbackRegistrar.add("Poser.ToggleMirrorChanges", [this](LLUICtrl*, const LLSD&) { onToggleMirrorChange(); }); mCommitCallbackRegistrar.add("Poser.ToggleSympatheticChanges", [this](LLUICtrl*, const LLSD&) { onToggleSympatheticChange(); }); mCommitCallbackRegistrar.add("Poser.AdjustTrackPadSensitivity", [this](LLUICtrl*, const LLSD&) { onAdjustTrackpadSensitivity(); }); @@ -87,12 +85,9 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key) mCommitCallbackRegistrar.add("Poser.Advanced.PositionSet", [this](LLUICtrl*, const LLSD&) { onAdvancedPositionSet(); }); mCommitCallbackRegistrar.add("Poser.Advanced.ScaleSet", [this](LLUICtrl*, const LLSD&) { onAdvancedScaleSet(); }); - mCommitCallbackRegistrar.add("Poser.UndoLastPosition", [this](LLUICtrl*, const LLSD&) { onUndoLastPosition(); }); - mCommitCallbackRegistrar.add("Poser.RedoLastPosition", [this](LLUICtrl*, const LLSD&) { onRedoLastPosition(); }); - mCommitCallbackRegistrar.add("Poser.ResetPosition", [this](LLUICtrl*, const LLSD&) { onResetPosition(); }); - mCommitCallbackRegistrar.add("Poser.ResetScale", [this](LLUICtrl*, const LLSD&) { onResetScale(); }); - mCommitCallbackRegistrar.add("Poser.UndoLastScale", [this](LLUICtrl*, const LLSD&) { onUndoLastScale(); }); - mCommitCallbackRegistrar.add("Poser.RedoLastScale", [this](LLUICtrl*, const LLSD&) { onRedoLastScale(); }); + mCommitCallbackRegistrar.add("Poser.UndoLastPosition", [this](LLUICtrl*, const LLSD&) { onUndoLastChange(); }); + mCommitCallbackRegistrar.add("Poser.RedoLastPosition", [this](LLUICtrl*, const LLSD&) { onRedoLastChange(); }); + mCommitCallbackRegistrar.add("Poser.ResetJoint", [this](LLUICtrl*, const LLSD& data) { onResetJoint(data); }); mCommitCallbackRegistrar.add("Poser.Save", [this](LLUICtrl*, const LLSD&) { onClickPoseSave(); }); mCommitCallbackRegistrar.add("Pose.Menu", [this](LLUICtrl*, const LLSD& data) { onPoseMenuAction(data); }); @@ -104,10 +99,9 @@ FSFloaterPoser::FSFloaterPoser(const LLSD& key) : LLFloater(key) mCommitCallbackRegistrar.add("Poser.FlipJoint", [this](LLUICtrl*, const LLSD&) { onClickFlipSelectedJoints(); }); 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)); + mCommitCallbackRegistrar.add("Poser.CommitSpinner", [this](LLUICtrl* spinner, const LLSD& data) { onCommitSpinner(spinner, data); }); + mCommitCallbackRegistrar.add("Poser.Symmetrize", [this](LLUICtrl*, const LLSD& data) { onClickSymmetrize(data); }); } bool FSFloaterPoser::postBuild() @@ -115,15 +109,6 @@ bool FSFloaterPoser::postBuild() mAvatarTrackball = getChild("limb_rotation"); mAvatarTrackball->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbTrackballChanged(); }); - mLimbYawSlider = getChild("limb_yaw"); - mLimbYawSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); }); - - mLimbPitchSlider = getChild("limb_pitch"); - mLimbPitchSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); }); - - mLimbRollSlider = getChild("limb_roll"); - mLimbRollSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); }); - mJointsTabs = getChild("joints_tabs"); mJointsTabs->setCommitCallback( [this](LLUICtrl*, const LLSD&) @@ -162,10 +147,6 @@ bool FSFloaterPoser::postBuild() mPosesScrollList->setCommitOnSelectionChange(true); mPosesScrollList->setCommitCallback([this](LLUICtrl *, const LLSD &) { onPoseFileSelect(); }); - mToggleAdvancedPanelBtn = getChild("toggleAdvancedPanel"); - if (gSavedSettings.getBOOL(POSER_ADVANCEDWINDOWSTATE_SAVE_KEY)) - mToggleAdvancedPanelBtn->setValue(true); - mTrackpadSensitivitySlider = getChild("trackpad_sensitivity_slider"); mPoseSaveNameEditor = getChild("pose_save_name"); @@ -204,7 +185,6 @@ bool FSFloaterPoser::postBuild() mSetToTposeButton = getChild("set_t_pose_button"); mJointsParentPnl = getChild("joints_parent_panel"); - mAdvancedParentPnl = getChild("advanced_parent_panel"); mTrackballPnl = getChild("trackball_panel"); mPositionRotationPnl = getChild("positionRotation_panel"); mBodyJointsPnl = getChild("body_joints_panel"); @@ -220,8 +200,11 @@ bool FSFloaterPoser::postBuild() mTrackpadSensitivitySpnr = getChild("trackpad_sensitivity_spinner"); mYawSpnr = getChild("limb_yaw_spinner"); + mYawSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); }); mPitchSpnr = getChild("limb_pitch_spinner"); - mRollSpnr = getChild("limb_roll_spinner"); + mPitchSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); }); + mRollSpnr = getChild("limb_roll_spinner"); + mRollSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); }); mUpDownSpnr = getChild("av_position_updown_spinner"); mLeftRightSpnr = getChild("av_position_leftright_spinner"); mInOutSpnr = getChild("av_position_inout_spinner"); @@ -241,7 +224,6 @@ void FSFloaterPoser::onOpen(const LLSD& key) onAvatarsRefresh(); refreshJointScrollListMembers(); onJointTabSelect(); - onOpenSetAdvancedPanel(); refreshPoseScroll(mHandPresetsScrollList, POSE_PRESETS_HANDS_SUBDIRECTORY); startPosingSelf(); @@ -250,9 +232,6 @@ void FSFloaterPoser::onOpen(const LLSD& key) void FSFloaterPoser::onClose(bool app_quitting) { - if (mToggleAdvancedPanelBtn) - gSavedSettings.setBOOL(POSER_ADVANCEDWINDOWSTATE_SAVE_KEY, mToggleAdvancedPanelBtn->getValue().asBoolean()); - if (gSavedSettings.getBOOL(POSER_STOPPOSINGWHENCLOSED_SAVE_KEY)) stopPosingAllAvatars(); @@ -582,8 +561,24 @@ 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::onClickSymmetrize(S32 ID) +{ + if (notDoubleClicked()) + return; + + LLVOAvatar* avatar = getUiSelectedAvatar(); + if (!avatar) + return; + + if (!mPoserAnimator.isPosingAvatar(avatar)) + return; + + mPoserAnimator.symmetrizeLeftToRightOrRightToLeft(avatar, ID == 2); + + refreshRotationSlidersAndSpinners(); + refreshTrackpadCursor(); +} + void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id) { if (!spinner) @@ -597,8 +592,6 @@ void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id) 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 @@ -624,24 +617,6 @@ void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id) 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) @@ -690,34 +665,6 @@ void FSFloaterPoser::onCommitSpinner(LLUICtrl* spinner, S32 id) } } -void FSFloaterPoser::onPoseJointsReset() -{ - if (notDoubleClicked()) - return; - - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.resetAvatarJoint(avatar, *item); - } - - refreshRotationSlidersAndSpinners(); - refreshTrackpadCursor(); - refreshAvatarPositionSlidersAndSpinners(); -} - void FSFloaterPoser::onPoseMenuAction(const LLSD& param) { std::string loadStyle = param.asString(); @@ -1018,7 +965,7 @@ void FSFloaterPoser::startPosingSelf() void FSFloaterPoser::stopPosingAllAvatars() { - if (!gAgentAvatarp || gAgentAvatarp.isNull()) + if (!gAgentAvatarp || gAgentAvatarp.isNull() || !mAvatarSelectionScrollList) return; for (auto listItem : mAvatarSelectionScrollList->getAllData()) @@ -1087,7 +1034,6 @@ bool FSFloaterPoser::havePermissionToAnimateAvatar(LLVOAvatar *avatar) const void FSFloaterPoser::poseControlsEnable(bool enable) { - mAdvancedParentPnl->setEnabled(enable); mTrackballPnl->setEnabled(enable); mFlipPoseBtn->setEnabled(enable); mFlipJointBtn->setEnabled(enable); @@ -1254,7 +1200,7 @@ void FSFloaterPoser::setRotationChangeButtons(bool togglingMirror, bool toggling refreshTrackpadCursor(); } -void FSFloaterPoser::onUndoLastRotation() +void FSFloaterPoser::onUndoLastChange() { LLVOAvatar* avatar = getUiSelectedAvatar(); if (!avatar) @@ -1271,59 +1217,15 @@ void FSFloaterPoser::onUndoLastRotation() { bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); if (currentlyPosing) - mPoserAnimator.undoLastJointRotation(avatar, *item, getUiSelectedBoneDeflectionStyle()); + mPoserAnimator.undoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle()); } enableOrDisableRedoButton(); refreshRotationSlidersAndSpinners(); refreshTrackpadCursor(); -} - -void FSFloaterPoser::onUndoLastPosition() -{ - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.undoLastJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle()); - } - - refreshAdvancedPositionSlidersAndSpinners(); + refreshPositionSlidersAndSpinners(); refreshAvatarPositionSlidersAndSpinners(); -} - -void FSFloaterPoser::onUndoLastScale() -{ - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.undoLastJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle()); - } - - refreshAdvancedScaleSlidersAndSpinners(); + refreshScaleSlidersAndSpinners(); } void FSFloaterPoser::onSetAvatarToTpose() @@ -1340,11 +1242,13 @@ void FSFloaterPoser::onSetAvatarToTpose() refreshTextHighlightingOnJointScrollLists(); } -void FSFloaterPoser::onResetPosition() +void FSFloaterPoser::onResetJoint(const LLSD data) { if (notDoubleClicked()) return; + int resetType = data.asInteger(); + LLVOAvatar* avatar = getUiSelectedAvatar(); if (!avatar) return; @@ -1359,41 +1263,20 @@ void FSFloaterPoser::onResetPosition() for (auto item : selectedJoints) { bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.resetJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle()); + if (!currentlyPosing) + continue; + + mPoserAnimator.resetJoint(avatar, *item, getUiSelectedBoneDeflectionStyle()); } - refreshAdvancedPositionSlidersAndSpinners(); + refreshRotationSlidersAndSpinners(); + refreshTrackpadCursor(); refreshAvatarPositionSlidersAndSpinners(); + refreshPositionSlidersAndSpinners(); + refreshScaleSlidersAndSpinners(); } -void FSFloaterPoser::onResetScale() -{ - if (notDoubleClicked()) - return; - - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.resetJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle()); - } - - refreshAdvancedScaleSlidersAndSpinners(); -} - -void FSFloaterPoser::onRedoLastRotation() +void FSFloaterPoser::onRedoLastChange() { LLVOAvatar* avatar = getUiSelectedAvatar(); if (!avatar) @@ -1410,61 +1293,17 @@ void FSFloaterPoser::onRedoLastRotation() { bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); if (currentlyPosing) - mPoserAnimator.redoLastJointRotation(avatar, *item, getUiSelectedBoneDeflectionStyle()); + mPoserAnimator.redoLastJointChange(avatar, *item, getUiSelectedBoneDeflectionStyle()); } enableOrDisableRedoButton(); refreshRotationSlidersAndSpinners(); refreshTrackpadCursor(); -} - -void FSFloaterPoser::onRedoLastPosition() -{ - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.redoLastJointPosition(avatar, *item, getUiSelectedBoneDeflectionStyle()); - } - - refreshAdvancedPositionSlidersAndSpinners(); + refreshScaleSlidersAndSpinners(); + refreshPositionSlidersAndSpinners(); refreshAvatarPositionSlidersAndSpinners(); } -void FSFloaterPoser::onRedoLastScale() -{ - LLVOAvatar* avatar = getUiSelectedAvatar(); - if (!avatar) - return; - - if (!mPoserAnimator.isPosingAvatar(avatar)) - return; - - auto selectedJoints = getUiSelectedPoserJoints(); - if (selectedJoints.size() < 1) - return; - - for (auto item : selectedJoints) - { - bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); - if (currentlyPosing) - mPoserAnimator.redoLastJointScale(avatar, *item, getUiSelectedBoneDeflectionStyle()); - } - - refreshAdvancedScaleSlidersAndSpinners(); -} - void FSFloaterPoser::enableOrDisableRedoButton() { LLVOAvatar* avatar = getUiSelectedAvatar(); @@ -1483,42 +1322,12 @@ void FSFloaterPoser::enableOrDisableRedoButton() { bool currentlyPosing = mPoserAnimator.isPosingAvatarJoint(avatar, *item); if (currentlyPosing) - shouldEnableRedoButton |= mPoserAnimator.canRedoJointRotation(avatar, *item); + shouldEnableRedoButton |= mPoserAnimator.canRedoJointChange(avatar, *item); } mRedoChangeBtn->setEnabled(shouldEnableRedoButton); } -void FSFloaterPoser::onOpenSetAdvancedPanel() -{ - bool advancedPanelExpanded = mToggleAdvancedPanelBtn->getValue().asBoolean(); - if (advancedPanelExpanded) - onToggleAdvancedPanel(); -} - -void FSFloaterPoser::onToggleAdvancedPanel() -{ - if (isMinimized()) - return; - - bool advancedPanelExpanded = mToggleAdvancedPanelBtn->getValue().asBoolean(); - - mAdvancedParentPnl->setVisible(advancedPanelExpanded); - - // change the height of the Poser panel - S32 currentHeight = getRect().getHeight(); - S32 advancedPanelHeight = mAdvancedParentPnl->getRect().getHeight(); - - S32 poserFloaterHeight = advancedPanelExpanded ? currentHeight + advancedPanelHeight : currentHeight - advancedPanelHeight; - S32 poserFloaterWidth = getRect().getWidth(); - - if (poserFloaterHeight < 0) - return; - - reshape(poserFloaterWidth, poserFloaterHeight); - onJointTabSelect(); -} - std::vector FSFloaterPoser::getUiSelectedPoserJoints() const { std::vector joints; @@ -1733,7 +1542,7 @@ void FSFloaterPoser::onAvatarPositionSet() mUpDownSpnr->setValue(posZ); setSelectedJointsPosition(posX, posY, posZ); - refreshAdvancedPositionSlidersAndSpinners(); + refreshPositionSlidersAndSpinners(); } void FSFloaterPoser::onLimbTrackballChanged() @@ -1769,13 +1578,9 @@ void FSFloaterPoser::onLimbTrackballChanged() // as tempting as it is to refactor the following to refreshRotationSliders(), don't. // getRotationOfFirstSelectedJoint/setSelectedJointsRotation are // not necessarily symmetric functions (see their remarks). - 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()); + mYawSpnr->setValue(trackPadPos.mV[VX] *= RAD_TO_DEG); + mPitchSpnr->setValue(trackPadPos.mV[VY] *= RAD_TO_DEG); + mRollSpnr->setValue(trackPadPos.mV[VZ] *= RAD_TO_DEG); } F32 FSFloaterPoser::unWrapScale(F32 scale) @@ -1792,12 +1597,12 @@ F32 FSFloaterPoser::unWrapScale(F32 scale) return result; } -void FSFloaterPoser::onYawPitchRollSliderChanged() +void FSFloaterPoser::onYawPitchRollChanged() { LLVector3 absoluteRotation, deltaRotation; - absoluteRotation.mV[VX] = mLimbYawSlider->getValueF32() * DEG_TO_RAD; - absoluteRotation.mV[VY] = mLimbPitchSlider->getValueF32() * DEG_TO_RAD; - absoluteRotation.mV[VZ] = mLimbRollSlider->getValueF32() * DEG_TO_RAD; + absoluteRotation.mV[VX] = (F32)mYawSpnr->getValue().asReal() * DEG_TO_RAD; + absoluteRotation.mV[VY] = (F32)mPitchSpnr->getValue().asReal() * DEG_TO_RAD; + absoluteRotation.mV[VZ] = (F32)mRollSpnr->getValue().asReal() * DEG_TO_RAD; deltaRotation = absoluteRotation - mLastSliderRotation; mLastSliderRotation = absoluteRotation; @@ -1817,10 +1622,6 @@ 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() @@ -1830,9 +1631,9 @@ void FSFloaterPoser::onAdjustTrackpadSensitivity() void FSFloaterPoser::refreshTrackpadCursor() { - F32 axis1 = mLimbYawSlider->getValueF32() * DEG_TO_RAD / NormalTrackpadRangeInRads; - F32 axis2 = mLimbPitchSlider->getValueF32() * DEG_TO_RAD / NormalTrackpadRangeInRads; - F32 axis3 = mLimbRollSlider->getValueF32() * DEG_TO_RAD / NormalTrackpadRangeInRads; + F32 axis1 = (F32)mYawSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; + F32 axis2 = (F32)mPitchSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; + F32 axis3 = (F32)mRollSpnr->getValue().asReal() * DEG_TO_RAD / NormalTrackpadRangeInRads; F32 trackPadSensitivity = llmax(gSavedSettings.getF32(POSER_TRACKPAD_SENSITIVITY_SAVE_KEY), 0.0001f); axis1 /= trackPadSensitivity; @@ -1867,15 +1668,12 @@ 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]); + mYawSpnr->setValue(rotation.mV[VX] *= RAD_TO_DEG); + mPitchSpnr->setValue(rotation.mV[VY] *= RAD_TO_DEG); + mRollSpnr->setValue(rotation.mV[VZ] *= RAD_TO_DEG); } -void FSFloaterPoser::refreshAdvancedPositionSlidersAndSpinners() +void FSFloaterPoser::refreshPositionSlidersAndSpinners() { LLVector3 position = getPositionOfFirstSelectedJoint(); @@ -1887,7 +1685,7 @@ void FSFloaterPoser::refreshAdvancedPositionSlidersAndSpinners() mAdvPosZSpnr->setValue(position.mV[VZ]); } -void FSFloaterPoser::refreshAdvancedScaleSlidersAndSpinners() +void FSFloaterPoser::refreshScaleSlidersAndSpinners() { LLVector3 rotation = getScaleOfFirstSelectedJoint(); @@ -2041,16 +1839,12 @@ LLVector3 FSFloaterPoser::getScaleOfFirstSelectedJoint() const void FSFloaterPoser::onJointTabSelect() { refreshAvatarPositionSlidersAndSpinners(); - refreshRotationSlidersAndSpinners(); + refreshRotationSlidersAndSpinners(); refreshTrackpadCursor(); enableOrDisableRedoButton(); + refreshPositionSlidersAndSpinners(); + refreshScaleSlidersAndSpinners(); onClickSetBaseRotZero(); - - if (mToggleAdvancedPanelBtn->getValue().asBoolean()) - { - refreshAdvancedPositionSlidersAndSpinners(); - refreshAdvancedScaleSlidersAndSpinners(); - } } E_BoneAxisTranslation FSFloaterPoser::getJointTranslation(const std::string& jointName) const diff --git a/indra/newview/fsfloaterposer.h b/indra/newview/fsfloaterposer.h index 0dbe809af7..bd17406e7f 100644 --- a/indra/newview/fsfloaterposer.h +++ b/indra/newview/fsfloaterposer.h @@ -220,25 +220,19 @@ class FSFloaterPoser : public LLFloater void onAvatarsRefresh(); void onAvatarSelect(); void onJointTabSelect(); - void onToggleAdvancedPanel(); void onToggleMirrorChange(); void onToggleSympatheticChange(); void setRotationChangeButtons(bool mirror, bool sympathetic); - void onUndoLastRotation(); - void onRedoLastRotation(); - void onUndoLastPosition(); - void onRedoLastPosition(); - void onUndoLastScale(); - void onRedoLastScale(); - void onResetPosition(); - void onResetScale(); + void onUndoLastChange(); + void onRedoLastChange(); + void onResetJoint(const LLSD data); void onSetAvatarToTpose(); void enableOrDisableRedoButton(); void onPoseStartStop(); void startPosingSelf(); void stopPosingAllAvatars(); void onLimbTrackballChanged(); - void onYawPitchRollSliderChanged(); + void onYawPitchRollChanged(); void onAvatarPositionSet(); void onAdvancedPositionSet(); void onAdvancedScaleSet(); @@ -246,22 +240,20 @@ class FSFloaterPoser : public LLFloater void onClickRecaptureSelectedBones(); void onClickFlipPose(); void onClickFlipSelectedJoints(); - void onPoseJointsReset(); - void onOpenSetAdvancedPanel(); void onAdjustTrackpadSensitivity(); void onClickLoadLeftHandPose(); void onClickLoadRightHandPose(); void onClickLoadHandPose(bool isRightHand); void onClickSetBaseRotZero(); - //void onCommitSpinner(LLUICtrl* spinner); void onCommitSpinner(LLUICtrl* spinner, S32 ID); + void onClickSymmetrize(S32 ID); // UI Refreshments void refreshRotationSlidersAndSpinners(); void refreshAvatarPositionSlidersAndSpinners(); void refreshTrackpadCursor(); - void refreshAdvancedPositionSlidersAndSpinners(); - void refreshAdvancedScaleSlidersAndSpinners(); + void refreshPositionSlidersAndSpinners(); + void refreshScaleSlidersAndSpinners(); /// /// Determines if we have permission to animate the supplied avatar. @@ -447,9 +439,6 @@ class FSFloaterPoser : public LLFloater FSVirtualTrackpad* mAvatarTrackball{ nullptr }; LLSliderCtrl* mTrackpadSensitivitySlider{ nullptr }; - LLSliderCtrl* mLimbYawSlider{ nullptr }; - LLSliderCtrl* mLimbPitchSlider{ nullptr }; // pointing your nose up or down - LLSliderCtrl* mLimbRollSlider{ nullptr }; // your ear touches your shoulder LLSliderCtrl* mPosXSlider{ nullptr }; LLSliderCtrl* mPosYSlider{ nullptr }; LLSliderCtrl* mPosZSlider{ nullptr }; @@ -473,7 +462,6 @@ class FSFloaterPoser : public LLFloater LLScrollListCtrl* mPosesScrollList{ nullptr }; LLScrollListCtrl* mHandPresetsScrollList{ nullptr }; - LLButton* mToggleAdvancedPanelBtn{ nullptr }; LLButton* mStartStopPosingBtn{ nullptr }; LLButton* mToggleLoadSavePanelBtn{ nullptr }; LLButton* mBrowserFolderBtn{ nullptr }; @@ -491,7 +479,6 @@ class FSFloaterPoser : public LLFloater LLLineEditor* mPoseSaveNameEditor{ nullptr }; - LLPanel* mAdvancedParentPnl{ nullptr }; LLPanel* mJointsParentPnl{ nullptr }; LLPanel* mTrackballPnl{ nullptr }; LLPanel* mPositionRotationPnl{ nullptr }; diff --git a/indra/newview/fsjointpose.cpp b/indra/newview/fsjointpose.cpp index 285e1c5322..1693331b41 100644 --- a/indra/newview/fsjointpose.cpp +++ b/indra/newview/fsjointpose.cpp @@ -30,7 +30,7 @@ #include "llcharacter.h" /// -/// The maximum length of any undo queue; adding new members preens older ones. +/// The maximum length of the undo queue; adding new members preens older ones. /// constexpr size_t MaximumUndoQueueLength = 20; @@ -48,103 +48,87 @@ FSJointPose::FSJointPose(LLJoint* joint, U32 usage, bool isCollisionVolume) mJointName = joint->getName(); mIsCollisionVolume = isCollisionVolume; - mRotation = FSJointRotation(joint->getRotation()); - mBeginningPosition = joint->getPosition(); - mBeginningScale = joint->getScale(); + mCurrentState = FSJointState(joint); + mBeginningState = FSJointState(joint); } -void FSJointPose::setPositionDelta(const LLVector3& pos) +void FSJointPose::setPublicPosition(const LLVector3& pos) { - addToUndo(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas, &mTimeLastUpdatedPosition); - mPositionDelta.set(pos); + addStateToUndo(FSJointState(mCurrentState)); + mCurrentState.mPosition.set(pos); } -void FSJointPose::setRotationDelta(const LLQuaternion& rot) +void FSJointPose::setPublicRotation(const LLQuaternion& rot) { - addToUndo(mRotation, &mUndoneRotationIndex, &mLastSetRotationDeltas, &mTimeLastUpdatedRotation); - mRotation = FSJointRotation(mRotation.baseRotation, rot); + addStateToUndo(FSJointState(mCurrentState)); + mCurrentState.mRotation.set(rot); } -void FSJointPose::setScaleDelta(const LLVector3& scale) +void FSJointPose::setPublicScale(const LLVector3& scale) { - addToUndo(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas, &mTimeLastUpdatedScale); - mScaleDelta.set(scale); + addStateToUndo(FSJointState(mCurrentState)); + mCurrentState.mScale.set(scale); } -void FSJointPose::undoLastPositionChange() +void FSJointPose::undoLastChange() { - mPositionDelta.set(undoLastChange(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas)); + mCurrentState = undoLastStateChange(FSJointState(mCurrentState)); } -void FSJointPose::undoLastRotationChange() +void FSJointPose::redoLastChange() { - mRotation.set(undoLastChange(mRotation, &mUndoneRotationIndex, &mLastSetRotationDeltas)); + mCurrentState = redoLastStateChange(FSJointState(mCurrentState)); } -void FSJointPose::undoLastScaleChange() { mScaleDelta.set(undoLastChange(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas)); } - -void FSJointPose::redoLastPositionChange() +void FSJointPose::addStateToUndo(FSJointState stateToAddToUndo) { - mPositionDelta.set(redoLastChange(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas)); -} - -void FSJointPose::redoLastRotationChange() -{ - mRotation.set(redoLastChange(mRotation, &mUndoneRotationIndex, &mLastSetRotationDeltas)); -} - -void FSJointPose::redoLastScaleChange() { mScaleDelta.set(redoLastChange(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas)); } - -template -inline void FSJointPose::addToUndo(T delta, size_t* undoIndex, std::deque* dequeue, - std::chrono::system_clock::time_point* timeLastUpdated) -{ - auto timeIntervalSinceLastChange = std::chrono::system_clock::now() - *timeLastUpdated; - *timeLastUpdated = std::chrono::system_clock::now(); + auto timeIntervalSinceLastChange = std::chrono::system_clock::now() - mTimeLastUpdatedCurrentState; + mTimeLastUpdatedCurrentState = std::chrono::system_clock::now(); if (timeIntervalSinceLastChange < UndoUpdateInterval) return; - if (*undoIndex > 0) + if (mUndoneJointStatesIndex > 0) { - for (size_t i = 0; i < *undoIndex; i++) - dequeue->pop_front(); + for (size_t i = 0; i <= mUndoneJointStatesIndex; i++) + if (!mLastSetJointStates.empty()) + mLastSetJointStates.pop_front(); - *undoIndex = 0; + mUndoneJointStatesIndex = 0; } - dequeue->push_front(delta); + mLastSetJointStates.push_front(stateToAddToUndo); - while (dequeue->size() > MaximumUndoQueueLength) - dequeue->pop_back(); + while (mLastSetJointStates.size() > MaximumUndoQueueLength) + mLastSetJointStates.pop_back(); } -template T FSJointPose::undoLastChange(T thingToSet, size_t* undoIndex, std::deque* dequeue) +FSJointPose::FSJointState FSJointPose::undoLastStateChange(FSJointState thingToSet) { - if (dequeue->empty()) + if (mLastSetJointStates.empty()) return thingToSet; - if (*undoIndex == 0) - dequeue->push_front(thingToSet); + if (mUndoneJointStatesIndex == 0) + mLastSetJointStates.push_front(thingToSet); - *undoIndex += 1; - *undoIndex = llclamp(*undoIndex, 0, dequeue->size() - 1); + mUndoneJointStatesIndex += 1; + mUndoneJointStatesIndex = llclamp(mUndoneJointStatesIndex, 0, mLastSetJointStates.size() - 1); - return dequeue->at(*undoIndex); + return mLastSetJointStates.at(mUndoneJointStatesIndex); } -template T FSJointPose::redoLastChange(T thingToSet, size_t* undoIndex, std::deque* dequeue) +FSJointPose::FSJointState FSJointPose::redoLastStateChange(FSJointState thingToSet) { - if (dequeue->empty()) + if (mLastSetJointStates.empty()) return thingToSet; - if (*undoIndex == 0) + if (mUndoneJointStatesIndex == 0) return thingToSet; - *undoIndex -= 1; - *undoIndex = llclamp(*undoIndex, 0, dequeue->size() - 1); - T result = dequeue->at(*undoIndex); - if (*undoIndex == 0) - dequeue->pop_front(); + mUndoneJointStatesIndex -= 1; + mUndoneJointStatesIndex = llclamp(mUndoneJointStatesIndex, 0, mLastSetJointStates.size() - 1); + auto result = mLastSetJointStates.at(mUndoneJointStatesIndex); + if (mUndoneJointStatesIndex == 0) + mLastSetJointStates.pop_front(); return result; } @@ -158,8 +142,8 @@ void FSJointPose::recaptureJoint() if (!joint) return; - addToUndo(mRotation, &mUndoneRotationIndex, &mLastSetRotationDeltas, &mTimeLastUpdatedRotation); - mRotation = FSJointRotation(joint->getRotation()); + addStateToUndo(FSJointState(mCurrentState)); + mCurrentState = FSJointState(joint); } void FSJointPose::swapRotationWith(FSJointPose* oppositeJoint) @@ -169,9 +153,9 @@ void FSJointPose::swapRotationWith(FSJointPose* oppositeJoint) if (mIsCollisionVolume) return; - auto tempRot = FSJointRotation(mRotation); - mRotation = FSJointRotation(oppositeJoint->mRotation); - oppositeJoint->mRotation = tempRot; + auto tempState = FSJointState(mCurrentState); + mCurrentState.cloneRotationFrom(oppositeJoint->mCurrentState); + oppositeJoint->mCurrentState.cloneRotationFrom(tempState); } void FSJointPose::cloneRotationFrom(FSJointPose* fromJoint) @@ -179,8 +163,8 @@ void FSJointPose::cloneRotationFrom(FSJointPose* fromJoint) if (!fromJoint) return; - addToUndo(mRotation, &mUndoneRotationIndex, &mLastSetRotationDeltas, &mTimeLastUpdatedRotation); - mRotation = FSJointRotation(fromJoint->mRotation); + addStateToUndo(FSJointState(mCurrentState)); + mCurrentState.cloneRotationFrom(fromJoint->mCurrentState); } void FSJointPose::mirrorRotationFrom(FSJointPose* fromJoint) @@ -189,11 +173,7 @@ void FSJointPose::mirrorRotationFrom(FSJointPose* fromJoint) return; cloneRotationFrom(fromJoint); - - mRotation.baseRotation = LLQuaternion(-mRotation.baseRotation.mQ[VX], mRotation.baseRotation.mQ[VY], -mRotation.baseRotation.mQ[VZ], - mRotation.baseRotation.mQ[VW]); - mRotation.deltaRotation = LLQuaternion(-mRotation.deltaRotation.mQ[VX], mRotation.deltaRotation.mQ[VY], -mRotation.deltaRotation.mQ[VZ], - mRotation.deltaRotation.mQ[VW]); + mCurrentState.reflectRotation(); } void FSJointPose::revertJoint() @@ -202,9 +182,9 @@ void FSJointPose::revertJoint() if (!joint) return; - joint->setRotation(mRotation.baseRotation); - joint->setPosition(mBeginningPosition); - joint->setScale(mBeginningScale); + joint->setRotation(mBeginningState.getTargetRotation()); + joint->setPosition(mBeginningState.getTargetPosition()); + joint->setScale(mBeginningState.getTargetScale()); } void FSJointPose::reflectRotation() @@ -212,7 +192,7 @@ void FSJointPose::reflectRotation() if (mIsCollisionVolume) return; - mRotation.reflectRotation(); + mCurrentState.reflectRotation(); } void FSJointPose::zeroBaseRotation() @@ -220,7 +200,7 @@ void FSJointPose::zeroBaseRotation() if (mIsCollisionVolume) return; - mRotation.baseRotation = LLQuaternion::DEFAULT; + mBeginningState.mRotation = LLQuaternion::DEFAULT; } bool FSJointPose::isBaseRotationZero() const @@ -228,5 +208,5 @@ bool FSJointPose::isBaseRotationZero() const if (mIsCollisionVolume) return true; - return mRotation.baseRotation == LLQuaternion::DEFAULT; + return mBeginningState.mRotation == LLQuaternion::DEFAULT; } diff --git a/indra/newview/fsjointpose.h b/indra/newview/fsjointpose.h index 1b50f908bd..b521458efe 100644 --- a/indra/newview/fsjointpose.h +++ b/indra/newview/fsjointpose.h @@ -58,34 +58,39 @@ class FSJointPose bool isCollisionVolume() const { return mIsCollisionVolume; } /// - /// Gets the position change the animator wishes the joint to have. + /// Gets the 'public' position of the joint. /// - LLVector3 getPositionDelta() const { return mPositionDelta; } + LLVector3 getPublicPosition() const { return mCurrentState.mPosition; } /// - /// Sets the position the animator wishes the joint to be in. + /// Sets the 'public' position of the joint. /// - void setPositionDelta(const LLVector3& pos); + void setPublicPosition(const LLVector3& pos); /// /// Undoes the last position set, if any. /// - void undoLastPositionChange(); + void undoLastChange(); /// /// Undoes the last position set, if any. /// - void redoLastPositionChange(); + void redoLastChange(); /// - /// Gets the rotation the animator wishes the joint to be in. + /// Gets the 'public' rotation of the joint. /// - LLQuaternion getRotationDelta() const { return mRotation.deltaRotation; } + LLQuaternion getPublicRotation() const { return mCurrentState.mRotation; } /// - /// Sets the rotation the animator wishes the joint to be in. + /// Sets the 'public' rotation of the joint. /// - void setRotationDelta(const LLQuaternion& rot); + /// + /// 'Public rotation' is the amount of rotation the user has added to the initial state. + /// Public rotation is what a user may save to an external format (such as BVH). + /// This distinguishes 'private' rotation, which is the state inherited from something like a pose in-world. + /// + void setPublicRotation(const LLQuaternion& rot); /// /// Reflects the base and delta rotation of the represented joint left-right. @@ -93,7 +98,7 @@ class FSJointPose void reflectRotation(); /// - /// Sets the base rotation of the represented joint to zero. + /// Sets the private rotation of the represented joint to zero. /// void zeroBaseRotation(); @@ -104,43 +109,20 @@ class FSJointPose bool isBaseRotationZero() const; /// - /// Undoes the last rotation set, if any. - /// Ordinarily the queue does not contain the current rotation, because we rely on time to add, and not button-up. - /// When we undo, if we are at the top of the queue, we need to add the current rotation so we can redo back to it. - /// Thus when we start undoing, mUndoneRotationIndex points at the current rotation. + /// Gets whether a redo of this joint may be performed. /// - void undoLastRotationChange(); + /// true if the joint may have a redo applied, otherwise false. + bool canPerformRedo() const { return mUndoneJointStatesIndex > 0; } /// - /// Redoes the last rotation set, if any. + /// Gets the 'public' scale of the joint. /// - void redoLastRotationChange(); + LLVector3 getPublicScale() const { return mCurrentState.mScale; } /// - /// Gets whether a redo of this joints rotation may be performed. + /// Sets the 'public' scale of the joint. /// - /// true if the joint can have a redo applied, otherwise false. - bool canRedoRotation() const { return mUndoneRotationIndex > 0; } - - /// - /// Gets the scale the animator wishes the joint to have. - /// - LLVector3 getScaleDelta() const { return mScaleDelta; } - - /// - /// Sets the scale the animator wishes the joint to have. - /// - void setScaleDelta(const LLVector3& scale); - - /// - /// Undoes the last scale set, if any. - /// - void undoLastScaleChange(); - - /// - /// Redoes the last scale set, if any. - /// - void redoLastScaleChange(); + void setPublicScale(const LLVector3& scale); /// /// Exchanges the rotations between two joints. @@ -168,52 +150,69 @@ class FSJointPose /// void revertJoint(); - LLVector3 getTargetPosition() const { return mPositionDelta + mBeginningPosition; } - LLQuaternion getTargetRotation() const { return mRotation.getTargetRotation(); } - LLVector3 getTargetScale() const { return mScaleDelta + mBeginningScale; } + LLQuaternion getTargetRotation() const { return mCurrentState.getTargetRotation(); } + LLVector3 getTargetPosition() const { return mCurrentState.getTargetPosition(); } + LLVector3 getTargetScale() const { return mCurrentState.getTargetScale(); } /// /// Gets the pointer to the jointstate for the joint this represents. /// LLPointer getJointState() const { return mJointState; } - /// - /// A class wrapping base and delta rotation, attempting to keep baseRotation as secret as possible. - /// Among other things, facilitates easy undo/redo through the joint-recapture process. - /// - class FSJointRotation + class FSJointState { public: - FSJointRotation(LLQuaternion base) { baseRotation.set(base); } - - FSJointRotation(LLQuaternion base, LLQuaternion delta) + FSJointState(LLJoint* joint) { - baseRotation.set(base); - deltaRotation.set(delta); + mBaseRotation.set(joint->getRotation()); + mBasePosition.set(joint->getPosition()); + mBaseScale.set(joint->getScale()); } - FSJointRotation() = default; + FSJointState() = default; - LLQuaternion baseRotation; - LLQuaternion deltaRotation; - LLQuaternion getTargetRotation() const { return deltaRotation * baseRotation; } + LLQuaternion getTargetRotation() const { return mRotation * mBaseRotation; } + LLVector3 getTargetPosition() const { return mPosition + mBasePosition; } + LLVector3 getTargetScale() const { return mScale + mBaseScale; } void reflectRotation() { - baseRotation.mQ[VX] *= -1; - baseRotation.mQ[VZ] *= -1; - deltaRotation.mQ[VX] *= -1; - deltaRotation.mQ[VZ] *= -1; + mBaseRotation.mQ[VX] *= -1; + mBaseRotation.mQ[VZ] *= -1; + mRotation.mQ[VX] *= -1; + mRotation.mQ[VZ] *= -1; } - void set(const FSJointRotation& jRot) + void cloneRotationFrom(FSJointState otherState) { - baseRotation.set(jRot.baseRotation); - deltaRotation.set(jRot.deltaRotation); + mBaseRotation.set(otherState.mBaseRotation); + mRotation.set(otherState.mRotation); } + + private: + FSJointState(FSJointState* state) + { + mBaseRotation.set(state->mBaseRotation); + mBasePosition.set(state->mBasePosition); + mBaseScale.set(state->mBaseScale); + + mRotation.set(state->mRotation); + mPosition.set(state->mPosition); + mScale.set(state->mScale); + } + + public: + LLQuaternion mRotation; + LLVector3 mPosition; + LLVector3 mScale; + + private: + LLQuaternion mBaseRotation; + LLVector3 mBasePosition; + LLVector3 mBaseScale; }; -private: + private: std::string mJointName = ""; // expected to be a match to LLJoint.getName() for a joint implementation. LLPointer mJointState{ nullptr }; @@ -223,32 +222,16 @@ private: /// bool mIsCollisionVolume{ false }; - FSJointRotation mRotation; - std::deque mLastSetRotationDeltas; - size_t mUndoneRotationIndex = 0; - std::chrono::system_clock::time_point mTimeLastUpdatedRotation = std::chrono::system_clock::now(); + std::deque mLastSetJointStates; + size_t mUndoneJointStatesIndex = 0; + std::chrono::system_clock::time_point mTimeLastUpdatedCurrentState = std::chrono::system_clock::now(); - LLVector3 mPositionDelta; - LLVector3 mBeginningPosition; - std::deque mLastSetPositionDeltas; - size_t mUndonePositionIndex = 0; - std::chrono::system_clock::time_point mTimeLastUpdatedPosition = std::chrono::system_clock::now(); + FSJointState mCurrentState; + FSJointState mBeginningState; - /// - /// Joint scales require special treatment, as they do not revert when we stop animating an avatar. - /// - LLVector3 mScaleDelta; - LLVector3 mBeginningScale; - std::deque mLastSetScaleDeltas; - size_t mUndoneScaleIndex = 0; - std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now(); - - template - void addToUndo(T delta, size_t* undoIndex, std::deque* dequeue, std::chrono::system_clock::time_point* timeLastUpdated); - - template T undoLastChange(T thingToSet, size_t* undoIndex, std::deque* dequeue); - - template T redoLastChange(T thingToSet, size_t* undoIndex, std::deque* dequeue); + void addStateToUndo(FSJointState stateToAddToUndo); + FSJointState undoLastStateChange(FSJointState currentState); + FSJointState redoLastStateChange(FSJointState currentState); }; #endif // FS_JOINTPPOSE_H diff --git a/indra/newview/fsposeranimator.cpp b/indra/newview/fsposeranimator.cpp index 6845e8419c..2aabb98985 100644 --- a/indra/newview/fsposeranimator.cpp +++ b/indra/newview/fsposeranimator.cpp @@ -78,7 +78,7 @@ void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoin posingMotion->removeJointFromState(jointPose); } -void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint) +void FSPoserAnimator::undoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) { if (!isAvatarSafeToUse(avatar)) return; @@ -94,27 +94,7 @@ void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& j if (!jointPose) return; - jointPose->setPositionDelta(LLVector3()); - jointPose->setRotationDelta(LLQuaternion()); -} - -void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->undoLastRotationChange(); + jointPose->undoLastChange(); if (style == NONE || style == DELTAMODE) return; @@ -123,10 +103,10 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi if (!oppositeJointPose) return; - oppositeJointPose->undoLastRotationChange(); + oppositeJointPose->undoLastChange(); } -void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) +void FSPoserAnimator::resetJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) { if (!isAvatarSafeToUse(avatar)) return; @@ -142,7 +122,9 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi if (!jointPose) return; - jointPose->undoLastPositionChange(); + jointPose->setPublicRotation(LLQuaternion()); + jointPose->setPublicPosition(LLVector3()); + jointPose->setPublicScale(LLVector3()); if (style == NONE || style == DELTAMODE) return; @@ -151,94 +133,12 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi if (!oppositeJointPose) return; - oppositeJointPose->undoLastPositionChange(); + oppositeJointPose->setPublicRotation(LLQuaternion()); + oppositeJointPose->setPublicPosition(LLVector3()); + oppositeJointPose->setPublicScale(LLVector3()); } -void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->undoLastScaleChange(); - - if (style == NONE || style == DELTAMODE) - return; - - FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName()); - if (!oppositeJointPose) - return; - - oppositeJointPose->undoLastScaleChange(); -} - -void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->setPositionDelta(LLVector3()); - - if (style == NONE || style == DELTAMODE) - return; - - FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName()); - if (!oppositeJointPose) - return; - - oppositeJointPose->setPositionDelta(LLVector3()); -} - -void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->setScaleDelta(LLVector3()); - - if (style == NONE || style == DELTAMODE) - return; - - FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName()); - if (!oppositeJointPose) - return; - - oppositeJointPose->setScaleDelta(LLVector3()); -} - -bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint) +bool FSPoserAnimator::canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint) { if (!isAvatarSafeToUse(avatar)) return false; @@ -254,10 +154,10 @@ bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoin if (!jointPose) return false; - return jointPose->canRedoRotation(); + return jointPose->canPerformRedo(); } -void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) +void FSPoserAnimator::redoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) { if (!isAvatarSafeToUse(avatar)) return; @@ -273,7 +173,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi if (!jointPose) return; - jointPose->redoLastRotationChange(); + jointPose->redoLastChange(); if (style == NONE || style == DELTAMODE) return; @@ -282,63 +182,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi if (!oppositeJointPose) return; - oppositeJointPose->redoLastRotationChange(); -} - -void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->redoLastPositionChange(); - - if (style == NONE || style == DELTAMODE) - return; - - FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName()); - if (!oppositeJointPose) - return; - - oppositeJointPose->redoLastPositionChange(); -} - -void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style) -{ - if (!isAvatarSafeToUse(avatar)) - return; - - FSPosingMotion* posingMotion = getPosingMotion(avatar); - if (!posingMotion) - return; - - if (posingMotion->isStopped()) - return; - - FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName()); - if (!jointPose) - return; - - jointPose->redoLastScaleChange(); - - if (style == NONE || style == DELTAMODE) - return; - - FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName()); - if (!oppositeJointPose) - return; - - oppositeJointPose->redoLastScaleChange(); + oppositeJointPose->redoLastChange(); } LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint) const @@ -355,7 +199,7 @@ LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoi if (!jointPose) return pos; - return jointPose->getPositionDelta(); + return jointPose->getPublicPosition(); } void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style) @@ -377,7 +221,7 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j if (!jointPose) return; - LLVector3 positionDelta = jointPose->getPositionDelta() - position; + LLVector3 positionDelta = jointPose->getPublicPosition() - position; switch (style) { @@ -385,13 +229,13 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j case MIRROR_DELTA: case SYMPATHETIC_DELTA: case SYMPATHETIC: - jointPose->setPositionDelta(position); + jointPose->setPublicPosition(position); break; case DELTAMODE: case NONE: default: - jointPose->setPositionDelta(position); + jointPose->setPublicPosition(position); return; } @@ -399,18 +243,18 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j if (!oppositeJointPose) return; - LLVector3 oppositeJointPosition = oppositeJointPose->getPositionDelta(); + LLVector3 oppositeJointPosition = oppositeJointPose->getPublicPosition(); switch (style) { case MIRROR: case MIRROR_DELTA: - oppositeJointPose->setPositionDelta(oppositeJointPosition + positionDelta); + oppositeJointPose->setPublicPosition(oppositeJointPosition + positionDelta); break; case SYMPATHETIC_DELTA: case SYMPATHETIC: - oppositeJointPose->setPositionDelta(oppositeJointPosition - positionDelta); + oppositeJointPose->setPublicPosition(oppositeJointPosition - positionDelta); break; default: @@ -493,7 +337,7 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoi if (!jointPose) return vec3; - return translateRotationFromQuaternion(translation, negation, jointPose->getRotationDelta()); + return translateRotationFromQuaternion(translation, negation, jointPose->getPublicRotation()); } void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& absRotation, @@ -523,27 +367,27 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j case SYMPATHETIC: case MIRROR: if (rotationStyle == DELTAIC_ROT) - jointPose->setRotationDelta(deltaRot * jointPose->getRotationDelta()); + jointPose->setPublicRotation(deltaRot * jointPose->getPublicRotation()); else - jointPose->setRotationDelta(absRot); + jointPose->setPublicRotation(absRot); break; case SYMPATHETIC_DELTA: case MIRROR_DELTA: - jointPose->setRotationDelta(deltaRot * jointPose->getRotationDelta()); + jointPose->setPublicRotation(deltaRot * jointPose->getPublicRotation()); break; case DELTAMODE: - jointPose->setRotationDelta(deltaRot * jointPose->getRotationDelta()); + jointPose->setPublicRotation(deltaRot * jointPose->getPublicRotation()); return; case NONE: default: if (rotationStyle == DELTAIC_ROT) - jointPose->setRotationDelta(deltaRot * jointPose->getRotationDelta()); + jointPose->setPublicRotation(deltaRot * jointPose->getPublicRotation()); else - jointPose->setRotationDelta(absRot); + jointPose->setPublicRotation(absRot); return; } @@ -560,7 +404,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j break; case SYMPATHETIC_DELTA: - oppositeJointPose->setRotationDelta(deltaRot * oppositeJointPose->getRotationDelta()); + oppositeJointPose->setPublicRotation(deltaRot * oppositeJointPose->getPublicRotation()); break; case MIRROR: @@ -569,7 +413,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j case MIRROR_DELTA: inv_quat = LLQuaternion(-deltaRot.mQ[VX], deltaRot.mQ[VY], -deltaRot.mQ[VZ], deltaRot.mQ[VW]); - oppositeJointPose->setRotationDelta(inv_quat * oppositeJointPose->getRotationDelta()); + oppositeJointPose->setPublicRotation(inv_quat * oppositeJointPose->getPublicRotation()); break; default: @@ -603,6 +447,45 @@ void FSPoserAnimator::reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint } } +void FSPoserAnimator::symmetrizeLeftToRightOrRightToLeft(LLVOAvatar* avatar, bool rightToLeft) +{ + if (!isAvatarSafeToUse(avatar)) + return; + + FSPosingMotion* posingMotion = getPosingMotion(avatar); + if (!posingMotion) + return; + + for (size_t index = 0; index != PoserJoints.size(); ++index) + { + if (!PoserJoints[index].dontFlipOnMirror()) + continue; + + bool currentlyPosing = isPosingAvatarJoint(avatar, PoserJoints[index]); + if (!currentlyPosing) + continue; + + auto oppositeJoint = getPoserJointByName(PoserJoints[index].mirrorJointName()); + if (!oppositeJoint) + continue; + + bool currentlyPosingOppositeJoint = isPosingAvatarJoint(avatar, *oppositeJoint); + if (!currentlyPosingOppositeJoint) + continue; + + FSJointPose* rightJointPose = posingMotion->getJointPoseByJointName(PoserJoints[index].jointName()); + FSJointPose* leftJointPose = posingMotion->getJointPoseByJointName(oppositeJoint->jointName()); + + if (!leftJointPose || !rightJointPose) + return; + + if (rightToLeft) + leftJointPose->mirrorRotationFrom(rightJointPose); + else + rightJointPose->mirrorRotationFrom(leftJointPose); + } +} + void FSPoserAnimator::flipEntirePose(LLVOAvatar* avatar) { if (!isAvatarSafeToUse(avatar)) @@ -750,7 +633,7 @@ LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint& if (!jointPose) return scale; - return jointPose->getScaleDelta(); + return jointPose->getPublicScale(); } void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style) @@ -772,7 +655,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join if (!jointPose) return; - jointPose->setScaleDelta(scale); + jointPose->setPublicScale(scale); FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName()); if (!oppositeJointPose) return; @@ -783,7 +666,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join case MIRROR: case SYMPATHETIC_DELTA: case MIRROR_DELTA: - oppositeJointPose->setScaleDelta(scale); + oppositeJointPose->setPublicScale(scale); break; case DELTAMODE: @@ -810,10 +693,10 @@ bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJo if (!jointPose) return false; - LLQuaternion rotationDelta = jointPose->getRotationDelta(); + LLQuaternion rotationDelta = jointPose->getPublicRotation(); rotationDelta.getEulerAngles(&rot->mV[VX], &rot->mV[VY], &rot->mV[VZ]); - pos->set(jointPose->getPositionDelta()); - scale->set(jointPose->getScaleDelta()); + pos->set(jointPose->getPublicPosition()); + scale->set(jointPose->getPublicScale()); *baseRotationIsZero = jointPose->isBaseRotationZero(); return true; @@ -836,7 +719,7 @@ void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint* jointPose->zeroBaseRotation(); LLQuaternion rot = translateRotationToQuaternion(SWAP_NOTHING, NEGATE_NOTHING, rotation); - jointPose->setRotationDelta(rot); + jointPose->setPublicRotation(rot); } void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, bool loadPositionAsDelta, LLVector3 position) @@ -853,9 +736,9 @@ void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint* return; if (loadPositionAsDelta) - jointPose->setPositionDelta(position); + jointPose->setPublicPosition(position); else - jointPose->setPositionDelta(position); + jointPose->setPublicPosition(position); } void FSPoserAnimator::loadJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, bool loadScaleAsDelta, LLVector3 scale) @@ -872,9 +755,9 @@ void FSPoserAnimator::loadJointScale(LLVOAvatar* avatar, const FSPoserJoint* joi return; if (loadScaleAsDelta) - jointPose->setScaleDelta(scale); + jointPose->setPublicScale(scale); else - jointPose->setScaleDelta(scale); + jointPose->setPublicScale(scale); } const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(const std::string& jointName) diff --git a/indra/newview/fsposeranimator.h b/indra/newview/fsposeranimator.h index 7f7ce6e334..cf6652a62f 100644 --- a/indra/newview/fsposeranimator.h +++ b/indra/newview/fsposeranimator.h @@ -398,46 +398,19 @@ public: void setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, bool shouldPose); /// - /// Resets the supplied PoserJoint to its position/rotation/scale it was when poser was started. - /// - /// The avatar having the joint to which we refer. - /// The joint to be reset. - void resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint); - - /// - /// Undoes the last applied rotation to the supplied PoserJoint. - /// - /// The avatar having the joint to which we refer. - /// The joint with the rotation to undo. - void undoLastJointRotation(LLVOAvatar* avatar, const 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, const FSPoserJoint& joint, E_BoneDeflectionStyles style); - - /// - /// Undoes the last applied scale to the supplied PoserJoint. - /// - /// The avatar having the joint to which we refer. - /// The joint with the scale to undo. - void undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); - - /// - /// Resets the position of the supplied PoserJoint. + /// Resets the supplied PoserJoint to the position it had when poser was started. /// /// The avatar having the joint to which we refer. /// The joint with the position to reset. - void resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); + /// The style to apply the reset with; if a style that support more than one joint, more that one joint will be reset. + void resetJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); /// - /// Resets the scale of the supplied joint to initial values. + /// Undoes the last applied change (rotation, position or scale) to the supplied PoserJoint. /// /// The avatar having the joint to which we refer. - /// The joint with the scale to reset. - void resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); + /// The joint with the rotation to undo. + void undoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); /// /// Determines if a redo action is currently permitted for the supplied joint. @@ -445,28 +418,14 @@ public: /// The avatar having the joint to which we refer. /// The joint to query. /// True if a redo action is available, otherwise false. - bool canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint); + bool canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint); /// - /// Re-does the last undone rotation to the supplied PoserJoint. + /// Re-does the last undone change (rotation, position or scale) to the supplied PoserJoint. /// /// The avatar having the joint to which we refer. /// The joint with the rotation to redo. - void redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); - - /// - /// Re-does the last undone position to the supplied PoserJoint. - /// - /// The avatar having the joint to which we refer. - /// The joint with the position to redo. - void redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); - - /// - /// Re-does the last undone scale to the supplied PoserJoint. - /// - /// The avatar having the joint to which we refer. - /// The joint with the scale to redo. - void redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); + void redoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style); /// /// Gets the position of a joint for the supplied avatar. @@ -541,6 +500,13 @@ public: /// The avatar whose pose should flip left-right. void flipEntirePose(LLVOAvatar* avatar); + /// + /// Symmetrizes the rotations of the joints from one side of the supplied avatar to the other. + /// + /// The avatar whose joints to symmetrizet. + /// Whether to symmetrize rotations from right to left, otherwise symmetrize left to right. + void symmetrizeLeftToRightOrRightToLeft(LLVOAvatar* avatar, bool rightToLeft); + /// /// Recaptures the rotation, position and scale state of the supplied joint for the supplied avatar. /// diff --git a/indra/newview/fsposingmotion.cpp b/indra/newview/fsposingmotion.cpp index fab282552c..fc418dd911 100644 --- a/indra/newview/fsposingmotion.cpp +++ b/indra/newview/fsposingmotion.cpp @@ -260,7 +260,7 @@ void FSPosingMotion::setAllRotationsToZero() for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter) { poserJoint_iter->zeroBaseRotation(); - poserJoint_iter->setRotationDelta(LLQuaternion::DEFAULT); + poserJoint_iter->setPublicRotation(LLQuaternion::DEFAULT); } } diff --git a/indra/newview/skins/default/xui/en/floater_fs_poser.xml b/indra/newview/skins/default/xui/en/floater_fs_poser.xml index 3ec5684a08..83a0ccdd81 100644 --- a/indra/newview/skins/default/xui/en/floater_fs_poser.xml +++ b/indra/newview/skins/default/xui/en/floater_fs_poser.xml @@ -1,11 +1,12 @@ +width="430"> Inv_BodyShape Inv_Object @@ -283,7 +284,7 @@ width="403"> name="poser_stack" orientation="vertical" top="0" - width="607"> + width="700"> + height="310" + width="700"> function="Poser.CommitSpinner" parameter="3"/> + - + - Rotation: - - + name="modifier_tabs" + tab_height="20" + tab_width="90" + tab_group="1" + tab_position="top" + top_pad="0" + width="215"> + + + + Up/Down: + + + Left/Right: + + + Roll: + + + + + + + + + + + + + + Position X: + + + + + + + + + Position Y: + + + + + + + + + Position Z: + + + + + + + + + Scale X: + + + + + + + + + Scale Y: + + + + + + + + + Scale Z: + + + + + + + + + + follows="left|top|bottom" + height="44" + background_visible="false" + layout="topleft" + mouse_opaque="false" + left="0" + top_pad="2" + name="trackball_button_panel" + width="232"> + + - - Up/Down: - - - - - - - Left/Right: - - - - - - - Roll: - - - - - background_visible="false" layout="topleft" mouse_opaque="false" - left_pad="2" + left_pad="-26" visible="false" name="poses_loadSave" top="0" width="225"> left="0" name="button_controls_panel" width="800"> - left_pad="0" top_delta="0" name="advbutton_spacer_panel" - width="36"/> + width="56" + top_pad="-1" + left="2"/> @@ -1390,7 +1652,7 @@ width="403"> name="load_poses_button" left_pad="1" top_delta="0" - width="97"/> + width="95"/> - - - - - - - - - - - - - - - - - - - - - - - - - - -