diff options
| author | Léo Lam <leo@leolam.fr> | 2022-05-01 22:40:51 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2022-06-21 00:29:14 +0200 |
| commit | d80ccb83714865bc182a305e773ab5df8be0980d (patch) | |
| tree | 721fd558c191f156f98ece6000ca43ec8ed30383 /src/KingSystem/Physics/Rig/physSkeletonMapper.cpp | |
| parent | 83ae6b5d522e669c4f543223e4e4921a252bcd06 (diff) | |
ksys/phys: Add SkeletonMapper
Diffstat (limited to 'src/KingSystem/Physics/Rig/physSkeletonMapper.cpp')
| -rw-r--r-- | src/KingSystem/Physics/Rig/physSkeletonMapper.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/KingSystem/Physics/Rig/physSkeletonMapper.cpp b/src/KingSystem/Physics/Rig/physSkeletonMapper.cpp new file mode 100644 index 00000000..d554b7f7 --- /dev/null +++ b/src/KingSystem/Physics/Rig/physSkeletonMapper.cpp @@ -0,0 +1,75 @@ +#include "KingSystem/Physics/Rig/physSkeletonMapper.h" +#include <Havok/Animation/Animation/Mapper/hkaSkeletonMapper.h> +#include <Havok/Animation/Animation/Rig/hkaPose.h> + +namespace ksys::phys { + +SkeletonMapper::SkeletonMapper() = default; + +SkeletonMapper::~SkeletonMapper() { + mModelBoneAccessor.finalize(); + mBoneAccessor.finalize(); +} + +bool SkeletonMapper::init(hkaSkeletonMapper* skeleton_mapper, + hkaSkeletonMapper* model_skeleton_mapper, gsys::Model* model, + sead::Heap* heap) { + if (!model || !skeleton_mapper || !model_skeleton_mapper) + return false; + + hkaSkeleton* skel_a = skeleton_mapper->m_mapping.m_skeletonA.val(); + if (skel_a != model_skeleton_mapper->m_mapping.m_skeletonB.val()) + return false; + + hkaSkeleton* skel_b = skeleton_mapper->m_mapping.m_skeletonB.val(); + if (skel_b != model_skeleton_mapper->m_mapping.m_skeletonA.val()) + return false; + + const int num_bones_a = skel_a->m_bones.getSize(); + const int num_bones_b = skel_b->m_bones.getSize(); + if (num_bones_a <= 0 || num_bones_b <= 0) + return false; + + const auto cleanup = [this] { + mModelBoneAccessor.finalize(); + mBoneAccessor.finalize(); + return false; + }; + + if (num_bones_a <= num_bones_b) { + mMapperA = model_skeleton_mapper; + mMapperB = skeleton_mapper; + + if (!mModelBoneAccessor.init(skeleton_mapper->m_mapping.m_skeletonB.val(), model, heap) || + !mBoneAccessor.init(skeleton_mapper->m_mapping.m_skeletonA.val(), heap)) { + return cleanup(); + } + } else { + mMapperA = skeleton_mapper; + mMapperB = model_skeleton_mapper; + + if (!mModelBoneAccessor.init(skeleton_mapper->m_mapping.m_skeletonA.val(), model, heap) || + !mBoneAccessor.init(skeleton_mapper->m_mapping.m_skeletonB.val(), heap)) { + return cleanup(); + } + } + + return true; +} + +void SkeletonMapper::mapPoseA() { + mBoneAccessor.resetPoseData(); + mMapperA->mapPose(mModelBoneAccessor.getPose()->getSyncedPoseModelSpace().data(), + mBoneAccessor.getPose()->getSkeleton()->m_referencePose.data(), + mBoneAccessor.getPose()->accessUnsyncedPoseModelSpace().data(), + hkaSkeletonMapper::REFERENCE_POSE); +} + +void SkeletonMapper::mapPoseB() { + const auto* original = mModelBoneAccessor.getPose()->getSyncedPoseLocalSpace().data(); + auto* out = mModelBoneAccessor.getPose()->accessUnsyncedPoseModelSpace().data(); + mMapperB->mapPose(mBoneAccessor.getPose()->getSyncedPoseModelSpace().data(), original, out, + hkaSkeletonMapper::NO_CONSTRAINTS); +} + +} // namespace ksys::phys |
