From f335bb8171193d1bff2f297c8c15be49fee0a83b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 26 Feb 2014 13:40:09 -0800 Subject: [PATCH] Preserve joint states when switching between LODs. Closes #2077. --- interface/src/renderer/FBXReader.cpp | 2 +- interface/src/renderer/Model.cpp | 32 ++++++++++++++++++++++------ interface/src/renderer/Model.h | 1 + 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/interface/src/renderer/FBXReader.cpp b/interface/src/renderer/FBXReader.cpp index 8b881940ca..c9201f8f51 100644 --- a/interface/src/renderer/FBXReader.cpp +++ b/interface/src/renderer/FBXReader.cpp @@ -1249,7 +1249,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) joint.boneRadius = 0.0f; joint.inverseBindRotation = joint.inverseDefaultRotation; geometry.joints.append(joint); - geometry.jointIndices.insert(model.name, geometry.joints.size() - 1); + geometry.jointIndices.insert(model.name, geometry.joints.size()); } // find our special joints diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index e1780ee9f5..7fc16855e7 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -46,6 +46,17 @@ void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locati program.release(); } +QVector Model::createJointStates(const FBXGeometry& geometry) { + QVector jointStates; + foreach (const FBXJoint& joint, geometry.joints) { + JointState state; + state.translation = joint.translation; + state.rotation = joint.rotation; + jointStates.append(state); + } + return jointStates; +} + bool Model::isLoadedWithTextures() const { if (!isActive()) { return false; @@ -106,9 +117,23 @@ void Model::reset() { void Model::simulate(float deltaTime) { // update our LOD + QVector newJointStates; if (_geometry) { QSharedPointer geometry = _geometry->getLODOrFallback(_lodDistance, _lodHysteresis); if (_geometry != geometry) { + if (!_jointStates.isEmpty()) { + // copy the existing joint states + const FBXGeometry& oldGeometry = _geometry->getFBXGeometry(); + const FBXGeometry& newGeometry = geometry->getFBXGeometry(); + newJointStates = createJointStates(newGeometry); + for (QHash::const_iterator it = oldGeometry.jointIndices.constBegin(); + it != oldGeometry.jointIndices.constEnd(); it++) { + int newIndex = newGeometry.jointIndices.value(it.key()); + if (newIndex != 0) { + newJointStates[newIndex - 1] = _jointStates.at(it.value() - 1); + } + } + } deleteGeometry(); _dilatedTextures.clear(); _geometry = geometry; @@ -121,12 +146,7 @@ void Model::simulate(float deltaTime) { // set up world vertices on first simulate after load const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (_jointStates.isEmpty()) { - foreach (const FBXJoint& joint, geometry.joints) { - JointState state; - state.translation = joint.translation; - state.rotation = joint.rotation; - _jointStates.append(state); - } + _jointStates = newJointStates.isEmpty() ? createJointStates(geometry) : newJointStates; foreach (const FBXMesh& mesh, geometry.meshes) { MeshState state; state.clusterMatrices.resize(mesh.clusters.size()); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index cf6e1fea6d..fd44361a1b 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -269,6 +269,7 @@ private: static SkinLocations _skinNormalMapLocations; static void initSkinProgram(ProgramObject& program, SkinLocations& locations); + static QVector createJointStates(const FBXGeometry& geometry); }; #endif /* defined(__interface__Model__) */