diff --git a/Assets/Scenes/VirtualMotionCapture.unity b/Assets/Scenes/VirtualMotionCapture.unity index 2a6e5bcd..ff085846 100644 --- a/Assets/Scenes/VirtualMotionCapture.unity +++ b/Assets/Scenes/VirtualMotionCapture.unity @@ -2430,7 +2430,7 @@ MonoBehaviour: m_EditorClassIdentifier: IsBeta: 0 IsPreRelease: 0 - VersionString: v0.54f1r1b7 + VersionString: v0.54f1r1b8 LeftWristTransform: {fileID: 0} RightWristTransform: {fileID: 0} CalibrationCamera: {fileID: 1312323656} diff --git a/Assets/Scripts/MocopiConnector.cs b/Assets/Scripts/MocopiConnector.cs index ff117d28..4b669b0c 100644 --- a/Assets/Scripts/MocopiConnector.cs +++ b/Assets/Scripts/MocopiConnector.cs @@ -22,12 +22,12 @@ public class MocopiConnector : MonoBehaviour private Animator modelAnimator; private Animator mocopiAnimator; - private Transform cloneRootTransform; + private Animator filteredAnimator; private VRIK vrik; private IKSolver ikSolver; - private List<(HumanBodyBones humanBodyBone, Transform source, Transform target)> boneTransformCache; + private List<(HumanBodyBones humanBodyBone, Transform source, Transform filtered, Transform target)> boneTransformCache; private Vector3 centerOffsetPosition; private float centerOffsetRotationY; @@ -55,7 +55,6 @@ private void OnEnable() private void OnDisable() { - isFrameArrived = false; StopUdpReceiver(); } private void Server_Received(object sender, DataReceivedEventArgs e) @@ -143,13 +142,24 @@ private void OnCurrentModelChanged(GameObject model) currentModel = model; modelAnimator = model.GetComponent(); - var (cloneAvatar, cloneRoot) = CreateCopyAvatar(model, transform); - mocopiAnimator = gameObject.AddComponent(); + var filteredAvatarObject = new GameObject("filteredAvatar"); + filteredAvatarObject.transform.SetParent(transform, false); + + var (filteredAvatar, _) = CreateCopyAvatar(model, filteredAvatarObject.transform); + + filteredAnimator = filteredAvatarObject.AddComponent(); + filteredAnimator.avatar = filteredAvatar; + + var mocopiAvatarObject = new GameObject("mocopiAvatar"); + mocopiAvatarObject.transform.SetParent(transform, false); + + var (cloneAvatar, _) = CreateCopyAvatar(model, mocopiAvatarObject.transform); + + mocopiAnimator = mocopiAvatarObject.AddComponent(); mocopiAnimator.avatar = cloneAvatar; - cloneRootTransform = cloneRoot; - mocopiAvatar = gameObject.AddComponent(); - mocopiAvatar.MotionSmoothness = 1.0f; + mocopiAvatar = mocopiAvatarObject.AddComponent(); + mocopiAvatar.MotionSmoothness = 0.0f; // mocopiAvatarのモーションスムージングは使用せず自前で補正する boneTransformCache = null; if (enabled) @@ -163,14 +173,12 @@ private void OnModelUnloading(GameObject model) //前回の生成物の削除 if (currentModel != null) { - DestroyImmediate(cloneRootTransform.gameObject); + DestroyImmediate(mocopiAnimator.gameObject); // Destroy SkeletonRoot foreach (Transform child in transform) { DestroyImmediate(child.gameObject); } - DestroyImmediate(mocopiAvatar); - DestroyImmediate(mocopiAnimator); if (ikSolver != null) { @@ -180,6 +188,7 @@ private void OnModelUnloading(GameObject model) vrik = null; currentModel = null; isFrameArrived = false; + boneTransformCache = null; } } @@ -230,6 +239,7 @@ private void StopUdpReceiver() } isFrameArrived = false; udpReceiver = null; + boneTransformCache = null; } public void InitializeSkeleton(int[] boneIds, int[] parentBoneIds, float[] rotationsX, float[] rotationsY, float[] rotationsZ, float[] rotationsW, float[] positionsX, float[] positionsY, float[] positionsZ) { @@ -276,7 +286,7 @@ private void ApplyMotion() if (boneTransformCache == null) { - boneTransformCache = new List<(HumanBodyBones humanBodyBone, Transform source, Transform target)>(); + boneTransformCache = new List<(HumanBodyBones humanBodyBone, Transform source, Transform filtered, Transform target)>(); var ReverseBodyBones = new HumanBodyBones[] { HumanBodyBones.Head , @@ -310,10 +320,17 @@ private void ApplyMotion() var mocopiBone = mocopiAnimator.GetBoneTransform(bone); if (mocopiBone == null) continue; + var filteredBone = filteredAnimator.GetBoneTransform(bone); + if (filteredBone == null) continue; + + // initialize filtered bone + filteredBone.localPosition = mocopiBone.localPosition; + filteredBone.localRotation = mocopiBone.localRotation; + var modelBone = modelAnimator.GetBoneTransform(bone); if (modelBone == null) continue; - boneTransformCache.Add((bone, mocopiBone, modelBone)); + boneTransformCache.Add((bone, mocopiBone, filteredBone, modelBone)); } } @@ -323,8 +340,19 @@ private void ApplyMotion() Vector3 defaultHeadPosition = headBone.position; Quaternion defaultHeadRotation = headBone.rotation; - foreach ((var bone, var source, var target) in boneTransformCache) + + + float lerpValue = 0.5f; + foreach ((var bone, var source, var filtered, var target) in boneTransformCache) { + //source to filtered + if (bone == HumanBodyBones.Hips) + { + filtered.localPosition = Vector3.Lerp(filtered.localPosition, source.localPosition, lerpValue); + } + filtered.localRotation = Quaternion.Lerp(filtered.localRotation, source.localRotation, lerpValue); + + // filtered to target bool apply = false; switch (bone) { @@ -332,12 +360,12 @@ private void ApplyMotion() hipBone = target; if (Settings.Current.mocopi_ApplyRootRotation) { - target.localRotation = source.localRotation; + target.localRotation = filtered.localRotation; target.Rotate(new Vector3(0, centerOffsetRotationY, 0), Space.World); } if (Settings.Current.mocopi_ApplyRootPosition) { - target.localPosition = source.localPosition + centerOffsetPosition; //Root位置だけは同期 + target.localPosition = filtered.localPosition + centerOffsetPosition; //Root位置だけは同期 } break; case HumanBodyBones.Spine: @@ -386,7 +414,7 @@ private void ApplyMotion() break; } - if (apply) target.localRotation = source.localRotation; + if (apply) target.localRotation = filtered.localRotation; } if (Settings.Current.mocopi_ApplyHead == false && hipBone != null && spineBone != null)