FIRE-34747: Refactor poser to work in deltas only

Refactor undo/redo to generic, tiny rework to UI sliders for delta usage
meow-7.2.2
Angeldark Raymaker 2024-11-08 16:56:51 +00:00
parent 16a0431a47
commit 951ca0a349
7 changed files with 243 additions and 405 deletions

View File

@ -1756,7 +1756,7 @@ LLVector3 FSFloaterPoser::getRotationOfFirstSelectedJoint() const
return rotation;
rotation = mPoserAnimator.getJointRotation(avatar, *selectedJoints.front(), getJointTranslation(selectedJoints.front()->jointName()),
getJointNegation(selectedJoints.front()->jointName()), TARGETROTATION);
getJointNegation(selectedJoints.front()->jointName()));
return rotation;
}

View File

@ -45,208 +45,117 @@ FSJointPose::FSJointPose(LLJoint* joint, U32 usage, bool isCollisionVolume)
mJointName = joint->getName();
mIsCollisionVolume = isCollisionVolume;
mBeginningRotation = mTargetRotation = joint->getRotation();
mBeginningPosition = mTargetPosition = joint->getPosition();
mBeginningScale = mTargetScale = joint->getScale();
mBeginningRotation = joint->getRotation();
mBeginningPosition = joint->getPosition();
mBeginningScale = joint->getScale();
}
void FSJointPose::addLastPositionToUndo()
void FSJointPose::setPositionDelta(const LLVector3& pos)
{
if (mUndonePositionIndex > 0)
{
for (int i = 0; i < mUndonePositionIndex; i++)
mLastSetPositions.pop_front();
addToUndo(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas, &mTimeLastUpdatedPosition);
mPositionDelta.set(pos);
}
mUndonePositionIndex = 0;
void FSJointPose::setRotationDelta(const LLQuaternion& rot)
{
addToUndo(mRotationDelta, &mUndoneRotationIndex, &mLastSetRotationDeltas, &mTimeLastUpdatedRotation);
mRotationDelta.set(rot);
}
void FSJointPose::setScaleDelta(LLVector3 scale)
{
addToUndo(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas, &mTimeLastUpdatedScale);
mScaleDelta.set(scale);
}
void FSJointPose::undoLastPositionChange()
{
mPositionDelta.set(undoLastChange(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas));
}
void FSJointPose::undoLastRotationChange()
{
mRotationDelta.set(undoLastChange(mRotationDelta, &mUndoneRotationIndex, &mLastSetRotationDeltas));
}
void FSJointPose::undoLastScaleChange() { mScaleDelta.set(undoLastChange(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas)); }
void FSJointPose::redoLastPositionChange()
{
mPositionDelta.set(redoLastChange(mPositionDelta, &mUndonePositionIndex, &mLastSetPositionDeltas));
}
void FSJointPose::redoLastRotationChange()
{
mRotationDelta.set(redoLastChange(mRotationDelta, &mUndoneRotationIndex, &mLastSetRotationDeltas));
}
void FSJointPose::redoLastScaleChange() { mScaleDelta.set(redoLastChange(mScaleDelta, &mUndoneScaleIndex, &mLastSetScaleDeltas)); }
template <typename T>
inline void FSJointPose::addToUndo(T delta, size_t* undoIndex, std::deque<T>* dequeue,
std::chrono::system_clock::time_point* timeLastUpdated)
{
auto timeIntervalSinceLastChange = std::chrono::system_clock::now() - *timeLastUpdated;
*timeLastUpdated = std::chrono::system_clock::now();
if (timeIntervalSinceLastChange < UndoUpdateInterval)
return;
if (*undoIndex > 0)
{
for (size_t i = 0; i < *undoIndex; i++)
dequeue->pop_front();
*undoIndex = 0;
}
mLastSetPositions.push_front(mTargetPosition);
dequeue->push_front(delta);
while (mLastSetPositions.size() > MaximumUndoQueueLength)
mLastSetPositions.pop_back();
while (dequeue->size() > MaximumUndoQueueLength)
dequeue->pop_back();
}
void FSJointPose::addLastRotationToUndo()
template <typename T> T FSJointPose::undoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue)
{
if (mUndoneRotationIndex > 0)
{
for (int i = 0; i < mUndoneRotationIndex; i++)
mLastSetRotations.pop_front();
if (dequeue->empty())
return thingToSet;
mUndoneRotationIndex = 0;
}
if (*undoIndex == 0)
dequeue->push_front(thingToSet);
mLastSetRotations.push_front(mTargetRotation);
*undoIndex += 1;
*undoIndex = llclamp(*undoIndex, 0, dequeue->size() - 1);
while (mLastSetRotations.size() > MaximumUndoQueueLength)
mLastSetRotations.pop_back();
return dequeue->at(*undoIndex);
}
void FSJointPose::addLastScaleToUndo()
template <typename T> T FSJointPose::redoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue)
{
if (mUndoneScaleIndex > 0)
{
for (int i = 0; i < mUndoneScaleIndex; i++)
mLastSetScales.pop_front();
if (dequeue->empty())
return thingToSet;
if (*undoIndex == 0)
return thingToSet;
mUndoneScaleIndex = 0;
}
*undoIndex -= 1;
*undoIndex = llclamp(*undoIndex, 0, dequeue->size() - 1);
T result = dequeue->at(*undoIndex);
if (*undoIndex == 0)
dequeue->pop_front();
mLastSetScales.push_front(mTargetScale);
while (mLastSetScales.size() > MaximumUndoQueueLength)
mLastSetScales.pop_back();
return result;
}
LLVector3 FSJointPose::getCurrentPosition()
void FSJointPose::recaptureJoint()
{
LLVector3 vec3;
if (mIsCollisionVolume)
return;
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();
mBeginningRotation = joint->getRotation();
}
void FSJointPose::revertJointScale()
@ -281,4 +190,18 @@ void FSJointPose::revertCollisionVolume()
joint->setScale(mBeginningScale);
}
void FSJointPose::setJointStartRotations(LLQuaternion quat) { mBeginningRotation = mTargetRotation = quat; }
void FSJointPose::zeroBaseRotation()
{
if (mIsCollisionVolume)
return;
mBeginningRotation = LLQuaternion::DEFAULT;
}
bool FSJointPose::isBaseRotationZero() const
{
if (mIsCollisionVolume)
return true;
return mBeginningRotation == LLQuaternion::DEFAULT;
}

View File

@ -58,9 +58,58 @@ class FSJointPose
bool isCollisionVolume() const { return mIsCollisionVolume; }
/// <summary>
/// Adds a last rotation to the deque.
/// Gets the position change the animator wishes the joint to have.
/// </summary>
void addLastRotationToUndo();
LLVector3 getPositionDelta() const { return mPositionDelta; }
/// <summary>
/// Sets the position the animator wishes the joint to be in.
/// </summary>
void setPositionDelta(const LLVector3& pos);
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void undoLastPositionChange();
/// <summary>
/// Undoes the last position set, if any.
/// </summary>
void redoLastPositionChange();
/// <summary>
/// Gets the rotation the animator wishes the joint to be in.
/// </summary>
LLQuaternion getRotationDelta() const { return mRotationDelta; }
/// <summary>
/// Sets the rotation the animator wishes the joint to be in.
/// </summary>
void setRotationDelta(const LLQuaternion& rot);
/// <summary>
/// Sets the base rotation of the represented joint to zero.
/// </summary>
void zeroBaseRotation();
/// <summary>
/// Queries whether the represented joint is zero.
/// </summary>
/// <returns>True if the represented joint is zero, otherwise false.</returns>
bool isBaseRotationZero() const;
/// <summary>
/// Undoes the last rotation set, if any.
/// Ordinarily the queue does not contain the current rotation, because we rely on time to add, and not button-up.
/// When we undo, if we are at the top of the queue, we need to add the current rotation so we can redo back to it.
/// Thus when we start undoing, mUndoneRotationIndex points at the current rotation.
/// </summary>
void undoLastRotationChange();
/// <summary>
/// Redoes the last rotation set, if any.
/// </summary>
void redoLastRotationChange();
/// <summary>
/// Gets whether a redo of this joints rotation may be performed.
@ -68,118 +117,30 @@ class FSJointPose
/// <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; }
LLVector3 getScaleDelta() const { return mScaleDelta; }
/// <summary>
/// Sets the scale the animator wishes the joint to have.
/// </summary>
void setTargetScale(LLVector3 scale);
void setScaleDelta(LLVector3 scale);
/// <summary>
/// Undoes the last scale set, if any.
/// </summary>
void undoLastScaleSet();
void undoLastScaleChange();
/// <summary>
/// Redoes the last scale set, if any.
/// </summary>
void redoLastScaleSet();
void redoLastScaleChange();
/// <summary>
/// Adds a last rotation to the deque.
/// Resets the beginning properties of the joint this represents.
/// </summary>
void addLastScaleToUndo();
void recaptureJoint();
/// <summary>
/// Restores the joint represented by this to the scale it had when this motion started.
@ -197,6 +158,10 @@ class FSJointPose
/// </summary>
void revertCollisionVolume();
LLVector3 getTargetPosition() const { return mPositionDelta + mBeginningPosition; }
LLQuaternion getTargetRotation() const { return mRotationDelta * mBeginningRotation; }
LLVector3 getTargetScale() const { return mScaleDelta + mBeginningScale; }
/// <summary>
/// Gets the pointer to the jointstate for the joint this represents.
/// </summary>
@ -212,27 +177,33 @@ private:
/// </summary>
bool mIsCollisionVolume{ false };
LLQuaternion mTargetRotation;
LLQuaternion mRotationDelta;
LLQuaternion mBeginningRotation;
std::deque<LLQuaternion> mLastSetRotations;
std::deque<LLQuaternion> mLastSetRotationDeltas;
size_t mUndoneRotationIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedRotation = std::chrono::system_clock::now();
LLVector3 mTargetPosition;
LLVector3 mPositionDelta;
LLVector3 mBeginningPosition;
std::deque<LLVector3> mLastSetPositions;
std::deque<LLVector3> mLastSetPositionDeltas;
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 mScaleDelta;
LLVector3 mBeginningScale;
std::deque<LLVector3> mLastSetScales;
std::deque<LLVector3> mLastSetScaleDeltas;
size_t mUndoneScaleIndex = 0;
std::chrono::system_clock::time_point mTimeLastUpdatedScale = std::chrono::system_clock::now();
template <typename T>
void addToUndo(T delta, size_t* undoIndex, std::deque<T>* dequeue, std::chrono::system_clock::time_point* timeLastUpdated);
template <typename T> T undoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue);
template <typename T> T redoLastChange(T thingToSet, size_t* undoIndex, std::deque<T>* dequeue);
};
#endif // FS_JOINTPPOSE_H

View File

@ -94,8 +94,8 @@ void FSPoserAnimator::resetAvatarJoint(LLVOAvatar* avatar, const FSPoserJoint& j
if (!jointPose)
return;
jointPose->setTargetPosition(jointPose->getBeginningPosition());
jointPose->setTargetRotation(jointPose->getBeginningRotation());
jointPose->setPositionDelta(LLVector3());
jointPose->setRotationDelta(LLQuaternion());
}
void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -114,7 +114,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
if (!jointPose)
return;
jointPose->undoLastRotationSet();
jointPose->undoLastRotationChange();
if (style == NONE)
return;
@ -123,7 +123,7 @@ void FSPoserAnimator::undoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
if (!oppositeJointPose)
return;
oppositeJointPose->undoLastRotationSet();
oppositeJointPose->undoLastRotationChange();
}
void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -142,7 +142,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
if (!jointPose)
return;
jointPose->undoLastPositionSet();
jointPose->undoLastPositionChange();
if (style == NONE)
return;
@ -151,7 +151,7 @@ void FSPoserAnimator::undoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
if (!oppositeJointPose)
return;
oppositeJointPose->undoLastPositionSet();
oppositeJointPose->undoLastPositionChange();
}
void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -170,7 +170,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
if (!jointPose)
return;
jointPose->undoLastScaleSet();
jointPose->undoLastScaleChange();
if (style == NONE)
return;
@ -179,7 +179,7 @@ void FSPoserAnimator::undoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
if (!oppositeJointPose)
return;
oppositeJointPose->undoLastScaleSet();
oppositeJointPose->undoLastScaleChange();
}
void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -198,7 +198,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint&
if (!jointPose)
return;
jointPose->setTargetPosition(jointPose->getBeginningPosition());
jointPose->setPositionDelta(LLVector3());
if (style == NONE)
return;
@ -207,7 +207,7 @@ void FSPoserAnimator::resetJointPosition(LLVOAvatar* avatar, const FSPoserJoint&
if (!oppositeJointPose)
return;
oppositeJointPose->setTargetPosition(oppositeJointPose->getBeginningPosition());
oppositeJointPose->setPositionDelta(LLVector3());
}
void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -226,7 +226,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& jo
if (!jointPose)
return;
jointPose->setTargetScale(jointPose->getBeginningScale());
jointPose->setScaleDelta(LLVector3());
if (style == NONE)
return;
@ -235,7 +235,7 @@ void FSPoserAnimator::resetJointScale(LLVOAvatar* avatar, const FSPoserJoint& jo
if (!oppositeJointPose)
return;
oppositeJointPose->setTargetScale(oppositeJointPose->getBeginningScale());
oppositeJointPose->setScaleDelta(LLVector3());
}
bool FSPoserAnimator::canRedoJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint)
@ -273,7 +273,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
if (!jointPose)
return;
jointPose->redoLastRotationSet();
jointPose->redoLastRotationChange();
if (style == NONE)
return;
@ -282,7 +282,7 @@ void FSPoserAnimator::redoLastJointRotation(LLVOAvatar* avatar, const FSPoserJoi
if (!oppositeJointPose)
return;
oppositeJointPose->redoLastRotationSet();
oppositeJointPose->redoLastRotationChange();
}
void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -301,7 +301,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
if (!jointPose)
return;
jointPose->redoLastPositionSet();
jointPose->redoLastPositionChange();
if (style == NONE)
return;
@ -310,7 +310,7 @@ void FSPoserAnimator::redoLastJointPosition(LLVOAvatar* avatar, const FSPoserJoi
if (!oppositeJointPose)
return;
oppositeJointPose->redoLastPositionSet();
oppositeJointPose->redoLastPositionChange();
}
void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneDeflectionStyles style)
@ -329,7 +329,7 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
if (!jointPose)
return;
jointPose->redoLastScaleSet();
jointPose->redoLastScaleChange();
if (style == NONE)
return;
@ -338,10 +338,10 @@ void FSPoserAnimator::redoLastJointScale(LLVOAvatar* avatar, const FSPoserJoint&
if (!oppositeJointPose)
return;
oppositeJointPose->redoLastScaleSet();
oppositeJointPose->redoLastScaleChange();
}
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint) const
{
LLVector3 pos;
if (!isAvatarSafeToUse(avatar))
@ -355,12 +355,7 @@ LLVector3 FSPoserAnimator::getJointPosition(LLVOAvatar* avatar, const FSPoserJoi
if (!jointPose)
return pos;
if (forRecapture)
pos = jointPose->getCurrentPosition();
else
pos = jointPose->getTargetPosition();
return pos;
return jointPose->getPositionDelta();
}
void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& position, E_BoneDeflectionStyles style)
@ -384,27 +379,27 @@ void FSPoserAnimator::setJointPosition(LLVOAvatar* avatar, const FSPoserJoint* j
if (style == NONE)
{
jointPose->setTargetPosition(position);
jointPose->setPositionDelta(position);
return;
}
LLVector3 positionDelta = jointPose->getTargetPosition() - position;
LLVector3 positionDelta = jointPose->getPositionDelta() - position;
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
if (!oppositeJointPose)
return;
LLVector3 oppositeJointPosition = oppositeJointPose->getTargetPosition();
LLVector3 oppositeJointPosition = oppositeJointPose->getPositionDelta();
switch (style)
{
case SYMPATHETIC:
jointPose->setTargetPosition(position);
oppositeJointPose->setTargetPosition(oppositeJointPosition - positionDelta);
jointPose->setPositionDelta(position);
oppositeJointPose->setPositionDelta(oppositeJointPosition - positionDelta);
break;
case MIRROR:
jointPose->setTargetPosition(position);
oppositeJointPose->setTargetPosition(oppositeJointPosition + positionDelta);
jointPose->setPositionDelta(position);
oppositeJointPose->setPositionDelta(oppositeJointPosition + positionDelta);
break;
default:
@ -441,40 +436,23 @@ void FSPoserAnimator::setAllAvatarStartingRotationsToZero(LLVOAvatar* avatar)
}
void FSPoserAnimator::recaptureJoint(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation)
{
LLVector3 newRotation = getJointRotation(avatar, joint, translation, negation, CURRENTROTATION);
LLVector3 newPosition = getJointPosition(avatar, joint, true);
LLVector3 newScale = getJointScale(avatar, joint, true);
setPosingAvatarJoint(avatar, joint, true);
setStartingJointRotation(avatar, &joint, newRotation, translation, negation);
// recapture of positions and scale does not reset starting values, since this this could result in unwanted residue deformation after posing stops.
setJointPosition(avatar, &joint, newPosition, NONE);
setJointScale(avatar, &joint, newScale, NONE);
}
void FSPoserAnimator::setStartingJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation,
E_BoneAxisTranslation translation, S32 negation)
{
if (!isAvatarSafeToUse(avatar))
return;
if (!joint)
return;
FSPosingMotion* posingMotion = getPosingMotion(avatar);
if (!posingMotion)
return;
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint->jointName());
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
if (!jointPose)
return;
LLQuaternion rot_quat = translateRotationToQuaternion(translation, negation, rotation);
jointPose->setJointStartRotations(rot_quat);
jointPose->recaptureJoint();
setPosingAvatarJoint(avatar, joint, true);
}
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation, E_BoneRotationType rotType) const
LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation) const
{
LLVector3 vec3;
if (!isAvatarSafeToUse(avatar))
@ -487,21 +465,8 @@ LLVector3 FSPoserAnimator::getJointRotation(LLVOAvatar* avatar, const FSPoserJoi
FSJointPose* jointPose = posingMotion->getJointPoseByJointName(joint.jointName());
if (!jointPose)
return vec3;
LLQuaternion rot;
switch (rotType)
{
case TARGETROTATION:
rot = jointPose->getTargetRotation();
break;
case CURRENTROTATION:
default:
rot = jointPose->getCurrentRotation();
break;
}
return translateRotationFromQuaternion(translation, negation, rot);
return translateRotationFromQuaternion(translation, negation, jointPose->getRotationDelta());
}
void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation, E_BoneDeflectionStyles style,
@ -525,16 +490,16 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
{
case SYMPATHETIC:
case MIRROR:
jointPose->setTargetRotation(rot_quat);
jointPose->setRotationDelta(rot_quat);
break;
case DELTAMODE:
jointPose->applyDeltaRotation(rot_quat);
jointPose->setRotationDelta(rot_quat * jointPose->getRotationDelta());
return;
case NONE:
default:
jointPose->setTargetRotation(rot_quat);
jointPose->setRotationDelta(rot_quat);
return;
}
@ -546,12 +511,12 @@ void FSPoserAnimator::setJointRotation(LLVOAvatar* avatar, const FSPoserJoint* j
switch (style)
{
case SYMPATHETIC:
oppositeJointPose->setTargetRotation(rot_quat);
oppositeJointPose->setRotationDelta(rot_quat);
break;
case MIRROR:
inv_quat = LLQuaternion(-rot_quat.mQ[VX], rot_quat.mQ[VY], -rot_quat.mQ[VZ], rot_quat.mQ[VW]);
oppositeJointPose->setTargetRotation(inv_quat);
oppositeJointPose->setRotationDelta(inv_quat);
break;
default:
@ -578,19 +543,19 @@ void FSPoserAnimator::reflectJoint(LLVOAvatar* avatar, const FSPoserJoint* joint
FSJointPose* oppositeJointPose = posingMotion->getJointPoseByJointName(joint->mirrorJointName());
if (!oppositeJointPose)
{
LLQuaternion rot_quat = jointPose->getTargetRotation();
LLQuaternion rot_quat = jointPose->getRotationDelta();
LLQuaternion inv_quat = LLQuaternion(-rot_quat.mQ[VX], rot_quat.mQ[VY], -rot_quat.mQ[VZ], rot_quat.mQ[VW]);
jointPose->setTargetRotation(inv_quat);
jointPose->setRotationDelta(inv_quat);
return;
}
LLQuaternion first_quat = jointPose->getTargetRotation();
LLQuaternion first_quat = jointPose->getRotationDelta();
LLQuaternion first_inv = LLQuaternion(-first_quat.mQ[VX], first_quat.mQ[VY], -first_quat.mQ[VZ], first_quat.mQ[VW]);
LLQuaternion second_quat = oppositeJointPose->getTargetRotation();
LLQuaternion second_quat = oppositeJointPose->getRotationDelta();
LLQuaternion second_inv = LLQuaternion(-second_quat.mQ[VX], second_quat.mQ[VY], -second_quat.mQ[VZ], second_quat.mQ[VW]);
jointPose->setTargetRotation(second_inv);
oppositeJointPose->setTargetRotation(first_inv);
jointPose->setRotationDelta(second_inv);
oppositeJointPose->setRotationDelta(first_inv);
}
void FSPoserAnimator::flipEntirePose(LLVOAvatar* avatar)
@ -725,7 +690,7 @@ LLVector3 FSPoserAnimator::translateRotationFromQuaternion(E_BoneAxisTranslation
return vec3;
}
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint, bool forRecapture) const
LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint) const
{
LLVector3 scale;
if (!isAvatarSafeToUse(avatar))
@ -739,12 +704,7 @@ LLVector3 FSPoserAnimator::getJointScale(LLVOAvatar* avatar, const FSPoserJoint&
if (!jointPose)
return scale;
if (forRecapture)
scale = jointPose->getCurrentScale();
else
scale = jointPose->getTargetScale();
return scale;
return jointPose->getScaleDelta();
}
void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& scale, E_BoneDeflectionStyles style)
@ -766,7 +726,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join
if (!jointPose)
return;
jointPose->setTargetScale(scale);
jointPose->setScaleDelta(scale);
if (style == NONE)
return;
@ -775,7 +735,7 @@ void FSPoserAnimator::setJointScale(LLVOAvatar* avatar, const FSPoserJoint* join
if (!oppositeJointPose)
return;
oppositeJointPose->setTargetScale(scale);
oppositeJointPose->setScaleDelta(scale);
}
bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJoint& joint, LLVector3* rot, LLVector3* pos, LLVector3* scale)
@ -794,11 +754,10 @@ bool FSPoserAnimator::tryGetJointSaveVectors(LLVOAvatar* avatar, const FSPoserJo
if (!jointPose)
return false;
LLQuaternion difference = jointPose->getTargetRotation() * jointPose->getBeginningRotation().conjugate(); // diff * q1 = q2 -> diff = q2 * inverse(q1)
difference.getEulerAngles(&rot->mV[VX], &rot->mV[VY], &rot->mV[VZ]);
pos->set(jointPose->getTargetPosition() - jointPose->getBeginningPosition());
scale->set(jointPose->getTargetScale() - jointPose->getBeginningScale());
LLQuaternion rotationDelta = jointPose->getRotationDelta();
rotationDelta.getEulerAngles(&rot->mV[VX], &rot->mV[VY], &rot->mV[VZ]);
pos->set(jointPose->getPositionDelta());
scale->set(jointPose->getScaleDelta());
return true;
}
@ -816,7 +775,7 @@ void FSPoserAnimator::loadJointRotation(LLVOAvatar* avatar, const FSPoserJoint*
return;
LLQuaternion rot = translateRotationToQuaternion(SWAP_NOTHING, NEGATE_NOTHING, rotation);
jointPose->setTargetRotation(rot * jointPose->getBeginningRotation());
jointPose->setRotationDelta(rot);
}
void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint* joint, bool loadPositionAsDelta, LLVector3 position)
@ -833,9 +792,9 @@ void FSPoserAnimator::loadJointPosition(LLVOAvatar* avatar, const FSPoserJoint*
return;
if (loadPositionAsDelta)
jointPose->setTargetPosition(jointPose->getBeginningPosition() + position);
jointPose->setPositionDelta(position);
else
jointPose->setTargetPosition(position);
jointPose->setPositionDelta(position);
}
void FSPoserAnimator::loadJointScale(LLVOAvatar* avatar, const FSPoserJoint* joint, bool loadScaleAsDelta, LLVector3 scale)
@ -852,9 +811,9 @@ void FSPoserAnimator::loadJointScale(LLVOAvatar* avatar, const FSPoserJoint* joi
return;
if (loadScaleAsDelta)
jointPose->setTargetScale(jointPose->getTargetScale() + scale);
jointPose->setScaleDelta(scale);
else
jointPose->setTargetScale(scale);
jointPose->setScaleDelta(scale);
}
const FSPoserAnimator::FSPoserJoint* FSPoserAnimator::getPoserJointByName(const std::string& jointName)

View File

@ -56,15 +56,6 @@ typedef enum E_BoneDeflectionStyles
DELTAMODE = 3, // each selected joint changes by the same supplied amount relative to their current
} E_BoneDeflectionStyles;
/// <summary>
/// When getting the rotation of a joint, we can apply different considerations to the rotation.
/// </summary>
typedef enum E_BoneRotationType
{
CURRENTROTATION = 0, // the current rotation the joint has
TARGETROTATION = 1, // the rotation the we want to achieve
} E_BoneRotationType;
/// <summary>
/// When we're going from bone-rotation to the UI sliders, some of the axes need swapping so they make sense in UI-terms.
/// eg: for one bone, the X-axis may mean up and down, but for another bone, the x-axis might be left-right.
@ -429,7 +420,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, const FSPoserJoint& joint, bool forRecapture = false) const;
LLVector3 getJointPosition(LLVOAvatar* avatar, const FSPoserJoint& joint) const;
/// <summary>
/// Sets the position of a joint for the supplied avatar.
@ -449,7 +440,7 @@ public:
/// <param name="negation">The style of negation to dis-apply to the get.</param>
/// <param name="rotType">The type of rotation to get from the supplied joint for the supplied avatar.</param>
/// <returns>The rotation of the requested joint, if determinable, otherwise a default vector.</returns>
LLVector3 getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation, E_BoneRotationType rotType) const;
LLVector3 getJointRotation(LLVOAvatar* avatar, const FSPoserJoint& joint, E_BoneAxisTranslation translation, S32 negation) const;
/// <summary>
/// Sets the rotation of a joint for the supplied avatar.
@ -469,7 +460,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, const FSPoserJoint& joint, bool forRecapture = false) const;
LLVector3 getJointScale(LLVOAvatar* avatar, const FSPoserJoint& joint) const;
/// <summary>
/// Sets the scale of a joint for the supplied avatar.
@ -622,9 +613,6 @@ public:
/// <returns>True if the avatar is safe to manipulate, otherwise false.</returns>
bool isAvatarSafeToUse(LLVOAvatar* avatar) const;
void setStartingJointRotation(LLVOAvatar* avatar, const FSPoserJoint* joint, const LLVector3& rotation,
E_BoneAxisTranslation translation, S32 negation);
/// <summary>
/// Maps the avatar's ID to the animation registered to them.
/// Thus we start/stop the same animation, and get/set the same rotations etc.

View File

@ -91,9 +91,9 @@ bool FSPosingMotion::onUpdate(F32 time, U8* joint_mask)
currentRotation = joint->getRotation();
currentPosition = joint->getPosition();
currentScale = joint->getScale();
targetRotation = jointPose.getTargetRotation();
targetPosition = jointPose.getTargetPosition();
targetScale = jointPose.getTargetScale();
targetRotation = jointPose.getTargetRotation();
targetPosition = jointPose.getTargetPosition();
targetScale = jointPose.getTargetScale();
if (currentPosition != targetPosition)
{
@ -254,13 +254,10 @@ bool FSPosingMotion::allStartingRotationsAreZero() const
LLQuaternion zeroQuat;
for (auto poserJoint_iter = mJointPoses.begin(); poserJoint_iter != mJointPoses.end(); ++poserJoint_iter)
{
if (poserJoint_iter->jointName() == "mPelvis")
continue;
if (poserJoint_iter->isCollisionVolume())
continue;
LLQuaternion quat = poserJoint_iter->getBeginningRotation();
if (quat != zeroQuat)
if (!poserJoint_iter->isBaseRotationZero())
return false;
}
@ -275,7 +272,7 @@ void FSPosingMotion::setAllRotationsToZero()
if (poserJoint_iter->isCollisionVolume())
continue;
poserJoint_iter->setJointStartRotations(zeroQuat);
poserJoint_iter->zeroBaseRotation();
}
}

View File

@ -1422,7 +1422,7 @@ width="403">
layout="topleft"
left="10"
max_val="2"
min_val="0"
min_val="-2"
name="Advanced_Scale_X"
top_pad="6"
width="380" >
@ -1441,7 +1441,7 @@ width="403">
layout="topleft"
left_delta="0"
max_val="2"
min_val="0"
min_val="-2"
name="Advanced_Scale_Y"
top_pad="1"
width="380" >
@ -1460,7 +1460,7 @@ width="403">
layout="topleft"
left_delta="0"
max_val="2"
min_val="0"
min_val="-2"
name="Advanced_Scale_Z"
top_pad="1"
width="380" >