use correct bone transform for animation + setter

This commit is contained in:
Nick Fisher
2023-11-18 13:33:54 +08:00
parent 0c698d16e3
commit 28bbc42e14
2 changed files with 59 additions and 8 deletions

View File

@@ -114,7 +114,11 @@ namespace polyvox
inline void updateTransform(SceneAsset &asset); inline void updateTransform(SceneAsset &asset);
void updateBoneTransformFromAnimationBuffer(const BoneAnimation& animation, int frameNumber); void updateBoneTransformFromAnimationBuffer(
const BoneAnimation& animation,
int frameNumber,
FilamentAsset *asset
);
}; };
} }

View File

@@ -379,7 +379,8 @@ namespace polyvox
} }
updateBoneTransformFromAnimationBuffer( updateBoneTransformFromAnimationBuffer(
animationStatus, animationStatus,
frameNumber); frameNumber,
asset.asset);
if (animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs) if (animationStatus.loop && elapsedInSecs >= animationStatus.durationInSecs)
{ {
@@ -404,6 +405,11 @@ namespace polyvox
const auto &entity = findEntityByName(sceneAsset, entityName); const auto &entity = findEntityByName(sceneAsset, entityName);
if(entity.isNull()) {
Log("Failed to find entity %s.", entityName);
return false;
}
RenderableManager &rm = _engine->getRenderableManager(); RenderableManager &rm = _engine->getRenderableManager();
const auto &renderableInstance = rm.getInstance(entity); const auto &renderableInstance = rm.getInstance(entity);
@@ -412,6 +418,13 @@ namespace polyvox
const auto &filamentInstance = sceneAsset.asset->getInstance(); 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); int numJoints = filamentInstance->getJointCountAt(skinIndex);
auto joints = filamentInstance->getJointsAt(skinIndex); auto joints = filamentInstance->getJointsAt(skinIndex);
int boneIndex = -1; int boneIndex = -1;
@@ -429,7 +442,6 @@ namespace polyvox
return false; return false;
} }
utils::Entity joint = filamentInstance->getJointsAt(skinIndex)[boneIndex]; utils::Entity joint = filamentInstance->getJointsAt(skinIndex)[boneIndex];
if (joint.isNull()) if (joint.isNull())
@@ -438,27 +450,62 @@ namespace polyvox
return false; 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( rm.setBones(
renderableInstance, renderableInstance,
&localTransform, &boneTransform,
1, 1,
boneIndex); boneIndex);
return true; 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(); RenderableManager &rm = _engine->getRenderableManager();
auto boneIndex = animation.boneIndex; 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) { 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); const auto &renderableInstance = rm.getInstance(meshTarget);
rm.setBones( rm.setBones(
renderableInstance, renderableInstance,
&transform, &boneTransform,
1, 1,
boneIndex boneIndex
); );