Poser: Refactor undo to one stack
Rework UI: removed 'advanced' panel. Remove yaw/pitch/roll sliders. Added Symmetrize L/R.master
parent
f9035a4b8b
commit
47a2a78089
|
|
@ -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<FSVirtualTrackpad>("limb_rotation");
|
||||
mAvatarTrackball->setCommitCallback([this](LLUICtrl *, const LLSD &) { onLimbTrackballChanged(); });
|
||||
|
||||
mLimbYawSlider = getChild<LLSliderCtrl>("limb_yaw");
|
||||
mLimbYawSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); });
|
||||
|
||||
mLimbPitchSlider = getChild<LLSliderCtrl>("limb_pitch");
|
||||
mLimbPitchSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); });
|
||||
|
||||
mLimbRollSlider = getChild<LLSliderCtrl>("limb_roll");
|
||||
mLimbRollSlider->setCommitCallback([this](LLUICtrl *, const LLSD &) { onYawPitchRollSliderChanged(); });
|
||||
|
||||
mJointsTabs = getChild<LLTabContainer>("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<LLButton>("toggleAdvancedPanel");
|
||||
if (gSavedSettings.getBOOL(POSER_ADVANCEDWINDOWSTATE_SAVE_KEY))
|
||||
mToggleAdvancedPanelBtn->setValue(true);
|
||||
|
||||
mTrackpadSensitivitySlider = getChild<LLSliderCtrl>("trackpad_sensitivity_slider");
|
||||
|
||||
mPoseSaveNameEditor = getChild<LLLineEditor>("pose_save_name");
|
||||
|
|
@ -204,7 +185,6 @@ bool FSFloaterPoser::postBuild()
|
|||
mSetToTposeButton = getChild<LLButton>("set_t_pose_button");
|
||||
|
||||
mJointsParentPnl = getChild<LLPanel>("joints_parent_panel");
|
||||
mAdvancedParentPnl = getChild<LLPanel>("advanced_parent_panel");
|
||||
mTrackballPnl = getChild<LLPanel>("trackball_panel");
|
||||
mPositionRotationPnl = getChild<LLPanel>("positionRotation_panel");
|
||||
mBodyJointsPnl = getChild<LLPanel>("body_joints_panel");
|
||||
|
|
@ -220,8 +200,11 @@ bool FSFloaterPoser::postBuild()
|
|||
|
||||
mTrackpadSensitivitySpnr = getChild<LLUICtrl>("trackpad_sensitivity_spinner");
|
||||
mYawSpnr = getChild<LLUICtrl>("limb_yaw_spinner");
|
||||
mYawSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); });
|
||||
mPitchSpnr = getChild<LLUICtrl>("limb_pitch_spinner");
|
||||
mRollSpnr = getChild<LLUICtrl>("limb_roll_spinner");
|
||||
mPitchSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); });
|
||||
mRollSpnr = getChild<LLUICtrl>("limb_roll_spinner");
|
||||
mRollSpnr->setCommitCallback([this](LLUICtrl*, const LLSD&) { onYawPitchRollChanged(); });
|
||||
mUpDownSpnr = getChild<LLUICtrl>("av_position_updown_spinner");
|
||||
mLeftRightSpnr = getChild<LLUICtrl>("av_position_leftright_spinner");
|
||||
mInOutSpnr = getChild<LLUICtrl>("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<FSPoserAnimator::FSPoserJoint*> FSFloaterPoser::getUiSelectedPoserJoints() const
|
||||
{
|
||||
std::vector<FSPoserAnimator::FSPoserJoint*> 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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
/// <summary>
|
||||
/// 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 };
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "llcharacter.h"
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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 <typename T>
|
||||
inline void FSJointPose::addToUndo(T delta, size_t* undoIndex, std::deque<T>* 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 <typename T> T FSJointPose::undoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* 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 <typename T> T FSJointPose::redoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,34 +58,39 @@ class FSJointPose
|
|||
bool isCollisionVolume() const { return mIsCollisionVolume; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position change the animator wishes the joint to have.
|
||||
/// Gets the 'public' position of the joint.
|
||||
/// </summary>
|
||||
LLVector3 getPositionDelta() const { return mPositionDelta; }
|
||||
LLVector3 getPublicPosition() const { return mCurrentState.mPosition; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position the animator wishes the joint to be in.
|
||||
/// Sets the 'public' position of the joint.
|
||||
/// </summary>
|
||||
void setPositionDelta(const LLVector3& pos);
|
||||
void setPublicPosition(const LLVector3& pos);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
void undoLastPositionChange();
|
||||
void undoLastChange();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
void redoLastPositionChange();
|
||||
void redoLastChange();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation the animator wishes the joint to be in.
|
||||
/// Gets the 'public' rotation of the joint.
|
||||
/// </summary>
|
||||
LLQuaternion getRotationDelta() const { return mRotation.deltaRotation; }
|
||||
LLQuaternion getPublicRotation() const { return mCurrentState.mRotation; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation the animator wishes the joint to be in.
|
||||
/// Sets the 'public' rotation of the joint.
|
||||
/// </summary>
|
||||
void setRotationDelta(const LLQuaternion& rot);
|
||||
/// <remarks>
|
||||
/// '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.
|
||||
/// </remarks>
|
||||
void setPublicRotation(const LLQuaternion& rot);
|
||||
|
||||
/// <summary>
|
||||
/// Reflects the base and delta rotation of the represented joint left-right.
|
||||
|
|
@ -93,7 +98,7 @@ class FSJointPose
|
|||
void reflectRotation();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the base rotation of the represented joint to zero.
|
||||
/// Sets the private rotation of the represented joint to zero.
|
||||
/// </summary>
|
||||
void zeroBaseRotation();
|
||||
|
||||
|
|
@ -104,43 +109,20 @@ class FSJointPose
|
|||
bool isBaseRotationZero() const;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
void undoLastRotationChange();
|
||||
/// <returns>true if the joint may have a redo applied, otherwise false.</returns>
|
||||
bool canPerformRedo() const { return mUndoneJointStatesIndex > 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Redoes the last rotation set, if any.
|
||||
/// Gets the 'public' scale of the joint.
|
||||
/// </summary>
|
||||
void redoLastRotationChange();
|
||||
LLVector3 getPublicScale() const { return mCurrentState.mScale; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether a redo of this joints rotation may be performed.
|
||||
/// Sets the 'public' scale of the joint.
|
||||
/// </summary>
|
||||
/// <returns>true if the joint can have a redo applied, otherwise false.</returns>
|
||||
bool canRedoRotation() const { return mUndoneRotationIndex > 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
LLVector3 getScaleDelta() const { return mScaleDelta; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
void setScaleDelta(const LLVector3& scale);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last scale set, if any.
|
||||
/// </summary>
|
||||
void undoLastScaleChange();
|
||||
|
||||
/// <summary>
|
||||
/// Redoes the last scale set, if any.
|
||||
/// </summary>
|
||||
void redoLastScaleChange();
|
||||
void setPublicScale(const LLVector3& scale);
|
||||
|
||||
/// <summary>
|
||||
/// Exchanges the rotations between two joints.
|
||||
|
|
@ -168,52 +150,69 @@ class FSJointPose
|
|||
/// </summary>
|
||||
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(); }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the jointstate for the joint this represents.
|
||||
/// </summary>
|
||||
LLPointer<LLJointState> getJointState() const { return mJointState; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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<LLJointState> mJointState{ nullptr };
|
||||
|
||||
|
|
@ -223,32 +222,16 @@ private:
|
|||
/// </summary>
|
||||
bool mIsCollisionVolume{ false };
|
||||
|
||||
FSJointRotation mRotation;
|
||||
std::deque<FSJointRotation> mLastSetRotationDeltas;
|
||||
size_t mUndoneRotationIndex = 0;
|
||||
std::chrono::system_clock::time_point mTimeLastUpdatedRotation = std::chrono::system_clock::now();
|
||||
std::deque<FSJointState> mLastSetJointStates;
|
||||
size_t mUndoneJointStatesIndex = 0;
|
||||
std::chrono::system_clock::time_point mTimeLastUpdatedCurrentState = std::chrono::system_clock::now();
|
||||
|
||||
LLVector3 mPositionDelta;
|
||||
LLVector3 mBeginningPosition;
|
||||
std::deque<LLVector3> mLastSetPositionDeltas;
|
||||
size_t mUndonePositionIndex = 0;
|
||||
std::chrono::system_clock::time_point mTimeLastUpdatedPosition = std::chrono::system_clock::now();
|
||||
FSJointState mCurrentState;
|
||||
FSJointState mBeginningState;
|
||||
|
||||
/// <summary>
|
||||
/// Joint scales require special treatment, as they do not revert when we stop animating an avatar.
|
||||
/// </summary>
|
||||
LLVector3 mScaleDelta;
|
||||
LLVector3 mBeginningScale;
|
||||
std::deque<LLVector3> mLastSetScaleDeltas;
|
||||
size_t mUndoneScaleIndex = 0;
|
||||
std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now();
|
||||
|
||||
template <typename T>
|
||||
void addToUndo(T delta, size_t* undoIndex, std::deque<T>* dequeue, std::chrono::system_clock::time_point* timeLastUpdated);
|
||||
|
||||
template <typename T> T undoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue);
|
||||
|
||||
template <typename T> T redoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue);
|
||||
void addStateToUndo(FSJointState stateToAddToUndo);
|
||||
FSJointState undoLastStateChange(FSJointState currentState);
|
||||
FSJointState redoLastStateChange(FSJointState currentState);
|
||||
};
|
||||
|
||||
#endif // FS_JOINTPPOSE_H
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -398,46 +398,19 @@ public:
|
|||
void setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, bool shouldPose);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the supplied PoserJoint to its position/rotation/scale it was when poser was started.
|
||||
/// </summary>
|
||||
/// <param name="avatar">The avatar having the joint to which we refer.</param>
|
||||
/// <param name="joint">The joint to be reset.</param>
|
||||
void resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last applied rotation 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 rotation to undo.</param>
|
||||
void undoLastJointRotation(LLVOAvatar* avatar, const 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, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last applied scale 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 scale to undo.</param>
|
||||
void undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the position of the supplied PoserJoint.
|
||||
/// Resets the supplied PoserJoint to the position it had when poser was started.
|
||||
/// </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, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
/// <param name="style">The style to apply the reset with; if a style that support more than one joint, more that one joint will be reset.</param>
|
||||
void resetJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the scale of the supplied joint to initial values.
|
||||
/// Undoes the last applied change (rotation, position or scale) 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 scale to reset.</param>
|
||||
void resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
/// <param name="joint">The joint with the rotation to undo.</param>
|
||||
void undoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a redo action is currently permitted for the supplied joint.
|
||||
|
|
@ -445,28 +418,14 @@ public:
|
|||
/// <param name="avatar">The avatar having the joint to which we refer.</param>
|
||||
/// <param name="joint">The joint to query.</param>
|
||||
/// <returns>True if a redo action is available, otherwise false.</returns>
|
||||
bool canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint);
|
||||
bool canRedoJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint);
|
||||
|
||||
/// <summary>
|
||||
/// Re-does the last undone rotation to the supplied PoserJoint.
|
||||
/// Re-does the last undone change (rotation, position or scale) 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 rotation to redo.</param>
|
||||
void redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Re-does the last undone 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 redo.</param>
|
||||
void redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Re-does the last undone scale 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 scale to redo.</param>
|
||||
void redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
void redoLastJointChange(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of a joint for the supplied avatar.
|
||||
|
|
@ -541,6 +500,13 @@ public:
|
|||
/// <param name="avatar">The avatar whose pose should flip left-right.</param>
|
||||
void flipEntirePose(LLVOAvatar* avatar);
|
||||
|
||||
/// <summary>
|
||||
/// Symmetrizes the rotations of the joints from one side of the supplied avatar to the other.
|
||||
/// </summary>
|
||||
/// <param name="avatar">The avatar whose joints to symmetrizet.</param>
|
||||
/// <param name="rightToLeft">Whether to symmetrize rotations from right to left, otherwise symmetrize left to right.</param>
|
||||
void symmetrizeLeftToRightOrRightToLeft(LLVOAvatar* avatar, bool rightToLeft);
|
||||
|
||||
/// <summary>
|
||||
/// Recaptures the rotation, position and scale state of the supplied joint for the supplied avatar.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue