-
Notifications
You must be signed in to change notification settings - Fork 0
/
motion_matching.h
143 lines (124 loc) · 4.54 KB
/
motion_matching.h
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#pragma once
#include "stack_alloc.h"
#include "basic_data_structures.h"
#include "linear_math/vector.h"
#include "rid.h"
#include "anim.h"
#include "file_queries.h"
#include "misc.h"
#define MM_POINT_COUNT 3
#define MM_COMPARISON_BONE_COUNT 2
#define MM_ANIM_CAPACITY 35
struct mm_info_debug_settings
{
bool ShowTrajectory;
bool ShowTrajectoryAngles;
bool ShowBonePositions;
bool ShowBoneVelocities;
bool Overlay;
};
struct mm_debug_settings
{
bool ShowSmoothGoals;
float TrajectoryDuration;
int TrajectorySampleCount;
bool ShowHipTrajectories;
bool ShowRootTrajectories;
bool ApplyRootMotion;
mm_info_debug_settings CurrentGoal;
mm_info_debug_settings MatchedGoal;
};
struct mm_fixed_params
{
fixed_stack<int32_t, MM_COMPARISON_BONE_COUNT> ComparisonBoneIndices;
fixed_stack<int32_t, MM_COMPARISON_BONE_COUNT> MirrorBoneIndices;
Anim::skeleton Skeleton;
float MetadataSamplingFrequency;
};
struct mm_dynamic_params
{
float TrajectoryTimeHorizon;
float BonePCoefficient;
float BoneVCoefficient;
float TrajPCoefficient;
float TrajVCoefficient;
float TrajAngleCoefficient;
float BlendInTime;
float MinTimeOffsetThreshold;
bool MatchMirroredAnimations;
float TrajectoryWeights[MM_POINT_COUNT];
Anim::skeleton_mirror_info MirrorInfo;
};
struct mm_params
{
fixed_stack<rid, MM_ANIM_CAPACITY> AnimRIDs;
fixed_stack<path, MM_ANIM_CAPACITY> AnimPaths;
mm_fixed_params FixedParams;
mm_dynamic_params DynamicParams;
};
struct mm_frame_info
{
vec3 BonePs[MM_COMPARISON_BONE_COUNT];
vec3 BoneVs[MM_COMPARISON_BONE_COUNT];
vec3 TrajectoryPs[MM_POINT_COUNT];
float TrajectoryVs[MM_POINT_COUNT];
float TrajectoryAngles[MM_POINT_COUNT];
};
struct mm_frame_info_range
{
float StartTimeInAnim;
int32_t Start;
int32_t End;
};
struct mm_controller_data
{
mm_params Params;
fixed_stack<Anim::animation*, MM_ANIM_CAPACITY> Animations;
fixed_stack<mm_frame_info_range, MM_ANIM_CAPACITY> AnimFrameInfoRanges;
array_handle<mm_frame_info> FrameInfos;
};
enum anim_endpoint_extrapolation_type
{
EXTRAPOLATE_None,
EXTRAPOLATE_Loop,
EXTRAPOLATE_Stop,
EXTRAPOLATE_Continue,
};
inline void
ResetMMParamsToDefault(mm_params* Params)
{
memset(Params, 0, sizeof(mm_params));
Params->DynamicParams.BonePCoefficient = 1.0f;
Params->DynamicParams.BoneVCoefficient = 0.05f;
Params->DynamicParams.TrajPCoefficient = 0.6f;
Params->DynamicParams.TrajVCoefficient = 0.0f;
Params->DynamicParams.TrajAngleCoefficient = 0.15f;
Params->DynamicParams.TrajectoryTimeHorizon = 0.45f;
Params->DynamicParams.BlendInTime = 0.2f;
Params->DynamicParams.MinTimeOffsetThreshold = 0.25f;
Params->DynamicParams.MatchMirroredAnimations = false;
Params->FixedParams.MetadataSamplingFrequency = 30.0f;
for(int i = 0; i < MM_POINT_COUNT; i++)
{
Params->DynamicParams.TrajectoryWeights[i] =
ClampFloat(0, 0.1f + float(i) / float(MM_POINT_COUNT - 1), 1);
}
}
// Main metadata precomputation
mm_controller_data* PrecomputeRuntimeMMData(Memory::stack_allocator* TempAlloc,
array_handle<Anim::animation*> Animations,
const mm_params& Params);
// Cost function used for search
float ComputeCost(const mm_frame_info& A, const mm_frame_info& B, float PosCoef, float VelCoef,
float TrajCoef, float TrajVCoef, float TrajAngleCoef, const float* TrajectoryWeights);
float ComputeCostComponents(float* BonePComp, float* BoneVComp, float* TrajPComp, float* TrajVComp,
float* TrajAComp, const mm_frame_info& A, const mm_frame_info& B,
float PosCoef, float VelCoef, float TrajCoef, float TrajVCoef,
float TrajAngleCoef, const float* TrajectoryWeights);
// Runtime API
float MotionMatch(int32_t* OutAnimIndex, float* OutLocalStartTime, mm_frame_info* OutBestMatch,
const mm_controller_data* MMData, mm_frame_info Goal);
float MotionMatchWithMirrors(int32_t* OutAnimIndex, float* OutLocalStartTime,
mm_frame_info* OutBestMatch, bool* OutMatchedMirrored,
const mm_controller_data* MMData, mm_frame_info Goal,
mm_frame_info MirroredGoal);