FIRE-34747: Move FSJointPose to own class
parent
8fa341cca7
commit
8a228daeff
|
|
@ -139,6 +139,7 @@ set(viewer_SOURCE_FILES
|
|||
fsfloatervramusage.cpp
|
||||
fsfloaterwearablefavorites.cpp
|
||||
fsfloaterwhitelisthelper.cpp
|
||||
fsjointpose.cpp
|
||||
fskeywords.cpp
|
||||
fslslbridge.cpp
|
||||
fslslbridgerequest.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
/**
|
||||
* @file fsposingmotion.cpp
|
||||
* @brief Model for posing your (and other) avatar(s).
|
||||
*
|
||||
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (c) 2024 Angeldark Raymaker @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <deque>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "fsposingmotion.h"
|
||||
#include "llcharacter.h"
|
||||
|
||||
constexpr size_t MaximumUndoQueueLength = 20;
|
||||
|
||||
/// <summary>
|
||||
/// The constant time interval, in seconds, specifying whether an 'undo' value should be added.
|
||||
/// </summary>
|
||||
constexpr std::chrono::duration<double> UndoUpdateInterval = std::chrono::duration<double>(0.3);
|
||||
|
||||
FSJointPose::FSJointPose(LLJoint* joint, U32 usage, bool isCollisionVolume)
|
||||
{
|
||||
mJointState = new LLJointState;
|
||||
mJointState->setJoint(joint);
|
||||
mJointState->setUsage(usage);
|
||||
|
||||
mJointName = joint->getName();
|
||||
mIsCollisionVolume = isCollisionVolume;
|
||||
|
||||
mBeginningRotation = mTargetRotation = joint->getRotation();
|
||||
mBeginningPosition = mTargetPosition = joint->getPosition();
|
||||
mBeginningScale = mTargetScale = joint->getScale();
|
||||
}
|
||||
|
||||
void 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 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 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 FSJointPose::getCurrentPosition()
|
||||
{
|
||||
LLVector3 vec3;
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return vec3;
|
||||
|
||||
vec3 = joint->getPosition();
|
||||
return vec3;
|
||||
}
|
||||
|
||||
void 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 FSJointPose::getCurrentRotation()
|
||||
{
|
||||
LLQuaternion quat;
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return quat;
|
||||
|
||||
quat = joint->getRotation();
|
||||
return quat;
|
||||
}
|
||||
|
||||
void 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 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 FSJointPose::getCurrentScale()
|
||||
{
|
||||
LLVector3 vec3;
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return vec3;
|
||||
|
||||
vec3 = joint->getScale();
|
||||
return vec3;
|
||||
}
|
||||
|
||||
void 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 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 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 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 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 FSJointPose::undoLastScaleSet()
|
||||
{
|
||||
if (mLastSetScales.empty())
|
||||
return;
|
||||
|
||||
if (mUndoneScaleIndex == 0)
|
||||
addLastScaleToUndo();
|
||||
|
||||
mUndoneScaleIndex++;
|
||||
mUndoneScaleIndex = llclamp(mUndoneScaleIndex, 0, mLastSetScales.size() - 1);
|
||||
mTargetScale.set(mLastSetScales[mUndoneScaleIndex]);
|
||||
}
|
||||
|
||||
void 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 FSJointPose::revertJointScale()
|
||||
{
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return;
|
||||
|
||||
joint->setScale(mBeginningScale);
|
||||
}
|
||||
|
||||
void FSJointPose::revertJointPosition()
|
||||
{
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return;
|
||||
|
||||
joint->setPosition(mBeginningPosition);
|
||||
}
|
||||
|
||||
void FSJointPose::revertCollisionVolume()
|
||||
{
|
||||
if (!mIsCollisionVolume)
|
||||
return;
|
||||
|
||||
LLJoint* joint = mJointState->getJoint();
|
||||
if (!joint)
|
||||
return;
|
||||
|
||||
joint->setRotation(mBeginningRotation);
|
||||
joint->setPosition(mBeginningPosition);
|
||||
joint->setScale(mBeginningScale);
|
||||
}
|
||||
|
||||
void FSJointPose::setJointStartRotations(LLQuaternion quat) { mBeginningRotation = mTargetRotation = quat; }
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/**
|
||||
* @file fsjointpose.h
|
||||
* @brief Container for the pose of a joint.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (c) 2024 Angeldark Raymaker @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef FS_JOINTPPOSE_H
|
||||
#define FS_JOINTPPOSE_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Header files
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "llmotion.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class FSJointPose
|
||||
//-----------------------------------------------------------------------------
|
||||
class FSJointPose
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// A class encapsulating the positions/rotations for a joint.
|
||||
/// </summary>
|
||||
/// <param name="joint">The joint this joint pose represents.</param>
|
||||
/// <param name="usage">The default usage the joint should have in a pose.</param>
|
||||
/// <param name="isCollisionVolume">Whether the supplied joint is a collision volume.</param>
|
||||
FSJointPose(LLJoint* joint, U32 usage, bool isCollisionVolume = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the joint.
|
||||
/// </summary>
|
||||
std::string jointName() const { return mJointName; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether this represents a collision volume.
|
||||
/// </summary>
|
||||
/// <returns>true if the joint is a collision volume, otherwise false.</returns>
|
||||
bool isCollisionVolume() const { return mIsCollisionVolume; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a last rotation to the deque.
|
||||
/// </summary>
|
||||
void addLastRotationToUndo();
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether a redo of this joints rotation may be performed.
|
||||
/// </summary>
|
||||
/// <returns>true if the joint can have a redo applied, otherwise false.</returns>
|
||||
bool canRedoRotation() const { return mUndoneRotationIndex > 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the joint was in when the animation was initialized.
|
||||
/// </summary>
|
||||
LLVector3 getBeginningPosition() const { return mBeginningPosition; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLVector3 getTargetPosition() const { return mTargetPosition; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLVector3 getCurrentPosition();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
void setTargetPosition(const LLVector3& pos);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a last position to the deque.
|
||||
/// </summary>
|
||||
void addLastPositionToUndo();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
void undoLastPositionSet();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
void redoLastPositionSet();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation the joint was in when the animation was initialized.
|
||||
/// </summary>
|
||||
LLQuaternion getBeginningRotation() const { return mBeginningRotation; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLQuaternion getTargetRotation() const { return mTargetRotation; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation of the joint.
|
||||
/// </summary>
|
||||
LLQuaternion getCurrentRotation();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the beginning and target rotations to the supplied rotation.
|
||||
/// </summary>
|
||||
void setJointStartRotations(LLQuaternion quat);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
void setTargetRotation(const LLQuaternion& rot);
|
||||
|
||||
/// <summary>
|
||||
/// Applies a delta to the rotation the joint currently targets.
|
||||
/// </summary>
|
||||
void applyDeltaRotation(const LLQuaternion& rot);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last rotation set, if any.
|
||||
/// Ordinarily the queue does not contain the current rotation, because we rely on time to add, and not button-up.
|
||||
/// When we undo, if we are at the top of the queue, we need to add the current rotation so we can redo back to it.
|
||||
/// Thus when we start undoing, mUndoneRotationIndex points at the current rotation.
|
||||
/// </summary>
|
||||
void undoLastRotationSet();
|
||||
|
||||
/// <summary>
|
||||
/// Redoes the last rotation set, if any.
|
||||
/// </summary>
|
||||
void redoLastRotationSet();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
LLVector3 getTargetScale() const { return mTargetScale; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the joint has.
|
||||
/// </summary>
|
||||
LLVector3 getCurrentScale();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the joint had when the animation was initialized.
|
||||
/// </summary>
|
||||
LLVector3 getBeginningScale() const { return mBeginningScale; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
void setTargetScale(LLVector3 scale);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last scale set, if any.
|
||||
/// </summary>
|
||||
void undoLastScaleSet();
|
||||
|
||||
/// <summary>
|
||||
/// Redoes the last scale set, if any.
|
||||
/// </summary>
|
||||
void redoLastScaleSet();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a last rotation to the deque.
|
||||
/// </summary>
|
||||
void addLastScaleToUndo();
|
||||
|
||||
/// <summary>
|
||||
/// Restores the joint represented by this to the scale it had when this motion started.
|
||||
/// </summary>
|
||||
void revertJointScale();
|
||||
|
||||
/// <summary>
|
||||
/// Restores the joint represented by this to the position it had when this motion started.
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the jointstate for the joint this represents.
|
||||
/// </summary>
|
||||
LLPointer<LLJointState> getJointState() const { return mJointState; }
|
||||
|
||||
private:
|
||||
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 mIsCollisionVolume{ false };
|
||||
|
||||
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 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 mTargetScale;
|
||||
LLVector3 mBeginningScale;
|
||||
std::deque<LLVector3> mLastSetScales;
|
||||
size_t mUndoneScaleIndex = 0;
|
||||
std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now();
|
||||
};
|
||||
|
||||
#endif // FS_JOINTPPOSE_H
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ bool FSPoserAnimator::isPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint
|
|||
if (posingMotion->isStopped())
|
||||
return false;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return false;
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ void FSPoserAnimator::setPosingAvatarJoint(LLVOAvatar* avatar, const FSPoserJoin
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& j
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -194,7 +194,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -222,7 +222,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& jo
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& jo
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -250,7 +250,7 @@ bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoin
|
|||
if (posingMotion->isStopped())
|
||||
return false;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return false;
|
||||
|
||||
|
|
@ -269,7 +269,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -325,7 +325,7 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (posingMotion->isStopped())
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint.mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -351,7 +351,7 @@ LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (!posingMotion)
|
||||
return pos;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return pos;
|
||||
|
||||
|
|
@ -378,7 +378,7 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(jn);
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(jn);
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -390,7 +390,7 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j
|
|||
|
||||
LLVector3 positionDelta = jointPose->getTargetPosition() - position;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -466,7 +466,7 @@ void FSPoserAnimator::setStartingJointRotation(LLVOAvatar* avatar, const FSPoser
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -484,7 +484,7 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoi
|
|||
if (!posingMotion)
|
||||
return vec3;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return vec3;
|
||||
|
||||
|
|
@ -516,7 +516,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -538,7 +538,7 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
|
|||
return;
|
||||
}
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -571,11 +571,11 @@ void FSPoserAnimator::reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
{
|
||||
LLQuaternion rot_quat = jointPose->getTargetRotation();
|
||||
|
|
@ -735,7 +735,7 @@ LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint&
|
|||
if (!posingMotion)
|
||||
return scale;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return scale;
|
||||
|
||||
|
|
@ -762,7 +762,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(jn);
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(jn);
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -771,7 +771,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join
|
|||
if (style == NONE)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
|
||||
if (!oppositeJointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -790,7 +790,7 @@ bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJo
|
|||
if (!posingMotion)
|
||||
return false;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
|
||||
if (!jointPose)
|
||||
return false;
|
||||
|
||||
|
|
@ -811,7 +811,7 @@ void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint*
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -828,7 +828,7 @@ void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint*
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
@ -847,7 +847,7 @@ void FSPoserAnimator::loadJointScale(LLVOAvatar* avatar, const FSPoserJoint* joi
|
|||
if (!posingMotion)
|
||||
return;
|
||||
|
||||
FSPosingMotion::FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
|
||||
if (!jointPose)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ LLMotion::LLMotionInitStatus FSPosingMotion::onInitialize(LLCharacter *character
|
|||
if (!targetJoint)
|
||||
continue;
|
||||
|
||||
FSJointPose jointPose = FSJointPose(targetJoint);
|
||||
FSJointPose jointPose = FSJointPose(targetJoint, POSER_JOINT_STATE);
|
||||
mJointPoses.push_back(jointPose);
|
||||
|
||||
addJointState(jointPose.getJointState());
|
||||
|
|
@ -213,7 +213,7 @@ void FSPosingMotion::setJointState(LLJoint* joint, U32 state)
|
|||
addJointState(jointPose->getJointState());
|
||||
}
|
||||
|
||||
FSPosingMotion::FSJointPose* FSPosingMotion::getJointPoseByJointName(const std::string& name)
|
||||
FSJointPose* FSPosingMotion::getJointPoseByJointName(const std::string& name)
|
||||
{
|
||||
if (mJointPoses.size() < 1)
|
||||
return nullptr;
|
||||
|
|
@ -285,251 +285,3 @@ constexpr size_t MaximumUndoQueueLength = 20;
|
|||
/// The constant time interval, in seconds, specifying whether an 'undo' value should be added.
|
||||
/// </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);
|
||||
}
|
||||
|
||||
void FSPosingMotion::FSJointPose::setJointStartRotations(LLQuaternion quat) { mBeginningRotation = mTargetRotation = quat; }
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file fsposingmotion.cpp
|
||||
* @file fsposingmotion.h
|
||||
* @brief Model for posing your (and other) avatar(s).
|
||||
*
|
||||
* $LicenseInfo:firstyear=2024&license=viewerlgpl$
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
// Header files
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "llmotion.h"
|
||||
#include "fsjointpose.h"
|
||||
|
||||
#define MIN_REQUIRED_PIXEL_AREA_POSING 500.f
|
||||
|
||||
|
|
@ -47,195 +48,6 @@ public:
|
|||
public:
|
||||
static LLMotion *create(const LLUUID &id) { return new FSPosingMotion(id); }
|
||||
|
||||
/// <summary>
|
||||
/// A class encapsulating the positions/rotations for a joint.
|
||||
/// </summary>
|
||||
class FSJointPose
|
||||
{
|
||||
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 mIsCollisionVolume{ false };
|
||||
|
||||
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 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 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();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a last rotation to the deque.
|
||||
/// </summary>
|
||||
void addLastRotationToUndo();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a last rotation to the deque.
|
||||
/// </summary>
|
||||
void addLastScaleToUndo();
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Gets the name of the joint.
|
||||
/// </summary>
|
||||
std::string jointName() const { return mJointName; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether this represents a collision volume.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool isCollisionVolume() const { return mIsCollisionVolume; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether a redo of this joints rotation may be performed.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool canRedoRotation() const { return mUndoneRotationIndex > 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the joint was in when the animation was initialized.
|
||||
/// </summary>
|
||||
LLVector3 getBeginningPosition() const { return mBeginningPosition; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLVector3 getTargetPosition() const { return mTargetPosition; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLVector3 getCurrentPosition();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
void setTargetPosition(const LLVector3& pos);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation the joint was in when the animation was initialized.
|
||||
/// </summary>
|
||||
LLQuaternion getBeginningRotation() const { return mBeginningRotation; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
LLQuaternion getTargetRotation() const { return mTargetRotation; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the rotation of the joint.
|
||||
/// </summary>
|
||||
LLQuaternion getCurrentRotation();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation the animator wishes the joint to be in.
|
||||
/// </summary>
|
||||
void setTargetRotation(const LLQuaternion& rot);
|
||||
|
||||
/// <summary>
|
||||
/// Applies a delta to the rotation the joint currently targets.
|
||||
/// </summary>
|
||||
void applyDeltaRotation(const LLQuaternion& rot);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
LLVector3 getTargetScale() const { return mTargetScale; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the joint has.
|
||||
/// </summary>
|
||||
LLVector3 getCurrentScale();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale the joint had when the animation was initialized.
|
||||
/// </summary>
|
||||
LLVector3 getBeginningScale() const { return mBeginningScale; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the scale the animator wishes the joint to have.
|
||||
/// </summary>
|
||||
void setTargetScale(LLVector3 scale);
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
void undoLastPositionSet();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last position set, if any.
|
||||
/// </summary>
|
||||
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, mUndoneRotationIndex points at the current rotation.
|
||||
/// </summary>
|
||||
void undoLastRotationSet();
|
||||
|
||||
/// <summary>
|
||||
/// Undoes the last rotation set, if any.
|
||||
/// </summary>
|
||||
void redoLastRotationSet();
|
||||
|
||||
void undoLastScaleSet();
|
||||
|
||||
void redoLastScaleSet();
|
||||
|
||||
/// <summary>
|
||||
/// Restores the joint represented by this to the scale it had when this motion started.
|
||||
/// </summary>
|
||||
void revertJointScale();
|
||||
|
||||
/// <summary>
|
||||
/// Restores the joint represented by this to the position it had when this motion started.
|
||||
/// </summary>
|
||||
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();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the beginning and target rotations to the supplied rotation.
|
||||
/// </summary>
|
||||
void setJointStartRotations(LLQuaternion quat);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the jointstate for the joint this represents.
|
||||
/// </summary>
|
||||
LLPointer<LLJointState> getJointState() const { return mJointState; }
|
||||
|
||||
FSJointPose(LLJoint* joint, bool isCollisionVolume = false);
|
||||
};
|
||||
|
||||
public:
|
||||
virtual bool getLoop() { return true; }
|
||||
|
||||
virtual F32 getDuration() { return 0.0; }
|
||||
|
|
@ -366,4 +178,3 @@ private:
|
|||
};
|
||||
|
||||
#endif // FS_POSINGMOTION_H
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue