remove extraneous roots from Model::_jointStates

This commit is contained in:
Andrew Meadows 2014-08-07 17:02:28 -07:00
parent bb33266635
commit 9a55252587
2 changed files with 45 additions and 19 deletions

View file

@ -515,9 +515,9 @@ void SkeletonModel::initRagdollPoints() {
initRagdollTransform();
// one point for each joint
int numJoints = _jointStates.size();
_ragdollPoints.fill(VerletPoint(), numJoints);
for (int i = 0; i < numJoints; ++i) {
int numStates = _jointStates.size();
_ragdollPoints.fill(VerletPoint(), numStates);
for (int i = 0; i < numStates; ++i) {
const JointState& state = _jointStates.at(i);
// _ragdollPoints start in model-frame
_ragdollPoints[i].initPosition(state.getPosition());
@ -719,8 +719,8 @@ void SkeletonModel::buildShapes() {
// ... then move shapes back to current joint positions
if (_ragdollPoints.size() == numStates) {
int numJoints = _jointStates.size();
for (int i = 0; i < numJoints; ++i) {
int numStates = _jointStates.size();
for (int i = 0; i < numStates; ++i) {
// ragdollPoints start in model-frame
_ragdollPoints[i].initPosition(_jointStates.at(i).getPosition());
}
@ -765,17 +765,15 @@ void SkeletonModel::updateMuscles() {
void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
// compute default joint transforms
int numJoints = geometry.joints.size();
if (numJoints != _ragdollPoints.size()) {
return;
}
int numStates = _jointStates.size();
QVector<glm::mat4> transforms;
transforms.fill(glm::mat4(), numJoints);
transforms.fill(glm::mat4(), numStates);
// compute the default transforms and slam the ragdoll positions accordingly
// (which puts the shapes where we want them)
for (int i = 0; i < numJoints; i++) {
const FBXJoint& joint = geometry.joints.at(i);
for (int i = 0; i < numStates; i++) {
JointState& state = _jointStates[i];
const FBXJoint& joint = state.getFBXJoint();
int parentIndex = joint.parentIndex;
if (parentIndex == -1) {
transforms[i] = _jointStates[i].getTransform();
@ -847,7 +845,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
if (geometry.joints.isEmpty() || _shapes.size() != geometry.joints.size()) {
if (geometry.joints.isEmpty()) {
return;
}

View file

@ -188,10 +188,38 @@ void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locati
QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
QVector<JointState> jointStates;
foreach (const FBXJoint& joint, geometry.joints) {
// NOTE: the state keeps a pointer to an FBXJoint
QVector<int> roots;
roots.fill(-1, geometry.joints.size());
for (int i = 0; i < geometry.joints.size(); ++i) {
const FBXJoint& joint = geometry.joints[i];
int parentIndex = joint.parentIndex;
// Some models may have multiple roots (?!), but these are causing problems in
// the Avatar Ragdoll simulation, so we prune them out of the JointState tree.
int rootIndex = 0;
if (parentIndex == -1) {
if (i != 0) {
// skip other root
continue;
}
} else {
rootIndex = roots[parentIndex];
if (rootIndex == -1) {
roots[i] = parentIndex;
rootIndex = parentIndex;
} else {
roots[i] = rootIndex;
}
if (rootIndex != 0) {
// skip child of other root
continue;
}
}
// store a pointer to the FBXJoint in the JointState
JointState state;
state.setFBXJoint(&joint);
jointStates.append(state);
}
return jointStates;
@ -199,8 +227,8 @@ QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
void Model::initJointTransforms() {
// compute model transforms
int numJoints = _jointStates.size();
for (int i = 0; i < numJoints; ++i) {
int numStates = _jointStates.size();
for (int i = 0; i < numStates; ++i) {
JointState& state = _jointStates[i];
const FBXJoint& joint = state.getFBXJoint();
int parentIndex = joint.parentIndex;
@ -538,9 +566,9 @@ void Model::setJointStates(QVector<JointState> states) {
_jointStates = states;
initJointTransforms();
int numJoints = _jointStates.size();
int numStates = _jointStates.size();
float radius = 0.0f;
for (int i = 0; i < numJoints; ++i) {
for (int i = 0; i < numStates; ++i) {
float distance = glm::length(_jointStates[i].getPosition());
if (distance > radius) {
radius = distance;