Reference
http://journal.cg-korea.org/archive/view_article?pid=jkcgs-29-3-159
https://www.gdcvault.com/play/1023280/Motion-Matching-and-The-Road
https://youtu.be/KSTn3ePDt50?si=oEy0Wp8rFkRyHlex
๋ชจ์ ๋งค์นญ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ
์ ๋น ์ํํธ์์ For Honor ๋ผ๋ ๊ฒ์์ ๊ฐ๋ฐํ๊ณ ์์์. ์ด ๊ฒ์์ ๋ฉํฐ ํ๋ ์ด ๊ฒ์์ธ๋ฐ ์๋จ, ์ข๋จ, ์ฐ๋จ์ ์ธ ๋ฐฉํฅ์ผ๋ก ๊ณต๊ฒฉ๊ณผ ๊ฐ๋๋ฅผ ํ๊ณ ๊ฐ๋๋ธ๋ ์ดํฌ(์ก๊ธฐ)์ ํํผ, ์ณ๋ด๊ธฐ(ํจ๋ง), ์บ์ฌ ๋ฑ ๋ค์ํ ์ก์ ์ด ์๋ ๊ฒ์์.
์ด ๊ฒ์์ ๋ค์ํ ์บ๋ฆญํฐ์ ์์ง์์ ์ค์ ์ธ๊ฐ์ฒ๋ผ ์์ฐ์ค๋ฝ๊ฒ ๊ตฌํํ๋ ค๋ ์ ๋๋ฉ์ด์ ์ ๊ด๋ฆฌํ๋ state machine์ด ๋งค์ฐ ๋ณต์กํด์ง๊ณ , ๊ด๋ฆฌํ๊ธฐ ์ด๋ ค์์ง (์๋๋ ์์ ์ด๋ฏธ์ง)
์ธ๊ฐ์ ๋ณต์กํ ์์ง์์ ๊ตฌํํ ์ ์์ผ๋ฉด์, ์ ๋๋ฉ์ด์ ๋ค์ ๊ฐ๋จํ๊ฒ ๊ด๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ์ด ํ์ํด์ง.
๊ทธ๋ฌ๋ค ๋ชจ์ ํ๋๋ผ๋ ๊ฐ๋ ์ ๋ฐ๊ฒฌํจ. ๋ชจ์ ํ๋๋ ์บ๋ฆญํฐ ์ ๋๋ฉ์ด์ ์ ์ํ ์๋ก์ด ๋ชจ์ ํํ ๋ฐฉ์์ผ๋ก, ๊ฐ ํ๋ ์์ ์บ๋ฆญํฐ์ ํ์ฌ ๋ชจ์ ๊ณผ ์ฐ๊ฒฐํ ์ ์๋ ๋ชจ๋ ๋ชจ์ ๋ค ์ค ํ ๋ชจ์ ์ ์ ํํ์ฌ ๋จ์ผ ํ๋ ์ ๋์ ํ์ฌ ๋ชจ์ ์์ ์ ํ๋ ๋ชจ์ ์ผ๋ก ์์ง์. ์ ๋๋ฉ์ด์ ์ ํ๋ ์๋ค์ ์ ์ฒ๋ผ ์ฐ์ด ์ด์ด์ ์บ๋ฆญํฐ์ ์ํ๊ฐ ํ๋ฅด๋ ์ด ๋ฐฉ์์ ์ฌ์ฉ์๊ฐ ์ค์๊ฐ์ผ๋ก ์บ๋ฆญํฐ๋ฅผ ์ ์ดํ ์ ์์ผ๋ฉฐ ์บ๋ฆญํฐ๊ฐ ์์ ํ ์ฐ์์ ์ผ๋ก ์๋ํ ์ ์๊ฒ ํจ. ๋ฐ๋ผ์ ์ํ ๋จธ์ ๊ณผ ๋น๊ตํ์ ๋ ์ฌ์ฉ์ ๋ช ๋ น์ ์งง์ ์๊ฐ๋ด์ ๋ฐ์ํ ์ ์๊ฒ ๋๋ฉฐ, ๋ชจ์ ๊ฐ์ ์ ํ์ ํ๋ํ๋ ์ ์ํ๊ณ ๊ด๋ฆฌํ ํ์๊ฐ ์์ด์ง๋ค๋ ์ฅ์ ์ด ์์.
๊ฒ ๋ฉ์ง ๋ชจ์ ํ๋๋ ์ ์ง๊ธ๊น์ง ๊ฒ์์์ ์ฌ์ฉ๋์ง ์์์๊น? ๋ฐฉ์ ์ ๋ฌด์์….๋ณต์กํ… ์คํ ์ดํธ ๋จธ์ ๋ ์ ๋์ํ๋๋ฐ ์ด ๋ณต์กํ ์ํ ๊ณต์์ด ๊ฐ๋ํ ๋ฐฉ์์ ์ฌ์ฉํ ํ์๊ฐ ์์๋ ๊ฒ.
์ํผ ์ ๋น ์ํํธ์์๋ ์ด ๋ชจ์ ํ๋์์ “์ด๋ค ํ๋ ์์ด๋ ์ฐ๋ฆฌ๊ฐ ์ํ๋ค๋ฉด ํด๋น ํ๋ ์์ผ๋ก ๊ฑด๋๋ฐ๊ธฐ ํ ์ ์๋ค.” ๋ผ๋ ์์ด๋์ด๋ฅผ ๊ฐ์ง๊ณ ์์ ์๊ธฐ๋ค ๊ฒ์์ ์ ์ฉํ๊ธฐ๋ก ํจ.
๊ทธ๋ ๊ฒ ๋ชจ์ ํ๋ ๊ฐ๋ ์ ๊ฐ์ ธ์ ์ฐ๊ตฌํ๋ ์ค ํ๊ฐ์ง ๋ฌธ์ ์ ๋ถ๋ํ. ์ํ๊ฐ ๊ฐ์๊ธฐ ๋ณํํ ๋ ์ด๋ค ๊ฒ์ ๊ธฐ์ค์ผ๋ก ์ต์ ์ ํ๋ ์์ ์ ํํ ๊ฒ์ธ๊ฐ? ์๋ฅผ ๋ค์ด, ์บ๋ฆญํฐ๊ฐ ๋ฌ๋ฆฌ๋ค๊ฐ ๊ฐ์๊ธฐ ๋ฉ์ถ ๋ ์ด๋ ์์ ์ Stop Animation์ ์์ํ ๊ฑด์ง?
์บ๋ฆญํฐ ํฌ์ฆ๋ฅผ ๊ธฐ์ค์ผ๋ก(pose matching)? ํน์ ์บ๋ฆญํฐ์ ์๋๋ฅผ ๊ธฐ์ค์ผ๋ก(velocity matching)?
์๋๋ฉด ์ ๋ฐํ๊ฒ ๋ฉ์ถ ์ง์ ์ ๊ณ์ฐํ์ฌ์ ํด๋น ์ง์ ์ ๋ง์ถฐ์ ๋ฉ์ถฐ์ผ ํ๋? (precise end position matching) 3๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ชจ๋ ์๋๋ค๋ฉด? 3๊ฐ์ง ๋ฐฉ์์ ๊ฐ์ค์น๋ฅผ ๋์ด์ ์ ์ ํ ์์ ์ ๊ณ์ฐํ๋ ๋ฐฉ์์ผ๋ก ๋ง์ด์ง.
๋ชจ์ ๋งค์นญ ?
๊ทธ๋ ๊ฒ ๊ฐ๋ฐํ๊ฒ ๋ ๊ฐ๋ ์ด “๋ชจ์ ๋งค์นญ”. ์ง์ ์๊ธฐ๋ค ๋ง๋ก ๊ตฌํํ๊ธฐ ์ฝ๊ณ , ๊ฐ๋จํ๊ณ , ๋ฉ์ง ๋ฐฉ์์ด๋ผ๊ณ ์๊ฐํจ.
๋ชจ์ ๋งค์นญ์ ํ ๋ฌธ์ฅ์ผ๋ก A ridiculously brute-force approach to animation selection. ์ฌ๊ธฐ์ brute-force๋ ์ฐ๋ฆฌ๊ฐ ์๋ ๊ทธ ์์ ํ์ ์๊ณ ๋ฆฌ์ฆ์ด ๋ง์. ๋ชจ์ ๋งค์นญ์ด ์ผ์ ํ๋ ์ ๊ฐ๊ฒฉ์ผ๋ก (์์ง์ ์ ๋ณด๊ฐ ๋ชจ๋ ๋ด๊ธด 15~20๋ถ ๋ถ๋์) mocap ์ ๋๋ฉ์ด์ ์ ํ๋ ์๋ค์ ์ดํด๋ณด๊ณ “๋ค์ ๋ชจ์ (jumping point)”์ ์ฐพ์๋ด ํด๋นํ๋ ์ ๋๋ฉ์ด์ ํ๋ ์์ผ๋ก ์ ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ผ์ ‘์ ๋๋ฉ์ด์ ์ ํ์ ์ํ ํฐ๋ฌด๋์๋ ์์ ํ์๋ฒ’ ์ด๋ผ๊ณ ํํํ๋ ๊ฑฐ์.
“๋ค์ ๋ชจ์
(Jumping Point)”์ ์ ์ ํ๊ธฐ ์ํด ์ ๋๋ฉ์ด์
ํ๋ ์๋ค์ ‘๋น์ฉ(cost)’ ๊ณ์ฐ ํจ.
๋น์ฉ์ ๋ค์ 2๊ฐ์ ์กฐ๊ฑด์ ๋ฐํ์ผ๋ก ๊ณ์ฐ ๋จ.
- ํ์ฌ ํฌ์ฆ์ ์ผ๋ง๋ ๋งค์น ๋๋์ง (Pose/Velocity Matching)
- ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉํฅ์ผ๋ก ๊ฐ๋ ๋ชจ์ ์ธ์ง (Trajectory Matching)
๋ ๊ฐ์ง ์กฐ๊ฑด์ ๋ชจ๋ ์๋ฒฝํ ์ถฉ์กฑํ๋ค๋ฉด ๋น์ฉ์ 0.
ํ์ฌ ํฌ์ฆ์ ์๋ ๊ทธ๋ฆฌ๊ณ ์บ๋ฆญํฐ๊ฐ ์ด๋ํ ๊ถค๋๊ฐ ์ด ๋น์ฉ์ ํ๋จํ๋๋ฐ ํ์ํจ.
๋น์ฉ์ด ๊ฐ์ฅ ์ ์ ํฌ์ฆ๊ฐ ํ์ฌ ํฌ์ฆ์์ ์ด์ด์ง ํฌ์ฆ๋ก ์ ํ๋จ.
ํ์ฌ ํฌ์ฆ์ ํ๋ณด ํฌ์ฆ๊ฐ ๋งค์น๋ ์ ์๋์ง ๋น๊ต(Pose/Velocity Matching)ํ๊ธฐ ์ํด์๋ ๋น์ฐํ ๋ ํฌ์ฆ๋ฅผ ๋น๊ตํ๋๋ฐ,
์ด๋ ๋ช ๊ฐ์ ๋ณธ(bone)๋ง์ ๋น๊ตํ์ฌ ๋ ํฌ์ฆ๊ฐ ๋งค์น๋ ์ ์๋์ง ๋น๊ตํจ.
์๋ฅผ ๋ค์ด์
- Local velocity
- Feet positions (Character Local)
- Feet velocites (Character Local)
- ๊ธฐํ ๋ฑ๋ฑ ์ฌ์ฉ์๊ฐ ์ํ๋ ์กฐ๊ฑด (๋จธ๋ฆฌ ๋ฐฉํฅ์ด๋ผ๋๊ฐ… ๋ฌด๊ธฐ ์์น๋ผ๋๊ฐ…)
๋ฑ์ ๊ณ ๋ คํด์ ํ๋ณด ํฌ์ฆ์ cost ๋ฅผ ๊ณ์ฐ. ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ๋น๊ต์ ํ์ํ ์ ๋ณด๋ค์ ๋ฏธ๋ฆฌ ๊ณ์ฐํด์ ์ ๋๋ฉ์ด์ ์ด๋ ํจ๊ป ์ ์ฅํ์ฌ ๋ฐํ์ ๋น๊ต์์ ๋น ๋ฅด๊ฒ ๊ณ์ฐํ ์ ์๋๋ก ํจ. ๊ทธ๋ฆฌ๊ณ ์๋ฐ์ ๋น๊ตํ๋ ์ด์ ๋ ์บ๋ฆญํฐ๊ฐ ์ด์กฑ ๋ณดํ์ผ ๊ฒฝ์ฐ ๋ ๋ฐ์ ๊ต์ฐจํด์ ์ด๋ํ๊ธฐ ๋๋ฌธ์ ์์ง์์ด ๊ฐ์ฅ ๋ง๊ธฐ๋ ํ๊ณ ๋ค๋ฅธ bone์ผ๋ก ๋น๊ตํ๋ฉด ์บ๋ฆญํฐ๊ฐ ํ ์ชฝ ๋ฐ๋ก๋ง ๊ฑท๊ฑฐ๋ ํ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ธฐ๋ ํ๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ํ๋ค.
์บ๋ฆญํฐ๋ฅผ ์ํ๋ ๋ฐฉํฅ(๊ถค๋)๋๋ก ๊ฐ๊ฒํ๋ ค๋ฉด ์ ๋๋ฉ์ด์ ์ ์ด๋ค ํ๋ ์์ ์ฌ์ํ์ ๋, ์ ๋๋ฉ์ด์ ์ ์งํ๊ถค๋๊ฐ ์ํ๋ ๊ถค๋์ ์ต๋ํ ์ ์ฌํด์ผํจ. ์ด๋ ์๋ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ํ๋ ๋ฐฉํฅ๊ณผ ์ผ๋ง๋ ์ ์ฌํ์ง ๋น๊ตํ๋ค.
- Future position
- Future orientation
- Future velocity/acceleration
int m_CurrentAnimIndex;
float m_CurrentAnimTime;
class TrajectoryPoint
{
Vector3 m_Position; // ๊ฐ๊ณ ์ ํ๋ ์๋ ์์น
float m_Sight; // ๊ฐ๊ณ ์ ํ๋ ์๋ ๋ฐฉํฅ
float m_TimeDelay; // m_Position ๊น์ง ๊ฐ๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ
};
class Goal
{
Array<TrajectoryPoint> m_DesiredTrajectroy;
// ... ๊ธฐํ ์ํ๋ ๊ฒ
};
// Goal - goal of this frame , dt - delta time
void AmoUpdate(Goal goal, float dt)
{
m_CurrentAnimTime += dt;
Pose currentPose = EvaluateLerpedPoseFromData(m_CurrentAnimIndex, m_CurrentAnimTime);
float bestCost = MAX_NUMBER;
Pose bestPose;
// loop all mocap
for(int i = 0; i < m_Poses.Size(); i++)
{
Pose candidatePose = m_Poses[i];
// every candidate jumping point has a cost
float thisCost = ComputeCost(currentPos, candidatePos, goal)
if(thisCost < bestCost)
{
// remember the best candidate
bestCost = thisCost;
bestPose = candidatePos;
}
}
bool theWinnerIsAtTheSameLocation =
m_CurrentAnimIndex == bestPose.m_AnimIndex &&
fabs(m_CurrentAnimTime - bestPose.m_AnimTime) < 0.2f;
if(!theWinnerIsAtTheSameLocation)
{
// blend to the winning location
m_CurrentAnimIndex = bestPose.m_AnimIndex;
m_CurrentAnimTime = bestPose.m_AnimTime;
PlayAnimStartingAtTime(m_CurrentAnimIndex, m_CurrentAnimTime, 0.25f);
}
}
float ComputeCost(Pose currentPose, Pose candidatePose, Goal goal)
{
float cost = 0.0f;
// how much the candidate jumping position matches the current situation
cost += ComputeCurrentCost(currentPose, candidatePose);
static float resonsivity = 1.0f;
// how much the candidiate piece of motion matched the desired trajectory
coost += resonsivity * ComputeFutureCost(candidatePose, goal);
return cost;
}
์ธ๋ฆฌ์ผ์์์ ๋ชจ์ ๋งค์นญ
์ธ๋ฆฌ์ผ์์ 5.4 ๋ถํฐ ๋ชจ์ ๋งค์นญ์ ์ ์์ผ๋ก ์ง์ํ๊ธฐ ์์ํ์. ์ธ๋ฆฌ์ผ์์๋ ๋ชจ์ ๋งค์นญ์ ๋ชจ์ ๊ทธ๋ํ์์ ๋ ธ๋๊ฐ์ ํธ๋์ง์ ์ ์๋ํํ ๊ธฐ๋ฅ์ด๋ผ๊ณ ํํํ๋ค.
๋ชจ์ ๋งค์นญ ๋ ธ๋๋ ํฌ์ฆ ํ์คํ ๋ฆฌ ๋ ธ๋๋ก๋ถํฐ ์์ง๋ ๊ธฐ์กด์ ์ ๋ณด์ Characetr Move Component์ ๋ชจ์ ๋ชจ๋ธ ์์ธก์ ์ฌ์ฉํด์ ์ง์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ๋ค์ ์ ๋๋ฉ์ด์ ์ ๊ฒ์ํจ. ๊ฒ์ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ํ์ฌ ํฌ์ฆ์ ์ฐ์๋์ง ์๋ ์ ๋๋ฉ์ด์ ์ ํฌ์ฆ๊ฐ ์ ํ๋ ๊ฒฝ์ฐ, ๋ชจ์ ๋งค์นญ ๋ ธ๋๋ ํ์ฌ ์ ๋๋ฉ์ด์ ํฌ์ฆ์ ์๋ก ์ ํ๋ ํฌ์ฆ๋ฅผ ๋ธ๋๋ฉ.
PoseSearchSchema
: Motion Matching์์ ํ์ํ ํฌ์ฆ๊ฐ์ ๋ฉํธ๋ฆญ์ ์ ์ํ๊ณ ๋งค์นญํ๋ ค๋ ํญ๋ณต์ ์ง์ ํ๋ ์์ ์ด๋ค.
์๋ฅผ ๋ค์ด์, ์บ๋ฆญํฐ์ ๋ฐ ์์น์ ์์ ๊ถค์ ๊ทธ๋ฆฌ๊ณ ๊ฐ ๋งค์นญ ํญ๋ณต์ ๊ฐ์ค์น์ธ weight๋ฅผ ์ค์ ํ ์ ์๋ค.
(Sample Rate(๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์๋๋ฉ์ด์ ๋ฐ์ดํฐ ์ํ๋ง ์ ๋ฐ์ดํธ ๋น๋)๋ฅผ ์ค์ ํ๊ฑฐ๋ Pose Matching ๊ณผ Trajectory Matching์ ๊ฐ์ค์น๋ฅผ ์ค์ ํ๊ฑฐ๋, Pose Match์ Sample Bone์ ์ค์ ํ ์ ์๋ค.)
์คํค๋ง๋ Channel๋ค์ ์งํฉ์ผ๋ก ์ ์๋๋๋ฐ, ๊ฐ ์ฑ๋์์๋ ๊ถค๋, ํฌ์ฆ, ํค๋ฉ, ํ์ด์ฆ ๋ฑ ๋ค์ํ ๋ชจ์ ๋งค์นญ ๊ท์น์ ์ค์ ํ ์ ์๋ค.
Trajectory Matching Channel
(offset์ ๋ฏธ๋ ์ ๋ณด ์ฟผ๋ฆฌ๋ฅผ ์ํด ์ค์ ํ๋ ๋ฐ์ดํฐ์ด๋ค. ์๋ฅผ๋ค์ด Offset์ด 0.5 ๋ผ๋ฉด 0.5์ด ๋ค์ flag์ ํด๋นํ๋ ์ ๋ณด๋ฅผ ์๋ฏธํ๋ค.)
Position Matching Channel
PoseSearchDatabase
: ๋ชจ์ ๋งค์นญ ์ ์บ๋ฆญํฐ์ ๋ค์ ํ๋ ์์ผ๋ก ์ฐ๊ฒฐ๋ ์ ์๋ ์ ๋๋ฉ์ด์ ๋ค๊ณผ PoseSearchSchema์ ๋ฐ๋ฅธ ์ํ๋ง ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ์์ . PoseSearchSchema์์ ์ค์ ํ๋ Sample Channel์ ๋ฐ๋ผ ์ ๋๋ฉ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ํ๋งํ์ฌ ์ ์ฅํ๋ค. ๋ชจ์ ๋งค์นญ ์ ์ด ์ํ๋ง ํด๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ์ผ๋ก ๋ค์ ํ๋ ์์ ์ฐ๊ฒฐ๋ ์ ๋๋ฉ์ด์ ์ ์ฐพ๋๋ค.
Pose Search Normalization Set
Chooser Table
'๐ฅ๏ธ Study Note' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฌธ์ ์ธ์ฝ๋ฉ (0) | 2025.07.24 |
---|