Found and fix source of memory corruption.

std::vector.reserve() and raw access do not mix.
raw access will only work if you push_back elements onto the vector
first.  However this worked fine on MacOSX, probably due to differences
in STL implementations.

Some code clean up and some commented out debugging lines.

Debug rendering of animaions of fight club model is not working.
Not sure what frame these transformations are in.
This commit is contained in:
Anthony J. Thibault 2015-08-03 18:31:32 -07:00
parent 69cc270802
commit d8a20340a0
4 changed files with 75 additions and 32 deletions

View file

@ -121,14 +121,14 @@ void AnimClip::copyFromNetworkAnim() {
// build a mapping from animation joint indices to skeleton joint indices.
// by matching joints with the same name.
const FBXGeometry& geom = _networkAnim->getGeometry();
const QVector<FBXJoint>& joints = geom.joints;
const QVector<FBXJoint>& animJoints = geom.joints;
std::vector<int> jointMap;
const int animJointCount = joints.count();
const int animJointCount = animJoints.count();
jointMap.reserve(animJointCount);
for (int i = 0; i < animJointCount; i++) {
int skeletonJoint = _skeleton->nameToJointIndex(joints.at(i).name);
int skeletonJoint = _skeleton->nameToJointIndex(animJoints.at(i).name);
if (skeletonJoint == -1) {
qCWarning(animation) << "animation contains joint =" << joints.at(i).name << " which is not in the skeleton, url =" << _url.c_str();
qCWarning(animation) << "animation contains joint =" << animJoints.at(i).name << " which is not in the skeleton, url =" << _url.c_str();
}
jointMap.push_back(skeletonJoint);
}
@ -138,10 +138,10 @@ void AnimClip::copyFromNetworkAnim() {
_anim.resize(frameCount);
for (int i = 0; i < frameCount; i++) {
// init all joints in animation to relative bind pose
// init all joints in animation to identity
_anim[i].reserve(skeletonJointCount);
for (int j = 0; j < skeletonJointCount; j++) {
_anim[i].push_back(_skeleton->getRelativeBindPose(j));
_anim[i].push_back(AnimPose::identity);
}
// init over all joint animations
@ -149,7 +149,7 @@ void AnimClip::copyFromNetworkAnim() {
int k = jointMap[j];
if (k >= 0 && k < skeletonJointCount) {
// currently FBX animations only have rotation.
_anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j];
_anim[i][k].rot = geom.animationFrames[i].rotations[j];
}
}
}

View file

@ -8,6 +8,7 @@
//
#include "AnimSkeleton.h"
#include "AnimationLogging.h"
#include "glmHelpers.h"
const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f),
@ -16,10 +17,22 @@ const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f),
AnimPose::AnimPose(const glm::mat4& mat) {
scale = extractScale(mat);
rot = glm::quat_cast(mat);
rot = glm::normalize(glm::quat_cast(mat));
trans = extractTranslation(mat);
}
glm::vec3 AnimPose::operator*(const glm::vec3& rhs) const {
return trans + (rot * (scale * rhs));
}
AnimPose AnimPose::operator*(const AnimPose& rhs) const {
return AnimPose(static_cast<glm::mat4>(*this) * static_cast<glm::mat4>(rhs));
}
AnimPose AnimPose::inverse() const {
return AnimPose(glm::inverse(static_cast<glm::mat4>(*this)));
}
AnimPose::operator glm::mat4() const {
glm::vec3 xAxis = rot * glm::vec3(scale.x, 0.0f, 0.0f);
glm::vec3 yAxis = rot * glm::vec3(0.0f, scale.y, 0.0f);
@ -28,6 +41,7 @@ AnimPose::operator glm::mat4() const {
glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f));
}
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
_joints = joints;
@ -35,17 +49,32 @@ AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
_absoluteBindPoses.reserve(joints.size());
_relativeBindPoses.reserve(joints.size());
for (size_t i = 0; i < joints.size(); i++) {
glm::mat4 absBindMat = _joints[i].bindTransform;
AnimPose absBindPose(_joints[i].bindTransform);
_absoluteBindPoses.push_back(absBindPose);
AnimPose absoluteBindPose(_joints[i].bindTransform);
_absoluteBindPoses.push_back(absoluteBindPose);
int parentIndex = getParentIndex(i);
if (parentIndex >= 0) {
glm::mat4 invParentAbsBindMat = glm::inverse(_joints[parentIndex].bindTransform);
glm::mat4 relBindMat = invParentAbsBindMat * absBindMat;
_relativeBindPoses.push_back(AnimPose(relBindMat));
AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse();
_relativeBindPoses.push_back(inverseParentAbsoluteBindPose * absoluteBindPose);
} else {
_relativeBindPoses.push_back(absBindPose);
_relativeBindPoses.push_back(absoluteBindPose);
}
// AJT:
// Attempt to use relative bind pose.. but it's not working.
/*
AnimPose relBindPose(glm::vec3(1.0f), _joints[i].rotation, _joints[i].translation);
_relativeBindPoses.push_back(relBindPose);
int parentIndex = getParentIndex(i);
if (parentIndex >= 0) {
AnimPose parentAbsBindPose = _absoluteBindPoses[parentIndex];
_absoluteBindPoses.push_back(parentAbsBindPose * relBindPose);
} else {
_absoluteBindPoses.push_back(relBindPose);
}
*/
}
}
@ -74,4 +103,6 @@ int AnimSkeleton::getParentIndex(int jointIndex) const {
return _joints[jointIndex].parentIndex;
}
const QString& AnimSkeleton::getJointName(int jointIndex) const {
return _joints[jointIndex].name;
}

View file

@ -16,18 +16,13 @@
struct AnimPose {
AnimPose() {}
AnimPose(const glm::mat4& mat);
explicit AnimPose(const glm::mat4& mat);
AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : scale(scaleIn), rot(rotIn), trans(transIn) {}
static const AnimPose identity;
glm::vec3 operator*(const glm::vec3& rhs) const {
return trans + (rot * (scale * rhs));
}
AnimPose operator*(const AnimPose& rhs) const {
return AnimPose(static_cast<glm::mat4>(*this) * static_cast<glm::mat4>(rhs));
}
glm::vec3 operator*(const glm::vec3& rhs) const;
AnimPose operator*(const AnimPose& rhs) const;
AnimPose inverse() const;
operator glm::mat4() const;
glm::vec3 scale;
@ -35,12 +30,18 @@ struct AnimPose {
glm::vec3 trans;
};
inline QDebug operator<<(QDebug debug, const AnimPose& pose) {
debug << "AnimPose, trans = (" << pose.trans.x << pose.trans.y << pose.trans.z << "), rot = (" << pose.rot.x << pose.rot.y << pose.rot.z << pose.rot.w << "), scale = (" << pose.scale.x << pose.scale.y << pose.scale.z << ")";
return debug;
}
class AnimSkeleton {
public:
typedef std::shared_ptr<AnimSkeleton> Pointer;
AnimSkeleton(const std::vector<FBXJoint>& joints);
int nameToJointIndex(const QString& jointName) const;
const QString& getJointName(int jointIndex) const;
int getNumJoints() const;
// absolute pose, not relative to parent

View file

@ -13,6 +13,7 @@
#include "AnimDebugDraw.h"
#include "AbstractViewStateInterface.h"
#include "RenderUtilsLogging.h"
struct Vertex {
glm::vec3 pos;
@ -218,7 +219,8 @@ void AnimDebugDraw::update() {
AnimSkeleton::Pointer& skeleton = iter.second.first;
numVerts += skeleton->getNumJoints() * 6;
for (int i = 0; i < skeleton->getNumJoints(); i++) {
if (skeleton->getParentIndex(i) >= 0) {
auto parentIndex = skeleton->getParentIndex(i);
if (parentIndex >= 0) {
numVerts += 2;
}
}
@ -229,8 +231,9 @@ void AnimDebugDraw::update() {
auto poses = animNode->getPosesInternal();
numVerts += poses.size() * 6;
auto skeleton = animNode->getSkeleton();
for (int i = 0; i < poses.size(); i++) {
if (skeleton->getParentIndex(i) >= 0) {
for (size_t i = 0; i < poses.size(); i++) {
auto parentIndex = skeleton->getParentIndex(i);
if (parentIndex >= 0) {
numVerts += 2;
}
}
@ -251,8 +254,14 @@ void AnimDebugDraw::update() {
addWireframeSphereWithAxes(rootPose, pose, radius, v);
// line to parent.
if (skeleton->getParentIndex(i) >= 0) {
AnimPose parentPose = skeleton->getAbsoluteBindPose(skeleton->getParentIndex(i));
auto parentIndex = skeleton->getParentIndex(i);
//qCDebug(renderutils) << skeleton->getJointName(i) << " index = " << i;
//qCDebug(renderutils) << " absPose =" << skeleton->getAbsoluteBindPose(i);
//qCDebug(renderutils) << " relPose =" << skeleton->getRelativeBindPose(i);
if (parentIndex >= 0) {
//qCDebug(renderutils) << " parent =" << parentIndex;
assert(parentIndex < skeleton->getNumJoints());
AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex);
addWireframeBoneAxis(rootPose, pose, parentPose, radius, v);
}
}
@ -266,7 +275,7 @@ void AnimDebugDraw::update() {
auto skeleton = animNode->getSkeleton();
std::vector<AnimPose> absAnimPose;
absAnimPose.reserve(skeleton->getNumJoints());
absAnimPose.resize(skeleton->getNumJoints());
for (size_t i = 0; i < poses.size(); i++) {
@ -282,18 +291,20 @@ void AnimDebugDraw::update() {
addWireframeSphereWithAxes(rootPose, absAnimPose[i], radius, v);
if (parentIndex >= 0) {
assert((size_t)parentIndex < poses.size());
// draw line to parent
addWireframeBoneAxis(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, v);
}
}
}
assert(numVerts == (v - verts));
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
for (int i = 0; i < numVerts; i++) {
indices[i] = i;
}
});
scene->enqueuePendingChanges(pendingChanges);
}