diff --git a/ios/include/AssetManager.hpp b/ios/include/AssetManager.hpp index ce45bd6d..f3d0dc9b 100644 --- a/ios/include/AssetManager.hpp +++ b/ios/include/AssetManager.hpp @@ -114,7 +114,11 @@ namespace polyvox inline void updateTransform(SceneAsset &asset); - void updateBoneTransformFromAnimationBuffer(const BoneAnimation& animation, int frameNumber); + void updateBoneTransformFromAnimationBuffer( + const BoneAnimation& animation, + int frameNumber, + FilamentAsset *asset + ); }; } diff --git a/ios/src/AssetManager.cpp b/ios/src/AssetManager.cpp index 14a3e99d..654bd74d 100644 --- a/ios/src/AssetManager.cpp +++ b/ios/src/AssetManager.cpp @@ -379,7 +379,8 @@ namespace polyvox } updateBoneTransformFromAnimationBuffer( animationStatus, - frameNumber); + frameNumber, + asset.asset); if (animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs) { @@ -404,6 +405,11 @@ namespace polyvox const auto &entity = findEntityByName(sceneAsset, entityName); + if(entity.isNull()) { + Log("Failed to find entity %s.", entityName); + return false; + } + RenderableManager &rm = _engine->getRenderableManager(); const auto &renderableInstance = rm.getInstance(entity); @@ -412,6 +418,13 @@ namespace polyvox const auto &filamentInstance = sceneAsset.asset->getInstance(); + size_t skinCount = filamentInstance->getSkinCount(); + + if (skinCount > 1) + { + Log("WARNING - skin count > 1 not currently implemented. This will probably not work"); + } + int numJoints = filamentInstance->getJointCountAt(skinIndex); auto joints = filamentInstance->getJointsAt(skinIndex); int boneIndex = -1; @@ -429,7 +442,6 @@ namespace polyvox return false; } - utils::Entity joint = filamentInstance->getJointsAt(skinIndex)[boneIndex]; if (joint.isNull()) @@ -438,27 +450,62 @@ namespace polyvox return false; } + const auto& inverseBindMatrix = filamentInstance->getInverseBindMatricesAt(skinIndex)[boneIndex]; + + auto jointTransformInstance = transformManager.getInstance(joint); + auto globalJointTransform = transformManager.getWorldTransform(jointTransformInstance); + + auto inverseGlobalTransform = inverse( + transformManager.getWorldTransform( + transformManager.getInstance(entity) + ) + ); + + const auto boneTransform = inverseGlobalTransform * globalJointTransform * + localTransform * inverseBindMatrix; + rm.setBones( renderableInstance, - &localTransform, + &boneTransform, 1, boneIndex); return true; - } + } - void AssetManager::updateBoneTransformFromAnimationBuffer(const BoneAnimation& animation, int frameNumber) + void AssetManager::updateBoneTransformFromAnimationBuffer( + const BoneAnimation& animation, + int frameNumber, + FilamentAsset *asset) { + auto filamentInstance = asset->getInstance(); + TransformManager &transformManager = _engine->getTransformManager(); RenderableManager &rm = _engine->getRenderableManager(); auto boneIndex = animation.boneIndex; - math::mat4f transform(animation.frameData[frameNumber]); + + math::mat4f localTransform(animation.frameData[frameNumber]); + + const auto& inverseBindMatrix = filamentInstance->getInverseBindMatricesAt(animation.skinIndex)[boneIndex]; for(const auto& meshTarget : animation.meshTargets) { + + const Entity joint = filamentInstance->getJointsAt(animation.skinIndex)[animation.boneIndex]; + + auto jointInstance = transformManager.getInstance(joint); + auto globalJointTransform = transformManager.getWorldTransform(jointInstance); + + + auto inverseGlobalTransform = inverse( + transformManager.getWorldTransform( + transformManager.getInstance(meshTarget) + ) + ); + const auto boneTransform = inverseGlobalTransform * globalJointTransform * localTransform * inverseBindMatrix; const auto &renderableInstance = rm.getInstance(meshTarget); rm.setBones( renderableInstance, - &transform, + &boneTransform, 1, boneIndex );