vault backup: 2023-09-05 15:12:43
This commit is contained in:
parent
a7da7c61f1
commit
eaf5224904
@ -15,8 +15,103 @@ rating: ⭐
|
||||
|
||||
重定向逻辑位于:FMixamoSkeletonRetargeter::Retarget()
|
||||
|
||||
## 判断骨骼格式
|
||||
## 生成TPose
|
||||
```c++
|
||||
static const TArray<FName> Mixamo_PreserveComponentSpacePose_BoneNames = {
|
||||
"Head",
|
||||
"LeftToeBase",
|
||||
"RightToeBase"
|
||||
|
||||
#ifdef MAR_UPPERARMS_PRESERVECS_EXPERIMENTAL_ENABLE_
|
||||
,"RightShoulder"
|
||||
,"RightArm" ,"LeftShoulder" ,"LeftArm"#endif
|
||||
};
|
||||
|
||||
static const TArray<TPair<FName, FName>> Mixamo_ParentChildBoneNamesToBypassOneChildConstraint = {
|
||||
{"LeftUpLeg", "LeftLeg"},
|
||||
{"LeftLeg", "LeftFoot"},
|
||||
{"LeftFoot", "LeftToeBase"},
|
||||
{"LeftToeBase", "LeftToe_End"},
|
||||
{"RightUpLeg", "RightLeg"},
|
||||
{"RightLeg", "RightFoot"},
|
||||
{"RightFoot", "RightToeBase"},
|
||||
{"RightToeBase", "RightToe_End"},
|
||||
{"Hips", "Spine"}, // Heuristic to try to align better the part.
|
||||
{"Spine", "Spine1"},
|
||||
{"Spine1", "Spine2"},
|
||||
{"Spine2", "Neck"}, // Heuristic to try to align better the part.
|
||||
{"Neck", "Head"},
|
||||
{"Head", "HeadTop_End"},
|
||||
{"LeftShoulder", "LeftArm"},
|
||||
{"LeftArm", "LeftForeArm"},
|
||||
{"LeftForeArm", "LeftHand"},
|
||||
{"LeftHand", "LeftHandMiddle1"}, // Heuristic to try to align better the part.
|
||||
{"LeftHandIndex1", "LeftHandIndex2"},
|
||||
{"LeftHandIndex2", "LeftHandIndex3"},
|
||||
{"LeftHandIndex3", "LeftHandIndex4"},
|
||||
{"LeftHandMiddle1", "LeftHandMiddle2"},
|
||||
{"LeftHandMiddle2", "LeftHandMiddle3"},
|
||||
{"LeftHandMiddle3", "LeftHandMiddle4"},
|
||||
{"LeftHandPinky1", "LeftHandPinky2"},
|
||||
{"LeftHandPinky2", "LeftHandPinky3"},
|
||||
{"LeftHandPinky3", "LeftHandPinky4"},
|
||||
{"LeftHandRing1", "LeftHandRing2"},
|
||||
{"LeftHandRing2", "LeftHandRing3"},
|
||||
{"LeftHandRing3", "LeftHandRing4"},
|
||||
{"LeftHandThumb1", "LeftHandThumb2"},
|
||||
{"LeftHandThumb2", "LeftHandThumb3"},
|
||||
{"LeftHandThumb3", "LeftHandThumb4"},
|
||||
{"RightShoulder", "RightArm"},
|
||||
{"RightArm", "RightForeArm"},
|
||||
{"RightForeArm", "RightHand"},
|
||||
{"RightHand", "RightHandMiddle1"}, // Heuristic to try to align better the part.
|
||||
{"RightHandIndex1", "RightHandIndex2"},
|
||||
{"RightHandIndex2", "RightHandIndex3"},
|
||||
{"RightHandIndex3", "RightHandIndex4"},
|
||||
{"RightHandMiddle1", "RightHandMiddle2"},
|
||||
{"RightHandMiddle2", "RightHandMiddle3"},
|
||||
{"RightHandMiddle3", "RightHandMiddle4"},
|
||||
{"RightHandPinky1", "RightHandPinky2"},
|
||||
{"RightHandPinky2", "RightHandPinky3"},
|
||||
{"RightHandPinky3", "RightHandPinky4"},
|
||||
{"RightHandRing1", "RightHandRing2"},
|
||||
{"RightHandRing2", "RightHandRing3"},
|
||||
{"RightHandRing3", "RightHandRing4"},
|
||||
{"RightHandThumb1", "RightHandThumb2"},
|
||||
{"RightHandThumb2", "RightHandThumb3"},
|
||||
{"RightHandThumb3", "RightHandThumb4"}
|
||||
};
|
||||
|
||||
RetargetBasePose(
|
||||
SkeletalMeshes,
|
||||
ReferenceSkeleton,
|
||||
Mixamo_PreserveComponentSpacePose_BoneNames,
|
||||
UEMannequinToMixamo_BoneNamesMapping.GetInverseMapper(),
|
||||
Mixamo_ParentChildBoneNamesToBypassOneChildConstraint,
|
||||
/*bApplyPoseToRetargetBasePose=*/true,
|
||||
UIKRetargeterController::GetController(IKRetargeter_UEMannequinToMixamo)
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 判断骨骼结构是否符合要求
|
||||
```c++
|
||||
bool FMixamoSkeletonRetargeter::IsMixamoSkeleton(const USkeleton * Skeleton) const
|
||||
{
|
||||
// We consider a Skeleton "coming from Mixamo" if it has at least X% of the expected bones.
|
||||
const float MINIMUM_MATCHING_PERCENTAGE = .75f;
|
||||
|
||||
// Convert the array of expected bone names (TODO: cache it...).
|
||||
TArray<FName> BoneNames;
|
||||
UE4MannequinToMixamo_BoneNamesMapping.GetDestination(BoneNames);
|
||||
// Look for and count the known Mixamo bones (see comments on IndexLastCheckedMixamoBone and UEMannequinToMixamo_BonesMapping).
|
||||
constexpr int32 NumBones = (IndexLastCheckedMixamoBone + 1) / 2;
|
||||
BoneNames.SetNum(NumBones);
|
||||
FSkeletonMatcher SkeletonMatcher(BoneNames, MINIMUM_MATCHING_PERCENTAGE);
|
||||
return SkeletonMatcher.IsMatching(Skeleton);
|
||||
}
|
||||
|
||||
bool FSkeletonMatcher::IsMatching(const USkeleton* Skeleton) const
|
||||
{
|
||||
// No Skeleton, No matching...
|
||||
@ -35,3 +130,73 @@ bool FSkeletonMatcher::IsMatching(const USkeleton* Skeleton) const
|
||||
return MatchedPercentage >= MinimumMatchingPerc;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
enum class ETargetSkeletonType
|
||||
{
|
||||
ST_UNKNOWN = 0,
|
||||
ST_UE4_MANNEQUIN,
|
||||
ST_UE5_MANNEQUIN,
|
||||
|
||||
ST_SIZE
|
||||
};
|
||||
|
||||
static const char* const kUE4MannequinToMixamo_BoneNamesMapping[] = {
|
||||
// UE Mannequin bone name MIXAMO bone name
|
||||
"root", "root",
|
||||
"pelvis", "Hips",
|
||||
"spine_01", "Spine",
|
||||
"spine_02", "Spine1",
|
||||
"spine_03", "Spine2",
|
||||
"neck_01", "Neck",
|
||||
"head", "head",
|
||||
"clavicle_l", "LeftShoulder",
|
||||
"upperarm_l", "LeftArm",
|
||||
"lowerarm_l", "LeftForeArm",
|
||||
"hand_l", "LeftHand",
|
||||
"clavicle_r", "RightShoulder",
|
||||
"upperarm_r", "RightArm",
|
||||
"lowerarm_r", "RightForeArm",
|
||||
"hand_r", "RightHand",
|
||||
"thigh_l", "LeftUpLeg",
|
||||
"calf_l", "LeftLeg",
|
||||
"foot_l", "LeftFoot",
|
||||
"ball_l", "LeftToeBase",
|
||||
"thigh_r", "RightUpLeg",
|
||||
"calf_r", "RightLeg",
|
||||
"foot_r", "RightFoot",
|
||||
"ball_r", "RightToeBase",
|
||||
// From here, ignored to determine if a skeleton is from Mixamo.
|
||||
// From here, ignored to determine if a skeleton is from UE Mannequin. "index_01_l", "LeftHandIndex1",
|
||||
"index_02_l", "LeftHandIndex2",
|
||||
"index_03_l", "LeftHandIndex3",
|
||||
"middle_01_l", "LeftHandMiddle1",
|
||||
"middle_02_l", "LeftHandMiddle2",
|
||||
"middle_03_l", "LeftHandMiddle3",
|
||||
"pinky_01_l", "LeftHandPinky1",
|
||||
"pinky_02_l", "LeftHandPinky2",
|
||||
"pinky_03_l", "LeftHandPinky3",
|
||||
"ring_01_l", "LeftHandRing1",
|
||||
"ring_02_l", "LeftHandRing2",
|
||||
"ring_03_l", "LeftHandRing3",
|
||||
"thumb_01_l", "LeftHandThumb1",
|
||||
"thumb_02_l", "LeftHandThumb2",
|
||||
"thumb_03_l", "LeftHandThumb3",
|
||||
"index_01_r", "RightHandIndex1",
|
||||
"index_02_r", "RightHandIndex2",
|
||||
"index_03_r", "RightHandIndex3",
|
||||
"middle_01_r", "RightHandMiddle1",
|
||||
"middle_02_r", "RightHandMiddle2",
|
||||
"middle_03_r", "RightHandMiddle3",
|
||||
"pinky_01_r", "RightHandPinky1",
|
||||
"pinky_02_r", "RightHandPinky2",
|
||||
"pinky_03_r", "RightHandPinky3",
|
||||
"ring_01_r", "RightHandRing1",
|
||||
"ring_02_r", "RightHandRing2",
|
||||
"ring_03_r", "RightHandRing3",
|
||||
"thumb_01_r", "RightHandThumb1",
|
||||
"thumb_02_r", "RightHandThumb2",
|
||||
"thumb_03_r", "RightHandThumb3",
|
||||
// Un-mapped bones (at the moment). Here for reference.
|
||||
//"lowerarm_twist_01_l", nullptr, //"upperarm_twist_01_l", nullptr, //"lowerarm_twist_01_r", nullptr, //"upperarm_twist_01_r", nullptr, //"calf_twist_01_l", nullptr, //"thigh_twist_01_l", nullptr, //"calf_twist_01_r", nullptr, //"thigh_twist_01_r", nullptr, //"ik_foot_root", nullptr, //"ik_foot_l", nullptr, //"ik_foot_r", nullptr, //"ik_hand_root", nullptr, //"ik_hand_gun", nullptr, //"ik_hand_l", nullptr, //"ik_hand_r", nullptr,};
|
Loading…
x
Reference in New Issue
Block a user