1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
|