Refactor the entire poser

master
Ansariel 2024-10-26 19:17:30 +02:00
parent 72ed042834
commit f4a502de24
10 changed files with 1270 additions and 1421 deletions

View File

@ -593,7 +593,7 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
return true;
}
bool LLPanel::hasString(std::string_view name)
bool LLPanel::hasString(std::string_view name) const
{
return mUIStrings.find(name) != mUIStrings.end();
}

View File

@ -169,7 +169,7 @@ public:
void initFromParams(const Params& p);
bool initPanelXML( LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params);
bool hasString(std::string_view name);
bool hasString(std::string_view name) const;
std::string getString(std::string_view name, const LLStringUtil::format_map_t& args) const;
std::string getString(std::string_view name) const;

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,14 @@
#include "llfloater.h"
#include "fsposeranimator.h"
class FSVirtualTrackpad;
class LLButton;
class LLCheckBoxCtrl;
class LLLineEditor;
class LLScrollListCtrl;
class LLSliderCtrl;
class LLTabContainer;
/// <summary>
/// Describes how to load a pose file.
/// </summary>
@ -68,23 +76,16 @@ class FSFloaterPoser : public LLFloater
friend class LLFloaterReg;
FSFloaterPoser(const LLSD &key);
private:
/*virtual*/ ~FSFloaterPoser();
/*virtual*/ bool postBuild();
/*virtual*/ void draw();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
private:
bool postBuild() override;
void onOpen(const LLSD& key) override;
void onClose(bool app_quitting) override;
/// <summary>
/// The amount of deflection 'one unit' on the trackpad translates to in radians.
/// The trackpad ordinarily has a range of +1..-1; multiplied by PI, gives PI to -PI, or all 360 degrees of deflection.
/// </summary>
const F32 normalTrackpadRangeInRads = F_PI;
/// <summary>
/// Refreshes the supplied pose list from the supplued subdirectory.
/// </summary>
void refreshPoseScroll(std::string_view scrollListName, std::string_view subDirectory);
void refreshPoseScroll(LLScrollListCtrl* posesScrollList, std::optional<std::string_view> subDirectory = std::nullopt);
/// <summary>
/// (Dis)Enables all of the posing controls; such as when you can't pose for reasons.
@ -105,7 +106,7 @@ class FSFloaterPoser : public LLFloater
/// This does a lookup into the poser XML for a friendly header title by joint name, if it exists.
/// </param>
/// <param name="bodyJointsScrollList">The scroll list to add the header-row to.</param>
void AddHeaderRowToScrollList(std::string jointName, LLScrollListCtrl *bodyJointsScrollList);
void addHeaderRowToScrollList(const std::string& jointName, LLScrollListCtrl* bodyJointsScrollList);
/// <summary>
/// Generates the data for a row to add to a scroll-list.
@ -114,52 +115,52 @@ class FSFloaterPoser : public LLFloater
/// <param name="jointName">The well-known joint name of the joint to add the row for, eg: mChest.</param>
/// <param name="isHeaderRow">Whether the joint is one which should come immediately after a header.</param>
/// <returns>The data required to make the row.</returns>
LLSD createRowForJoint(std::string jointName, bool isHeaderRow);
LLSD createRowForJoint(const std::string& jointName, bool isHeaderRow);
/// <summary>
/// Gets the collection of poser joints currently selected on the active bones-tab of the UI.
/// </summary>
/// <returns>The selected joints</returns>
std::vector<FSPoserAnimator::FSPoserJoint *> getUiSelectedPoserJoints() const;
std::vector<FSPoserAnimator::FSPoserJoint*> getUiSelectedPoserJoints() const;
/// <summary>
/// Gets a detectable avatar by its UUID.
/// </summary>
/// <param name="avatarToFind">The ID of the avatar to find.</param>
/// <returns>The avatar, if found, otherwise nullptr.</returns>
LLVOAvatar* getAvatarByUuid(LLUUID avatarToFind);
LLVOAvatar* getAvatarByUuid(const LLUUID& avatarToFind) const;
/// <summary>
/// Gets the currently selected avatar or animesh.
/// </summary>
/// <returns>The currently selected avatar or animesh.</returns>
LLVOAvatar *getUiSelectedAvatar();
LLVOAvatar* getUiSelectedAvatar() const;
/// <summary>
/// Gets the current bone-deflection style: encapsulates 'anything else you want to do' while you're manipulating a joint.
/// Such as: fiddle the opposite joint too.
/// </summary>
/// <returns>A E_BoneDeflectionStyles member.</returns>
E_BoneDeflectionStyles getUiSelectedBoneDeflectionStyle();
E_BoneDeflectionStyles getUiSelectedBoneDeflectionStyle() const;
/// <summary>
/// Gets the collection of UUIDs for nearby avatars.
/// </summary>
/// <returns>A the collection of UUIDs for nearby avatars.</returns>
uuid_vec_t getNearbyAvatarsAndAnimeshes();
uuid_vec_t getNearbyAvatarsAndAnimeshes() const;
/// <summary>
/// Gets a collection of UUIDs for avatars currently being presented on the UI.
/// </summary>
/// <returns>A the collection of UUIDs.</returns>
uuid_vec_t getCurrentlyListedAvatarsAndAnimeshes();
uuid_vec_t getCurrentlyListedAvatarsAndAnimeshes() const;
/// <summary>
/// Gets the scroll-list index of the supplied avatar.
/// </summary>
/// <param name="toFind">The avatar UUID to find on the avatars scroll list.</param>
/// <returns>The scroll-list index for the supplied avatar, if found, otherwise -1.</returns>
S32 getAvatarListIndexForUuid(LLUUID toFind);
S32 getAvatarListIndexForUuid(const LLUUID& toFind) const;
/// <summary>
/// There are several control-callbacks manipulating rotations etc, they all devolve to these.
@ -182,21 +183,21 @@ class FSFloaterPoser : public LLFloater
/// There may be +/- PI difference two axes, because harmonics.
/// Thus keep your UI synced with less gets.
/// </remarks>
LLVector3 getRotationOfFirstSelectedJoint();
LLVector3 getPositionOfFirstSelectedJoint();
LLVector3 getScaleOfFirstSelectedJoint();
LLVector3 getRotationOfFirstSelectedJoint() const;
LLVector3 getPositionOfFirstSelectedJoint() const;
LLVector3 getScaleOfFirstSelectedJoint() const;
// Pose load/save
void onToggleLoadSavePanel();
void onClickPoseSave();
void onPoseFileSelect();
bool savePoseToXml(LLVOAvatar* avatar, std::string posePath);
bool savePoseToBvh(LLVOAvatar* avatar, std::string posePath);
bool savePoseToXml(LLVOAvatar* avatar, const std::string& posePath);
bool savePoseToBvh(LLVOAvatar* avatar, const std::string& posePath);
void onClickBrowsePoseCache();
void onPoseMenuAction(const LLSD& param);
void loadPoseFromXml(LLVOAvatar* avatar, std::string poseFileName, E_LoadPoseMethods loadMethod);
void loadPoseFromXml(LLVOAvatar* avatar, const std::string& poseFileName, E_LoadPoseMethods loadMethod);
void setPoseSaveFileTextBoxToUiSelectedAvatarSaveFileName();
void setUiSelectedAvatarSaveFileName(std::string saveFileName);
void setUiSelectedAvatarSaveFileName(const std::string& saveFileName);
void showOrHideAdvancedSaveOptions();
// UI Event Handlers:
@ -246,20 +247,20 @@ class FSFloaterPoser : public LLFloater
/// </summary>
/// <param name="avatar">The avatar to animate.</param>
/// <returns>True if we have permission to animate, otherwise false.</returns>
bool havePermissionToAnimateAvatar(LLVOAvatar *avatar);
bool havePermissionToAnimateAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Determines if we could animate the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to animate.</param>
/// <returns>True if the avatar is non-null, not dead, in the same region as self, otherwise false.</returns>
bool couldAnimateAvatar(LLVOAvatar *avatar);
bool couldAnimateAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Our instance of the class which lets us do the business of manipulating the avatar.
/// This separates that business from the code-behind the UI.
/// </summary>
FSPoserAnimator _poserAnimator;
FSPoserAnimator mPoserAnimator;
/// <summary>
/// The supplied Joint name has a quaternion describing its rotation.
@ -274,14 +275,14 @@ class FSFloaterPoser : public LLFloater
/// No the translation isn't untangling all of that, it's not needed until it is.
/// We're not landing on Mars with this code, just offering a user reasonable thumb-twiddlings.
/// </remarks>
E_BoneAxisTranslation getJointTranslation(std::string jointName);
E_BoneAxisTranslation getJointTranslation(const std::string& jointName) const;
/// <summary>
/// Gets the collection of E_BoneAxisNegation values for the supplied joint.
/// </summary>
/// <param name="jointName">The name of the joind to get the axis transformation for.</param>
/// <returns>The kind of axis transformation to perform.</returns>
S32 getJointNegation(std::string jointName);
S32 getJointNegation(const std::string& jointName) const;
/// <summary>
/// The smallest text embiggens the noble selection.
@ -293,18 +294,18 @@ class FSFloaterPoser : public LLFloater
/// </summary>
/// <param name="listName">The name of the list to adjust text-face for.</param>
/// <param name="avatar">The avatar to whom the list is relevant.</param>
void addBoldToScrollList(std::string listName, LLVOAvatar *avatar);
void addBoldToScrollList(LLScrollListCtrl* list, LLVOAvatar* avatar);
/// <summary>
/// The time when the last click of a button was made.
/// Utilized for controls needing a 'double click do' function.
/// </summary>
std::chrono::system_clock::time_point _timeLastClickedJointReset = std::chrono::system_clock::now();
std::chrono::system_clock::time_point mTimeLastClickedJointReset = std::chrono::system_clock::now();
/// <summary>
/// The constant time interval, in seconds, a user must click twice within to successfully double-click a button.
/// </summary>
std::chrono::duration<double> const _doubleClickInterval = std::chrono::duration<double>(0.3);
std::chrono::duration<double> const mDoubleClickInterval = std::chrono::duration<double>(0.3);
/// <summary>
/// Unwraps a normalized value from the trackball to a slider value.
@ -312,6 +313,65 @@ class FSFloaterPoser : public LLFloater
/// <param name="scale">The scale value from the trackball.</param>
/// <returns>A value appropriate for fitting a slider.</returns>
static F32 unWrapScale(F32 scale);
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 };
LLSliderCtrl* mAdvPosXSlider{ nullptr };
LLSliderCtrl* mAdvPosYSlider{ nullptr };
LLSliderCtrl* mAdvPosZSlider{ nullptr };
LLSliderCtrl* mAdvScaleXSlider{ nullptr };
LLSliderCtrl* mAdvScaleYSlider{ nullptr };
LLSliderCtrl* mAdvScaleZSlider{ nullptr };
LLTabContainer* mJointsTabs{ nullptr };
LLTabContainer* mHandsTabs{ nullptr };
LLScrollListCtrl* mAvatarSelectionScrollList{ nullptr };
LLScrollListCtrl* mBodyJointsScrollList{ nullptr };
LLScrollListCtrl* mFaceJointsScrollList{ nullptr };
LLScrollListCtrl* mHandJointsScrollList{ nullptr };
LLScrollListCtrl* mMiscJointsScrollList{ nullptr };
LLScrollListCtrl* mCollisionVolumesScrollList{ nullptr };
LLScrollListCtrl* mEntireAvJointScroll{ nullptr };
LLScrollListCtrl* mPosesScrollList{ nullptr };
LLScrollListCtrl* mHandPresetsScrollList{ nullptr };
LLButton* mToggleAdvancedPanelBtn{ nullptr };
LLButton* mStartStopPosingBtn{ nullptr };
LLButton* mToggleLoadSavePanelBtn{ nullptr };
LLButton* mBrowserFolderBtn{ nullptr };
LLButton* mLoadPosesBtn{ nullptr };
LLButton* mSavePosesBtn{ nullptr };
LLButton* mFlipPoseBtn{ nullptr };
LLButton* mFlipJointBtn{ nullptr };
LLButton* mRecaptureBtn{ nullptr };
LLButton* mTogglePosingBonesBtn{ nullptr };
LLButton* mToggleMirrorRotationBtn{ nullptr };
LLButton* mToggleSympatheticRotationBtn{ nullptr };
LLButton* mToggleDeltaModeBtn{ nullptr };
LLButton* mRedoChangeBtn{ nullptr };
LLCheckBoxCtrl* mAlsoSaveBvhCbx{ nullptr };
LLLineEditor* mPoseSaveNameEditor{ nullptr };
LLPanel* mAdvancedParentPnl{ nullptr };
LLPanel* mJointsParentPnl{ nullptr };
LLPanel* mTrackballPnl{ nullptr };
LLPanel* mPositionRotationPnl{ nullptr };
LLPanel* mBodyJointsPnl{ nullptr };
LLPanel* mFaceJointsPnl{ nullptr };
LLPanel* mHandsJointsPnl{ nullptr };
LLPanel* mMiscJointsPnl{ nullptr };
LLPanel* mCollisionVolumesPnl{ nullptr };
LLPanel* mSaveFilePptionsPnl{ nullptr };
LLPanel* mPosesLoadSavePnl{ nullptr };
};
#endif

View File

@ -31,11 +31,9 @@
#include "llagent.h"
#include "fsposingmotion.h"
FSPoserAnimator::FSPoserAnimator() {}
FSPoserAnimator::~FSPoserAnimator() {}
std::map<LLUUID, LLAssetID> FSPoserAnimator::_avatarIdToRegisteredAnimationId;
std::map<LLUUID, LLAssetID> FSPoserAnimator::sAvatarIdToRegisteredAnimationId;
bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -54,7 +52,7 @@ bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint
return posingMotion->currentlyPosingJoint(jointPose);
}
void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint, bool shouldPose)
void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, bool shouldPose)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -80,7 +78,7 @@ void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint join
posingMotion->removeJointFromState(jointPose);
}
void FSPoserAnimator::resetAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -100,7 +98,7 @@ void FSPoserAnimator::resetAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint)
jointPose->setTargetRotation(jointPose->getBeginningRotation());
}
void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -128,7 +126,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->undoLastRotationSet();
}
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -156,7 +154,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->undoLastPositionSet();
}
void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -184,7 +182,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->undoLastScaleSet();
}
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -212,7 +210,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->setTargetPosition(oppositeJointPose->getBeginningPosition());
}
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -240,7 +238,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_
oppositeJointPose->setTargetScale(oppositeJointPose->getBeginningScale());
}
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint joint)
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint)
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -259,7 +257,7 @@ bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, FSPoserJoint join
return jointPose->canRedoRotation();
}
void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -287,7 +285,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->redoLastRotationSet();
}
void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -315,7 +313,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
oppositeJointPose->redoLastPositionSet();
}
void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style)
void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -343,7 +341,7 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
oppositeJointPose->redoLastScaleSet();
}
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture)
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
{
LLVector3 pos;
if (!isAvatarSafeToUse(avatar))
@ -365,7 +363,7 @@ LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, FSPoserJoint joi
return pos;
}
void FSPoserAnimator::setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 position, E_BoneDeflectionStyles style)
void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -414,7 +412,7 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *j
}
}
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar *avatar, FSPoserJoint joint, E_BoneAxisTranslation translation, S32 negation, bool forRecapture)
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation, bool forRecapture) const
{
LLVector3 vec3;
if (!isAvatarSafeToUse(avatar))
@ -437,7 +435,7 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar *avatar, FSPoserJoint joi
return translateRotationFromQuaternion(translation, negation, rot);
}
void FSPoserAnimator::setJointRotation(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 rotation, E_BoneDeflectionStyles style,
void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation, E_BoneDeflectionStyles style,
E_BoneAxisTranslation translation, S32 negation)
{
if (!isAvatarSafeToUse(avatar))
@ -492,7 +490,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar *avatar, const FSPoserJoint *j
}
}
void FSPoserAnimator::reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint)
void FSPoserAnimator::reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -526,7 +524,7 @@ void FSPoserAnimator::reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint
oppositeJointPose->setTargetRotation(first_inv);
}
void FSPoserAnimator::flipEntirePose(LLVOAvatar *avatar)
void FSPoserAnimator::flipEntirePose(LLVOAvatar* avatar)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -553,8 +551,7 @@ void FSPoserAnimator::flipEntirePose(LLVOAvatar *avatar)
}
// from the UI to the bone, the inverse translation, the un-swap, the backwards
LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslation translation, S32 negation,
LLVector3 rotation)
LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslation translation, S32 negation, LLVector3 rotation)
{
if (negation & NEGATE_ALL)
{
@ -608,7 +605,7 @@ LLQuaternion FSPoserAnimator::translateRotationToQuaternion(E_BoneAxisTranslatio
}
// from the bone to the UI; this is the 'forwards' use of the enum
LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, LLQuaternion rotation)
LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, const LLQuaternion& rotation) const
{
LLVector3 vec3;
@ -659,7 +656,7 @@ LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation
return vec3;
}
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture)
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
{
LLVector3 scale;
if (!isAvatarSafeToUse(avatar))
@ -681,7 +678,7 @@ LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, FSPoserJoint joint,
return scale;
}
void FSPoserAnimator::setJointScale(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 scale, E_BoneDeflectionStyles style)
void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style)
{
if (!isAvatarSafeToUse(avatar))
return;
@ -712,7 +709,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar *avatar, const FSPoserJoint *join
oppositeJointPose->setTargetScale(scale);
}
const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(std::string jointName)
const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(const std::string& jointName)
{
for (size_t index = 0; index != PoserJoints.size(); ++index)
{
@ -758,7 +755,7 @@ void FSPoserAnimator::stopPosingAvatar(LLVOAvatar *avatar)
avatar->stopMotion(posingMotion->motionId());
}
bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar)
bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar) const
{
if (!isAvatarSafeToUse(avatar))
return false;
@ -770,15 +767,15 @@ bool FSPoserAnimator::isPosingAvatar(LLVOAvatar* avatar)
return !posingMotion->isStopped();
}
FSPosingMotion* FSPoserAnimator::getPosingMotion(LLVOAvatar* avatar)
FSPosingMotion* FSPoserAnimator::getPosingMotion(LLVOAvatar* avatar) const
{
if (!isAvatarSafeToUse(avatar))
return nullptr;
if (_avatarIdToRegisteredAnimationId.find(avatar->getID()) == _avatarIdToRegisteredAnimationId.end())
if (sAvatarIdToRegisteredAnimationId.find(avatar->getID()) == sAvatarIdToRegisteredAnimationId.end())
return nullptr;
return dynamic_cast<FSPosingMotion*>(avatar->findMotion(_avatarIdToRegisteredAnimationId[avatar->getID()]));
return dynamic_cast<FSPosingMotion*>(avatar->findMotion(sAvatarIdToRegisteredAnimationId[avatar->getID()]));
}
FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
@ -792,7 +789,7 @@ FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
LLAssetID animationAssetId = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
if (avatar->registerMotion(animationAssetId, FSPosingMotion::create))
_avatarIdToRegisteredAnimationId[avatar->getID()] = animationAssetId;
sAvatarIdToRegisteredAnimationId[avatar->getID()] = animationAssetId;
return dynamic_cast<FSPosingMotion*>(avatar->createMotion(animationAssetId));
}
@ -800,7 +797,7 @@ FSPosingMotion* FSPoserAnimator::findOrCreatePosingMotion(LLVOAvatar* avatar)
return motion;
}
bool FSPoserAnimator::isAvatarSafeToUse(LLVOAvatar *avatar)
bool FSPoserAnimator::isAvatarSafeToUse(LLVOAvatar* avatar) const
{
if (!avatar)
return false;
@ -829,7 +826,7 @@ bool FSPoserAnimator::writePoseAsBvh(llofstream* fileStream, LLVOAvatar* avatar)
return true;
}
bool FSPoserAnimator::writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, int tabStops)
bool FSPoserAnimator::writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, S32 tabStops)
{
if (!joint)
return false;
@ -903,30 +900,21 @@ bool FSPoserAnimator::writeBvhMotion(llofstream* fileStream, LLVOAvatar* avatar,
return true;
}
std::string FSPoserAnimator::vec3ToXYZString(LLVector3 val)
std::string FSPoserAnimator::vec3ToXYZString(const LLVector3& val)
{
return f32ToString(val[VX]) + " " + f32ToString(val[VY]) + " " + f32ToString(val[VZ]);
return std::to_string(val[VX]) + " " + std::to_string(val[VY]) + " " + std::to_string(val[VZ]);
}
std::string FSPoserAnimator::rotationToYZXString(LLVector3 val)
std::string FSPoserAnimator::rotationToYZXString(const LLVector3& val)
{
return f32ToString(val[VY] * RAD_TO_DEG) + " " + f32ToString(val[VZ] * RAD_TO_DEG) + " " + f32ToString(val[VX] * RAD_TO_DEG);
return std::to_string(val[VY] * RAD_TO_DEG) + " " + std::to_string(val[VZ] * RAD_TO_DEG) + " " + std::to_string(val[VX] * RAD_TO_DEG);
}
std::string FSPoserAnimator::getTabs(int numOfTabstops)
std::string FSPoserAnimator::getTabs(S32 numOfTabstops)
{
std::string tabSpaces;
for (int i = 0; i < numOfTabstops; i++)
for (S32 i = 0; i < numOfTabstops; i++)
tabSpaces += "\t";
return tabSpaces;
}
std::string FSPoserAnimator::f32ToString(F32 val)
{
std::string str;
char buf[20];
snprintf(buf, 20, "%f", val);
str = buf;
return str;
}

View File

@ -88,9 +88,9 @@ typedef enum E_BoneAxisNegation
class FSPoserAnimator
{
public:
FSPoserAnimator();
FSPoserAnimator() = default;
virtual ~FSPoserAnimator();
virtual ~FSPoserAnimator() = default;
/// <summary>
/// A class encapsulating 'metadata' for a joint, such as its catagory and its opposite joint name.
@ -98,56 +98,57 @@ public:
/// </summary>
class FSPoserJoint
{
std::string _jointName; // expected to be a match to LLJoint.getName() for a joint implementation.
std::string _mirrorJointName;
E_BoneTypes _boneList;
std::vector<std::string> _bvhChildren;
bool _dontFlipOnMirror = false;
std::string mJointName; // expected to be a match to LLJoint.getName() for a joint implementation.
std::string mMirrorJointName;
E_BoneTypes mBoneList;
std::vector<std::string> mBvhChildren;
bool mDontFlipOnMirror = false;
public:
/// <summary>
/// Gets the name of the joint.
/// </summary>
std::string jointName() const { return _jointName; }
std::string jointName() const { return mJointName; }
/// <summary>
/// Gets the name of the mirror of this joint, or an empty string if there is no mirror.
/// </summary>
std::string mirrorJointName() const { return _mirrorJointName; }
std::string mirrorJointName() const { return mMirrorJointName; }
/// <summary>
/// Gets the E_BoneTypes of the joint.
/// </summary>
E_BoneTypes boneType() const { return _boneList; }
E_BoneTypes boneType() const { return mBoneList; }
/// <summary>
/// Gets whether when mirroring the entire body, should this joint flip its counterpart.
/// </summary>
bool dontFlipOnMirror() const { return _dontFlipOnMirror; }
bool dontFlipOnMirror() const { return mDontFlipOnMirror; }
/// <summary>
/// Gets the collection of child bvh joints for this.
/// </summary>
std::vector<std::string> bvhChildren() const { return _bvhChildren; }
std::vector<std::string> bvhChildren() const { return mBvhChildren; }
/// <summary>
/// Creates a new instance of a PoserJoint.
/// </summary>
/// <param name="a">
/// <param name="joint_name">
/// The joint name, should be one of the well known bones/joints/thingos.
/// An example for an LLJoints implementation would be what LLJoint.getName() returns, like 'mChest'.
/// Very likely case-sensitive.
/// </param>
/// <param name="b">The opposite joint name, if any. Also expected to be a well-known name.</param>
/// <param name="c">The type of bone, often determining with which other bones the new instance would appear with.</param>
/// <param name="d">The optional array of joints, needed for BVH saving, which are the direct decendent(s) of this joint.</param>
/// <param name="e">The option for whether this joint should rotation-flip it counterpart when mirroring the pose of the entire body.</param>
FSPoserJoint(std::string a, std::string b, E_BoneTypes c, std::vector<std::string> d = {}, bool e = false)
/// <param name="mirror_joint_name">The opposite joint name, if any. Also expected to be a well-known name.</param>
/// <param name="bone_list">The type of bone, often determining with which other bones the new instance would appear with.</param>
/// <param name="bhv_children">The optional array of joints, needed for BVH saving, which are the direct decendent(s) of this joint.</param>
/// <param name="dont_flip_on_mirror">The option for whether this joint should rotation-flip it counterpart when mirroring the pose of the entire body.</param>
FSPoserJoint(std::string joint_name, std::string mirror_joint_name, E_BoneTypes bone_list, std::vector<std::string> bhv_children = {}, bool dont_flip_on_mirror = false)
{
_jointName = a;
_mirrorJointName = b;
_boneList = c;
_bvhChildren = d;
_dontFlipOnMirror = e;
mJointName = joint_name;
mMirrorJointName = mirror_joint_name;
mBoneList = bone_list;
mBvhChildren = bhv_children;
mDontFlipOnMirror = dont_flip_on_mirror;
}
};
@ -159,56 +160,132 @@ public:
/// <remarks>
/// For an implementation of something other than LLJoints, different name(s) may be required.
/// </remarks>
const std::vector<FSPoserJoint> PoserJoints {
const std::vector<FSPoserJoint> PoserJoints{
// head, torso, legs
{"mHead", "", BODY}, {"mNeck", "", BODY, {"mHead"}}, {"mPelvis", "", WHOLEAVATAR, {"mTorso", "mHipLeft", "mHipRight"}}, {"mChest", "", BODY, {"mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot"}}, {"mTorso", "", BODY, {"mChest"}},
{"mCollarLeft", "mCollarRight", BODY, {"mShoulderLeft"}}, {"mShoulderLeft", "mShoulderRight", BODY, {"mElbowLeft"}}, {"mElbowLeft", "mElbowRight", BODY, {"mWristLeft"}}, {"mWristLeft", "mWristRight", BODY},
{"mCollarRight", "mCollarLeft", BODY, {"mShoulderRight"}, true}, {"mShoulderRight", "mShoulderLeft", BODY, {"mElbowRight"}, true}, {"mElbowRight", "mElbowLeft", BODY, {"mWristRight"}, true}, {"mWristRight", "mWristLeft", BODY, {}, true},
{"mHipLeft", "mHipRight", BODY, {"mKneeLeft"}}, {"mKneeLeft", "mKneeRight", BODY, {"mAnkleLeft"}}, {"mAnkleLeft", "mAnkleRight", BODY},
{"mHipRight", "mHipLeft", BODY, {"mKneeRight"}, true}, {"mKneeRight", "mKneeLeft", BODY, {"mAnkleRight"}, true}, {"mAnkleRight", "mAnkleLeft", BODY, {}, true},
{ "mHead", "", BODY },
{ "mNeck", "", BODY, { "mHead" } },
{ "mPelvis", "", WHOLEAVATAR, { "mTorso", "mHipLeft", "mHipRight" } },
{ "mChest", "", BODY, { "mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot" } },
{ "mTorso", "", BODY, { "mChest" } },
{ "mCollarLeft", "mCollarRight", BODY, { "mShoulderLeft" } },
{ "mShoulderLeft", "mShoulderRight", BODY, { "mElbowLeft" } },
{ "mElbowLeft", "mElbowRight", BODY, { "mWristLeft" } },
{ "mWristLeft", "mWristRight", BODY },
{ "mCollarRight", "mCollarLeft", BODY, { "mShoulderRight" }, true },
{ "mShoulderRight", "mShoulderLeft", BODY, { "mElbowRight" }, true },
{ "mElbowRight", "mElbowLeft", BODY, { "mWristRight" }, true },
{ "mWristRight", "mWristLeft", BODY, {}, true },
{ "mHipLeft", "mHipRight", BODY, { "mKneeLeft" } },
{ "mKneeLeft", "mKneeRight", BODY, { "mAnkleLeft" } },
{ "mAnkleLeft", "mAnkleRight", BODY },
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, true },
{ "mKneeRight", "mKneeLeft", BODY, { "mAnkleRight" }, true },
{ "mAnkleRight", "mAnkleLeft", BODY, {}, true },
// face
{"mFaceForeheadLeft", "mFaceForeheadRight", FACE}, {"mFaceForeheadCenter", "", FACE}, {"mFaceForeheadRight", "mFaceForeheadLeft", FACE, {}, true},
{"mFaceEyebrowOuterLeft", "mFaceEyebrowOuterRight", FACE}, {"mFaceEyebrowCenterLeft", "mFaceEyebrowCenterRight", FACE}, {"mFaceEyebrowInnerLeft", "mFaceEyebrowInnerRight", FACE},
{"mFaceEyebrowOuterRight", "mFaceEyebrowOuterLeft", FACE, {}, true}, {"mFaceEyebrowCenterRight", "mFaceEyebrowCenterLeft", FACE, {}, true}, {"mFaceEyebrowInnerRight", "mFaceEyebrowInnerLeft", FACE, {}, true},
{ "mFaceForeheadLeft", "mFaceForeheadRight", FACE },
{ "mFaceForeheadCenter", "", FACE },
{ "mFaceForeheadRight", "mFaceForeheadLeft", FACE, {}, true },
{ "mFaceEyebrowOuterLeft", "mFaceEyebrowOuterRight", FACE },
{ "mFaceEyebrowCenterLeft", "mFaceEyebrowCenterRight", FACE },
{ "mFaceEyebrowInnerLeft", "mFaceEyebrowInnerRight", FACE },
{ "mFaceEyebrowOuterRight", "mFaceEyebrowOuterLeft", FACE, {}, true },
{ "mFaceEyebrowCenterRight", "mFaceEyebrowCenterLeft", FACE, {}, true },
{ "mFaceEyebrowInnerRight", "mFaceEyebrowInnerLeft", FACE, {}, true },
{"mEyeLeft", "mEyeRight", FACE}, {"mEyeRight", "mEyeLeft", FACE, {}, true},
{"mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE}, {"mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE}, {"mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, true}, {"mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, true},
{ "mEyeLeft", "mEyeRight", FACE },
{ "mEyeRight", "mEyeLeft", FACE, {}, true },
{ "mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE },
{ "mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE },
{ "mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, true },
{ "mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, true },
{"mFaceCheekUpperLeft", "mFaceCheekUpperRight", FACE}, {"mFaceCheekLowerLeft", "mFaceCheekLowerRight", FACE}, {"mFaceCheekUpperRight", "mFaceCheekUpperLeft", FACE, {}, true}, {"mFaceCheekLowerRight", "mFaceCheekLowerLeft", FACE, {}, true},
{"mFaceLipUpperLeft", "mFaceLipUpperRight", FACE}, {"mFaceLipUpperCenter", "", FACE}, {"mFaceLipUpperRight", "mFaceLipUpperLeft", FACE, {}, true},
{"mFaceLipCornerLeft", "mFaceLipCornerRight", FACE}, {"mFaceLipCornerRight", "mFaceLipCornerLeft", FACE, {}, true},
{"mFaceTongueBase", "", FACE}, {"mFaceTongueTip", "", FACE, {}, true},
{"mFaceLipLowerLeft", "mFaceLipLowerRight", FACE}, {"mFaceLipLowerCenter", "", FACE}, {"mFaceLipLowerRight", "mFaceLipLowerLeft", FACE, {}, true},
{"mFaceJaw", "", FACE},
{ "mFaceCheekUpperLeft", "mFaceCheekUpperRight", FACE },
{ "mFaceCheekLowerLeft", "mFaceCheekLowerRight", FACE },
{ "mFaceCheekUpperRight", "mFaceCheekUpperLeft", FACE, {}, true },
{ "mFaceCheekLowerRight", "mFaceCheekLowerLeft", FACE, {}, true },
{ "mFaceLipUpperLeft", "mFaceLipUpperRight", FACE },
{ "mFaceLipUpperCenter", "", FACE },
{ "mFaceLipUpperRight", "mFaceLipUpperLeft", FACE, {}, true },
{ "mFaceLipCornerLeft", "mFaceLipCornerRight", FACE },
{ "mFaceLipCornerRight", "mFaceLipCornerLeft", FACE, {}, true },
{ "mFaceTongueBase", "", FACE },
{ "mFaceTongueTip", "", FACE, {}, true },
{ "mFaceLipLowerLeft", "mFaceLipLowerRight", FACE },
{ "mFaceLipLowerCenter", "", FACE },
{ "mFaceLipLowerRight", "mFaceLipLowerLeft", FACE, {}, true },
{ "mFaceJaw", "", FACE },
//left hand
{"mHandThumb1Left", "mHandThumb1Right", HANDS}, {"mHandThumb2Left", "mHandThumb2Right", HANDS}, {"mHandThumb3Left", "mHandThumb3Right", HANDS},
{"mHandIndex1Left", "mHandIndex1Right", HANDS}, {"mHandIndex2Left", "mHandIndex2Right", HANDS}, {"mHandIndex3Left", "mHandIndex3Right", HANDS},
{"mHandMiddle1Left", "mHandMiddle1Right", HANDS}, {"mHandMiddle2Left", "mHandMiddle2Right", HANDS}, {"mHandMiddle3Left", "mHandMiddle3Right", HANDS},
{"mHandRing1Left", "mHandRing1Right", HANDS}, {"mHandRing2Left", "mHandRing2Right", HANDS}, {"mHandRing3Left", "mHandRing3Right", HANDS},
{"mHandPinky1Left", "mHandPinky1Right", HANDS}, {"mHandPinky2Left", "mHandPinky2Right", HANDS}, {"mHandPinky3Left", "mHandPinky3Right", HANDS},
// left hand
{ "mHandThumb1Left", "mHandThumb1Right", HANDS },
{ "mHandThumb2Left", "mHandThumb2Right", HANDS },
{ "mHandThumb3Left", "mHandThumb3Right", HANDS },
{ "mHandIndex1Left", "mHandIndex1Right", HANDS },
{ "mHandIndex2Left", "mHandIndex2Right", HANDS },
{ "mHandIndex3Left", "mHandIndex3Right", HANDS },
{ "mHandMiddle1Left", "mHandMiddle1Right", HANDS },
{ "mHandMiddle2Left", "mHandMiddle2Right", HANDS },
{ "mHandMiddle3Left", "mHandMiddle3Right", HANDS },
{ "mHandRing1Left", "mHandRing1Right", HANDS },
{ "mHandRing2Left", "mHandRing2Right", HANDS },
{ "mHandRing3Left", "mHandRing3Right", HANDS },
{ "mHandPinky1Left", "mHandPinky1Right", HANDS },
{ "mHandPinky2Left", "mHandPinky2Right", HANDS },
{ "mHandPinky3Left", "mHandPinky3Right", HANDS },
// right hand
{"mHandThumb1Right", "mHandThumb1Left", HANDS, {}, true}, {"mHandThumb2Right", "mHandThumb2Left", HANDS, {}, true}, {"mHandThumb3Right", "mHandThumb3Left", HANDS, {}, true},
{"mHandIndex1Right", "mHandIndex1Left", HANDS, {}, true}, {"mHandIndex2Right", "mHandIndex2Left", HANDS, {}, true}, {"mHandIndex3Right", "mHandIndex3Left", HANDS, {}, true},
{"mHandMiddle1Right", "mHandMiddle1Left", HANDS, {}, true}, {"mHandMiddle2Right", "mHandMiddle2Left", HANDS, {}, true}, {"mHandMiddle3Right", "mHandMiddle3Left", HANDS, {}, true},
{"mHandRing1Right", "mHandRing1Left", HANDS, {}, true}, {"mHandRing2Right", "mHandRing2Left", HANDS, {}, true}, {"mHandRing3Right", "mHandRing3Left", HANDS, {}, true},
{"mHandPinky1Right", "mHandPinky1Left", HANDS, {}, true}, {"mHandPinky2Right", "mHandPinky2Left", HANDS, {}, true}, {"mHandPinky3Right", "mHandPinky3Left", HANDS, {}, true},
{ "mHandThumb1Right", "mHandThumb1Left", HANDS, {}, true },
{ "mHandThumb2Right", "mHandThumb2Left", HANDS, {}, true },
{ "mHandThumb3Right", "mHandThumb3Left", HANDS, {}, true },
{ "mHandIndex1Right", "mHandIndex1Left", HANDS, {}, true },
{ "mHandIndex2Right", "mHandIndex2Left", HANDS, {}, true },
{ "mHandIndex3Right", "mHandIndex3Left", HANDS, {}, true },
{ "mHandMiddle1Right", "mHandMiddle1Left", HANDS, {}, true },
{ "mHandMiddle2Right", "mHandMiddle2Left", HANDS, {}, true },
{ "mHandMiddle3Right", "mHandMiddle3Left", HANDS, {}, true },
{ "mHandRing1Right", "mHandRing1Left", HANDS, {}, true },
{ "mHandRing2Right", "mHandRing2Left", HANDS, {}, true },
{ "mHandRing3Right", "mHandRing3Left", HANDS, {}, true },
{ "mHandPinky1Right", "mHandPinky1Left", HANDS, {}, true },
{ "mHandPinky2Right", "mHandPinky2Left", HANDS, {}, true },
{ "mHandPinky3Right", "mHandPinky3Left", HANDS, {}, true },
// tail and hind limbs
{"mTail1", "", MISC}, {"mTail2", "", MISC}, {"mTail3", "", MISC}, {"mTail4", "", MISC}, {"mTail5", "", MISC}, {"mTail6", "", MISC}, {"mGroin", "", MISC},
{"mHindLimbsRoot", "", MISC},
{"mHindLimb1Left", "mHindLimb1Right", MISC}, {"mHindLimb2Left", "mHindLimb2Right", MISC}, {"mHindLimb3Left", "mHindLimb3Right", MISC}, {"mHindLimb4Left", "mHindLimb4Right", MISC},
{"mHindLimb1Right", "mHindLimb1Left", MISC, {}, true}, {"mHindLimb2Right", "mHindLimb2Left", MISC, {}, true}, {"mHindLimb3Right", "mHindLimb3Left", MISC, {}, true}, {"mHindLimb4Right", "mHindLimb4Left", MISC, {}, true},
{ "mTail1", "", MISC },
{ "mTail2", "", MISC },
{ "mTail3", "", MISC },
{ "mTail4", "", MISC },
{ "mTail5", "", MISC },
{ "mTail6", "", MISC },
{ "mGroin", "", MISC },
{ "mHindLimbsRoot", "", MISC },
{ "mHindLimb1Left", "mHindLimb1Right", MISC },
{ "mHindLimb2Left", "mHindLimb2Right", MISC },
{ "mHindLimb3Left", "mHindLimb3Right", MISC },
{ "mHindLimb4Left", "mHindLimb4Right", MISC },
{ "mHindLimb1Right", "mHindLimb1Left", MISC, {}, true },
{ "mHindLimb2Right", "mHindLimb2Left", MISC, {}, true },
{ "mHindLimb3Right", "mHindLimb3Left", MISC, {}, true },
{ "mHindLimb4Right", "mHindLimb4Left", MISC, {}, true },
// wings
{"mWingsRoot", "", MISC},
{"mWing1Left", "mWing1Right", MISC}, {"mWing2Left", "mWing2Right", MISC}, {"mWing3Left", "mWing3Right", MISC}, {"mWing4Left", "mWing4Right", MISC}, {"mWing4FanLeft", "mWing4FanRight", MISC},
{"mWing1Right", "mWing1Left", MISC, {}, true}, {"mWing2Right", "mWing2Left", MISC, {}, true}, {"mWing3Right", "mWing3Left", MISC, {}, true}, {"mWing4Right", "mWing4Left", MISC, {}, true}, {"mWing4FanRight", "mWing4FanLeft", MISC, {}, true},
{ "mWingsRoot", "", MISC },
{ "mWing1Left", "mWing1Right", MISC },
{ "mWing2Left", "mWing2Right", MISC },
{ "mWing3Left", "mWing3Right", MISC },
{ "mWing4Left", "mWing4Right", MISC },
{ "mWing4FanLeft", "mWing4FanRight", MISC },
{ "mWing1Right", "mWing1Left", MISC, {}, true },
{ "mWing2Right", "mWing2Left", MISC, {}, true },
{ "mWing3Right", "mWing3Left", MISC, {}, true },
{ "mWing4Right", "mWing4Left", MISC, {}, true },
{ "mWing4FanRight", "mWing4FanLeft", MISC, {}, true },
// Collision Volumes
{"LEFT_PEC", "RIGHT_PEC", COL_VOLUMES}, {"RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, true}, {"BELLY", "", COL_VOLUMES}, {"BUTT", "", COL_VOLUMES},
{ "LEFT_PEC", "RIGHT_PEC", COL_VOLUMES },
{ "RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, true },
{ "BELLY", "", COL_VOLUMES },
{ "BUTT", "", COL_VOLUMES },
};
public:
@ -217,27 +294,27 @@ public:
/// </summary>
/// <param name="jointName">The name of the joint to match.</param>
/// <returns>The matching joint if found, otherwise nullptr</returns>
const FSPoserJoint* getPoserJointByName(std::string jointName);
const FSPoserJoint* getPoserJointByName(const std::string& jointName);
/// <summary>
/// Tries to start posing the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to begin posing.</param>
/// <returns>True if the avatar was able to begin posing, otherwise false.</returns>
bool tryPosingAvatar(LLVOAvatar *avatar);
bool tryPosingAvatar(LLVOAvatar* avatar);
/// <summary>
/// Stops posing the supplied avatar.
/// </summary>
/// <param name="avatar">The avatar to stop posing.</param>
void stopPosingAvatar(LLVOAvatar *avatar);
void stopPosingAvatar(LLVOAvatar* avatar);
/// <summary>
/// Determines if the supplied avatar is being posed by this.
/// </summary>
/// <param name="avatar">The avatar to query posing status for.</param>
/// <returns>True if this is posing the supplied avatar, otherwise false.</returns>
bool isPosingAvatar(LLVOAvatar *avatar);
bool isPosingAvatar(LLVOAvatar* avatar) const;
/// <summary>
/// Determines whether the supplied PoserJoint for the supplied avatar is being posed.
@ -245,7 +322,7 @@ public:
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint being queried for.</param>
/// <returns>True if this is joint is being posed for the supplied avatar, otherwise false.</returns>
bool isPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint);
bool isPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& joint);
/// <summary>
/// Sets whether the supplied PoserJoint for the supplied avatar should be posed.
@ -256,49 +333,49 @@ public:
/// <remarks>
/// If this is not posing the joint, then it is free to be posed by other things.
/// </remarks>
void setPosingAvatarJoint(LLVOAvatar *avatar, FSPoserJoint joint, bool shouldPose);
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, FSPoserJoint joint);
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, FSPoserJoint joint, E_BoneDeflectionStyles style);
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, FSPoserJoint joint, E_BoneDeflectionStyles style);
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, FSPoserJoint joint, E_BoneDeflectionStyles style);
void undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the position of 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 reset.</param>
void resetJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
void resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Resets the scale of the supplied joint to initial values.
/// </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, FSPoserJoint joint, E_BoneDeflectionStyles style);
void resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Determines if a redo action is currently permitted for the supplied joint.
@ -306,28 +383,28 @@ 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, FSPoserJoint joint);
bool canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint);
/// <summary>
/// Re-does the last undone 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 redo.</param>
void redoLastJointRotation(LLVOAvatar* avatar, FSPoserJoint joint, E_BoneDeflectionStyles style);
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, FSPoserJoint joint, E_BoneDeflectionStyles style);
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, FSPoserJoint joint, E_BoneDeflectionStyles style);
void redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style);
/// <summary>
/// Gets the position of a joint for the supplied avatar.
@ -335,7 +412,7 @@ public:
/// <param name="avatar">The avatar whose joint is being queried.</param>
/// <param name="joint">The joint to determine the position for.</param>
/// <returns>The position of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointPosition(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture = false);
LLVector3 getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture = false) const;
/// <summary>
/// Sets the position of a joint for the supplied avatar.
@ -344,7 +421,7 @@ public:
/// <param name="joint">The joint to set.</param>
/// <param name="position">The position to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
void setJointPosition(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 position, E_BoneDeflectionStyles style);
void setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style);
/// <summary>
/// Gets the rotation of a joint for the supplied avatar.
@ -355,8 +432,8 @@ public:
/// <param name="negation">The style of negation to apply to the set.</param>
/// <param name="forRecapture">Get the current non-poser rotation, for recapture opportunity.</param>
/// <returns>The rotation of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointRotation(LLVOAvatar *avatar, FSPoserJoint joint, E_BoneAxisTranslation translation, S32 negation,
bool forRecapture = false);
LLVector3 getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation,
bool forRecapture = false) const;
/// <summary>
/// Sets the rotation of a joint for the supplied avatar.
@ -366,7 +443,7 @@ public:
/// <param name="rotation">The rotation to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
/// <param name="translation">The axial translation form the supplied joint.</param>
void setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, LLVector3 rotation, E_BoneDeflectionStyles style,
void setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation, E_BoneDeflectionStyles style,
E_BoneAxisTranslation translation, S32 negation);
/// <summary>
@ -375,7 +452,7 @@ public:
/// <param name="avatar">The avatar whose joint is being queried.</param>
/// <param name="joint">The joint to determine the scale for.</param>
/// <returns>The scale of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointScale(LLVOAvatar* avatar, FSPoserJoint joint, bool forRecapture = false);
LLVector3 getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture = false) const;
/// <summary>
/// Sets the scale of a joint for the supplied avatar.
@ -384,20 +461,20 @@ public:
/// <param name="joint">The joint to set.</param>
/// <param name="scale">The scale to set the joint to.</param>
/// <param name="style">Any ancilliary action to be taken with the change to be made.</param>
void setJointScale(LLVOAvatar *avatar, const FSPoserJoint *joint, LLVector3 scale, E_BoneDeflectionStyles style);
void setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style);
/// <summary>
/// Reflects the joint with its opposite if it has one, or just mirror the rotation of itself.
/// </summary>
/// <param name="avatar">The avatar whose joint should flip left-right.</param>
/// <param name="joint">The joint to mirror rotation for.</param>
void reflectJoint(LLVOAvatar *avatar, const FSPoserJoint *joint);
void reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint);
/// <summary>
/// Reflects every joint of the supplied avatar with its opposite if it has one, or mirrors the rotation of the joint if it does not have an opposite.
/// </summary>
/// <param name="avatar">The avatar whose pose should flip left-right.</param>
void flipEntirePose(LLVOAvatar *avatar);
void flipEntirePose(LLVOAvatar* avatar);
/// <summary>
/// Determines whether the supplied PoserJoint for the supplied avatar is being posed.
@ -405,7 +482,7 @@ public:
/// <param name="avatar">The avatar having the joint to which we refer.</param>
/// <param name="joint">The joint being queried for.</param>
/// <returns>True if this is joint is being posed for the supplied avatar, otherwise false.</returns>
bool writePoseAsBvh(llofstream *fileStream, LLVOAvatar* avatar);
bool writePoseAsBvh(llofstream* fileStream, LLVOAvatar* avatar);
private:
/// <summary>
@ -423,7 +500,7 @@ public:
/// <param name="translation">The axis translation to perform.</param>
/// <param name="rotation">The rotation to transform to matrix.</param>
/// <returns>The rotation vector.</returns>
LLVector3 translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, LLQuaternion rotation);
LLVector3 translateRotationFromQuaternion(E_BoneAxisTranslation translation, S32 negation, const LLQuaternion& rotation) const;
/// <summary>
/// Creates a posing motion for the supplied avatar.
@ -441,14 +518,14 @@ public:
/// </summary>
/// <param name="avatar">The avatar to get the posing motion for.</param>
/// <returns>The posing motion if found, otherwise nullptr.</returns>
FSPosingMotion* getPosingMotion(LLVOAvatar* avatar);
FSPosingMotion* getPosingMotion(LLVOAvatar* avatar) const;
/// <summary>
/// Determines if the avatar can be used.
/// </summary>
/// <param name="avatar">The avatar to test if it is safe to animate.</param>
/// <returns>True if the avatar is safe to manipulate, otherwise false.</returns>
bool isAvatarSafeToUse(LLVOAvatar* avatar);
bool isAvatarSafeToUse(LLVOAvatar* avatar) const;
/// <summary>
/// Recursively writes a fragment of a BVH file format representation of the supplied joint, then that joints BVH child(ren).
@ -458,7 +535,7 @@ public:
/// <param name="joint">The joint whose fragment should be written, and whose child(ren) will also be written.</param>
/// <param name="tabStops">The number of tab-stops to include for formatting purpose.</param>
/// <returns>True if the fragment wrote successfully, otherwise false.</returns>
bool writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, int tabStops);
bool writeBvhFragment(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint, S32 tabStops);
/// <summary>
/// Writes a fragment of the 'single line' representing an animation frame within the BVH file respresenting the positions and/or rotations.
@ -469,26 +546,21 @@ public:
/// <returns></returns>
bool writeBvhMotion(llofstream* fileStream, LLVOAvatar* avatar, const FSPoserJoint* joint);
/// <summary>
/// Converts an F32 to a nice string.
/// </summary>
std::string static f32ToString(F32 val);
/// <summary>
/// Generates a string with the supplied number of tab-chars.
/// </summary>
std::string static getTabs(int numOfTabstops);
std::string static getTabs(S32 numOfTabstops);
/// <summary>
/// Transforms a rotation such that llbvhloader.cpp can resolve it to something vaguely approximating the supplied angle.
/// When I say vague, I mean, it's numbers, buuuuut.
/// </summary>
std::string static rotationToYZXString(LLVector3 val);
std::string static rotationToYZXString(const LLVector3& val);
/// <summary>
/// Transforms the supplied vector into a string of three numbers, format suiting to writing into a BVH file.
/// </summary>
std::string static vec3ToXYZString(LLVector3 val);
std::string static vec3ToXYZString(const LLVector3& val);
/// <summary>
/// Maps the avatar's ID to the animation registered to them.
@ -497,7 +569,7 @@ public:
/// An avatar's animation exists so long as their session does, and there is consideration for renewal (like if they relog/crash and their character is renewed).
/// Is static, so the animationId is not lost between sessions (such as when the UI floater is closed and reopened).
/// </summary>
static std::map<LLUUID, LLAssetID> _avatarIdToRegisteredAnimationId;
static std::map<LLUUID, LLAssetID> sAvatarIdToRegisteredAnimationId;
};
#endif // LL_FSPoserAnimator_H

View File

@ -32,7 +32,7 @@
FSPosingMotion::FSPosingMotion(const LLUUID &id) : LLMotion(id)
{
mName = "fs_poser_pose";
_motionID = id;
mMotionID = id;
}
LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character)
@ -40,7 +40,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
if (!character)
return STATUS_FAILURE;
_jointPoses.clear();
mJointPoses.clear();
LLJoint* targetJoint;
for (S32 i = 0; (targetJoint = character->getCharacterJoint(i)); ++i)
@ -49,7 +49,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
continue;
FSJointPose jointPose = FSJointPose(targetJoint);
_jointPoses.push_back(jointPose);
mJointPoses.push_back(jointPose);
addJointState(jointPose.getJointState());
}
@ -60,7 +60,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
continue;
FSJointPose jointPose = FSJointPose(targetJoint, true);
_jointPoses.push_back(jointPose);
mJointPoses.push_back(jointPose);
addJointState(jointPose.getJointState());
}
@ -68,7 +68,10 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
return STATUS_SUCCESS;
}
bool FSPosingMotion::onActivate() { return true; }
bool FSPosingMotion::onActivate()
{
return true;
}
bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
{
@ -79,7 +82,7 @@ bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
LLVector3 currentScale;
LLVector3 targetScale;
for (FSJointPose jointPose : _jointPoses)
for (FSJointPose jointPose : mJointPoses)
{
LLJoint* joint = jointPose.getJointState()->getJoint();
if (!joint)
@ -94,19 +97,19 @@ bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
if (currentPosition != targetPosition)
{
currentPosition = lerp(currentPosition, targetPosition, _interpolationTime);
currentPosition = lerp(currentPosition, targetPosition, mInterpolationTime);
jointPose.getJointState()->setPosition(currentPosition);
}
if (currentRotation != targetRotation)
{
currentRotation = slerp(_interpolationTime, currentRotation, targetRotation);
currentRotation = slerp(mInterpolationTime, currentRotation, targetRotation);
jointPose.getJointState()->setRotation(currentRotation);
}
if (currentScale != targetScale)
{
currentScale = lerp(currentScale, targetScale, _interpolationTime);
currentScale = lerp(currentScale, targetScale, mInterpolationTime);
jointPose.getJointState()->setScale(currentScale);
}
}
@ -118,7 +121,7 @@ void FSPosingMotion::onDeactivate() { revertChangesToPositionsScalesAndCollision
void FSPosingMotion::revertChangesToPositionsScalesAndCollisionVolumes()
{
for (FSJointPose jointPose : _jointPoses)
for (FSJointPose jointPose : mJointPoses)
{
jointPose.revertJointScale();
jointPose.revertJointPosition();
@ -176,13 +179,19 @@ void FSPosingMotion::removeJointFromState(FSJointPose* joint)
setJointState(avJoint, 0);
}
void FSPosingMotion::addJointToState(LLJoint* joint) { setJointState(joint, POSER_JOINT_STATE); }
void FSPosingMotion::removeJointFromState(LLJoint *joint) { setJointState(joint, 0); }
void FSPosingMotion::setJointState(LLJoint *joint, U32 state)
void FSPosingMotion::addJointToState(LLJoint* joint)
{
if (_jointPoses.size() < 1)
setJointState(joint, POSER_JOINT_STATE);
}
void FSPosingMotion::removeJointFromState(LLJoint* joint)
{
setJointState(joint, 0);
}
void FSPosingMotion::setJointState(LLJoint* joint, U32 state)
{
if (mJointPoses.size() < 1)
return;
if (!joint)
return;
@ -204,13 +213,12 @@ void FSPosingMotion::setJointState(LLJoint *joint, U32 state)
addJointState(jointPose->getJointState());
}
FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(std::string name)
FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(const std::string& name)
{
if (_jointPoses.size() < 1)
if (mJointPoses.size() < 1)
return nullptr;
std::vector<FSPosingMotion::FSJointPose>::iterator poserJoint_iter;
for (poserJoint_iter = _jointPoses.begin(); poserJoint_iter != _jointPoses.end(); ++poserJoint_iter)
for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter)
{
if (!boost::iequals(poserJoint_iter->jointName(), name))
continue;
@ -223,7 +231,7 @@ FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(std::string
bool FSPosingMotion::currentlyPosingJoint(LLJoint* joint)
{
if (_jointPoses.size() < 1)
if (mJointPoses.size() < 1)
return false;
if (!joint)
@ -240,3 +248,257 @@ bool FSPosingMotion::currentlyPosingJoint(LLJoint* joint)
U32 state = jointState->getUsage();
return (state & POSER_JOINT_STATE);
}
constexpr size_t MaximumUndoQueueLength = 20;
/// <summary>
/// The constant time interval, in seconds,
/// </summary>
constexpr std::chrono::duration<double> UndoUpdateInterval = std::chrono::duration<double>(0.3);
void FSPosingMotion::FSJointPose::addLastPositionToUndo()
{
if (mUndonePositionIndex > 0)
{
for (int i = 0; i < mUndonePositionIndex; i++)
mLastSetPositions.pop_front();
mUndonePositionIndex = 0;
}
mLastSetPositions.push_front(mTargetPosition);
while (mLastSetPositions.size() > MaximumUndoQueueLength)
mLastSetPositions.pop_back();
}
void FSPosingMotion::FSJointPose::addLastRotationToUndo()
{
if (mUndoneRotationIndex > 0)
{
for (int i = 0; i < mUndoneRotationIndex; i++)
mLastSetRotations.pop_front();
mUndoneRotationIndex = 0;
}
mLastSetRotations.push_front(mTargetRotation);
while (mLastSetRotations.size() > MaximumUndoQueueLength)
mLastSetRotations.pop_back();
}
void FSPosingMotion::FSJointPose::addLastScaleToUndo()
{
if (mUndoneScaleIndex > 0)
{
for (int i = 0; i < mUndoneScaleIndex; i++)
mLastSetScales.pop_front();
mUndoneScaleIndex = 0;
}
mLastSetScales.push_front(mTargetScale);
while (mLastSetScales.size() > MaximumUndoQueueLength)
mLastSetScales.pop_back();
}
LLVector3 FSPosingMotion::FSJointPose::getCurrentPosition()
{
LLVector3 vec3;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getPosition();
return vec3;
}
void FSPosingMotion::FSJointPose::setTargetPosition(const LLVector3& pos)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedPosition;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastPositionToUndo();
mTimeLastUpdatedPosition = std::chrono::system_clock::now();
mTargetPosition.set(pos);
}
LLQuaternion FSPosingMotion::FSJointPose::getCurrentRotation()
{
LLQuaternion quat;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return quat;
quat = joint->getRotation();
return quat;
}
void FSPosingMotion::FSJointPose::setTargetRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastRotationToUndo();
mTimeLastUpdatedRotation = std::chrono::system_clock::now();
mTargetRotation.set(rot);
}
void FSPosingMotion::FSJointPose::applyDeltaRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - mTimeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > UndoUpdateInterval)
addLastRotationToUndo();
mTimeLastUpdatedRotation = std::chrono::system_clock::now();
mTargetRotation = mTargetRotation * rot;
}
LLVector3 FSPosingMotion::FSJointPose::getCurrentScale()
{
LLVector3 vec3;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getScale();
return vec3;
}
void FSPosingMotion::FSJointPose::setTargetScale(LLVector3 scale)
{
auto timeIntervalSinceLastScaleChange = std::chrono::system_clock::now() - mTimeLastUpdatedScale;
if (timeIntervalSinceLastScaleChange > UndoUpdateInterval)
addLastScaleToUndo();
mTimeLastUpdatedScale = std::chrono::system_clock::now();
mTargetScale.set(scale);
}
void FSPosingMotion::FSJointPose::undoLastPositionSet()
{
if (mLastSetPositions.empty())
return;
if (mUndonePositionIndex == 0) // at the top of the queue add the current
addLastPositionToUndo();
mUndonePositionIndex++;
mUndonePositionIndex = llclamp(mUndonePositionIndex, 0, mLastSetPositions.size() - 1);
mTargetPosition.set(mLastSetPositions[mUndonePositionIndex]);
}
void FSPosingMotion::FSJointPose::redoLastPositionSet()
{
if (mLastSetPositions.empty())
return;
mUndonePositionIndex--;
mUndonePositionIndex = llclamp(mUndonePositionIndex, 0, mLastSetPositions.size() - 1);
mTargetPosition.set(mLastSetPositions[mUndonePositionIndex]);
if (mUndonePositionIndex == 0)
mLastSetPositions.pop_front();
}
void FSPosingMotion::FSJointPose::undoLastRotationSet()
{
if (mLastSetRotations.empty())
return;
if (mUndoneRotationIndex == 0) // at the top of the queue add the current
addLastRotationToUndo();
mUndoneRotationIndex++;
mUndoneRotationIndex = llclamp(mUndoneRotationIndex, 0, mLastSetRotations.size() - 1);
mTargetRotation.set(mLastSetRotations[mUndoneRotationIndex]);
}
void FSPosingMotion::FSJointPose::redoLastRotationSet()
{
if (mLastSetRotations.empty())
return;
mUndoneRotationIndex--;
mUndoneRotationIndex = llclamp(mUndoneRotationIndex, 0, mLastSetRotations.size() - 1);
mTargetRotation.set(mLastSetRotations[mUndoneRotationIndex]);
if (mUndoneRotationIndex == 0)
mLastSetRotations.pop_front();
}
void FSPosingMotion::FSJointPose::undoLastScaleSet()
{
if (mLastSetScales.empty())
return;
if (mUndoneScaleIndex == 0)
addLastScaleToUndo();
mUndoneScaleIndex++;
mUndoneScaleIndex = llclamp(mUndoneScaleIndex, 0, mLastSetScales.size() - 1);
mTargetScale.set(mLastSetScales[mUndoneScaleIndex]);
}
void FSPosingMotion::FSJointPose::redoLastScaleSet()
{
if (mLastSetScales.empty())
return;
mUndoneScaleIndex--;
mUndoneScaleIndex = llclamp(mUndoneScaleIndex, 0, mLastSetScales.size() - 1);
mTargetScale.set(mLastSetScales[mUndoneScaleIndex]);
if (mUndoneScaleIndex == 0)
mLastSetScales.pop_front();
}
void FSPosingMotion::FSJointPose::revertJointScale()
{
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setScale(mBeginningScale);
}
void FSPosingMotion::FSJointPose::revertJointPosition()
{
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setPosition(mBeginningPosition);
}
void FSPosingMotion::FSJointPose::revertCollisionVolume()
{
if (!mIsCollisionVolume)
return;
LLJoint* joint = mJointState->getJoint();
if (!joint)
return;
joint->setRotation(mBeginningRotation);
joint->setPosition(mBeginningPosition);
joint->setScale(mBeginningScale);
}
FSPosingMotion::FSJointPose::FSJointPose(LLJoint* joint, bool isCollisionVolume)
{
mJointState = new LLJointState;
mJointState->setJoint(joint);
mJointState->setUsage(POSER_JOINT_STATE);
mJointName = joint->getName();
mIsCollisionVolume = isCollisionVolume;
mBeginningRotation = mTargetRotation = joint->getRotation();
mBeginningPosition = mTargetPosition = joint->getPosition();
mBeginningScale = mTargetScale = joint->getScale();
}

View File

@ -52,398 +52,186 @@ public:
/// </summary>
class FSJointPose
{
const size_t MaximumUndoQueueLength = 20;
/// <summary>
/// The constant time interval, in seconds,
/// </summary>
std::chrono::duration<double> const _undoUpdateInterval = std::chrono::duration<double>(0.3);
std::string _jointName = ""; // expected to be a match to LLJoint.getName() for a joint implementation.
LLPointer<LLJointState> _jointState;
std::string mJointName = ""; // expected to be a match to LLJoint.getName() for a joint implementation.
LLPointer<LLJointState> mJointState{ nullptr };
/// <summary>
/// Collision Volumes require special treatment when we stop animating an avatar, as they do not revert to their original state natively.
/// </summary>
bool _isCollisionVolume = false;
bool mIsCollisionVolume{ false };
LLQuaternion _targetRotation;
LLQuaternion _beginningRotation;
std::deque<LLQuaternion> _lastSetRotations;
size_t _undoneRotationIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedRotation = std::chrono::system_clock::now();
LLQuaternion mTargetRotation;
LLQuaternion mBeginningRotation;
std::deque<LLQuaternion> mLastSetRotations;
size_t mUndoneRotationIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedRotation = std::chrono::system_clock::now();
LLVector3 _targetPosition;
LLVector3 _beginningPosition;
std::deque<LLVector3> _lastSetPositions;
size_t _undonePositionIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedPosition = std::chrono::system_clock::now();
LLVector3 mTargetPosition;
LLVector3 mBeginningPosition;
std::deque<LLVector3> mLastSetPositions;
size_t mUndonePositionIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedPosition = std::chrono::system_clock::now();
/// <summary>
/// Joint scales require special treatment, as they do not revert when we stop animating an avatar.
/// </summary>
LLVector3 _targetScale;
LLVector3 _beginningScale;
std::deque<LLVector3> _lastSetScales;
size_t _undoneScaleIndex = 0;
std::chrono::system_clock::time_point _timeLastUpdatedScale = std::chrono::system_clock::now();
LLVector3 mTargetScale;
LLVector3 mBeginningScale;
std::deque<LLVector3> mLastSetScales;
size_t mUndoneScaleIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now();
/// <summary>
/// Adds a last position to the deque.
/// </summary>
void addLastPositionToUndo()
{
if (_undonePositionIndex > 0)
{
for (int i = 0; i < _undonePositionIndex; i++)
_lastSetPositions.pop_front();
_undonePositionIndex = 0;
}
_lastSetPositions.push_front(_targetPosition);
while (_lastSetPositions.size() > MaximumUndoQueueLength)
_lastSetPositions.pop_back();
}
void addLastPositionToUndo();
/// <summary>
/// Adds a last rotation to the deque.
/// </summary>
void addLastRotationToUndo()
{
if (_undoneRotationIndex > 0)
{
for (int i = 0; i < _undoneRotationIndex; i++)
_lastSetRotations.pop_front();
_undoneRotationIndex = 0;
}
_lastSetRotations.push_front(_targetRotation);
while (_lastSetRotations.size() > MaximumUndoQueueLength)
_lastSetRotations.pop_back();
}
void addLastRotationToUndo();
/// <summary>
/// Adds a last rotation to the deque.
/// </summary>
void addLastScaleToUndo()
{
if (_undoneScaleIndex > 0)
{
for (int i = 0; i < _undoneScaleIndex; i++)
_lastSetScales.pop_front();
_undoneScaleIndex = 0;
}
_lastSetScales.push_front(_targetScale);
while (_lastSetScales.size() > MaximumUndoQueueLength)
_lastSetScales.pop_back();
}
void addLastScaleToUndo();
public:
/// <summary>
/// Gets the name of the joint.
/// </summary>
std::string jointName() const { return _jointName; }
std::string jointName() const { return mJointName; }
/// <summary>
/// Gets whether this represents a collision volume.
/// </summary>
/// <returns></returns>
bool isCollisionVolume() const { return _isCollisionVolume; }
bool isCollisionVolume() const { return mIsCollisionVolume; }
/// <summary>
/// Gets whether a redo of this joints rotation may be performed.
/// </summary>
/// <returns></returns>
bool canRedoRotation() const { return _undoneRotationIndex > 0; }
bool canRedoRotation() const { return mUndoneRotationIndex > 0; }
/// <summary>
/// Gets the position the joint was in when the animation was initialized.
/// </summary>
LLVector3 getBeginningPosition() const { return _beginningPosition; }
LLVector3 getBeginningPosition() const { return mBeginningPosition; }
/// <summary>
/// Gets the position the animator wishes the joint to be in.
/// </summary>
LLVector3 getTargetPosition() const { return _targetPosition; }
LLVector3 getTargetPosition() const { return mTargetPosition; }
/// <summary>
/// Gets the position the animator wishes the joint to be in.
/// </summary>
LLVector3 getCurrentPosition()
{
LLVector3 vec3;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getPosition();
return vec3;
}
LLVector3 getCurrentPosition();
/// <summary>
/// Sets the position the animator wishes the joint to be in.
/// </summary>
void setTargetPosition(const LLVector3& pos)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedPosition;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastPositionToUndo();
_timeLastUpdatedPosition = std::chrono::system_clock::now();
_targetPosition.set(pos);
}
void setTargetPosition(const LLVector3& pos);
/// <summary>
/// Gets the rotation the joint was in when the animation was initialized.
/// </summary>
LLQuaternion getBeginningRotation() const { return _beginningRotation; }
LLQuaternion getBeginningRotation() const { return mBeginningRotation; }
/// <summary>
/// Gets the rotation the animator wishes the joint to be in.
/// </summary>
LLQuaternion getTargetRotation() const { return _targetRotation; }
LLQuaternion getTargetRotation() const { return mTargetRotation; }
/// <summary>
/// Gets the rotation of the joint.
/// </summary>
LLQuaternion getCurrentRotation()
{
LLQuaternion quat;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return quat;
quat = joint->getRotation();
return quat;
}
LLQuaternion getCurrentRotation();
/// <summary>
/// Sets the rotation the animator wishes the joint to be in.
/// </summary>
void setTargetRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastRotationToUndo();
_timeLastUpdatedRotation = std::chrono::system_clock::now();
_targetRotation.set(rot);
}
void setTargetRotation(const LLQuaternion& rot);
/// <summary>
/// Applies a delta to the rotation the joint currently targets.
/// </summary>
void applyDeltaRotation(const LLQuaternion& rot)
{
auto timeIntervalSinceLastRotationChange = std::chrono::system_clock::now() - _timeLastUpdatedRotation;
if (timeIntervalSinceLastRotationChange > _undoUpdateInterval)
addLastRotationToUndo();
_timeLastUpdatedRotation = std::chrono::system_clock::now();
_targetRotation = _targetRotation * rot;
}
void applyDeltaRotation(const LLQuaternion& rot);
/// <summary>
/// Gets the scale the animator wishes the joint to have.
/// </summary>
LLVector3 getTargetScale() const { return _targetScale; }
LLVector3 getTargetScale() const { return mTargetScale; }
/// <summary>
/// Gets the scale the joint has.
/// </summary>
LLVector3 getCurrentScale()
{
LLVector3 vec3;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return vec3;
vec3 = joint->getScale();
return vec3;
}
LLVector3 getCurrentScale();
/// <summary>
/// Gets the scale the joint had when the animation was initialized.
/// </summary>
LLVector3 getBeginningScale() const { return _beginningScale; }
LLVector3 getBeginningScale() const { return mBeginningScale; }
/// <summary>
/// Sets the scale the animator wishes the joint to have.
/// </summary>
void setTargetScale(LLVector3 scale)
{
auto timeIntervalSinceLastScaleChange = std::chrono::system_clock::now() - _timeLastUpdatedScale;
if (timeIntervalSinceLastScaleChange > _undoUpdateInterval)
addLastScaleToUndo();
_timeLastUpdatedScale = std::chrono::system_clock::now();
_targetScale.set(scale);
}
void setTargetScale(LLVector3 scale);
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void undoLastPositionSet()
{
if (_lastSetPositions.empty())
return;
if (_undonePositionIndex == 0) // at the top of the queue add the current
addLastPositionToUndo();
_undonePositionIndex++;
_undonePositionIndex = llclamp(_undonePositionIndex, 0, _lastSetPositions.size() - 1);
_targetPosition.set(_lastSetPositions[_undonePositionIndex]);
}
void undoLastPositionSet();
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void redoLastPositionSet()
{
if (_lastSetPositions.empty())
return;
_undonePositionIndex--;
_undonePositionIndex = llclamp(_undonePositionIndex, 0, _lastSetPositions.size() - 1);
_targetPosition.set(_lastSetPositions[_undonePositionIndex]);
if (_undonePositionIndex == 0)
_lastSetPositions.pop_front();
}
void redoLastPositionSet();
/// <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, _undoneRotationIndex points at the current rotation.
/// Thus when we start undoing, mUndoneRotationIndex points at the current rotation.
/// </summary>
void undoLastRotationSet()
{
if (_lastSetRotations.empty())
return;
if (_undoneRotationIndex == 0) // at the top of the queue add the current
addLastRotationToUndo();
_undoneRotationIndex++;
_undoneRotationIndex = llclamp(_undoneRotationIndex, 0, _lastSetRotations.size() - 1);
_targetRotation.set(_lastSetRotations[_undoneRotationIndex]);
}
void undoLastRotationSet();
/// <summary>
/// Undoes the last rotation set, if any.
/// </summary>
void redoLastRotationSet()
{
if (_lastSetRotations.empty())
return;
void redoLastRotationSet();
_undoneRotationIndex--;
_undoneRotationIndex = llclamp(_undoneRotationIndex, 0, _lastSetRotations.size() - 1);
void undoLastScaleSet();
_targetRotation.set(_lastSetRotations[_undoneRotationIndex]);
if (_undoneRotationIndex == 0)
_lastSetRotations.pop_front();
}
void undoLastScaleSet()
{
if (_lastSetScales.empty())
return;
if (_undoneScaleIndex == 0)
addLastScaleToUndo();
_undoneScaleIndex++;
_undoneScaleIndex = llclamp(_undoneScaleIndex, 0, _lastSetScales.size() - 1);
_targetScale.set(_lastSetScales[_undoneScaleIndex]);
}
void redoLastScaleSet()
{
if (_lastSetScales.empty())
return;
_undoneScaleIndex--;
_undoneScaleIndex = llclamp(_undoneScaleIndex, 0, _lastSetScales.size() - 1);
_targetScale.set(_lastSetScales[_undoneScaleIndex]);
if (_undoneScaleIndex == 0)
_lastSetScales.pop_front();
}
void redoLastScaleSet();
/// <summary>
/// Restores the joint represented by this to the scale it had when this motion started.
/// </summary>
void revertJointScale()
{
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setScale(_beginningScale);
}
void revertJointScale();
/// <summary>
/// Restores the joint represented by this to the position it had when this motion started.
/// </summary>
void revertJointPosition()
{
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setPosition(_beginningPosition);
}
void revertJointPosition();
/// <summary>
/// Collision Volumes do not 'reset' their position/rotation when the animation stops.
/// This requires special treatment to revert changes we've made this animation session.
/// </summary>
void revertCollisionVolume()
{
if (!_isCollisionVolume)
return;
LLJoint* joint = _jointState->getJoint();
if (!joint)
return;
joint->setRotation(_beginningRotation);
joint->setPosition(_beginningPosition);
joint->setScale(_beginningScale);
}
void revertCollisionVolume();
/// <summary>
/// Gets the pointer to the jointstate for the joint this represents.
/// </summary>
LLPointer<LLJointState> getJointState() const { return _jointState; }
LLPointer<LLJointState> getJointState() const { return mJointState; }
FSJointPose(LLJoint* joint, bool isCollisionVolume = false)
{
_jointState = new LLJointState;
_jointState->setJoint(joint);
_jointState->setUsage(POSER_JOINT_STATE);
_jointName = joint->getName();
_isCollisionVolume = isCollisionVolume;
_beginningRotation = _targetRotation = joint->getRotation();
_beginningPosition = _targetPosition = joint->getPosition();
_beginningScale = _targetScale = joint->getScale();
}
FSJointPose(LLJoint* joint, bool isCollisionVolume = false);
};
public:
virtual bool getLoop() { return TRUE; }
virtual bool getLoop() { return true; }
virtual F32 getDuration() { return 0.0; }
@ -499,13 +287,13 @@ public:
/// </summary>
/// <param name="name">The name of the joint to get the pose for.</param>
/// <returns>The matching joint pose, if found, otherwise null.</returns>
FSJointPose* getJointPoseByJointName(std::string name);
FSJointPose* getJointPoseByJointName(const std::string& name);
/// <summary>
/// Gets the motion identity for this animation.
/// </summary>
/// <returns>The unique, per-session, per-character motion identity.</returns>
LLAssetID motionId() const { return _motionID; }
LLAssetID motionId() const { return mMotionID; }
private:
/// <summary>
@ -516,7 +304,7 @@ private:
/// <summary>
/// The unique identity of this motion.
/// </summary>
LLAssetID _motionID;
LLAssetID mMotionID;
/// <summary>
/// The amount of time, in seconds, we use for transitioning between one animation-state to another; this affects the 'fluidity'
@ -524,12 +312,12 @@ private:
/// Use caution making this larger than the subjective amount of time between adjusting a joint and then choosing to use 'undo' it.
/// Undo-function waits a similar amount of time after the last user-incited joint change to add a 'restore point'.
/// </summary>
const F32 _interpolationTime = 0.25f;
const F32 mInterpolationTime = 0.25f;
/// <summary>
/// The collection of joint poses this motion uses to pose the joints of the character this is animating.
/// </summary>
std::vector<FSJointPose> _jointPoses;
std::vector<FSJointPose> mJointPoses;
/// <summary>
/// Removes the current joint state for the supplied joint, and adds a new one.

View File

@ -54,18 +54,18 @@ FSVirtualTrackpad::FSVirtualTrackpad(const FSVirtualTrackpad::Params &p)
mImgSunBack(p.image_sun_back),
mImgSunFront(p.image_sun_front),
mImgSphere(p.image_sphere),
_allowPinchMode(p.pinch_mode),
_infiniteScrollMode(p.infinite_scroll_mode)
mAllowPinchMode(p.pinch_mode),
mInfiniteScrollMode(p.infinite_scroll_mode)
{
LLRect border_rect = getLocalRect();
_cursorValueX = _pinchCursorValueX = border_rect.getCenterX();
_cursorValueY = _pinchCursorValueY = border_rect.getCenterY();
_cursorValueZ = _pinchCursorValueZ = 0;
mCursorValueX = mPinchCursorValueX = border_rect.getCenterX();
mCursorValueY = mPinchCursorValueY = border_rect.getCenterY();
mCursorValueZ = mPinchCursorValueZ = 0;
_thumbClickOffsetX = _thumbClickOffsetY = _pinchThumbClickOffsetX = _pinchThumbClickOffsetY = 0;
_posXwhenCtrlDown = _posYwhenCtrlDown = 0;
_pinchValueDeltaX = _pinchValueDeltaY = _pinchValueDeltaZ = 0;
_valueDeltaX = _valueDeltaY = _valueDeltaZ = 0;
mThumbClickOffsetX = mThumbClickOffsetY = mPinchThumbClickOffsetX = mPinchThumbClickOffsetY = 0;
mPosXwhenCtrlDown = mPosYwhenCtrlDown = 0;
mPinchValueDeltaX = mPinchValueDeltaY = mPinchValueDeltaZ = 0;
mValueDeltaX = mValueDeltaY = mValueDeltaZ = 0;
LLViewBorder::Params border = p.border;
border.rect(border_rect);
@ -93,8 +93,8 @@ void FSVirtualTrackpad::drawThumb(bool isPinchThumb)
else
thumb = isPinchThumb ? mImgSunBack : mImgMoonBack;
S32 x = isPinchThumb ? _pinchCursorValueX : _cursorValueX;
S32 y = isPinchThumb ? _pinchCursorValueY : _cursorValueY;
S32 x = isPinchThumb ? mPinchCursorValueX : mCursorValueX;
S32 y = isPinchThumb ? mPinchCursorValueY : mCursorValueY;
wrapOrClipCursorPosition(&x, &y);
@ -122,11 +122,11 @@ void FSVirtualTrackpad::determineThumbClickError(S32 x, S32 y)
if (!mImgSunFront)
return;
_thumbClickOffsetX = 0;
_thumbClickOffsetY = 0;
mThumbClickOffsetX = 0;
mThumbClickOffsetY = 0;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
wrapOrClipCursorPosition(&errorX, &errorY);
errorX -= x;
errorY -= y;
@ -136,37 +136,37 @@ void FSVirtualTrackpad::determineThumbClickError(S32 x, S32 y)
if (fabs(errorY) > mImgSunFront->getHeight() / 2.0)
return;
_thumbClickOffsetX = errorX;
_thumbClickOffsetY = errorY;
mThumbClickOffsetX = errorX;
mThumbClickOffsetY = errorY;
}
void FSVirtualTrackpad::updateClickErrorIfInfiniteScrolling()
{
if (!_infiniteScrollMode)
if (!mInfiniteScrollMode)
return;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
LLRect rect = mTouchArea->getRect();
while (errorX > rect.mRight)
{
errorX -= rect.getWidth();
_thumbClickOffsetX += rect.getWidth();
mThumbClickOffsetX += rect.getWidth();
}
while (errorX < rect.mLeft)
{
errorX += rect.getWidth();
_thumbClickOffsetX -= rect.getWidth();
mThumbClickOffsetX -= rect.getWidth();
}
while (errorY > rect.mTop)
{
errorY -= rect.getHeight();
_thumbClickOffsetY += rect.getHeight();
mThumbClickOffsetY += rect.getHeight();
}
while (errorY < rect.mBottom)
{
errorY += rect.getHeight();
_thumbClickOffsetY -= rect.getHeight();
mThumbClickOffsetY -= rect.getHeight();
}
}
@ -177,11 +177,11 @@ void FSVirtualTrackpad::determineThumbClickErrorForPinch(S32 x, S32 y)
if (!mImgMoonFront)
return;
_pinchThumbClickOffsetX = 0;
_pinchThumbClickOffsetY = 0;
mPinchThumbClickOffsetX = 0;
mPinchThumbClickOffsetY = 0;
S32 errorX = _pinchCursorValueX;
S32 errorY = _pinchCursorValueY;
S32 errorX = mPinchCursorValueX;
S32 errorY = mPinchCursorValueY;
wrapOrClipCursorPosition(&errorX, &errorY);
errorX -= x;
errorY -= y;
@ -191,37 +191,37 @@ void FSVirtualTrackpad::determineThumbClickErrorForPinch(S32 x, S32 y)
if (fabs(errorY) > mImgMoonFront->getHeight() / 2.0)
return;
_pinchThumbClickOffsetX = errorX;
_pinchThumbClickOffsetY = errorY;
mPinchThumbClickOffsetX = errorX;
mPinchThumbClickOffsetY = errorY;
}
void FSVirtualTrackpad::updateClickErrorIfInfiniteScrollingForPinch()
{
if (!_infiniteScrollMode)
if (!mInfiniteScrollMode)
return;
S32 errorX = _cursorValueX;
S32 errorY = _cursorValueY;
S32 errorX = mCursorValueX;
S32 errorY = mCursorValueY;
LLRect rect = mTouchArea->getRect();
while (errorX > rect.mRight)
{
errorX -= rect.getWidth();
_pinchThumbClickOffsetX += rect.getWidth();
mPinchThumbClickOffsetX += rect.getWidth();
}
while (errorX < rect.mLeft)
{
errorX += rect.getWidth();
_pinchThumbClickOffsetX -= rect.getWidth();
mPinchThumbClickOffsetX -= rect.getWidth();
}
while (errorY > rect.mTop)
{
errorY -= rect.getHeight();
_pinchThumbClickOffsetY += rect.getHeight();
mPinchThumbClickOffsetY += rect.getHeight();
}
while (errorY < rect.mBottom)
{
errorY += rect.getHeight();
_pinchThumbClickOffsetY -= rect.getHeight();
mPinchThumbClickOffsetY -= rect.getHeight();
}
}
@ -229,7 +229,7 @@ void FSVirtualTrackpad::draw()
{
mImgSphere->draw(mTouchArea->getRect(), mTouchArea->isInEnabledChain() ? UI_VERTEX_COLOR : UI_VERTEX_COLOR % 0.5f);
if (_allowPinchMode)
if (mAllowPinchMode)
drawThumb(true);
drawThumb(false);
@ -258,25 +258,25 @@ void FSVirtualTrackpad::setValue(const LLSD& value)
void FSVirtualTrackpad::setValue(F32 x, F32 y, F32 z)
{
convertNormalizedToPixelPos(x, y, z, &_cursorValueX, &_cursorValueY, &_cursorValueZ);
_valueX = _cursorValueX;
_valueY = _cursorValueY;
_valueZ = _cursorValueZ;
convertNormalizedToPixelPos(x, y, z, &mCursorValueX, &mCursorValueY, &mCursorValueZ);
mValueX = mCursorValueX;
mValueY = mCursorValueY;
mValueZ = mCursorValueZ;
}
void FSVirtualTrackpad::setPinchValue(F32 x, F32 y, F32 z)
{
convertNormalizedToPixelPos(x, y, z, &_pinchCursorValueX, &_pinchCursorValueY, &_pinchCursorValueZ);
_pinchValueX = _pinchCursorValueX;
_pinchValueY = _pinchCursorValueY;
_pinchValueZ = _pinchCursorValueZ;
convertNormalizedToPixelPos(x, y, z, &mPinchCursorValueX, &mPinchCursorValueY, &mPinchCursorValueZ);
mPinchValueX = mPinchCursorValueX;
mPinchValueY = mPinchCursorValueY;
mPinchValueZ = mPinchCursorValueZ;
}
LLSD FSVirtualTrackpad::getValue() const { return normalizePixelPos(_valueX, _valueY, _valueZ).getValue(); }
LLSD FSVirtualTrackpad::getValueDelta() { return normalizeDelta(_valueDeltaX, _valueDeltaY, _valueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getValue() const { return normalizePixelPos(mValueX, mValueY, mValueZ).getValue(); }
LLSD FSVirtualTrackpad::getValueDelta() { return normalizeDelta(mValueDeltaX, mValueDeltaY, mValueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValue() { return normalizePixelPos(_pinchValueX, _pinchValueY, _pinchValueZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValueDelta() { return normalizeDelta(_pinchValueDeltaX, _pinchValueDeltaY, _pinchValueDeltaZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValue() { return normalizePixelPos(mPinchValueX, mPinchValueY, mPinchValueZ).getValue(); }
LLSD FSVirtualTrackpad::getPinchValueDelta() { return normalizeDelta(mPinchValueDeltaX, mPinchValueDeltaY, mPinchValueDeltaZ).getValue(); }
void FSVirtualTrackpad::wrapOrClipCursorPosition(S32* x, S32* y) const
{
@ -284,7 +284,7 @@ void FSVirtualTrackpad::wrapOrClipCursorPosition(S32* x, S32* y) const
return;
LLRect rect = mTouchArea->getRect();
if (_infiniteScrollMode)
if (mInfiniteScrollMode)
{
while (*x > rect.mRight)
*x -= rect.getWidth();
@ -323,152 +323,152 @@ void FSVirtualTrackpad::getHoverMovementDeltas(S32 x, S32 y, MASK mask, S32* del
return;
S32 fromX, fromY;
fromX = _doingPinchMode ? _pinchCursorValueX : _cursorValueX;
fromY = _doingPinchMode ? _pinchCursorValueY : _cursorValueY;
fromX = mDoingPinchMode ? mPinchCursorValueX : mCursorValueX;
fromY = mDoingPinchMode ? mPinchCursorValueY : mCursorValueY;
if (mask & MASK_CONTROL)
{
if (!_heldDownControlBefore)
if (!mHeldDownControlBefore)
{
_posXwhenCtrlDown = x;
_posYwhenCtrlDown = y;
_heldDownControlBefore = true;
mPosXwhenCtrlDown = x;
mPosYwhenCtrlDown = y;
mHeldDownControlBefore = true;
}
if (_doingPinchMode)
if (mDoingPinchMode)
{
*deltaX = _posXwhenCtrlDown - (_posXwhenCtrlDown - x) / 8 + _pinchThumbClickOffsetX - fromX;
*deltaY = _posYwhenCtrlDown - (_posYwhenCtrlDown - y) / 8 + _pinchThumbClickOffsetY - fromY;
*deltaX = mPosXwhenCtrlDown - (mPosXwhenCtrlDown - x) / 8 + mPinchThumbClickOffsetX - fromX;
*deltaY = mPosYwhenCtrlDown - (mPosYwhenCtrlDown - y) / 8 + mPinchThumbClickOffsetY - fromY;
}
else
{
*deltaX = _posXwhenCtrlDown - (_posXwhenCtrlDown - x) / 8 + _thumbClickOffsetX - fromX;
*deltaY = _posYwhenCtrlDown - (_posYwhenCtrlDown - y) / 8 + _thumbClickOffsetY - fromY;
*deltaX = mPosXwhenCtrlDown - (mPosXwhenCtrlDown - x) / 8 + mThumbClickOffsetX - fromX;
*deltaY = mPosYwhenCtrlDown - (mPosYwhenCtrlDown - y) / 8 + mThumbClickOffsetY - fromY;
}
}
else
{
if (_heldDownControlBefore)
if (mHeldDownControlBefore)
{
_thumbClickOffsetX = fromX - x;
_thumbClickOffsetY = fromY - y;
_heldDownControlBefore = false;
mThumbClickOffsetX = fromX - x;
mThumbClickOffsetY = fromY - y;
mHeldDownControlBefore = false;
}
if (_doingPinchMode)
if (mDoingPinchMode)
{
*deltaX = x + _pinchThumbClickOffsetX - fromX;
*deltaY = y + _pinchThumbClickOffsetY - fromY;
*deltaX = x + mPinchThumbClickOffsetX - fromX;
*deltaY = y + mPinchThumbClickOffsetY - fromY;
}
else
{
*deltaX = x + _thumbClickOffsetX - fromX;
*deltaY = y + _thumbClickOffsetY - fromY;
*deltaX = x + mThumbClickOffsetX - fromX;
*deltaY = y + mThumbClickOffsetY - fromY;
}
}
}
void FSVirtualTrackpad::applyHoverMovementDeltas(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
_pinchCursorValueX += deltaX;
_pinchCursorValueY += deltaY;
if (!_infiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&_pinchCursorValueX, &_pinchCursorValueY);
mPinchCursorValueX += deltaX;
mPinchCursorValueY += deltaY;
if (!mInfiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&mPinchCursorValueX, &mPinchCursorValueY);
}
else
{
_cursorValueX += deltaX;
_cursorValueY += deltaY;
mCursorValueX += deltaX;
mCursorValueY += deltaY;
if (!_infiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&_cursorValueX, &_cursorValueY);
if (!mInfiniteScrollMode) // then constrain the cursor within control area
wrapOrClipCursorPosition(&mCursorValueX, &mCursorValueY);
}
}
void FSVirtualTrackpad::applyDeltasToValues(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_pinchValueY += deltaY;
_pinchValueZ += deltaX;
mPinchValueY += deltaY;
mPinchValueZ += deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_pinchValueX += deltaX;
_pinchValueZ += deltaY;
mPinchValueX += deltaX;
mPinchValueZ += deltaY;
}
else
{
_pinchValueX += deltaX;
_pinchValueY += deltaY;
mPinchValueX += deltaX;
mPinchValueY += deltaY;
}
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_valueY += deltaY;
_valueZ += deltaX;
mValueY += deltaY;
mValueZ += deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_valueX += deltaX;
_valueZ += deltaY;
mValueX += deltaX;
mValueZ += deltaY;
}
else
{
_valueX += deltaX;
_valueY += deltaY;
mValueX += deltaX;
mValueY += deltaY;
}
}
}
void FSVirtualTrackpad::applyDeltasToDeltaValues(S32 deltaX, S32 deltaY, MASK mask)
{
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_pinchValueDeltaX = 0;
_pinchValueDeltaY = deltaY;
_pinchValueDeltaZ = deltaX;
mPinchValueDeltaX = 0;
mPinchValueDeltaY = deltaY;
mPinchValueDeltaZ = deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_pinchValueDeltaX = deltaX;
_pinchValueDeltaY = 0;
_pinchValueDeltaZ = deltaY;
mPinchValueDeltaX = deltaX;
mPinchValueDeltaY = 0;
mPinchValueDeltaZ = deltaY;
}
else
{
_pinchValueDeltaX = deltaX;
_pinchValueDeltaY = deltaY;
_pinchValueDeltaZ = 0;
mPinchValueDeltaX = deltaX;
mPinchValueDeltaY = deltaY;
mPinchValueDeltaZ = 0;
}
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
{
_valueDeltaX = 0;
_valueDeltaY = deltaY;
_valueDeltaZ = deltaX;
mValueDeltaX = 0;
mValueDeltaY = deltaY;
mValueDeltaZ = deltaX;
}
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
{
_valueDeltaX = deltaX;
_valueDeltaY = 0;
_valueDeltaZ = deltaY;
mValueDeltaX = deltaX;
mValueDeltaY = 0;
mValueDeltaZ = deltaY;
}
else
{
_valueDeltaX = deltaX;
_valueDeltaY = deltaY;
_valueDeltaZ = 0;
mValueDeltaX = deltaX;
mValueDeltaY = deltaY;
mValueDeltaZ = 0;
}
}
}
@ -520,7 +520,7 @@ void FSVirtualTrackpad::convertNormalizedToPixelPos(F32 x, F32 y, F32 z, S32 *va
S32 width = rect.getWidth();
S32 height = rect.getHeight();
if (_infiniteScrollMode)
if (mInfiniteScrollMode)
{
*valX = centerX + ll_round(x * width / 2);
*valY = centerY + ll_round(y * height / 2);
@ -539,7 +539,7 @@ bool FSVirtualTrackpad::handleMouseUp(S32 x, S32 y, MASK mask)
if (hasMouseCapture())
{
gFocusMgr.setMouseCapture(NULL);
_heldDownControlBefore = false;
mHeldDownControlBefore = false;
make_ui_sound("UISndClickRelease");
}
@ -563,7 +563,7 @@ bool FSVirtualTrackpad::handleRightMouseUp(S32 x, S32 y, MASK mask)
{
if (hasMouseCapture())
{
_doingPinchMode = false;
mDoingPinchMode = false;
gFocusMgr.setMouseCapture(NULL);
make_ui_sound("UISndClickRelease");
@ -575,14 +575,14 @@ bool FSVirtualTrackpad::handleRightMouseUp(S32 x, S32 y, MASK mask)
// move pinch cursor
bool FSVirtualTrackpad::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (!_allowPinchMode)
if (!mAllowPinchMode)
return LLView::handleRightMouseDown(x, y, mask);
if (isPointInTouchArea(x, y))
{
determineThumbClickErrorForPinch(x, y);
updateClickErrorIfInfiniteScrollingForPinch();
_doingPinchMode = true;
mDoingPinchMode = true;
gFocusMgr.setMouseCapture(this);
make_ui_sound("UISndClick");
@ -602,23 +602,23 @@ bool FSVirtualTrackpad::handleScrollWheel(S32 x, S32 y, S32 clicks)
if (mask & MASK_CONTROL)
changeAmount /= 5;
if (_doingPinchMode)
if (mDoingPinchMode)
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
_pinchValueX -= clicks * changeAmount;
mPinchValueX -= clicks * changeAmount;
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
_pinchValueY -= clicks * changeAmount;
mPinchValueY -= clicks * changeAmount;
else
_pinchValueZ -= clicks * changeAmount;
mPinchValueZ -= clicks * changeAmount;
}
else
{
if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_ALT)
_valueX -= clicks * changeAmount;
mValueX -= clicks * changeAmount;
else if ((mask & (MASK_SHIFT | MASK_ALT)) == MASK_SHIFT)
_valueY -= clicks * changeAmount;
mValueY -= clicks * changeAmount;
else
_valueZ -= clicks * changeAmount;
mValueZ -= clicks * changeAmount;
}
if (!hasMouseCapture())

View File

@ -100,8 +100,8 @@ protected:
FSVirtualTrackpad(const Params&);
protected:
LLPanel* mTouchArea;
LLViewBorder* mBorder;
LLPanel* mTouchArea{ nullptr };
LLViewBorder* mBorder{ nullptr };
private:
const F32 ThirdAxisQuantization = 0.001f; // To avoid quantizing the third axis as we add integer wheel clicks, use this to preserve some precision as int.
@ -124,21 +124,21 @@ private:
void applyDeltasToValues(S32 deltaX, S32 deltaY, MASK mask);
void applyDeltasToDeltaValues(S32 deltaX, S32 deltaY, MASK mask);
LLUIImage* mImgMoonBack;
LLUIImage* mImgMoonFront;
LLUIImage* mImgSunBack;
LLUIImage* mImgSunFront;
LLUIImage* mImgSphere;
LLUIImage* mImgMoonBack{ nullptr };
LLUIImage* mImgMoonFront{ nullptr };
LLUIImage* mImgSunBack{ nullptr };
LLUIImage* mImgSunFront{ nullptr };
LLUIImage* mImgSphere{ nullptr };
/// <summary>
/// Whether we allow the second cursor to appear.
/// </summary>
bool _allowPinchMode = false;
bool mAllowPinchMode{ false };
/// <summary>
/// Whether we should be moving the pinch cursor now
/// </summary>
bool _doingPinchMode = false;
bool mDoingPinchMode{ false };
/// <summary>
/// Whether to allow the cursor(s) to 'wrap'.
@ -148,48 +148,48 @@ private:
/// When true, the cursor 'disappears' out the top, and starts from the bottom,
/// effectively allowing infinite scrolling.
/// </example>
bool _infiniteScrollMode = false;
bool mInfiniteScrollMode{ false };
bool _heldDownControlBefore = false;
bool mHeldDownControlBefore{ false };
/// <summary>
/// The values the owner will get and set.
/// </summary>
S32 _valueX;
S32 _valueY;
S32 _valueZ;
S32 _pinchValueX;
S32 _pinchValueY;
S32 _pinchValueZ;
S32 mValueX{ 0 };
S32 mValueY{ 0 };
S32 mValueZ{ 0 };
S32 mPinchValueX{ 0 };
S32 mPinchValueY{ 0 };
S32 mPinchValueZ{ 0 };
/// <summary>
/// The delta values the owner will get and set.
/// </summary>
S32 _valueDeltaX;
S32 _valueDeltaY;
S32 _valueDeltaZ;
S32 _pinchValueDeltaX;
S32 _pinchValueDeltaY;
S32 _pinchValueDeltaZ;
S32 mValueDeltaX{ 0 };
S32 mValueDeltaY{ 0 };
S32 mValueDeltaZ{ 0 };
S32 mPinchValueDeltaX{ 0 };
S32 mPinchValueDeltaY{ 0 };
S32 mPinchValueDeltaZ{ 0 };
/// <summary>
/// The various values placing the cursors and documenting behaviours.
/// Where relevant, all are scaled in pixels.
/// </summary>
S32 _cursorValueX;
S32 _cursorValueY;
S32 _cursorValueZ;
S32 _pinchCursorValueX;
S32 _pinchCursorValueY;
S32 _pinchCursorValueZ;
S32 mCursorValueX{ 0 };
S32 mCursorValueY{ 0 };
S32 mCursorValueZ{ 0 };
S32 mPinchCursorValueX{ 0 };
S32 mPinchCursorValueY{ 0 };
S32 mPinchCursorValueZ{ 0 };
// if one clicks on or about the thumb, we don't move it, instead we calculate the click-position error and factor it out
S32 _thumbClickOffsetX;
S32 _thumbClickOffsetY;
S32 _pinchThumbClickOffsetX;
S32 _pinchThumbClickOffsetY;
S32 _posXwhenCtrlDown;
S32 _posYwhenCtrlDown;
S32 mThumbClickOffsetX{ 0 };
S32 mThumbClickOffsetY{ 0 };
S32 mPinchThumbClickOffsetX{ 0 };
S32 mPinchThumbClickOffsetY{ 0 };
S32 mPosXwhenCtrlDown{ 0 };
S32 mPosYwhenCtrlDown{ 0 };
};
#endif