From 7edb97744661933c6bffafb262835c9b9dca6826 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 13 Dec 2012 21:04:37 +0000 Subject: [PATCH] Fixed bugs in skeletal animation --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40188 --- KREngine/KREngine/Classes/KRNode.cpp | 48 ++++++++++++++------ KREngine/KREngine/Classes/KRNode.h | 1 + KREngine/KREngine/Classes/KRResource+fbx.cpp | 1 + KREngine/KREngine/Shaders/ObjectShader.vsh | 27 +++++------ 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index 0a10fe2..13b7d3f 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -111,18 +111,27 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) { void KRNode::setLocalTranslation(const KRVector3 &v, bool set_original) { m_localTranslation = v; - if(set_original) m_initialLocalTranslation = v; + if(set_original) { + m_initialLocalTranslation = v; + invalidateBindPoseMatrix(); + } invalidateModelMatrix(); } void KRNode::setLocalScale(const KRVector3 &v, bool set_original) { m_localScale = v; - if(set_original) m_initialLocalScale = v; + if(set_original) { + m_initialLocalScale = v; + invalidateBindPoseMatrix(); + } invalidateModelMatrix(); } void KRNode::setLocalRotation(const KRVector3 &v, bool set_original) { m_localRotation = v; - if(set_original) m_initialLocalRotation = v; + if(set_original) { + m_initialLocalRotation = v; + invalidateBindPoseMatrix(); + } invalidateModelMatrix(); } @@ -224,6 +233,16 @@ void KRNode::invalidateModelMatrix() } } +void KRNode::invalidateBindPoseMatrix() +{ + m_bindPoseMatrixValid = false; + m_inverseBindPoseMatrixValid = false; + for(std::vector::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { + KRNode *child = (*itr); + child->invalidateBindPoseMatrix(); + } +} + const KRMat4 &KRNode::getModelMatrix() { @@ -251,6 +270,7 @@ const KRMat4 &KRNode::getBindPoseMatrix() if(!m_bindPoseMatrixValid) { m_bindPoseMatrix = KRMat4(); + m_bindPoseMatrix.scale(m_initialLocalScale); m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); @@ -258,8 +278,8 @@ const KRMat4 &KRNode::getBindPoseMatrix() m_bindPoseMatrix.translate(m_initialLocalTranslation); KRBone *parentBone = dynamic_cast(m_parentNode); - if(parentBone) { + m_bindPoseMatrix *= parentBone->getBindPoseMatrix(); } @@ -291,42 +311,42 @@ void KRNode::SetAttribute(node_attribute_type attrib, float v) { const float DEGREES_TO_RAD = M_PI / 180.0f; - //printf("%s - ", m_name.c_str()); + printf("%s - ", m_name.c_str()); switch(attrib) { case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X: - //printf("translate_x: %f\n", v); + printf("translate_x: %f\n", v); setLocalTranslation(KRVector3(v, m_localTranslation.y, m_localTranslation.z)); break; case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y: - //printf("translate_y: %f\n", v); + printf("translate_y: %f\n", v); setLocalTranslation(KRVector3(m_localTranslation.x, v, m_localTranslation.z)); break; case KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z: - //printf("translate_z: %f\n", v); + printf("translate_z: %f\n", v); setLocalTranslation(KRVector3(m_localTranslation.x, m_localTranslation.y, v)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_X: - //printf("scale_x: %f\n", v); + printf("scale_x: %f\n", v); setLocalScale(KRVector3(v, m_localScale.y, m_localScale.z)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_Y: - //printf("scale_y: %f\n", v); + printf("scale_y: %f\n", v); setLocalScale(KRVector3(m_localScale.x, v, m_localScale.z)); break; case KRENGINE_NODE_ATTRIBUTE_SCALE_Z: - //printf("scale_z: %f\n", v); + printf("scale_z: %f\n", v); setLocalScale(KRVector3(m_localScale.x, m_localScale.y, v)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_X: - //printf("rotate_x: %f\n", v); + printf("rotate_x: %f\n", v); setLocalRotation(KRVector3(v * DEGREES_TO_RAD, m_localRotation.y, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Y: - //printf("rotate_y: %f\n", v); + printf("rotate_y: %f\n", v); setLocalRotation(KRVector3(m_localRotation.x, v * DEGREES_TO_RAD, m_localRotation.z)); break; case KRENGINE_NODE_ATTRIBUTE_ROTATE_Z: - //printf("rotate_z: %f\n", v); + printf("rotate_z: %f\n", v); setLocalRotation(KRVector3(m_localRotation.x, m_localRotation.y, v * DEGREES_TO_RAD)); break; } diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index 44794b7..f68d998 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -108,6 +108,7 @@ protected: private: void invalidateModelMatrix(); + void invalidateBindPoseMatrix(); KRMat4 m_modelMatrix; KRMat4 m_bindPoseMatrix; KRMat4 m_inverseBindPoseMatrix; diff --git a/KREngine/KREngine/Classes/KRResource+fbx.cpp b/KREngine/KREngine/Classes/KRResource+fbx.cpp index 7d18357..1d33a73 100644 --- a/KREngine/KREngine/Classes/KRResource+fbx.cpp +++ b/KREngine/KREngine/Classes/KRResource+fbx.cpp @@ -534,6 +534,7 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorGetMemberCount(); for(int iLayer=0; iLayer < cLayers; iLayer++) { FbxAnimLayer *pFbxAnimLayer = pAnimStack->GetMember(iLayer); + float weight = pFbxAnimLayer->Weight.Get(); KRAnimationLayer *pAnimationLayer = pAnimation->getLayer(pFbxAnimLayer->GetName()); FbxAnimCurve *pAnimCurve = pNode->LclRotation.GetCurve(pFbxAnimLayer, FBXSDK_CURVENODE_COMPONENT_X); diff --git a/KREngine/KREngine/Shaders/ObjectShader.vsh b/KREngine/KREngine/Shaders/ObjectShader.vsh index e6f0fa8..fc93872 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.vsh +++ b/KREngine/KREngine/Shaders/ObjectShader.vsh @@ -35,7 +35,7 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t #if BONE_COUNT > 0 attribute highp vec4 bone_weights; - attribute lowp vec4 bone_indexes; + attribute mediump vec4 bone_indexes; uniform highp mat4 bone_transforms[BONE_COUNT]; #else #define vertex_position_skinned vertex_position @@ -165,23 +165,24 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t void main() { #if BONE_COUNT > 0 + mediump vec4 scaled_bone_indexes = bone_indexes; highp vec3 vertex_position_skinned = - ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.x) + - ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.y) + - ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.z) + - ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.w); + ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_position, 1.0)).xyz * bone_weights.w); highp vec3 vertex_normal_skinned = normalize( - ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.x) + - ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.y) + - ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.z) + - ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.w)); + ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_normal, 1.0)).xyz * bone_weights.w)); highp vec3 vertex_tangent_skinned = normalize( - ((bone_transforms[ int(bone_indexes.x) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.x) + - ((bone_transforms[ int(bone_indexes.y) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.y) + - ((bone_transforms[ int(bone_indexes.z) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.z) + - ((bone_transforms[ int(bone_indexes.w) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.w)); + ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.x) + + ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.y) + + ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.z) + + ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_tangent, 1.0)).xyz * bone_weights.w)); #endif