mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 18:55:06 +08:00
feat: add support for A-pose/T-pose conversion in Setup Outfit (#828)
* feat: add support for A-pose/T-pose conversion in Setup Outfit * chore: 2019 compat * chore: minor cleanups * chore: 2019 fixes
This commit is contained in:
parent
84ab43b2af
commit
2467b5bc28
@ -134,7 +134,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var outfitRoot = cmd.context as GameObject;
|
||||
var avatarArmature = avatarHips.transform.parent;
|
||||
var outfitArmature = outfitHips.transform.parent;
|
||||
|
||||
|
||||
if (outfitArmature.GetComponent<ModularAvatarMergeArmature>() == null)
|
||||
{
|
||||
var merge = Undo.AddComponent<ModularAvatarMergeArmature>(outfitArmature.gameObject);
|
||||
@ -182,6 +182,8 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
FixAPose(avatarRoot, outfitArmature);
|
||||
|
||||
if (outfitRoot != null
|
||||
&& outfitRoot.GetComponent<ModularAvatarMeshSettings>() == null
|
||||
&& outfitRoot.GetComponentInParent<ModularAvatarMeshSettings>() == null)
|
||||
@ -214,6 +216,70 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
}
|
||||
}
|
||||
|
||||
private static void FixAPose(GameObject avatarRoot, Transform outfitArmature)
|
||||
{
|
||||
var mergeArmature = outfitArmature.GetComponent<ModularAvatarMergeArmature>();
|
||||
if (mergeArmature == null) return;
|
||||
|
||||
var mergeTarget = mergeArmature.mergeTarget.Get(mergeArmature)?.transform;
|
||||
if (mergeTarget == null) return;
|
||||
|
||||
var rootAnimator = avatarRoot.GetComponent<Animator>();
|
||||
if (rootAnimator == null) return;
|
||||
|
||||
FixSingleArm(HumanBodyBones.LeftShoulder);
|
||||
FixSingleArm(HumanBodyBones.RightShoulder);
|
||||
FixSingleArm(HumanBodyBones.LeftUpperArm);
|
||||
FixSingleArm(HumanBodyBones.RightUpperArm);
|
||||
|
||||
void FixSingleArm(HumanBodyBones arm)
|
||||
{
|
||||
var lowerArm = (HumanBodyBones)((int)arm + 2);
|
||||
|
||||
// check if the rotation of the arm differs, but distances and origin point are the same
|
||||
var avatarArm = rootAnimator.GetBoneTransform(arm);
|
||||
var outfitArm = avatarToOutfit(avatarArm);
|
||||
|
||||
var avatarLowerArm = rootAnimator.GetBoneTransform(lowerArm);
|
||||
var outfitLowerArm = avatarToOutfit(avatarLowerArm);
|
||||
|
||||
if (outfitArm == null) return;
|
||||
if (outfitLowerArm == null) return;
|
||||
|
||||
if ((avatarArm.position - outfitArm.position).magnitude > 0.001f) return;
|
||||
|
||||
// check relative distance to lower arm as well
|
||||
var avatarArmLength = (avatarLowerArm.position - avatarArm.position).magnitude;
|
||||
var outfitArmLength = (outfitLowerArm.position - outfitArm.position).magnitude;
|
||||
|
||||
if (Mathf.Abs(avatarArmLength - outfitArmLength) > 0.001f) return;
|
||||
|
||||
// Rotate the outfit arm to ensure these two points match.
|
||||
var relRot = Quaternion.FromToRotation(
|
||||
outfitLowerArm.position - outfitArm.position,
|
||||
avatarLowerArm.position - avatarArm.position
|
||||
);
|
||||
outfitArm.rotation = relRot * outfitArm.rotation;
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(outfitArm);
|
||||
EditorUtility.SetDirty(outfitArm);
|
||||
}
|
||||
|
||||
Transform avatarToOutfit(Transform avBone)
|
||||
{
|
||||
if (avBone == null) return null;
|
||||
if (!avBone.IsChildOf(mergeTarget)) return null;
|
||||
var parts = RuntimeUtil.RelativePath(mergeTarget.gameObject, avBone.gameObject)
|
||||
.Split('/');
|
||||
var outfitPath = string.Join("/", parts.Select(p => mergeArmature.prefix + p + mergeArmature.suffix));
|
||||
var candidate = outfitArmature.transform.Find(outfitPath);
|
||||
|
||||
var merger = candidate.GetComponentInParent<ModularAvatarMergeArmature>();
|
||||
if (merger != mergeArmature) return null;
|
||||
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
private static void FindConsistentSettings(
|
||||
GameObject avatarRoot,
|
||||
Transform avatarHips,
|
||||
|
Loading…
Reference in New Issue
Block a user