mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
Convert JointData from relative frame to absolute.
This commit is contained in:
parent
06d1bd5728
commit
55b0060df9
6 changed files with 63 additions and 48 deletions
|
@ -165,6 +165,7 @@ void Rig::destroyAnimGraph() {
|
||||||
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) {
|
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) {
|
||||||
|
|
||||||
_geometryOffset = AnimPose(geometry.offset);
|
_geometryOffset = AnimPose(geometry.offset);
|
||||||
|
_invGeometryOffset = _geometryOffset.inverse();
|
||||||
setModelOffset(modelOffset);
|
setModelOffset(modelOffset);
|
||||||
|
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
||||||
|
@ -193,6 +194,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
|
||||||
|
|
||||||
void Rig::reset(const FBXGeometry& geometry) {
|
void Rig::reset(const FBXGeometry& geometry) {
|
||||||
_geometryOffset = AnimPose(geometry.offset);
|
_geometryOffset = AnimPose(geometry.offset);
|
||||||
|
_invGeometryOffset = _geometryOffset.inverse();
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
||||||
|
|
||||||
_internalPoseSet._relativePoses.clear();
|
_internalPoseSet._relativePoses.clear();
|
||||||
|
@ -272,24 +274,6 @@ void Rig::setModelOffset(const glm::mat4& modelOffsetMat) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Rig::getJointStateRotation(int index, glm::quat& rotation) const {
|
|
||||||
if (isIndexValid(index)) {
|
|
||||||
rotation = _internalPoseSet._relativePoses[index].rot;
|
|
||||||
return !isEqual(rotation, _animSkeleton->getRelativeDefaultPose(index).rot);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const {
|
|
||||||
if (isIndexValid(index)) {
|
|
||||||
translation = _internalPoseSet._relativePoses[index].trans;
|
|
||||||
return !isEqual(translation, _animSkeleton->getRelativeDefaultPose(index).trans);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rig::clearJointState(int index) {
|
void Rig::clearJointState(int index) {
|
||||||
if (isIndexValid(index)) {
|
if (isIndexValid(index)) {
|
||||||
_internalPoseSet._overrideFlags[index] = false;
|
_internalPoseSet._overrideFlags[index] = false;
|
||||||
|
@ -446,6 +430,23 @@ void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds,
|
||||||
*alphaOut = alpha;
|
*alphaOut = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Rig::getJointData(int index, JointData& jointDataOut) const {
|
||||||
|
if (isIndexValid(index)) {
|
||||||
|
jointDataOut.rotation = _internalPoseSet._absolutePoses[index].rot;
|
||||||
|
jointDataOut.rotationSet = !isEqual(jointDataOut.rotation, _animSkeleton->getAbsoluteDefaultPose(index).rot);
|
||||||
|
|
||||||
|
// geometry offset is used here so that translations are in meters, this is what the avatar mixer expects
|
||||||
|
jointDataOut.translation = _geometryOffset * _internalPoseSet._absolutePoses[index].trans;
|
||||||
|
jointDataOut.translationSet = !isEqual(jointDataOut.translation, _animSkeleton->getAbsoluteDefaultPose(index).trans);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
jointDataOut.translationSet = false;
|
||||||
|
jointDataOut.rotationSet = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rig::setEnableInverseKinematics(bool enable) {
|
void Rig::setEnableInverseKinematics(bool enable) {
|
||||||
_enableInverseKinematics = enable;
|
_enableInverseKinematics = enable;
|
||||||
}
|
}
|
||||||
|
@ -1232,21 +1233,44 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
||||||
jointDataVec.resize((int)getJointStateCount());
|
jointDataVec.resize((int)getJointStateCount());
|
||||||
for (auto i = 0; i < jointDataVec.size(); i++) {
|
for (auto i = 0; i < jointDataVec.size(); i++) {
|
||||||
JointData& data = jointDataVec[i];
|
JointData& data = jointDataVec[i];
|
||||||
data.rotationSet |= getJointStateRotation(i, data.rotation);
|
getJointData(i, data);
|
||||||
// geometry offset is used here so that translations are in meters.
|
|
||||||
// this is what the avatar mixer expects
|
|
||||||
data.translationSet |= getJointStateTranslation(i, data.translation);
|
|
||||||
data.translation = _geometryOffset * data.translation;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
||||||
AnimPose invGeometryOffset = _geometryOffset.inverse();
|
|
||||||
for (int i = 0; i < jointDataVec.size(); i++) {
|
if (_animSkeleton) {
|
||||||
const JointData& data = jointDataVec.at(i);
|
|
||||||
setJointRotation(i, data.rotationSet, data.rotation, 1.0f);
|
std::vector<bool> overrideFlags(_internalPoseSet._overridePoses.size(), false);
|
||||||
// geometry offset is used here to undo the fact that avatar mixer translations are in meters.
|
AnimPoseVec overridePoses = _animSkeleton->getAbsoluteDefaultPoses(); // start with the default poses.
|
||||||
setJointTranslation(i, data.translationSet, invGeometryOffset * data.translation, 1.0f);
|
|
||||||
|
ASSERT(overrideFlags.size() == absoluteOverridePoses.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < jointDataVec.size(); i++) {
|
||||||
|
if (isIndexValid(i)) {
|
||||||
|
const JointData& data = jointDataVec.at(i);
|
||||||
|
if (data.rotationSet) {
|
||||||
|
overrideFlags[i] = true;
|
||||||
|
overridePoses[i].rot = data.rotation;
|
||||||
|
}
|
||||||
|
if (data.translationSet) {
|
||||||
|
overrideFlags[i] = true;
|
||||||
|
// convert from meters back into geometry units.
|
||||||
|
overridePoses[i].trans = _invGeometryOffset * data.translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(_internalPoseSet._overrideFlags.size() == _internalPoseSet._overridePoses.size());
|
||||||
|
|
||||||
|
_animSkeleton->convertAbsolutePosesToRelative(overridePoses);
|
||||||
|
|
||||||
|
for (int i = 0; i < jointDataVec.size(); i++) {
|
||||||
|
if (overrideFlags[i]) {
|
||||||
|
_internalPoseSet._overrideFlags[i] = true;
|
||||||
|
_internalPoseSet._overridePoses[i] = overridePoses[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,12 +104,6 @@ public:
|
||||||
|
|
||||||
void setModelOffset(const glm::mat4& modelOffsetMat);
|
void setModelOffset(const glm::mat4& modelOffsetMat);
|
||||||
|
|
||||||
// geometry space
|
|
||||||
bool getJointStateRotation(int index, glm::quat& rotation) const;
|
|
||||||
|
|
||||||
// geometry space
|
|
||||||
bool getJointStateTranslation(int index, glm::vec3& translation) const;
|
|
||||||
|
|
||||||
void clearJointState(int index);
|
void clearJointState(int index);
|
||||||
void clearJointStates();
|
void clearJointStates();
|
||||||
void clearJointAnimationPriority(int index);
|
void clearJointAnimationPriority(int index);
|
||||||
|
@ -119,8 +113,6 @@ public:
|
||||||
|
|
||||||
// geometry space
|
// geometry space
|
||||||
void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority);
|
void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority);
|
||||||
|
|
||||||
// geometry space
|
|
||||||
void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority);
|
void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority);
|
||||||
|
|
||||||
// legacy
|
// legacy
|
||||||
|
@ -237,8 +229,12 @@ protected:
|
||||||
void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
|
void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
|
||||||
void calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const;
|
void calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const;
|
||||||
|
|
||||||
|
// geometry space
|
||||||
|
bool getJointData(int index, JointData& jointDataOut) const;
|
||||||
|
|
||||||
AnimPose _modelOffset; // model to rig space
|
AnimPose _modelOffset; // model to rig space
|
||||||
AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets)
|
AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets)
|
||||||
|
AnimPose _invGeometryOffset;
|
||||||
|
|
||||||
struct PoseSet {
|
struct PoseSet {
|
||||||
AnimPoseVec _relativePoses; // geometry space relative to parent.
|
AnimPoseVec _relativePoses; // geometry space relative to parent.
|
||||||
|
|
|
@ -121,6 +121,8 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
|
||||||
_handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition());
|
_handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WANT_DEBUG
|
||||||
|
|
||||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||||
// TODO: DRY this up to a shared method
|
// TODO: DRY this up to a shared method
|
||||||
// that can pack any type given the number of bytes
|
// that can pack any type given the number of bytes
|
||||||
|
@ -329,7 +331,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
if (sendAll) {
|
//if (sendAll) {
|
||||||
qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll
|
qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll
|
||||||
<< "rotations:" << rotationSentCount << "translations:" << translationSentCount
|
<< "rotations:" << rotationSentCount << "translations:" << translationSentCount
|
||||||
<< "largest:" << maxTranslationDimension
|
<< "largest:" << maxTranslationDimension
|
||||||
|
@ -339,7 +341,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||||
<< (beforeTranslations - beforeRotations) << "+"
|
<< (beforeTranslations - beforeRotations) << "+"
|
||||||
<< (destinationBuffer - beforeTranslations) << "="
|
<< (destinationBuffer - beforeTranslations) << "="
|
||||||
<< (destinationBuffer - startPosition);
|
<< (destinationBuffer - startPosition);
|
||||||
}
|
//}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||||
|
|
|
@ -174,7 +174,8 @@ const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57;
|
||||||
|
|
||||||
enum class AvatarMixerPacketVersion : PacketVersion {
|
enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
TranslationSupport = 17,
|
TranslationSupport = 17,
|
||||||
SoftAttachmentSupport
|
SoftAttachmentSupport,
|
||||||
|
AbsoluteFortyEightBitRotations
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
|
@ -726,10 +726,6 @@ glm::vec3 Model::calculateScaledOffsetPoint(const glm::vec3& point) const {
|
||||||
return translatedPoint;
|
return translatedPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::getJointState(int index, glm::quat& rotation) const {
|
|
||||||
return _rig->getJointStateRotation(index, rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Model::clearJointState(int index) {
|
void Model::clearJointState(int index) {
|
||||||
_rig->clearJointState(index);
|
_rig->clearJointState(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,10 +252,6 @@ protected:
|
||||||
/// Returns the scaled equivalent of a point in model space.
|
/// Returns the scaled equivalent of a point in model space.
|
||||||
glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const;
|
glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const;
|
||||||
|
|
||||||
/// Fetches the joint state at the specified index.
|
|
||||||
/// \return whether or not the joint state is "valid" (that is, non-default)
|
|
||||||
bool getJointState(int index, glm::quat& rotation) const;
|
|
||||||
|
|
||||||
/// Clear the joint states
|
/// Clear the joint states
|
||||||
void clearJointState(int index);
|
void clearJointState(int index);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue