mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:33:36 +02:00
AnimSkeleton: Added default poses
This commit is contained in:
parent
5ffef7f41a
commit
3a74d188b0
2 changed files with 71 additions and 15 deletions
|
@ -70,6 +70,14 @@ const AnimPose& AnimSkeleton::getRelativeBindPose(int jointIndex) const {
|
|||
return _relativeBindPoses[jointIndex];
|
||||
}
|
||||
|
||||
const AnimPose& AnimSkeleton::getRelativeDefaultPose(int jointIndex) const {
|
||||
return _relativeDefaultPoses[jointIndex];
|
||||
}
|
||||
|
||||
const AnimPose& AnimSkeleton::getAbsoluteDefaultPose(int jointIndex) const {
|
||||
return _absoluteDefaultPoses[jointIndex];
|
||||
}
|
||||
|
||||
int AnimSkeleton::getParentIndex(int jointIndex) const {
|
||||
return _joints[jointIndex].parentIndex;
|
||||
}
|
||||
|
@ -93,14 +101,31 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints,
|
|||
_absoluteBindPoses.reserve(joints.size());
|
||||
_relativeBindPoses.reserve(joints.size());
|
||||
|
||||
// build a chache of default poses
|
||||
_absoluteDefaultPoses.reserve(joints.size());
|
||||
_relativeDefaultPoses.reserve(joints.size());
|
||||
|
||||
// iterate over FBXJoints and extract the bind pose information.
|
||||
for (size_t i = 0; i < joints.size(); i++) {
|
||||
|
||||
// build relative and absolute default poses
|
||||
glm::mat4 rotTransform = glm::mat4_cast(_joints[i].preRotation * _joints[i].rotation * _joints[i].postRotation);
|
||||
glm::mat4 relDefaultMat = glm::translate(_joints[i].translation) * _joints[i].preTransform * rotTransform * _joints[i].postTransform;
|
||||
AnimPose relDefaultPose(relDefaultMat);
|
||||
_relativeDefaultPoses.push_back(relDefaultPose);
|
||||
int parentIndex = getParentIndex(i);
|
||||
if (parentIndex >= 0) {
|
||||
_absoluteDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex] * relDefaultPose);
|
||||
} else {
|
||||
_absoluteDefaultPoses.push_back(relDefaultPose);
|
||||
}
|
||||
|
||||
// build relative and absolute bind poses
|
||||
if (_joints[i].bindTransformFoundInCluster) {
|
||||
// Use the FBXJoint::bindTransform, which is absolute model coordinates
|
||||
// i.e. not relative to it's parent.
|
||||
AnimPose absoluteBindPose(_joints[i].bindTransform);
|
||||
_absoluteBindPoses.push_back(absoluteBindPose);
|
||||
int parentIndex = getParentIndex(i);
|
||||
if (parentIndex >= 0) {
|
||||
AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse();
|
||||
_relativeBindPoses.push_back(inverseParentAbsoluteBindPose * absoluteBindPose);
|
||||
|
@ -108,39 +133,40 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints,
|
|||
_relativeBindPoses.push_back(absoluteBindPose);
|
||||
}
|
||||
} else {
|
||||
// use FBXJoint's local transform, instead
|
||||
glm::mat4 rotTransform = glm::mat4_cast(_joints[i].preRotation * _joints[i].rotation * _joints[i].postRotation);
|
||||
glm::mat4 relBindMat = glm::translate(_joints[i].translation) * _joints[i].preTransform * rotTransform * _joints[i].postTransform;
|
||||
AnimPose relBindPose(relBindMat);
|
||||
_relativeBindPoses.push_back(relBindPose);
|
||||
|
||||
int parentIndex = getParentIndex(i);
|
||||
// use default transform instead
|
||||
_relativeBindPoses.push_back(relDefaultPose);
|
||||
if (parentIndex >= 0) {
|
||||
_absoluteBindPoses.push_back(_absoluteBindPoses[parentIndex] * relBindPose);
|
||||
_absoluteBindPoses.push_back(_absoluteBindPoses[parentIndex] * relDefaultPose);
|
||||
} else {
|
||||
_absoluteBindPoses.push_back(relBindPose);
|
||||
_absoluteBindPoses.push_back(relDefaultPose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now we want to normalize scale from geometryOffset to all poses.
|
||||
// This will ensure our bone translations will be in meters, even if the model was authored with some other unit of mesure.
|
||||
for (auto& absPose : _absoluteBindPoses) {
|
||||
normalizeScale(geometryOffset, _relativeBindPoses, _absoluteBindPoses);
|
||||
normalizeScale(geometryOffset, _relativeDefaultPoses, _absoluteDefaultPoses);
|
||||
}
|
||||
|
||||
void AnimSkeleton::normalizeScale(const AnimPose& geometryOffset, AnimPoseVec& relPoses, AnimPoseVec& absPoses) const {
|
||||
for (auto& absPose : absPoses) {
|
||||
absPose.trans = (geometryOffset * absPose).trans;
|
||||
absPose.scale = vec3(1, 1, 1);
|
||||
}
|
||||
|
||||
// re-compute relative poses based on the modified absolute poses.
|
||||
for (size_t i = 0; i < _relativeBindPoses.size(); i++) {
|
||||
for (size_t i = 0; i < relPoses.size(); i++) {
|
||||
int parentIndex = getParentIndex(i);
|
||||
if (parentIndex >= 0) {
|
||||
_relativeBindPoses[i] = _absoluteBindPoses[parentIndex].inverse() * _absoluteBindPoses[i];
|
||||
relPoses[i] = absPoses[parentIndex].inverse() * absPoses[i];
|
||||
} else {
|
||||
_relativeBindPoses[i] = _absoluteBindPoses[i];
|
||||
relPoses[i] = absPoses[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DUMP_FBX_JOINTS
|
||||
|
||||
#ifndef NDEBUG
|
||||
void AnimSkeleton::dump() const {
|
||||
qCDebug(animation) << "[";
|
||||
|
@ -150,6 +176,25 @@ void AnimSkeleton::dump() const {
|
|||
qCDebug(animation) << " name =" << getJointName(i);
|
||||
qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i);
|
||||
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
|
||||
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
|
||||
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
|
||||
#ifdef DUMP_FBX_JOINTS
|
||||
qCDebug(animation) << " isFree =" << _joints[i].isFree;
|
||||
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
|
||||
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
|
||||
qCDebug(animation) << " translation =" << _joints[i].translation;
|
||||
qCDebug(animation) << " preTransform =" << _joints[i].preTransform;
|
||||
qCDebug(animation) << " preRotation =" << _joints[i].preRotation;
|
||||
qCDebug(animation) << " rotation =" << _joints[i].rotation;
|
||||
qCDebug(animation) << " postRotation =" << _joints[i].postRotation;
|
||||
qCDebug(animation) << " postTransform =" << _joints[i].postTransform;
|
||||
qCDebug(animation) << " transform =" << _joints[i].transform;
|
||||
qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax;
|
||||
qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation;
|
||||
qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation;
|
||||
qCDebug(animation) << " bindTransform" << _joints[i].bindTransform;
|
||||
qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint;
|
||||
#endif
|
||||
if (getParentIndex(i) >= 0) {
|
||||
qCDebug(animation) << " parent =" << getJointName(getParentIndex(i));
|
||||
}
|
||||
|
@ -166,6 +211,8 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const {
|
|||
qCDebug(animation) << " name =" << getJointName(i);
|
||||
qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i);
|
||||
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
|
||||
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
|
||||
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
|
||||
qCDebug(animation) << " pose =" << poses[i];
|
||||
if (getParentIndex(i) >= 0) {
|
||||
qCDebug(animation) << " parent =" << getJointName(getParentIndex(i));
|
||||
|
|
|
@ -38,6 +38,12 @@ public:
|
|||
const AnimPose& getRelativeBindPose(int jointIndex) const;
|
||||
const AnimPoseVec& getRelativeBindPoses() const { return _relativeBindPoses; }
|
||||
|
||||
// the default poses are the orientations of the joints on frame 0.
|
||||
const AnimPose& getRelativeDefaultPose(int jointIndex) const;
|
||||
const AnimPoseVec& getRelativeDefaultPoses() const { return _relativeDefaultPoses; }
|
||||
const AnimPose& getAbsoluteDefaultPose(int jointIndex) const;
|
||||
const AnimPoseVec& getAbsoluteDefaultPoses() const { return _absoluteDefaultPoses; }
|
||||
|
||||
int getParentIndex(int jointIndex) const;
|
||||
|
||||
AnimPose getAbsolutePose(int jointIndex, const AnimPoseVec& poses) const;
|
||||
|
@ -49,10 +55,13 @@ public:
|
|||
|
||||
protected:
|
||||
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset);
|
||||
void normalizeScale(const AnimPose& geometryOffset, AnimPoseVec& relPoses, AnimPoseVec& absPoses) const;
|
||||
|
||||
std::vector<FBXJoint> _joints;
|
||||
AnimPoseVec _absoluteBindPoses;
|
||||
AnimPoseVec _relativeBindPoses;
|
||||
AnimPoseVec _relativeDefaultPoses;
|
||||
AnimPoseVec _absoluteDefaultPoses;
|
||||
|
||||
// no copies
|
||||
AnimSkeleton(const AnimSkeleton&) = delete;
|
||||
|
|
Loading…
Reference in a new issue