mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 17:03:43 +02:00
Normalize scale on AnimSkeleton bind pose.
This commit is contained in:
parent
9786954585
commit
0d98ab3365
4 changed files with 53 additions and 12 deletions
|
@ -1240,25 +1240,26 @@ void MyAvatar::setupNewAnimationSystem() {
|
|||
for (auto& joint : geom.joints) {
|
||||
joints.push_back(joint);
|
||||
}
|
||||
_animSkeleton = make_shared<AnimSkeleton>(joints);
|
||||
AnimPose geometryOffset(_skeletonModel.getGeometry()->getFBXGeometry().offset);
|
||||
_animSkeleton = make_shared<AnimSkeleton>(joints, geometryOffset);
|
||||
|
||||
// add skeleton to the debug renderer, so we can see it.
|
||||
/*
|
||||
AnimPose xform(_skeletonModel.getScale(), glm::quat(), _skeletonModel.getOffset());
|
||||
AnimDebugDraw::getInstance().addSkeleton("my-avatar", _animSkeleton, xform);
|
||||
*/
|
||||
AnimDebugDraw::getInstance().addSkeleton("my-avatar-skeleton", _animSkeleton, AnimPose::identity);
|
||||
//_animSkeleton->dump();
|
||||
|
||||
qCDebug(interfaceapp) << "geomOffset =" << geometryOffset;
|
||||
|
||||
// load the anim graph
|
||||
// https://gist.github.com/hyperlogic/7d6a0892a7319c69e2b9
|
||||
// python2 -m SimpleHTTPServer&
|
||||
//auto graphUrl = QUrl("http://localhost:8000/avatar.json");
|
||||
auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/7d6a0892a7319c69e2b9/raw/403651948de088ca4dcdda4f873e225b091c779a/avatar.json");
|
||||
auto graphUrl = QUrl("http://localhost:8000/avatar.json");
|
||||
//auto graphUrl = QUrl("https://gist.githubusercontent.com/hyperlogic/7d6a0892a7319c69e2b9/raw/403651948de088ca4dcdda4f873e225b091c779a/avatar.json");
|
||||
_animLoader.reset(new AnimNodeLoader(graphUrl));
|
||||
connect(_animLoader.get(), &AnimNodeLoader::success, [this](AnimNode::Pointer nodeIn) {
|
||||
_animNode = nodeIn;
|
||||
_animNode->setSkeleton(_animSkeleton);
|
||||
AnimPose xform(_skeletonModel.getScale() / 10.0f, glm::quat(), _skeletonModel.getOffset() + glm::vec3(0, 0, 1));
|
||||
AnimDebugDraw::getInstance().addAnimNode("node", _animNode, xform);
|
||||
AnimPose xform(glm::vec3(1), glm::quat(), glm::vec3(0, 0, -1));
|
||||
AnimDebugDraw::getInstance().addAnimNode("my-avatar-animation", _animNode, xform);
|
||||
});
|
||||
connect(_animLoader.get(), &AnimNodeLoader::error, [this, graphUrl](int error, QString str) {
|
||||
qCCritical(interfaceapp) << "Error loading" << graphUrl << "code = " << error << "str =" << str;
|
||||
|
@ -1266,6 +1267,8 @@ void MyAvatar::setupNewAnimationSystem() {
|
|||
}
|
||||
|
||||
void MyAvatar::teardownNewAnimationSystem() {
|
||||
AnimDebugDraw::getInstance().removeSkeleton("my-avatar-skeleton");
|
||||
AnimDebugDraw::getInstance().removeAnimNode("my-avatar-animation");
|
||||
_animSkeleton = nullptr;
|
||||
_animLoader = nullptr;
|
||||
_animNode = nullptr;
|
||||
|
|
|
@ -62,13 +62,14 @@ static bool matrixIsIdentity(const glm::mat4& m) {
|
|||
return m == IDENTITY;
|
||||
}
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset) {
|
||||
_joints = joints;
|
||||
|
||||
// build a cache of bind poses
|
||||
_absoluteBindPoses.reserve(joints.size());
|
||||
_relativeBindPoses.reserve(joints.size());
|
||||
|
||||
// iterate over FBXJoints and extract the bind pose information.
|
||||
for (size_t i = 0; i < joints.size(); i++) {
|
||||
if (_joints[i].bindTransformIsValid) {
|
||||
// Use the FBXJoint::bindTransform, which is absolute model coordinates
|
||||
|
@ -97,6 +98,23 @@ AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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++) {
|
||||
int parentIndex = getParentIndex(i);
|
||||
if (parentIndex >= 0) {
|
||||
_relativeBindPoses[i] = _absoluteBindPoses[parentIndex].inverse() * _absoluteBindPoses[i];
|
||||
} else {
|
||||
_relativeBindPoses[i] = _absoluteBindPoses[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
||||
|
@ -127,3 +145,20 @@ int AnimSkeleton::getParentIndex(int jointIndex) const {
|
|||
const QString& AnimSkeleton::getJointName(int jointIndex) const {
|
||||
return _joints[jointIndex].name;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void AnimSkeleton::dump() const {
|
||||
qCDebug(animation) << "[";
|
||||
for (int i = 0; i < getNumJoints(); i++) {
|
||||
qCDebug(animation) << " {";
|
||||
qCDebug(animation) << " name =" << getJointName(i);
|
||||
qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i);
|
||||
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
|
||||
if (getParentIndex(i) >= 0) {
|
||||
qCDebug(animation) << " parent =" << getJointName(getParentIndex(i));
|
||||
}
|
||||
qCDebug(animation) << " },";
|
||||
}
|
||||
qCDebug(animation) << "]";
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
using Pointer = std::shared_ptr<AnimSkeleton>;
|
||||
using ConstPointer = std::shared_ptr<const AnimSkeleton>;
|
||||
|
||||
AnimSkeleton(const std::vector<FBXJoint>& joints);
|
||||
AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset);
|
||||
int nameToJointIndex(const QString& jointName) const;
|
||||
const QString& getJointName(int jointIndex) const;
|
||||
int getNumJoints() const;
|
||||
|
@ -59,6 +59,10 @@ public:
|
|||
|
||||
int getParentIndex(int jointIndex) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::vector<FBXJoint> _joints;
|
||||
AnimPoseVec _absoluteBindPoses;
|
||||
|
|
|
@ -44,7 +44,6 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl
|
|||
switchState(animVars, desiredState);
|
||||
}
|
||||
|
||||
|
||||
assert(_currentState);
|
||||
auto currentStateNode = _currentState->getNode();
|
||||
assert(currentStateNode);
|
||||
|
|
Loading…
Reference in a new issue