mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 10:28:57 +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) {
|
||||
|
||||
_geometryOffset = AnimPose(geometry.offset);
|
||||
_invGeometryOffset = _geometryOffset.inverse();
|
||||
setModelOffset(modelOffset);
|
||||
|
||||
_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) {
|
||||
_geometryOffset = AnimPose(geometry.offset);
|
||||
_invGeometryOffset = _geometryOffset.inverse();
|
||||
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
||||
|
||||
_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) {
|
||||
if (isIndexValid(index)) {
|
||||
_internalPoseSet._overrideFlags[index] = false;
|
||||
|
@ -446,6 +430,23 @@ void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds,
|
|||
*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) {
|
||||
_enableInverseKinematics = enable;
|
||||
}
|
||||
|
@ -1232,21 +1233,44 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
|||
jointDataVec.resize((int)getJointStateCount());
|
||||
for (auto i = 0; i < jointDataVec.size(); i++) {
|
||||
JointData& data = jointDataVec[i];
|
||||
data.rotationSet |= getJointStateRotation(i, data.rotation);
|
||||
// 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;
|
||||
getJointData(i, data);
|
||||
}
|
||||
}
|
||||
|
||||
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
||||
AnimPose invGeometryOffset = _geometryOffset.inverse();
|
||||
for (int i = 0; i < jointDataVec.size(); i++) {
|
||||
const JointData& data = jointDataVec.at(i);
|
||||
setJointRotation(i, data.rotationSet, data.rotation, 1.0f);
|
||||
// geometry offset is used here to undo the fact that avatar mixer translations are in meters.
|
||||
setJointTranslation(i, data.translationSet, invGeometryOffset * data.translation, 1.0f);
|
||||
|
||||
if (_animSkeleton) {
|
||||
|
||||
std::vector<bool> overrideFlags(_internalPoseSet._overridePoses.size(), false);
|
||||
AnimPoseVec overridePoses = _animSkeleton->getAbsoluteDefaultPoses(); // start with the default poses.
|
||||
|
||||
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);
|
||||
|
||||
// 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 clearJointStates();
|
||||
void clearJointAnimationPriority(int index);
|
||||
|
@ -119,8 +113,6 @@ public:
|
|||
|
||||
// geometry space
|
||||
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);
|
||||
|
||||
// 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 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 _geometryOffset; // geometry to model space (includes unit offset & fst offsets)
|
||||
AnimPose _invGeometryOffset;
|
||||
|
||||
struct PoseSet {
|
||||
AnimPoseVec _relativePoses; // geometry space relative to parent.
|
||||
|
|
|
@ -121,6 +121,8 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
|
|||
_handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition());
|
||||
}
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||
// TODO: DRY this up to a shared method
|
||||
// that can pack any type given the number of bytes
|
||||
|
@ -329,7 +331,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
|||
}
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
if (sendAll) {
|
||||
//if (sendAll) {
|
||||
qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll
|
||||
<< "rotations:" << rotationSentCount << "translations:" << translationSentCount
|
||||
<< "largest:" << maxTranslationDimension
|
||||
|
@ -339,7 +341,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
|||
<< (beforeTranslations - beforeRotations) << "+"
|
||||
<< (destinationBuffer - beforeTranslations) << "="
|
||||
<< (destinationBuffer - startPosition);
|
||||
}
|
||||
//}
|
||||
#endif
|
||||
|
||||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||
|
|
|
@ -174,7 +174,8 @@ const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57;
|
|||
|
||||
enum class AvatarMixerPacketVersion : PacketVersion {
|
||||
TranslationSupport = 17,
|
||||
SoftAttachmentSupport
|
||||
SoftAttachmentSupport,
|
||||
AbsoluteFortyEightBitRotations
|
||||
};
|
||||
|
||||
#endif // hifi_PacketHeaders_h
|
||||
|
|
|
@ -726,10 +726,6 @@ glm::vec3 Model::calculateScaledOffsetPoint(const glm::vec3& point) const {
|
|||
return translatedPoint;
|
||||
}
|
||||
|
||||
bool Model::getJointState(int index, glm::quat& rotation) const {
|
||||
return _rig->getJointStateRotation(index, rotation);
|
||||
}
|
||||
|
||||
void Model::clearJointState(int index) {
|
||||
_rig->clearJointState(index);
|
||||
}
|
||||
|
|
|
@ -252,10 +252,6 @@ protected:
|
|||
/// Returns the scaled equivalent of a point in model space.
|
||||
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
|
||||
void clearJointState(int index);
|
||||
|
||||
|
|
Loading…
Reference in a new issue