parent
7d07df07be
commit
e6121931d9
|
|
@ -8056,17 +8056,6 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPoserAdvancedWindowState</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether the 'advanced' pane is shown when opening the Avatar/Animesh Poser.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPoserSaveExternalFileAlso</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -8089,6 +8078,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPoserOnSaveConfirmOverwrite</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Whether to confirm overwriting a save file.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSPoserStopPosingWhenClosed</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ constexpr std::string_view POSER_TRACKPAD_SENSITIVITY_SAVE_KEY = "FSPoserTrackpa
|
|||
constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed";
|
||||
constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit";
|
||||
constexpr std::string_view POSER_SAVEEXTERNALFORMAT_SAVE_KEY = "FSPoserSaveExternalFileAlso";
|
||||
constexpr std::string_view POSER_SAVECONFIRMREQUIRED_SAVE_KEY = "FSPoserOnSaveConfirmOverwrite";
|
||||
} // namespace
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -178,6 +179,7 @@ bool FSFloaterPoser::postBuild()
|
|||
mBrowserFolderBtn = getChild<LLButton>("open_poseDir_button");
|
||||
mLoadPosesBtn = getChild<LLButton>("load_poses_button");
|
||||
mSavePosesBtn = getChild<LLButton>("save_poses_button");
|
||||
mSavePosesBtn->setMouseLeaveCallback([this](LLUICtrl*, const LLSD&) { onMouseLeaveSavePoseBtn(); });
|
||||
|
||||
mFlipPoseBtn = getChild<LLButton>("FlipPose_avatar");
|
||||
mFlipJointBtn = getChild<LLButton>("FlipJoint_avatar");
|
||||
|
|
@ -356,16 +358,22 @@ void FSFloaterPoser::onPoseFileSelect()
|
|||
mPoseSaveNameEditor->setText(name);
|
||||
|
||||
bool isDeltaSave = !poseFileStartsFromTeePose(name);
|
||||
if (isDeltaSave)
|
||||
if (isDeltaSave && hasString("LoadDiffLabel"))
|
||||
mLoadPosesBtn->setLabel(getString("LoadDiffLabel"));
|
||||
else
|
||||
else if (hasString("LoadPoseLabel"))
|
||||
mLoadPosesBtn->setLabel(getString("LoadPoseLabel"));
|
||||
}
|
||||
|
||||
void FSFloaterPoser::onClickPoseSave()
|
||||
{
|
||||
std::string filename = mPoseSaveNameEditor->getValue().asString();
|
||||
if (filename.empty())
|
||||
if (filename.empty() && hasString("icon_save_failed_button"))
|
||||
{
|
||||
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirmFileOverwrite(filename))
|
||||
return;
|
||||
|
||||
LLVOAvatar* avatar = getUiSelectedAvatar();
|
||||
|
|
@ -381,8 +389,49 @@ void FSFloaterPoser::onClickPoseSave()
|
|||
if (getSavingToBvh())
|
||||
savePoseToBvh(avatar, filename);
|
||||
|
||||
// TODO: provide feedback for save
|
||||
if (hasString("icon_rotation_is_own_work"))
|
||||
mSavePosesBtn->setImageOverlay(getString("icon_rotation_is_own_work"), mSavePosesBtn->getImageOverlayHAlign());
|
||||
|
||||
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasString("icon_save_failed_button"))
|
||||
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
|
||||
}
|
||||
}
|
||||
|
||||
bool FSFloaterPoser::confirmFileOverwrite(std::string fileName)
|
||||
{
|
||||
if (fileName.empty())
|
||||
return false;
|
||||
|
||||
if (!gSavedSettings.getBOOL(POSER_SAVECONFIRMREQUIRED_SAVE_KEY))
|
||||
return false;
|
||||
|
||||
if (!hasString("icon_save_query"))
|
||||
return false;
|
||||
|
||||
if (mSavePosesBtn->getImageOverlay().notNull() && mSavePosesBtn->getImageOverlay()->getName() == getString("icon_save_query"))
|
||||
return false;
|
||||
|
||||
std::string fullSavePath =
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, POSE_SAVE_SUBDIRECTORY, fileName + POSE_INTERNAL_FORMAT_FILE_EXT);
|
||||
|
||||
if (!gDirUtilp->fileExists(fullSavePath))
|
||||
return false;
|
||||
|
||||
mSavePosesBtn->setImageOverlay(getString("icon_save_query"), mSavePosesBtn->getImageOverlayHAlign());
|
||||
if (hasString("OverWriteLabel"))
|
||||
mSavePosesBtn->setLabel(getString("OverWriteLabel"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FSFloaterPoser::onMouseLeaveSavePoseBtn()
|
||||
{
|
||||
if (hasString("icon_save_button"))
|
||||
mSavePosesBtn->setImageOverlay(getString("icon_save_button"), mSavePosesBtn->getImageOverlayHAlign());
|
||||
}
|
||||
|
||||
void FSFloaterPoser::createUserPoseDirectoryIfNeeded()
|
||||
|
|
@ -2305,7 +2354,8 @@ void FSFloaterPoser::refreshTextHighlightingOnJointScrollLists()
|
|||
|
||||
void FSFloaterPoser::setSavePosesButtonText(bool setAsSaveDiff)
|
||||
{
|
||||
setAsSaveDiff ? mSavePosesBtn->setLabel("Save Diff") : mSavePosesBtn->setLabel("Save Pose");
|
||||
if (hasString("SavePoseLabel") && hasString("SaveDiffLabel"))
|
||||
setAsSaveDiff ? mSavePosesBtn->setLabel(getString("SaveDiffLabel")) : mSavePosesBtn->setLabel(getString("SavePoseLabel"));
|
||||
}
|
||||
|
||||
void FSFloaterPoser::addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar)
|
||||
|
|
@ -2600,8 +2650,8 @@ S32 FSFloaterPoser::getBvhJointNegation(const std::string& jointName) const
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool FSFloaterPoser::getWhetherToResetBaseRotationOnEdit() { return gSavedSettings.getBOOL(POSER_RESETBASEROTONEDIT_SAVE_KEY); }
|
||||
|
||||
void FSFloaterPoser::onClickSetBaseRotZero() { mAlsoSaveBvhCbx->setEnabled(getWhetherToResetBaseRotationOnEdit()); }
|
||||
|
||||
bool FSFloaterPoser::getSavingToBvh()
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ public:
|
|||
void createUserPoseDirectoryIfNeeded();
|
||||
void onToggleLoadSavePanel();
|
||||
void onClickPoseSave();
|
||||
void onMouseLeaveSavePoseBtn();
|
||||
void onPoseFileSelect();
|
||||
bool savePoseToXml(LLVOAvatar* avatar, const std::string& posePath);
|
||||
bool savePoseToBvh(LLVOAvatar* avatar, const std::string& posePath);
|
||||
|
|
@ -229,6 +230,7 @@ public:
|
|||
bool poseFileStartsFromTeePose(const std::string& poseFileName);
|
||||
void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName();
|
||||
void setUiSelectedAvatarSaveFileName(const std::string& saveFileName);
|
||||
bool confirmFileOverwrite(std::string fileName);
|
||||
void startPosingSelf();
|
||||
void stopPosingAllAvatars();
|
||||
// visual manipulators control
|
||||
|
|
|
|||
|
|
@ -504,13 +504,13 @@ public:
|
|||
/// <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="avatar">The avatar to symmetrize.</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.
|
||||
/// AsDelta variant retians the original base and creates a delta relative to it.
|
||||
/// AsDelta variant retains the original base and creates a delta relative to it.
|
||||
/// </summary>
|
||||
/// <param name="avatar">The avatar whose joint is to be recaptured.</param>
|
||||
/// <param name="joint">The joint to recapture.</param>
|
||||
|
|
@ -533,14 +533,11 @@ public:
|
|||
void setAllAvatarStartingRotationsToZero(LLVOAvatar* avatar);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the kind of save to perform should be a 'delta' save, or a complete save.
|
||||
/// Determines if the supplied joint has a base rotation of zero.
|
||||
/// </summary>
|
||||
/// <param name="avatar">The avatar whose pose-rotations are being considered for saving.</param>
|
||||
/// <returns>True if the save should save only 'deltas' to the rotation, otherwise false.</returns>
|
||||
/// <remarks>
|
||||
/// A save of the rotation 'deltas' facilitates a user saving their changes to an existing animation.
|
||||
/// Thus the save represents 'nothing other than the changes the user made', to some other pose which they may have limited rights to.
|
||||
/// </remarks>
|
||||
/// <param name="avatar">The avatar owning the supplied joint.</param>
|
||||
/// <param name="joint">The joint to query.</param>
|
||||
/// <returns>True if the supplied joint has a 'base' rotation of zero (thus user-supplied change only), otherwise false.</returns>
|
||||
bool baseRotationIsZero(LLVOAvatar* avatar, const FSPoserJoint& joint) const;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ width="430">
|
|||
<string name="icon_bone" translate="false"></string>
|
||||
<string name="icon_object" translate="false">Inv_Object</string>
|
||||
<string name="icon_rotation_is_own_work" translate="false">Check_Mark</string>
|
||||
<string name="icon_save_button" translate="false">Icon_Dock_Foreground</string>
|
||||
<string name="icon_save_failed_button" translate="false">Parcel_Exp_Color</string>
|
||||
<string name="icon_save_query" translate="false">Info</string>
|
||||
|
||||
<!-- Provides for axis-swapping per joint for slider/trackpad control -->
|
||||
<!-- Begins with joint_transform_ then has an internal joint name, ONE swap choice of:
|
||||
|
|
@ -278,7 +281,10 @@ width="430">
|
|||
<string name="bvh_joint_transform_mHead" translate="false">SWAP_X2Y_Y2Z_Z2X</string>
|
||||
|
||||
<string name="LoadPoseLabel">Load Pose</string>
|
||||
<string name="SavePoseLabel">Save Pose</string>
|
||||
<string name="LoadDiffLabel">Load Diff</string>
|
||||
<string name="SaveDiffLabel">Save Diff</string>
|
||||
<string name="OverWriteLabel">Overwrite?</string>
|
||||
|
||||
<!-- The layout is a vertical stack of 3 rows, and each row a horizontal stack of panels -->
|
||||
<layout_stack
|
||||
|
|
@ -925,6 +931,16 @@ width="430">
|
|||
tool_tip="When you save your pose, also write a BVH file, which can be uploaded via the 'Build > Upload > Animation' to pose yourself or others in-world. This needs joints to reset their 'base' to zero, because BVH requires original work."
|
||||
top_pad="2"
|
||||
width="134" />
|
||||
<check_box
|
||||
control_name="FSPoserOnSaveConfirmOverwrite"
|
||||
name="confirm_overwrite_on_save_checkbox"
|
||||
height="16"
|
||||
label="Confirm Overwrite"
|
||||
follows="left|top"
|
||||
left="5"
|
||||
tool_tip="When you save a pose, if the file already exists, you need to click the save button again to confirm you are sure you want to overwrite."
|
||||
top_pad="5"
|
||||
width="134" />
|
||||
</panel>
|
||||
</tab_container>
|
||||
<button
|
||||
|
|
|
|||
Loading…
Reference in New Issue