From b14c3f6f40c8259b5d92e5f6b9245b2dcbac1445 Mon Sep 17 00:00:00 2001 From: "qsxft258@gmail.com" Date: Sat, 21 Mar 2026 16:28:41 +0900 Subject: [PATCH] =?UTF-8?q?Fix=20:=20=EB=AA=A8=EC=BA=A1=20=EC=9E=94?= =?UTF-8?q?=EB=96=A8=EB=A6=BC=20=EA=B4=80=EB=A0=A8=ED=95=9C=20=EB=8C=80?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EA=B4=80=EB=A0=A8=20=EC=9D=B4=EC=8A=88=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseAvatar - OptiTrack 5 bone.fbx.meta | 689 +++++++------- .../BaseAvatar - OptiTrack 5 bone.prefab | 4 +- .../BaseAvatar 5bone/OptitrackRestPose.asset | 3 + .../OptitrackRestPose.asset.meta} | 4 +- .../OptiTrack/BaseAvatar ver 2.meta | 8 - .../BaseAvatar - OptiTrack ver 2.fbx | 3 - .../BaseAvatar - OptiTrack ver 2.fbx.meta | 843 ------------------ .../OptiTrack/BaseAvatar.meta | 8 - .../OptiTrack/BaseAvatar/Y Bot.Avatar.meta | 8 - .../BaseAvatar/Y Bot.Avatar/VrmAvatar.asset | 3 - .../Y Bot.Avatar/VrmAvatar.asset.meta | 8 - .../OptiTrack/BaseAvatar/Y Bot.Materials.meta | 8 - .../Y Bot.Materials/Alpha_Body_MAT.asset | 3 - .../Y Bot.Materials/Alpha_Joints_MAT.asset | 3 - .../Alpha_Joints_MAT.asset.meta | 8 - .../OptiTrack/BaseAvatar/Y Bot.Meshes.meta | 8 - .../Y Bot.Meshes/Alpha_Joints.baked.asset | 3 - .../Alpha_Joints.baked.asset.meta | 8 - .../Y Bot.Meshes/Alpha_Surface.baked.asset | 3 - .../Alpha_Surface.baked.asset.meta | 8 - .../OptiTrack/BaseAvatar/Y Bot.prefab | 3 - .../OptiTrack/Editor/OptitrackSetupWindow.cs | 396 ++++++++ .../Editor/OptitrackSetupWindow.cs.meta | 2 + .../Editor/OptitrackSkeletonAnimatorEditor.cs | 259 +----- .../BaseAvatar - OptiTrack ver 2.prefab | 3 - .../Prefabs/BaseAvatar - OptiTrack.prefab | 3 - .../BaseAvatar - OptiTrack.prefab.meta | 7 - .../OptiTrack/Prefabs/Horse_TM.fbx | 3 - .../OptiTrack/Prefabs/Horse_TM.fbx.meta | 107 --- .../Retargeted Skeleton - OptiTrack.prefab | 3 - ...etargeted Skeleton - OptiTrack.prefab.meta | 7 - .../Scripts/OptitrackRestPoseData.cs | 48 + .../Scripts/OptitrackRestPoseData.cs.meta | 2 + .../OptitrackSkeletonAnimator_Mingle.cs | 353 +++++--- .../Scripts/OptitrackStreamingClient.cs | 286 +++--- .../External/OptiTrack Unity Plugin/README.md | 3 + .../Y Bot.prefab.meta => README.md.meta} | 4 +- .../CustomRetargetingScript.cs | 5 +- Assets/Scripts/KindRetargeting/README.md | 3 + .../KindRetargeting/README.md.meta} | 4 +- .../Remote/RetargetingRemoteController.cs | 14 +- 41 files changed, 1258 insertions(+), 1890 deletions(-) create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset rename Assets/External/OptiTrack Unity Plugin/OptiTrack/{BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset.meta => BaseAvatar 5bone/OptitrackRestPose.asset.meta} (64%) delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab delete mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab.meta create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs.meta create mode 100644 Assets/External/OptiTrack Unity Plugin/README.md rename Assets/External/OptiTrack Unity Plugin/{OptiTrack/BaseAvatar/Y Bot.prefab.meta => README.md.meta} (62%) create mode 100644 Assets/Scripts/KindRetargeting/README.md rename Assets/{External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab.meta => Scripts/KindRetargeting/README.md.meta} (62%) diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.fbx.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.fbx.meta index 1a1994bba..d2bfc7806 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.fbx.meta +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.fbx.meta @@ -86,19 +86,354 @@ ModelImporter: skeleton: - name: BaseAvatar - OptiTrack 5 bone(Clone) parentName: - position: {x: 0, y: 0, z: 0} - rotation: {x: 0, y: 0, z: 0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_Root - parentName: BaseAvatar - OptiTrack 5 bone(Clone) position: {x: -0, y: 0, z: 0} rotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071067} scale: {x: 1, y: 1, z: 1} - name: 001_Hips - parentName: 001_Root + parentName: BaseAvatar - OptiTrack 5 bone(Clone) position: {x: -0, y: -0.00000014102463, z: 0.865603} rotation: {x: 0.7071068, y: 0, z: -0, w: 0.7071067} scale: {x: 1, y: 1, z: 1} + - name: 001_Spine + parentName: 001_Hips + position: {x: -0, y: 0.03325814, z: 0} + rotation: {x: 0.0888559, y: 0, z: -0, w: 0.9960445} + scale: {x: 1, y: 0.99999994, z: 0.99999994} + - name: 001_Spine1 + parentName: 001_Spine + position: {x: -0, y: 0.059864596, z: 0} + rotation: {x: 0.0035778934, y: 0, z: -0, w: 0.9999936} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_Spine2 + parentName: 001_Spine1 + position: {x: -0, y: 0.066516146, z: 0.000000011175871} + rotation: {x: -0.09237056, y: 0, z: -0, w: 0.9957247} + scale: {x: 1, y: 1, z: 1} + - name: 001_Spine3 + parentName: 001_Spine2 + position: {x: -0, y: 0.07815656, z: 7.712515e-10} + rotation: {x: -0.049721405, y: 0, z: -0, w: 0.99876314} + scale: {x: 0.99999994, y: 0.99999994, z: 1} + - name: 001_Spine4 + parentName: 001_Spine3 + position: {x: -0, y: 0.17460515, z: -0.0000000069849193} + rotation: {x: -0.024432134, y: 0, z: -0, w: 0.9997015} + scale: {x: 1, y: 1, z: 0.9999999} + - name: 001_Neck + parentName: 001_Spine4 + position: {x: -0, y: 0.10975203, z: 0.010808894} + rotation: {x: 0.13785088, y: 0, z: -0, w: 0.990453} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + - name: 001_Neck1 + parentName: 001_Neck + position: {x: -0, y: 0.0740802, z: -9.313226e-10} + rotation: {x: 0.000000052154068, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_Head + parentName: 001_Neck1 + position: {x: -0, y: 0.07597939, z: -0.000000016763806} + rotation: {x: -0.10018798, y: 0, z: -0, w: 0.99496853} + scale: {x: 1, y: 1, z: 0.99999994} + - name: 001_HeadEnd + parentName: 001_Head + position: {x: -0, y: 0.22000016, z: -0.000000004656613} + rotation: {x: -0.000000018626451, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_HeadEnd_end + parentName: 001_HeadEnd + position: {x: -0, y: 0.22000012, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftShoulder + parentName: 001_Spine4 + position: {x: -0.0358696, y: 0.045248758, z: -0.0049734665} + rotation: {x: -0.00000016391277, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftArm + parentName: 001_LeftShoulder + position: {x: -0.134977, y: 0.000000013154931, z: 0.000000019557774} + rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} + scale: {x: 0.99999994, y: 1, z: 1} + - name: 001_LeftForeArm + parentName: 001_LeftArm + position: {x: -0.273732, y: 0.000000011816155, z: -0.000000006519258} + rotation: {x: 0.0000000037252903, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHand + parentName: 001_LeftForeArm + position: {x: -0.19546905, y: 0.000000011990778, z: -0.000000008381903} + rotation: {x: -0.00000008195639, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandThumb1 + parentName: 001_LeftHand + position: {x: -0.018752277, y: -0.021309385, z: 0.029833077} + rotation: {x: 0.45188782, y: 0.3447067, z: -0.19831167, w: 0.7985282} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandThumb2 + parentName: 001_LeftHandThumb1 + position: {x: -0.02832238, y: 0.000000027939677, z: -0.000000055909595} + rotation: {x: -0.000000834465, y: -0.0000023841858, z: 0.028025687, w: 0.9996072} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_LeftHandThumb3 + parentName: 001_LeftHandThumb2 + position: {x: -0.024207503, y: -0.000000015943257, z: -0.0000000066128223} + rotation: {x: 0.0000014528632, y: 0.00000007765939, z: 9.01501e-14, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LThumb3End + parentName: 001_LeftHandThumb3 + position: {x: -0.026628096, y: -0.0000000408308, z: -0.000000017800573} + rotation: {x: 0.000000014901161, y: 1.4210855e-13, z: -1.4654944e-14, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LThumb3End_end + parentName: 001_LThumb3End + position: {x: -0, y: 0.026628118, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandIndex1 + parentName: 001_LeftHand + position: {x: -0.07671362, y: 0.000000024912879, z: 0.029833097} + rotation: {x: 0.087155744, y: 0, z: -0, w: 0.9961947} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandIndex2 + parentName: 001_LeftHandIndex1 + position: {x: -0.042618692, y: -0.0000000088475645, z: -0.0000000018626451} + rotation: {x: 0.000000058207664, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_LeftHandIndex3 + parentName: 001_LeftHandIndex2 + position: {x: -0.021309257, y: -0.0000000060535967, z: -9.313226e-10} + rotation: {x: -0.000000041443855, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LIndex3End + parentName: 001_LeftHandIndex3 + position: {x: -0.023440301, y: -0.000000007916242, z: -9.313226e-10} + rotation: {x: -4.656613e-10, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LIndex3End_end + parentName: 001_LIndex3End + position: {x: -0, y: 0.023440227, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandMiddle1 + parentName: 001_LeftHand + position: {x: -0.07671362, y: 0.00000009732321, z: 0.009887521} + rotation: {x: 0.000000067055225, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_LeftHandMiddle2 + parentName: 001_LeftHandMiddle1 + position: {x: -0.046880484, y: -0.000000022235326, z: 0.000000010244548} + rotation: {x: -0.000000040978193, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandMiddle3 + parentName: 001_LeftHandMiddle2 + position: {x: -0.025571287, y: 0.00000009633368, z: 0.0000000121071935} + rotation: {x: -0.000000048428774, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LMiddle3End + parentName: 001_LeftHandMiddle3 + position: {x: -0.028128326, y: 0.00000009551877, z: 0.000000014901161} + rotation: {x: 0.0000000037252903, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LMiddle3End_end + parentName: 001_LMiddle3End + position: {x: -0, y: 0.028128315, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandRing1 + parentName: 001_LeftHand + position: {x: -0.07245177, y: -0.00000006821938, z: -0.009887559} + rotation: {x: 0.000000115484, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandRing2 + parentName: 001_LeftHandRing1 + position: {x: -0.04261875, y: 0.000000047963113, z: 0.000000013038516} + rotation: {x: -0.0000000037252903, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandRing3 + parentName: 001_LeftHandRing2 + position: {x: -0.021309197, y: 0.000000047730282, z: 0.000000031664968} + rotation: {x: 0.00000033527613, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LRing3End + parentName: 001_LeftHandRing3 + position: {x: -0.023440242, y: 0.00000015622936, z: 0.000000018626451} + rotation: {x: -0.000000007450581, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LRing3End_end + parentName: 001_LRing3End + position: {x: -0, y: 0.02344036, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandPinky1 + parentName: 001_LeftHand + position: {x: -0.06818998, y: 0.00000012246892, z: -0.0298331} + rotation: {x: -0.08715575, y: 0, z: -0, w: 0.9961947} + scale: {x: 1, y: 1.0000001, z: 0.99999994} + - name: 001_LeftHandPinky2 + parentName: 001_LeftHandPinky1 + position: {x: -0.03409493, y: 0.00000008754432, z: -0.000000044703484} + rotation: {x: 0.0000005662441, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LeftHandPinky3 + parentName: 001_LeftHandPinky2 + position: {x: -0.017047465, y: 0.00000005122274, z: -0.0000000037252903} + rotation: {x: -0.000000692904, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LPinky3End + parentName: 001_LeftHandPinky3 + position: {x: -0.018752158, y: 0.00000009872019, z: -0.000000048428774} + rotation: {x: 0.000000014901161, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_LPinky3End_end + parentName: 001_LPinky3End + position: {x: -0, y: 0.018752106, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightShoulder + parentName: 001_Spine4 + position: {x: 0.0358696, y: 0.045248758, z: -0.0049734665} + rotation: {x: -0.00000016391277, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightArm + parentName: 001_RightShoulder + position: {x: 0.134977, y: 0.000000013154931, z: 0.000000019557774} + rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} + scale: {x: 0.99999994, y: 1, z: 1} + - name: 001_RightForeArm + parentName: 001_RightArm + position: {x: 0.273732, y: 0.000000011816155, z: -0.000000006519258} + rotation: {x: 0.000000007450581, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_RightHand + parentName: 001_RightForeArm + position: {x: 0.19546905, y: 0.00000013131648, z: -0.000000008381903} + rotation: {x: -0.000000078231096, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandThumb1 + parentName: 001_RightHand + position: {x: 0.018752277, y: -0.021309385, z: 0.029833062} + rotation: {x: 0.4518857, y: -0.3447039, z: 0.1983145, w: 0.7985298} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandThumb2 + parentName: 001_RightHandThumb1 + position: {x: 0.028322378, y: -0.000000031664968, z: 0.000000053137} + rotation: {x: -0.0000018179417, y: -0.0000015795231, z: -0.028029457, w: 0.99960715} + scale: {x: 1.0000001, y: 1, z: 1} + - name: 001_RightHandThumb3 + parentName: 001_RightHandThumb2 + position: {x: 0.024207383, y: -0.000000059786174, z: -0.000000082027555} + rotation: {x: 0.0000014454124, y: -0.00000007765938, z: -9.8754345e-14, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: 001_RThumb3End + parentName: 001_RightHandThumb3 + position: {x: 0.026628036, y: -0.000000084079474, z: -0.00000003786181} + rotation: {x: -8.285039e-15, y: -1.2789769e-13, z: 5.162537e-15, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RThumb3End_end + parentName: 001_RThumb3End + position: {x: -0, y: 0.026628118, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandIndex1 + parentName: 001_RightHand + position: {x: 0.07671362, y: -0.00000009406358, z: 0.029833067} + rotation: {x: 0.08715574, y: 0, z: -0, w: 0.9961947} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandIndex2 + parentName: 001_RightHandIndex1 + position: {x: 0.04261881, y: -0.0000000088475645, z: 0.0000000027939677} + rotation: {x: 0.000000058673326, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_RightHandIndex3 + parentName: 001_RightHandIndex2 + position: {x: 0.021309316, y: -0.00000012526289, z: 0.000000004656613} + rotation: {x: -0.000000040512532, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RIndex3End + parentName: 001_RightHandIndex3 + position: {x: 0.023440242, y: -0.00000012712553, z: 0.000000004656613} + rotation: {x: 4.656613e-10, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RIndex3End_end + parentName: 001_RIndex3End + position: {x: -0, y: 0.023440227, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandMiddle1 + parentName: 001_RightHand + position: {x: 0.07671362, y: -0.00000002188608, z: 0.009887507} + rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} + scale: {x: 1, y: 0.99999994, z: 1} + - name: 001_RightHandMiddle2 + parentName: 001_RightHandMiddle1 + position: {x: 0.046880543, y: 0.00000009697396, z: -0.0000000044237822} + rotation: {x: -0.000000052154064, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandMiddle3 + parentName: 001_RightHandMiddle2 + position: {x: 0.025571287, y: -0.00000002287561, z: -0.000000002561137} + rotation: {x: -0.000000052154064, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RMiddle3End + parentName: 001_RightHandMiddle3 + position: {x: 0.028128386, y: -0.000000023690518, z: -0.0000000146683306} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RMiddle3End_end + parentName: 001_RMiddle3End + position: {x: -0, y: 0.028128315, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandRing1 + parentName: 001_RightHand + position: {x: 0.07245177, y: -0.00000018742867, z: -0.009887574} + rotation: {x: 0.00000010803342, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandRing2 + parentName: 001_RightHandRing1 + position: {x: 0.042618692, y: 0.000000047963113, z: -0.0000000018626451} + rotation: {x: -0.000000007450581, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandRing3 + parentName: 001_RightHandRing2 + position: {x: 0.021309316, y: 0.000000047730282, z: 0.0000000018626451} + rotation: {x: 0.00000032782555, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RRing3End + parentName: 001_RightHandRing3 + position: {x: 0.023440242, y: 0.000000037020072, z: -0.000000013038516} + rotation: {x: -0.000000011175871, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RRing3End_end + parentName: 001_RRing3End + position: {x: -0, y: 0.02344036, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandPinky1 + parentName: 001_RightHand + position: {x: 0.06818998, y: 0.0000000027939677, z: -0.029833127} + rotation: {x: -0.08715576, y: 0, z: -0, w: 0.9961947} + scale: {x: 1, y: 1.0000001, z: 0.99999994} + - name: 001_RightHandPinky2 + parentName: 001_RightHandPinky1 + position: {x: 0.03409493, y: -0.000000029802322, z: -0.000000011175871} + rotation: {x: 0.0000005736947, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RightHandPinky3 + parentName: 001_RightHandPinky2 + position: {x: 0.017047405, y: 0.000000053085387, z: -0.000000033527613} + rotation: {x: -0.00000068545336, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + - name: 001_RPinky3End + parentName: 001_RightHandPinky3 + position: {x: 0.018752217, y: -0.000000018626451, z: -0.000000022351742} + rotation: {x: 0.000000014901161, y: 0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} + - name: 001_RPinky3End_end + parentName: 001_RPinky3End + position: {x: -0, y: 0.018752106, z: 0} + rotation: {x: 0, y: -0, z: -0, w: 1} + scale: {x: 1, y: 1, z: 1} - name: 001_LeftUpLeg parentName: 001_Hips position: {x: -0.0897235, y: 3.3639758e-14, z: 0} @@ -159,346 +494,6 @@ ModelImporter: position: {x: -0, y: 0.043999996, z: 0} rotation: {x: 0, y: -0, z: -0, w: 1} scale: {x: 1, y: 1, z: 1} - - name: 001_Spine - parentName: 001_Hips - position: {x: -0, y: 0.03325814, z: 0} - rotation: {x: 0.0888559, y: 0, z: -0, w: 0.9960445} - scale: {x: 1, y: 0.99999994, z: 0.99999994} - - name: 001_Spine1 - parentName: 001_Spine - position: {x: -0, y: 0.059864596, z: 0} - rotation: {x: 0.0035778934, y: 0, z: -0, w: 0.9999936} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_Spine2 - parentName: 001_Spine1 - position: {x: -0, y: 0.066516146, z: 0.000000011175871} - rotation: {x: -0.09237056, y: 0, z: -0, w: 0.9957247} - scale: {x: 1, y: 1, z: 1} - - name: 001_Spine3 - parentName: 001_Spine2 - position: {x: -0, y: 0.07815656, z: 7.712515e-10} - rotation: {x: -0.049721405, y: 0, z: -0, w: 0.99876314} - scale: {x: 0.99999994, y: 0.99999994, z: 1} - - name: 001_Spine4 - parentName: 001_Spine3 - position: {x: -0, y: 0.17460515, z: -0.0000000069849193} - rotation: {x: -0.024432134, y: 0, z: -0, w: 0.9997015} - scale: {x: 1, y: 1, z: 0.9999999} - - name: 001_LeftShoulder - parentName: 001_Spine4 - position: {x: -0.0358696, y: 0.045248758, z: -0.0049734665} - rotation: {x: -0.00000016391277, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftArm - parentName: 001_LeftShoulder - position: {x: -0.134977, y: 0.000000013154931, z: 0.000000019557774} - rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} - scale: {x: 0.99999994, y: 1, z: 1} - - name: 001_LeftForeArm - parentName: 001_LeftArm - position: {x: -0.273732, y: 0.000000011816155, z: -0.000000006519258} - rotation: {x: 0.0000000037252903, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHand - parentName: 001_LeftForeArm - position: {x: -0.19546905, y: 0.000000011990778, z: -0.000000008381903} - rotation: {x: -0.00000008195639, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandIndex1 - parentName: 001_LeftHand - position: {x: -0.07671362, y: 0.000000024912879, z: 0.029833097} - rotation: {x: 0.087155744, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandIndex2 - parentName: 001_LeftHandIndex1 - position: {x: -0.042618692, y: -0.0000000088475645, z: -0.0000000018626451} - rotation: {x: 0.000000058207664, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_LeftHandIndex3 - parentName: 001_LeftHandIndex2 - position: {x: -0.021309257, y: -0.0000000060535967, z: -9.313226e-10} - rotation: {x: -0.000000041443855, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LIndex3End - parentName: 001_LeftHandIndex3 - position: {x: -0.023440301, y: -0.000000007916242, z: -9.313226e-10} - rotation: {x: -4.656613e-10, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LIndex3End_end - parentName: 001_LIndex3End - position: {x: -0, y: 0.023440227, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandMiddle1 - parentName: 001_LeftHand - position: {x: -0.07671362, y: 0.00000009732321, z: 0.009887521} - rotation: {x: 0.000000067055225, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_LeftHandMiddle2 - parentName: 001_LeftHandMiddle1 - position: {x: -0.046880484, y: -0.000000022235326, z: 0.000000010244548} - rotation: {x: -0.000000040978193, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandMiddle3 - parentName: 001_LeftHandMiddle2 - position: {x: -0.025571287, y: 0.00000009633368, z: 0.0000000121071935} - rotation: {x: -0.000000048428774, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LMiddle3End - parentName: 001_LeftHandMiddle3 - position: {x: -0.028128326, y: 0.00000009551877, z: 0.000000014901161} - rotation: {x: 0.0000000037252903, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LMiddle3End_end - parentName: 001_LMiddle3End - position: {x: -0, y: 0.028128315, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandPinky1 - parentName: 001_LeftHand - position: {x: -0.06818998, y: 0.00000012246892, z: -0.0298331} - rotation: {x: -0.08715575, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1.0000001, z: 0.99999994} - - name: 001_LeftHandPinky2 - parentName: 001_LeftHandPinky1 - position: {x: -0.03409493, y: 0.00000008754432, z: -0.000000044703484} - rotation: {x: 0.0000005662441, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandPinky3 - parentName: 001_LeftHandPinky2 - position: {x: -0.017047465, y: 0.00000005122274, z: -0.0000000037252903} - rotation: {x: -0.000000692904, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LPinky3End - parentName: 001_LeftHandPinky3 - position: {x: -0.018752158, y: 0.00000009872019, z: -0.000000048428774} - rotation: {x: 0.000000014901161, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LPinky3End_end - parentName: 001_LPinky3End - position: {x: -0, y: 0.018752106, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandRing1 - parentName: 001_LeftHand - position: {x: -0.07245177, y: -0.00000006821938, z: -0.009887559} - rotation: {x: 0.000000115484, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandRing2 - parentName: 001_LeftHandRing1 - position: {x: -0.04261875, y: 0.000000047963113, z: 0.000000013038516} - rotation: {x: -0.0000000037252903, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandRing3 - parentName: 001_LeftHandRing2 - position: {x: -0.021309197, y: 0.000000047730282, z: 0.000000031664968} - rotation: {x: 0.00000033527613, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LRing3End - parentName: 001_LeftHandRing3 - position: {x: -0.023440242, y: 0.00000015622936, z: 0.000000018626451} - rotation: {x: -0.000000007450581, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LRing3End_end - parentName: 001_LRing3End - position: {x: -0, y: 0.02344036, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandThumb1 - parentName: 001_LeftHand - position: {x: -0.018752277, y: -0.021309385, z: 0.029833077} - rotation: {x: 0.4072523, y: 0.34298575, z: 0.23624216, w: 0.81283206} - scale: {x: 1, y: 1, z: 1} - - name: 001_LeftHandThumb2 - parentName: 001_LeftHandThumb1 - position: {x: -0.02832238, y: 0.000000027939677, z: -0.000000055909595} - rotation: {x: 0, y: 0, z: 0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_LeftHandThumb3 - parentName: 001_LeftHandThumb2 - position: {x: -0.024207503, y: -0.000000015943257, z: -0.0000000066128223} - rotation: {x: 0.0000014528632, y: 0.00000007765939, z: 9.01501e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LThumb3End - parentName: 001_LeftHandThumb3 - position: {x: -0.026628096, y: -0.0000000408308, z: -0.000000017800573} - rotation: {x: 0.000000014901161, y: 1.4210855e-13, z: -1.4654944e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_LThumb3End_end - parentName: 001_LThumb3End - position: {x: -0, y: 0.026628118, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_Neck - parentName: 001_Spine4 - position: {x: -0, y: 0.10975203, z: 0.010808894} - rotation: {x: 0.13785088, y: 0, z: -0, w: 0.990453} - scale: {x: 1, y: 0.9999999, z: 0.9999999} - - name: 001_Neck1 - parentName: 001_Neck - position: {x: -0, y: 0.0740802, z: -9.313226e-10} - rotation: {x: 0.000000052154068, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_Head - parentName: 001_Neck1 - position: {x: -0, y: 0.07597939, z: -0.000000016763806} - rotation: {x: -0.10018798, y: 0, z: -0, w: 0.99496853} - scale: {x: 1, y: 1, z: 0.99999994} - - name: 001_HeadEnd - parentName: 001_Head - position: {x: -0, y: 0.22000016, z: -0.000000004656613} - rotation: {x: -0.000000018626451, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_HeadEnd_end - parentName: 001_HeadEnd - position: {x: -0, y: 0.22000012, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightShoulder - parentName: 001_Spine4 - position: {x: 0.0358696, y: 0.045248758, z: -0.0049734665} - rotation: {x: -0.00000016391277, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightArm - parentName: 001_RightShoulder - position: {x: 0.134977, y: 0.000000013154931, z: 0.000000019557774} - rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} - scale: {x: 0.99999994, y: 1, z: 1} - - name: 001_RightForeArm - parentName: 001_RightArm - position: {x: 0.273732, y: 0.000000011816155, z: -0.000000006519258} - rotation: {x: 0.000000007450581, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_RightHand - parentName: 001_RightForeArm - position: {x: 0.19546905, y: 0.00000013131648, z: -0.000000008381903} - rotation: {x: -0.000000078231096, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandIndex1 - parentName: 001_RightHand - position: {x: 0.07671362, y: -0.00000009406358, z: 0.029833067} - rotation: {x: 0.08715574, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandIndex2 - parentName: 001_RightHandIndex1 - position: {x: 0.04261881, y: -0.0000000088475645, z: 0.0000000027939677} - rotation: {x: 0.000000058673326, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_RightHandIndex3 - parentName: 001_RightHandIndex2 - position: {x: 0.021309316, y: -0.00000012526289, z: 0.000000004656613} - rotation: {x: -0.000000040512532, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RIndex3End - parentName: 001_RightHandIndex3 - position: {x: 0.023440242, y: -0.00000012712553, z: 0.000000004656613} - rotation: {x: 4.656613e-10, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RIndex3End_end - parentName: 001_RIndex3End - position: {x: -0, y: 0.023440227, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandMiddle1 - parentName: 001_RightHand - position: {x: 0.07671362, y: -0.00000002188608, z: 0.009887507} - rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} - scale: {x: 1, y: 0.99999994, z: 1} - - name: 001_RightHandMiddle2 - parentName: 001_RightHandMiddle1 - position: {x: 0.046880543, y: 0.00000009697396, z: -0.0000000044237822} - rotation: {x: -0.000000052154064, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandMiddle3 - parentName: 001_RightHandMiddle2 - position: {x: 0.025571287, y: -0.00000002287561, z: -0.000000002561137} - rotation: {x: -0.000000052154064, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RMiddle3End - parentName: 001_RightHandMiddle3 - position: {x: 0.028128386, y: -0.000000023690518, z: -0.0000000146683306} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RMiddle3End_end - parentName: 001_RMiddle3End - position: {x: -0, y: 0.028128315, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandPinky1 - parentName: 001_RightHand - position: {x: 0.06818998, y: 0.0000000027939677, z: -0.029833127} - rotation: {x: -0.08715576, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1.0000001, z: 0.99999994} - - name: 001_RightHandPinky2 - parentName: 001_RightHandPinky1 - position: {x: 0.03409493, y: -0.000000029802322, z: -0.000000011175871} - rotation: {x: 0.0000005736947, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandPinky3 - parentName: 001_RightHandPinky2 - position: {x: 0.017047405, y: 0.000000053085387, z: -0.000000033527613} - rotation: {x: -0.00000068545336, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1.0000001, z: 1.0000001} - - name: 001_RPinky3End - parentName: 001_RightHandPinky3 - position: {x: 0.018752217, y: -0.000000018626451, z: -0.000000022351742} - rotation: {x: 0.000000014901161, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RPinky3End_end - parentName: 001_RPinky3End - position: {x: -0, y: 0.018752106, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandRing1 - parentName: 001_RightHand - position: {x: 0.07245177, y: -0.00000018742867, z: -0.009887574} - rotation: {x: 0.00000010803342, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandRing2 - parentName: 001_RightHandRing1 - position: {x: 0.042618692, y: 0.000000047963113, z: -0.0000000018626451} - rotation: {x: -0.000000007450581, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandRing3 - parentName: 001_RightHandRing2 - position: {x: 0.021309316, y: 0.000000047730282, z: 0.0000000018626451} - rotation: {x: 0.00000032782555, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RRing3End - parentName: 001_RightHandRing3 - position: {x: 0.023440242, y: 0.000000037020072, z: -0.000000013038516} - rotation: {x: -0.000000011175871, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RRing3End_end - parentName: 001_RRing3End - position: {x: -0, y: 0.02344036, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandThumb1 - parentName: 001_RightHand - position: {x: 0.018752277, y: -0.021309385, z: 0.029833062} - rotation: {x: 0.4072523, y: -0.34298575, z: -0.23624216, w: 0.81283206} - scale: {x: 1, y: 1, z: 1} - - name: 001_RightHandThumb2 - parentName: 001_RightHandThumb1 - position: {x: 0.028322378, y: -0.000000031664968, z: 0.000000053137} - rotation: {x: 0, y: 0, z: 0, w: 1} - scale: {x: 1.0000001, y: 1, z: 1} - - name: 001_RightHandThumb3 - parentName: 001_RightHandThumb2 - position: {x: 0.024207383, y: -0.000000059786174, z: -0.000000082027555} - rotation: {x: 0.0000014454124, y: -0.00000007765938, z: -9.8754345e-14, w: 1} - scale: {x: 1, y: 1.0000001, z: 1.0000001} - - name: 001_RThumb3End - parentName: 001_RightHandThumb3 - position: {x: 0.026628036, y: -0.000000084079474, z: -0.00000003786181} - rotation: {x: -8.285039e-15, y: -1.2789769e-13, z: 5.162537e-15, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: 001_RThumb3End_end - parentName: 001_RThumb3End - position: {x: -0, y: 0.026628118, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} armTwist: 0.5 foreArmTwist: 0.5 upperLegTwist: 0.5 @@ -509,7 +504,7 @@ ModelImporter: globalScale: 1 rootMotionBoneName: hasTranslationDoF: 0 - hasExtraRoot: 1 + hasExtraRoot: 0 skeletonHasParents: 1 lastHumanDescriptionAvatarSource: {instanceID: 0} autoGenerateAvatarMappingIfUnspecified: 1 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.prefab index 33f27aa2b..c11a77082 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.prefab +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/BaseAvatar - OptiTrack 5 bone.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a963eb7286e4684c83f0319792bf23bd4aff2a40ac2c20bac8e652d48d10a67 -size 114732 +oid sha256:f9f72404d4a8e80ae82777cad20b119ac1e0bce3b4ee9e986486dc425d05f0b8 +size 105286 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset new file mode 100644 index 000000000..fecfd7148 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c07041233ca8df50e8152714c53027f5cb578be01c769c2f282641dd16e0a288 +size 17540 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset.meta similarity index 64% rename from Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset.meta rename to Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset.meta index a479bc753..056cc18f7 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset.meta +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar 5bone/OptitrackRestPose.asset.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: 3d3b7ae32885a034c88552023d1db036 +guid: 75f2e1a5c10097440b114e4fffcfb1a2 NativeFormatImporter: externalObjects: {} - mainObjectFileID: 2100000 + mainObjectFileID: 11400000 userData: assetBundleName: assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2.meta deleted file mode 100644 index c4f777846..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4c6874ed36813b048bb2f591a8659061 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx deleted file mode 100644 index f69f2a50f..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1cc8415e20be2176deafc33ceb9e1380d53e932b97cb5f58765142c6c3482ebc -size 59152 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx.meta deleted file mode 100644 index 73678b36e..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar ver 2/BaseAvatar - OptiTrack ver 2.fbx.meta +++ /dev/null @@ -1,843 +0,0 @@ -fileFormatVersion: 2 -guid: 67637b4ba7aa0214da607e0169e11290 -ModelImporter: - serializedVersion: 24200 - internalIDToNameTable: [] - externalObjects: {} - materials: - materialImportMode: 2 - materialName: 0 - materialSearch: 1 - materialLocation: 1 - animations: - legacyGenerateAnimations: 4 - bakeSimulation: 0 - resampleCurves: 1 - optimizeGameObjects: 0 - removeConstantScaleCurves: 0 - motionNodeName: - animationImportErrors: - animationImportWarnings: - animationRetargetingWarnings: - animationDoRetargetingWarnings: 0 - importAnimatedCustomProperties: 0 - importConstraints: 0 - animationCompression: 3 - animationRotationError: 0.5 - animationPositionError: 0.5 - animationScaleError: 0.5 - animationWrapMode: 0 - extraExposedTransformPaths: [] - extraUserProperties: [] - clipAnimations: [] - isReadable: 0 - meshes: - lODScreenPercentages: [] - globalScale: 1 - meshCompression: 0 - addColliders: 0 - useSRGBMaterialColor: 1 - sortHierarchyByName: 1 - importPhysicalCameras: 1 - importVisibility: 1 - importBlendShapes: 1 - importCameras: 1 - importLights: 1 - nodeNameCollisionStrategy: 1 - fileIdsGeneration: 2 - swapUVChannels: 0 - generateSecondaryUV: 0 - useFileUnits: 1 - keepQuads: 0 - weldVertices: 1 - bakeAxisConversion: 0 - preserveHierarchy: 0 - skinWeightsMode: 0 - maxBonesPerVertex: 4 - minBoneWeight: 0.001 - optimizeBones: 1 - generateMeshLods: 0 - meshLodGenerationFlags: 0 - maximumMeshLod: -1 - meshOptimizationFlags: -1 - indexFormat: 0 - secondaryUVAngleDistortion: 8 - secondaryUVAreaDistortion: 15.000001 - secondaryUVHardAngle: 88 - secondaryUVMarginMethod: 1 - secondaryUVMinLightmapResolution: 40 - secondaryUVMinObjectScale: 1 - secondaryUVPackMargin: 4 - useFileScale: 1 - strictVertexDataChecks: 0 - tangentSpace: - normalSmoothAngle: 60 - normalImportMode: 0 - tangentImportMode: 3 - normalCalculationMode: 4 - legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 - blendShapeNormalImportMode: 1 - normalSmoothingSource: 0 - referencedClips: [] - importAnimation: 1 - humanDescription: - serializedVersion: 3 - human: - - boneName: Hips - humanName: Hips - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftUpLeg - humanName: LeftUpperLeg - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightUpLeg - humanName: RightUpperLeg - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftLeg - humanName: LeftLowerLeg - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightLeg - humanName: RightLowerLeg - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftFoot - humanName: LeftFoot - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightFoot - humanName: RightFoot - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: Spine - humanName: Spine - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: Spine1 - humanName: Chest - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: Neck - humanName: Neck - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: Head - humanName: Head - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftShoulder - humanName: LeftShoulder - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightShoulder - humanName: RightShoulder - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftArm - humanName: LeftUpperArm - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightArm - humanName: RightUpperArm - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftForeArm - humanName: LeftLowerArm - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightForeArm - humanName: RightLowerArm - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHand - humanName: LeftHand - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHand - humanName: RightHand - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftToeBase - humanName: LeftToes - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightToeBase - humanName: RightToes - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandThumb1 - humanName: Left Thumb Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandThumb2 - humanName: Left Thumb Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandThumb3 - humanName: Left Thumb Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandIndex1 - humanName: Left Index Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandIndex2 - humanName: Left Index Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandIndex3 - humanName: Left Index Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandMiddle1 - humanName: Left Middle Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandMiddle2 - humanName: Left Middle Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandMiddle3 - humanName: Left Middle Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandRing1 - humanName: Left Ring Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandRing2 - humanName: Left Ring Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandRing3 - humanName: Left Ring Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandPinky1 - humanName: Left Little Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandPinky2 - humanName: Left Little Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: LeftHandPinky3 - humanName: Left Little Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandThumb1 - humanName: Right Thumb Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandThumb2 - humanName: Right Thumb Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandThumb3 - humanName: Right Thumb Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandIndex1 - humanName: Right Index Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandIndex2 - humanName: Right Index Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandIndex3 - humanName: Right Index Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandMiddle1 - humanName: Right Middle Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandMiddle2 - humanName: Right Middle Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandMiddle3 - humanName: Right Middle Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandRing1 - humanName: Right Ring Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandRing2 - humanName: Right Ring Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandRing3 - humanName: Right Ring Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandPinky1 - humanName: Right Little Proximal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandPinky2 - humanName: Right Little Intermediate - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - - boneName: RightHandPinky3 - humanName: Right Little Distal - limit: - min: {x: 0, y: 0, z: 0} - max: {x: 0, y: 0, z: 0} - value: {x: 0, y: 0, z: 0} - length: 0 - modified: 0 - skeleton: - - name: BaseAvatar - OptiTrack ver 2(Clone) - parentName: - position: {x: -0, y: 0, z: 0} - rotation: {x: 0.000000021855694, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: Hips - parentName: BaseAvatar - OptiTrack ver 2(Clone) - position: {x: -0, y: 0.75835896, z: 0} - rotation: {x: 0.000000059604645, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftUpLeg - parentName: Hips - position: {x: -0.091811396, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftLeg - parentName: LeftUpLeg - position: {x: -0, y: -0.29867896, z: -9.094947e-15} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftFoot - parentName: LeftLeg - position: {x: -0, y: -0.386231, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftToeBase - parentName: LeftFoot - position: {x: -0, y: -0.0596774, z: 0.137717} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LToeEnd - parentName: LeftToeBase - position: {x: -0, y: 0, z: 0.036724567} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightUpLeg - parentName: Hips - position: {x: 0.091811396, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightLeg - parentName: RightUpLeg - position: {x: -0, y: -0.29867896, z: -9.094947e-15} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightFoot - parentName: RightLeg - position: {x: -0, y: -0.386231, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightToeBase - parentName: RightFoot - position: {x: -0, y: -0.0596774, z: 0.137717} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RToeEnd - parentName: RightToeBase - position: {x: -0, y: 0, z: 0.036724567} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: Spine - parentName: Hips - position: {x: -0, y: 0.07528534, z: -9.094947e-15} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: Spine1 - parentName: Spine - position: {x: -0, y: 0.25163397, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftShoulder - parentName: Spine1 - position: {x: -0.036669, y: 0.21769409, z: -0.00494359} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftArm - parentName: LeftShoulder - position: {x: -0.07529169, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftForeArm - parentName: LeftArm - position: {x: -0.30853298, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHand - parentName: LeftForeArm - position: {x: -0.22326599, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandIndex1 - parentName: LeftHand - position: {x: -0.078498684, y: 0, z: 0.030527297} - rotation: {x: 0.087155685, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandIndex2 - parentName: LeftHandIndex1 - position: {x: -0.043610383, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandIndex3 - parentName: LeftHandIndex2 - position: {x: -0.021805191, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LIndex3End - parentName: LeftHandIndex3 - position: {x: -0.020019684, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandMiddle1 - parentName: LeftHand - position: {x: -0.078498684, y: 0, z: 0.0101176} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandMiddle2 - parentName: LeftHandMiddle1 - position: {x: -0.047971494, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandMiddle3 - parentName: LeftHandMiddle2 - position: {x: -0.026166229, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LMiddle3End - parentName: LeftHandMiddle3 - position: {x: -0.024023589, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandPinky1 - parentName: LeftHand - position: {x: -0.069776684, y: 0, z: -0.030527297} - rotation: {x: -0.087155685, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandPinky2 - parentName: LeftHandPinky1 - position: {x: -0.034888305, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandPinky3 - parentName: LeftHandPinky2 - position: {x: -0.017444229, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LPinky3End - parentName: LeftHandPinky3 - position: {x: -0.016015777, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandRing1 - parentName: LeftHand - position: {x: -0.07413765, y: 0, z: -0.0101176} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandRing2 - parentName: LeftHandRing1 - position: {x: -0.043610383, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandRing3 - parentName: LeftHandRing2 - position: {x: -0.021805191, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LRing3End - parentName: LeftHandRing3 - position: {x: -0.020019684, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandThumb1 - parentName: LeftHand - position: {x: -0.019188613, y: -0.021805115, z: 0.030527297} - rotation: {x: 0.4072523, y: 0.34298575, z: 0.23624216, w: 0.81283206} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandThumb2 - parentName: LeftHandThumb1 - position: {x: -0.028981552, y: 0, z: -0.000000076293944} - rotation: {x: -0.000000029802326, y: -0.000001192093, z: 0.028031828, w: 0.999607} - scale: {x: 1, y: 1, z: 1} - - name: LeftHandThumb3 - parentName: LeftHandThumb2 - position: {x: -0.02477066, y: 0, z: 0} - rotation: {x: 0.000000014901161, y: 2.842171e-14, z: -1.4210855e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: LThumb3End - parentName: LeftHandThumb3 - position: {x: -0.022742309, y: 0, z: 0} - rotation: {x: 0.000000014901161, y: 2.842171e-14, z: -1.4210855e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: Neck - parentName: Spine1 - position: {x: -0, y: 0.26999587, z: 9.094947e-15} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: Head - parentName: Neck - position: {x: -0, y: 0.14230804, z: 0.018362299} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: HeadEnd - parentName: Head - position: {x: -0, y: 0.18362273, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightShoulder - parentName: Spine1 - position: {x: 0.036669, y: 0.21769409, z: -0.00494359} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightArm - parentName: RightShoulder - position: {x: 0.07529169, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightForeArm - parentName: RightArm - position: {x: 0.30853298, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHand - parentName: RightForeArm - position: {x: 0.22326599, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandIndex1 - parentName: RightHand - position: {x: 0.078498684, y: 0, z: 0.030527297} - rotation: {x: 0.087155685, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: RightHandIndex2 - parentName: RightHandIndex1 - position: {x: 0.043610383, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandIndex3 - parentName: RightHandIndex2 - position: {x: 0.021805191, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RIndex3End - parentName: RightHandIndex3 - position: {x: 0.020019684, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandMiddle1 - parentName: RightHand - position: {x: 0.078498684, y: 0, z: 0.0101176} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandMiddle2 - parentName: RightHandMiddle1 - position: {x: 0.047971494, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandMiddle3 - parentName: RightHandMiddle2 - position: {x: 0.026166229, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RMiddle3End - parentName: RightHandMiddle3 - position: {x: 0.024023589, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandPinky1 - parentName: RightHand - position: {x: 0.069776684, y: 0, z: -0.030527297} - rotation: {x: -0.087155685, y: 0, z: -0, w: 0.9961947} - scale: {x: 1, y: 1, z: 1} - - name: RightHandPinky2 - parentName: RightHandPinky1 - position: {x: 0.034888305, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandPinky3 - parentName: RightHandPinky2 - position: {x: 0.017444229, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RPinky3End - parentName: RightHandPinky3 - position: {x: 0.016015777, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandRing1 - parentName: RightHand - position: {x: 0.07413765, y: 0, z: -0.0101176} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandRing2 - parentName: RightHandRing1 - position: {x: 0.043610383, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandRing3 - parentName: RightHandRing2 - position: {x: 0.021805191, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RRing3End - parentName: RightHandRing3 - position: {x: 0.020019684, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RightHandThumb1 - parentName: RightHand - position: {x: 0.019188613, y: -0.021805115, z: 0.030527297} - rotation: {x: 0.4072523, y: -0.34298575, z: -0.23624216, w: 0.81283206} - scale: {x: 1, y: 1, z: 1} - - name: RightHandThumb2 - parentName: RightHandThumb1 - position: {x: 0.028981552, y: 0, z: -0.000000076293944} - rotation: {x: -0.000000029802326, y: 0.000001192093, z: -0.028031828, w: 0.999607} - scale: {x: 1, y: 1, z: 1} - - name: RightHandThumb3 - parentName: RightHandThumb2 - position: {x: 0.02477066, y: 0, z: 0} - rotation: {x: 0.000000014901161, y: -2.842171e-14, z: 1.4210855e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: RThumb3End - parentName: RightHandThumb3 - position: {x: 0.022742309, y: 0, z: 0} - rotation: {x: 0.000000014901161, y: -2.842171e-14, z: 1.4210855e-14, w: 1} - scale: {x: 1, y: 1, z: 1} - armTwist: 0.5 - foreArmTwist: 0.5 - upperLegTwist: 0.5 - legTwist: 0.5 - armStretch: 0.05 - legStretch: 0.05 - feetSpacing: 0 - globalScale: 1 - rootMotionBoneName: - hasTranslationDoF: 0 - hasExtraRoot: 0 - skeletonHasParents: 1 - lastHumanDescriptionAvatarSource: {instanceID: 0} - autoGenerateAvatarMappingIfUnspecified: 1 - animationType: 3 - humanoidOversampling: 1 - avatarSetup: 1 - addHumanoidExtraRootOnlyWhenUsingAvatar: 1 - importBlendShapeDeformPercent: 1 - remapMaterialsIfMaterialImportModeIsNone: 0 - additionalBone: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar.meta deleted file mode 100644 index 3ebc1e00f..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 01e904bb240e86040803984638031e2b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar.meta deleted file mode 100644 index d77956fdc..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c2a29c299fbfb684fad514a825e18e98 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset deleted file mode 100644 index e06af3342..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:525f9fc56e32f66b60e96bd8b68fb64d318c1dc1550c053c593c3eb7327c488c -size 97149 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset.meta deleted file mode 100644 index b753e4394..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Avatar/VrmAvatar.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: acd2877d503a16e409e366297fbcea8b -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 9000000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials.meta deleted file mode 100644 index 67459b347..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 1a08ef839c7d43549985f6cb6a0267a5 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset deleted file mode 100644 index 2458cca42..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Body_MAT.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:651885b63ff3edbdb7a37c3d5800a432c8f908e5b5f65d3be5dad285e721a5e4 -size 45119 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset deleted file mode 100644 index c4b8ced3a..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8f90cf5cdf0f57311959a425b5e2c96d528a3ee922451b630b44709658a1df1 -size 45121 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset.meta deleted file mode 100644 index 54e201867..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Materials/Alpha_Joints_MAT.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 17378a42694cecf4d830641783cb0c69 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 2100000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes.meta deleted file mode 100644 index 4fe899a5c..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 19d0e42a2077486408ca1a3aa2188b02 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset deleted file mode 100644 index 7246590c0..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac59760e5d645e5c0bb4189c12df5e2bd1facfe235153f18c1382c4682d4a092 -size 2915190 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset.meta deleted file mode 100644 index d3dcdb2ad..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Joints.baked.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3fdf147a4927f794c8f15d82ff2403a3 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 4300000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset deleted file mode 100644 index 5e9fb61be..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:39a7eea2e93f929d415eadb41f2a555f996a681c197a0b0cb58ea5793c94da65 -size 5247269 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset.meta deleted file mode 100644 index d4d6092a1..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.Meshes/Alpha_Surface.baked.asset.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 737c3076344703b4fb517641ba144c79 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 4300000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab deleted file mode 100644 index 0db110c1d..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:81f25f621de5bd873b3a7bc5a7d8ee7f7da9ecd19c6e82f6c1c6c31cae5eebb1 -size 95149 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs new file mode 100644 index 000000000..c11d76366 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs @@ -0,0 +1,396 @@ +using UnityEditor; +using UnityEngine; +using System.Collections.Generic; + +public class OptitrackSetupWindow : EditorWindow +{ + private OptitrackSkeletonAnimator_Mingle m_target; + private int m_tab = 0; + private static readonly string[] TabLabels = { "본 매핑", "T-포즈" }; + + private bool m_showMappingFoldout = true; + private Vector2 m_mappingScroll; + private Vector2 m_restPoseScroll; + private Dictionary m_cachedTransformMap; + private OptitrackSkeletonAnimator_Mingle m_cachedTransformTarget; + + // ── 진입점 ──────────────────────────────────────────────────────────────── + + [MenuItem("OptiTrack/Animator 설정 창")] + public static void OpenFromMenu() => GetWindow("OptiTrack 설정").Show(); + + public static void Open(OptitrackSkeletonAnimator_Mingle target) + { + var win = GetWindow("OptiTrack 설정"); + win.m_target = target; + win.Show(); + } + + private void OnSelectionChange() + { + if (Selection.activeGameObject == null) return; + var found = Selection.activeGameObject.GetComponent(); + if (found != null) { m_target = found; InvalidateTransformCache(); Repaint(); } + } + + // ── 창 ──────────────────────────────────────────────────────────────────── + + private void OnGUI() + { + // 대상 선택 + EditorGUI.BeginChangeCheck(); + var newTarget = (OptitrackSkeletonAnimator_Mingle)EditorGUILayout.ObjectField( + "대상", m_target, typeof(OptitrackSkeletonAnimator_Mingle), true); + if (EditorGUI.EndChangeCheck()) { m_target = newTarget; InvalidateTransformCache(); } + + if (m_target == null) + { + EditorGUILayout.HelpBox("대상 컴포넌트를 선택하거나 Inspector에서 창을 여세요.", MessageType.Info); + return; + } + + // SO 없으면 경고 + 생성 버튼 + if (m_target.RestPoseAsset == null) + { + DrawSeparator(); + EditorGUILayout.HelpBox("스켈레톤 설정 에셋이 없습니다. 생성하거나 기존 에셋을 연결하세요.", MessageType.Warning); + + EditorGUI.BeginChangeCheck(); + var linked = (OptitrackRestPoseData)EditorGUILayout.ObjectField( + "Setup Asset", null, typeof(OptitrackRestPoseData), false); + if (EditorGUI.EndChangeCheck() && linked != null) + AssignAsset(linked); + + if (GUILayout.Button("새 설정 에셋 생성", GUILayout.Height(28))) + CreateAndAssignAsset(); + return; + } + + DrawSeparator(); + + // SO 필드 + EditorGUI.BeginChangeCheck(); + var newAsset = (OptitrackRestPoseData)EditorGUILayout.ObjectField( + "Setup Asset", m_target.RestPoseAsset, typeof(OptitrackRestPoseData), false); + if (EditorGUI.EndChangeCheck()) AssignAsset(newAsset); + + DrawSeparator(); + + m_tab = GUILayout.Toolbar(m_tab, TabLabels, GUILayout.Height(26)); + + DrawSeparator(); + + switch (m_tab) + { + case 0: DrawMappingTab(); break; + case 1: DrawRestPoseTab(); break; + } + + if (Application.isPlaying) Repaint(); + } + + // ── 본 매핑 탭 ──────────────────────────────────────────────────────────── + + private void DrawMappingTab() + { + var so = m_target.RestPoseAsset; + + // 자동 생성 버튼 + var prevBg = GUI.backgroundColor; + GUI.backgroundColor = new Color(0.4f, 0.8f, 0.4f); + if (GUILayout.Button("FBX 분석 → 자동 매핑 생성", GUILayout.Height(32))) + { + Undo.RecordObject(so, "Auto Generate Bone Mappings"); + AutoGenerateMappings(so); + EditorUtility.SetDirty(so); + AssetDatabase.SaveAssets(); + } + GUI.backgroundColor = prevBg; + + EditorGUILayout.Space(4); + + if (so.boneMappings == null || so.boneMappings.Count == 0) + { + EditorGUILayout.HelpBox("매핑 없음. 위 버튼으로 자동 생성하세요.", MessageType.None); + } + else + { + int mapped = 0, unmapped = 0; + foreach (var m in so.boneMappings) + { + if (m.isMapped) mapped++; + else unmapped++; + } + EditorGUILayout.HelpBox( + $"매핑: {mapped} 성공 / {unmapped} 실패 (총 {so.boneMappings.Count})", + unmapped > 0 ? MessageType.Warning : MessageType.Info); + + EditorGUILayout.Space(4); + m_showMappingFoldout = EditorGUILayout.Foldout(m_showMappingFoldout, + $"본 매핑 목록 ({so.boneMappings.Count})", true, EditorStyles.foldoutHeader); + + if (m_showMappingFoldout) + { + m_mappingScroll = EditorGUILayout.BeginScrollView(m_mappingScroll, GUILayout.MaxHeight(320)); + DrawMappingList(so); + EditorGUILayout.EndScrollView(); + } + + EditorGUILayout.Space(4); + prevBg = GUI.backgroundColor; + GUI.backgroundColor = new Color(0.85f, 0.35f, 0.35f); + if (GUILayout.Button("매핑 초기화")) + { + Undo.RecordObject(so, "Clear Bone Mappings"); + so.boneMappings.Clear(); + EditorUtility.SetDirty(so); + } + GUI.backgroundColor = prevBg; + } + } + + private void DrawMappingList(OptitrackRestPoseData so) + { + var transformMap = GetTransformMap(); + + for (int i = 0; i < so.boneMappings.Count; i++) + { + var mapping = so.boneMappings[i]; + EditorGUILayout.BeginHorizontal(); + + // 상태 아이콘 + var prevContent = GUI.contentColor; + GUI.contentColor = mapping.isMapped ? Color.green : Color.red; + GUILayout.Label(mapping.isMapped ? "●" : "○", GUILayout.Width(14)); + GUI.contentColor = prevContent; + + GUILayout.Label(mapping.optiTrackBoneName, GUILayout.Width(90)); + GUILayout.Label("→", GUILayout.Width(16)); + + // FBX 노드 이름 편집 + EditorGUI.BeginChangeCheck(); + string newName = EditorGUILayout.TextField(mapping.fbxNodeName); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(so, "Edit Bone Mapping"); + mapping.fbxNodeName = newName; + mapping.isMapped = transformMap.ContainsKey(newName); + EditorUtility.SetDirty(so); + } + + // P / R 토글 + EditorGUI.BeginChangeCheck(); + bool newPos = GUILayout.Toggle(mapping.applyPosition, "P", "Button", GUILayout.Width(24)); + bool newRot = GUILayout.Toggle(mapping.applyRotation, "R", "Button", GUILayout.Width(24)); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(so, "Toggle Bone Apply"); + mapping.applyPosition = newPos; + mapping.applyRotation = newRot; + EditorUtility.SetDirty(so); + } + + EditorGUILayout.EndHorizontal(); + } + } + + // ── T-포즈 탭 ───────────────────────────────────────────────────────────── + + private void DrawRestPoseTab() + { + var so = m_target.RestPoseAsset; + bool hasEntries = so.restPoseEntries.Count > 0; + + if (hasEntries) + EditorGUILayout.HelpBox($"{so.restPoseEntries.Count}개 본 저장됨", MessageType.Info); + else + EditorGUILayout.HelpBox("T-포즈 없음 — 아바타를 T-포즈로 맞추고 캡처하세요.", MessageType.Warning); + + EditorGUILayout.Space(6); + + var prevBg = GUI.backgroundColor; + GUI.backgroundColor = new Color(0.35f, 0.65f, 1f); + if (GUILayout.Button("현재 포즈 → T-포즈로 캡처", GUILayout.Height(32))) + CaptureRestPose(so); + GUI.backgroundColor = prevBg; + + using (new EditorGUI.DisabledScope(!hasEntries)) + { + if (GUILayout.Button("씬에 적용 (미리보기)", GUILayout.Height(26))) + PreviewRestPose(so); + } + + if (hasEntries) + { + DrawSeparator(); + EditorGUILayout.LabelField($"저장된 본 목록 ({so.restPoseEntries.Count})", EditorStyles.boldLabel); + m_restPoseScroll = EditorGUILayout.BeginScrollView(m_restPoseScroll, GUILayout.MaxHeight(260)); + foreach (var e in so.restPoseEntries) + { + EditorGUILayout.BeginHorizontal(); + GUILayout.Label(e.boneName, GUILayout.Width(110)); + GUILayout.Label($"pos {e.localPosition:F3}", EditorStyles.miniLabel); + EditorGUILayout.EndHorizontal(); + } + EditorGUILayout.EndScrollView(); + } + } + + private void CaptureRestPose(OptitrackRestPoseData so) + { + var transformMap = GetTransformMap(); + + Undo.RecordObject(so, "Capture Rest Pose"); + so.restPoseEntries.Clear(); + int count = 0; + foreach (var mapping in so.boneMappings) + { + if (string.IsNullOrEmpty(mapping.fbxNodeName) || mapping.fbxNodeName.Contains("(미발견)")) + continue; + if (!transformMap.TryGetValue(mapping.fbxNodeName, out Transform t)) + continue; + + so.restPoseEntries.Add(new OptitrackRestPoseData.RestPoseEntry + { + boneName = mapping.optiTrackBoneName, + localPosition = t.localPosition, + localRotation = t.localRotation + }); + count++; + } + + EditorUtility.SetDirty(so); + AssetDatabase.SaveAssets(); + Debug.Log($"[OptiTrack] T-포즈 캡처 완료: {count}개 본 → {AssetDatabase.GetAssetPath(so)}"); + } + + private void PreviewRestPose(OptitrackRestPoseData so) + { + var transformMap = GetTransformMap(); + var poseByName = new Dictionary(so.restPoseEntries.Count); + foreach (var e in so.restPoseEntries) + poseByName[e.boneName] = e; + + foreach (var mapping in so.boneMappings) + { + if (!transformMap.TryGetValue(mapping.fbxNodeName, out Transform t)) continue; + if (!poseByName.TryGetValue(mapping.optiTrackBoneName, out var entry)) continue; + Undo.RecordObject(t, "Preview Rest Pose"); + t.localPosition = entry.localPosition; + t.localRotation = entry.localRotation; + } + } + + // ── SO 관리 ─────────────────────────────────────────────────────────────── + + private void AssignAsset(OptitrackRestPoseData asset) + { + Undo.RecordObject(m_target, "Set Skeleton Setup Asset"); + m_target.RestPoseAsset = asset; + EditorUtility.SetDirty(m_target); + } + + private void CreateAndAssignAsset() + { + string path = EditorUtility.SaveFilePanelInProject( + "스켈레톤 설정 에셋 저장", "OptitrackSkeletonSetup", "asset", "저장 위치를 선택하세요."); + if (string.IsNullOrEmpty(path)) return; + + var asset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(asset, path); + AssetDatabase.SaveAssets(); + AssignAsset(asset); + } + + // ── 자동 매핑 생성 ──────────────────────────────────────────────────────── + + private void AutoGenerateMappings(OptitrackRestPoseData so) + { + so.boneMappings.Clear(); + var transformMap = GetTransformMap(); + + string prefix = ""; + foreach (var kvp in transformMap) + { + if (kvp.Key.EndsWith("Hips")) + { + int idx = kvp.Key.LastIndexOf("Hips"); + if (idx > 0) { prefix = kvp.Key.Substring(0, idx); break; } + } + } + if (!string.IsNullOrEmpty(prefix)) + Debug.Log($"[OptiTrack 매핑] 감지된 접두사: \"{prefix}\""); + + int mapped = 0; + foreach (var kvp in OptitrackSkeletonAnimator_Mingle.DefaultOptiToFbxSuffix) + { + var mapping = new OptiTrackBoneMapping + { + optiTrackBoneName = kvp.Key, + applyPosition = true, + applyRotation = true, + isMapped = false + }; + + string fullName = prefix + kvp.Value; + if (transformMap.TryGetValue(fullName, out Transform found)) + { + mapping.fbxNodeName = fullName; + mapping.cachedTransform = found; + mapping.isMapped = true; + } + else if (transformMap.TryGetValue(kvp.Value, out Transform found2)) + { + mapping.fbxNodeName = kvp.Value; + mapping.cachedTransform = found2; + mapping.isMapped = true; + } + else + { + foreach (var t in transformMap) + { + if (t.Key.EndsWith(kvp.Value) || t.Key.EndsWith("_" + kvp.Value)) + { + mapping.fbxNodeName = t.Key; + mapping.cachedTransform = t.Value; + mapping.isMapped = true; + break; + } + } + } + + if (!mapping.isMapped) + mapping.fbxNodeName = prefix + kvp.Value + " (미발견)"; + else + mapped++; + + so.boneMappings.Add(mapping); + } + + Debug.Log($"[OptiTrack 매핑] 완료: {mapped}/{so.boneMappings.Count} 본 매핑 성공"); + } + + // ── 유틸 ────────────────────────────────────────────────────────────────── + + private Dictionary GetTransformMap() + { + if (m_target == null) return new Dictionary(); + if (m_cachedTransformMap != null && m_cachedTransformTarget == m_target) + return m_cachedTransformMap; + m_cachedTransformMap = new Dictionary(); + foreach (var t in m_target.GetComponentsInChildren(true)) + if (!m_cachedTransformMap.ContainsKey(t.name)) + m_cachedTransformMap[t.name] = t; + m_cachedTransformTarget = m_target; + return m_cachedTransformMap; + } + + private void InvalidateTransformCache() => m_cachedTransformMap = null; + + private static void DrawSeparator() + { + EditorGUILayout.Space(5); + EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1f), new Color(0.35f, 0.35f, 0.35f)); + EditorGUILayout.Space(4); + } +} diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs.meta new file mode 100644 index 000000000..d564cc96f --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSetupWindow.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: df7ba0fc2f63e424cb886dc9965c9c9c \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSkeletonAnimatorEditor.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSkeletonAnimatorEditor.cs index d0c80bfdf..6ff4f96a6 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSkeletonAnimatorEditor.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Editor/OptitrackSkeletonAnimatorEditor.cs @@ -1,264 +1,33 @@ using UnityEditor; using UnityEngine; -using System.Collections.Generic; [CustomEditor(typeof(OptitrackSkeletonAnimator_Mingle))] public class OptitrackSkeletonAnimatorEditor : Editor { - private bool showMappingFoldout = true; - private bool showDebugBonesFoldout = false; - public override void OnInspectorGUI() { DrawDefaultInspector(); - OptitrackSkeletonAnimator_Mingle skeletonAnimator = (OptitrackSkeletonAnimator_Mingle)target; + var anim = (OptitrackSkeletonAnimator_Mingle)target; - GUILayout.Space(10); - EditorGUILayout.LabelField("스켈레톤 상태", EditorStyles.boldLabel); - - GUI.backgroundColor = skeletonAnimator.isSkeletonFound ? Color.green : Color.red; + // 연결 상태 배지 + EditorGUILayout.Space(8); + var prevBg = GUI.backgroundColor; + GUI.backgroundColor = anim.isSkeletonFound ? new Color(0.3f, 0.8f, 0.3f) : new Color(0.8f, 0.3f, 0.3f); EditorGUILayout.BeginHorizontal(EditorStyles.helpBox); - GUILayout.Label(skeletonAnimator.isSkeletonFound ? "연결됨" : "연결 안됨", - new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter }); + string status = anim.isSkeletonFound + ? $"연결됨 — {anim.SkeletonAssetName}" + : "연결 안됨 — Motive 스켈레톤 확인 필요"; + GUILayout.Label(status, new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter }); EditorGUILayout.EndHorizontal(); - GUI.backgroundColor = Color.white; + GUI.backgroundColor = prevBg; - if (skeletonAnimator.isSkeletonFound) - { - EditorGUILayout.LabelField($"스켈레톤 이름: {skeletonAnimator.SkeletonAssetName}"); - } - else - { - EditorGUILayout.HelpBox("Motive에서 스켈레톤이 활성화되어 있는지 확인해주세요.", MessageType.Warning); - } + // 설정 창 열기 + EditorGUILayout.Space(6); + if (GUILayout.Button("본 매핑 / T-포즈 설정 창 열기", GUILayout.Height(28))) + OptitrackSetupWindow.Open(anim); - // ── 본 매핑 도구 ── - GUILayout.Space(10); - EditorGUILayout.LabelField("본 매핑 도구", EditorStyles.boldLabel); - - GUI.backgroundColor = new Color(0.4f, 0.8f, 0.4f); - if (GUILayout.Button("FBX 분석 → 자동 매핑 생성", GUILayout.Height(35))) - { - Undo.RecordObject(skeletonAnimator, "Auto Generate Bone Mappings"); - AutoGenerateMappingsEditor(skeletonAnimator); - EditorUtility.SetDirty(skeletonAnimator); - } - GUI.backgroundColor = Color.white; - - // 매핑 상태 요약 - if (skeletonAnimator.boneMappings != null && skeletonAnimator.boneMappings.Count > 0) - { - int mapped = 0; - int unmapped = 0; - foreach (var m in skeletonAnimator.boneMappings) - { - if (m.isMapped) mapped++; - else unmapped++; - } - - EditorGUILayout.Space(5); - EditorGUILayout.HelpBox( - $"매핑 상태: {mapped}개 성공 / {unmapped}개 실패 (총 {skeletonAnimator.boneMappings.Count}개)", - unmapped > 0 ? MessageType.Warning : MessageType.Info); - - // 매핑 리스트 - EditorGUILayout.Space(5); - showMappingFoldout = EditorGUILayout.Foldout(showMappingFoldout, $"본 매핑 목록 ({skeletonAnimator.boneMappings.Count})", true); - if (showMappingFoldout) - { - EditorGUI.indentLevel++; - for (int i = 0; i < skeletonAnimator.boneMappings.Count; i++) - { - var mapping = skeletonAnimator.boneMappings[i]; - Color labelColor = mapping.isMapped ? Color.green : Color.red; - - EditorGUILayout.BeginHorizontal(); - - var prevColor = GUI.contentColor; - GUI.contentColor = labelColor; - EditorGUILayout.LabelField(mapping.isMapped ? "●" : "○", GUILayout.Width(15)); - GUI.contentColor = prevColor; - - EditorGUILayout.LabelField(mapping.optiTrackBoneName, GUILayout.Width(100)); - EditorGUILayout.LabelField("→", GUILayout.Width(20)); - - // FBX 노드 이름 — 수동 편집 가능 - EditorGUI.BeginChangeCheck(); - string newName = EditorGUILayout.TextField(mapping.fbxNodeName); - if (EditorGUI.EndChangeCheck()) - { - Undo.RecordObject(skeletonAnimator, "Edit Bone Mapping"); - mapping.fbxNodeName = newName; - var allTransforms = skeletonAnimator.GetComponentsInChildren(true); - mapping.cachedTransform = null; - mapping.isMapped = false; - foreach (var t in allTransforms) - { - if (t.name == newName) - { - mapping.cachedTransform = t; - mapping.isMapped = true; - break; - } - } - EditorUtility.SetDirty(skeletonAnimator); - } - - // Position / Rotation 토글 - EditorGUI.BeginChangeCheck(); - mapping.applyPosition = EditorGUILayout.ToggleLeft("P", mapping.applyPosition, GUILayout.Width(30)); - mapping.applyRotation = EditorGUILayout.ToggleLeft("R", mapping.applyRotation, GUILayout.Width(30)); - if (EditorGUI.EndChangeCheck()) - { - Undo.RecordObject(skeletonAnimator, "Toggle Bone Apply"); - EditorUtility.SetDirty(skeletonAnimator); - } - - EditorGUILayout.EndHorizontal(); - } - EditorGUI.indentLevel--; - } - } - - EditorGUILayout.Space(5); - GUI.backgroundColor = new Color(0.9f, 0.4f, 0.4f); - if (GUILayout.Button("매핑 초기화")) - { - Undo.RecordObject(skeletonAnimator, "Clear Bone Mappings"); - skeletonAnimator.boneMappings.Clear(); - EditorUtility.SetDirty(skeletonAnimator); - } - GUI.backgroundColor = Color.white; - - // ── 런타임 수신 본 디버그 ── - GUILayout.Space(10); - EditorGUILayout.LabelField("Motive 수신 본 디버그 (런타임)", EditorStyles.boldLabel); - - if (!Application.isPlaying) - { - EditorGUILayout.HelpBox("플레이 모드에서 Motive 연결 후 확인할 수 있습니다.", MessageType.Info); - } - else if (skeletonAnimator.debugReceivedBoneNames.Count == 0) - { - EditorGUILayout.HelpBox("아직 본 데이터를 수신하지 못했습니다. Motive 스켈레톤이 활성화되어 있는지 확인해주세요.", MessageType.Warning); - } - else - { - EditorGUILayout.LabelField($"수신된 본 수: {skeletonAnimator.debugReceivedBoneCount}"); - - showDebugBonesFoldout = EditorGUILayout.Foldout(showDebugBonesFoldout, $"Motive 본 목록 ({skeletonAnimator.debugReceivedBoneNames.Count})", true); - if (showDebugBonesFoldout) - { - EditorGUI.indentLevel++; - foreach (var boneName in skeletonAnimator.debugReceivedBoneNames) - { - EditorGUILayout.LabelField(boneName); - } - EditorGUI.indentLevel--; - } - - EditorGUILayout.Space(3); - if (GUILayout.Button("Console에 전체 본 목록 출력")) - { - var sb = new System.Text.StringBuilder(); - sb.AppendLine($"=== Motive 수신 본 목록 ({skeletonAnimator.SkeletonAssetName}) ==="); - sb.AppendLine($"총 {skeletonAnimator.debugReceivedBoneCount}개"); - sb.AppendLine(); - foreach (var bn in skeletonAnimator.debugReceivedBoneNames) - { - sb.AppendLine(bn); - } - Debug.Log(sb.ToString()); - } - } - - // 플레이 모드일 때 자동 갱신 if (Application.isPlaying) Repaint(); - - GUILayout.Space(10); - } - - private void AutoGenerateMappingsEditor(OptitrackSkeletonAnimator_Mingle script) - { - script.boneMappings.Clear(); - - var allTransforms = script.GetComponentsInChildren(true); - var transformMap = new Dictionary(); - foreach (var t in allTransforms) - { - if (!transformMap.ContainsKey(t.name)) - transformMap[t.name] = t; - } - - // 접두사 자동 감지 (예: "001_Hips" → "001_") - string prefix = ""; - foreach (var kvp in transformMap) - { - if (kvp.Key.EndsWith("Hips")) - { - int idx = kvp.Key.LastIndexOf("Hips"); - if (idx > 0) - { - prefix = kvp.Key.Substring(0, idx); - break; - } - } - } - - if (!string.IsNullOrEmpty(prefix)) - Debug.Log($"[OptiTrack 매핑] 감지된 접두사: \"{prefix}\""); - - int mapped = 0; - foreach (var kvp in OptitrackSkeletonAnimator_Mingle.DefaultOptiToFbxSuffix) - { - var mapping = new OptiTrackBoneMapping - { - optiTrackBoneName = kvp.Key, - applyPosition = true, - applyRotation = true, - isMapped = false - }; - - // 1순위: 접두사 + FBX 접미사 - string fullName = prefix + kvp.Value; - if (transformMap.TryGetValue(fullName, out Transform found)) - { - mapping.fbxNodeName = fullName; - mapping.cachedTransform = found; - mapping.isMapped = true; - } - // 2순위: 접미사만 - else if (transformMap.TryGetValue(kvp.Value, out Transform found2)) - { - mapping.fbxNodeName = kvp.Value; - mapping.cachedTransform = found2; - mapping.isMapped = true; - } - // 3순위: 끝나는 이름으로 부분 검색 - else - { - foreach (var t in transformMap) - { - if (t.Key.EndsWith(kvp.Value) || t.Key.EndsWith("_" + kvp.Value)) - { - mapping.fbxNodeName = t.Key; - mapping.cachedTransform = t.Value; - mapping.isMapped = true; - break; - } - } - } - - if (!mapping.isMapped) - mapping.fbxNodeName = prefix + kvp.Value + " (미발견)"; - else - mapped++; - - script.boneMappings.Add(mapping); - } - - Debug.Log($"[OptiTrack 매핑] 완료: {mapped}/{script.boneMappings.Count} 본 매핑 성공"); } } diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab deleted file mode 100644 index 6c7e1e99d..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c1c459ecfa19b8ef6e585d2649bb6b0ab50e658855f151ed22c4c0b6083c0ab -size 53070 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab deleted file mode 100644 index 49db9ec54..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d6bce863f16ba7fd5c42879cdf2da6e72c0695135ab77c9df32e3363288d743 -size 102557 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab.meta deleted file mode 100644 index aa4a68101..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: c1e31e5077eae1f4f823f68fde521408 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx deleted file mode 100644 index eaebe14d1..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4bdf0d00a84d60de81172742651783ba4c0671cb10ae7655bebc455c88a5f6c2 -size 509504 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta deleted file mode 100644 index ea3dd8f2d..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta +++ /dev/null @@ -1,107 +0,0 @@ -fileFormatVersion: 2 -guid: 14ec801d62fadf547921258a8b1dadc5 -ModelImporter: - serializedVersion: 22200 - internalIDToNameTable: [] - externalObjects: {} - materials: - materialImportMode: 2 - materialName: 0 - materialSearch: 1 - materialLocation: 1 - animations: - legacyGenerateAnimations: 4 - bakeSimulation: 0 - resampleCurves: 1 - optimizeGameObjects: 0 - removeConstantScaleCurves: 0 - motionNodeName: - animationImportErrors: - animationImportWarnings: - animationRetargetingWarnings: - animationDoRetargetingWarnings: 0 - importAnimatedCustomProperties: 0 - importConstraints: 0 - animationCompression: 1 - animationRotationError: 0.5 - animationPositionError: 0.5 - animationScaleError: 0.5 - animationWrapMode: 0 - extraExposedTransformPaths: [] - extraUserProperties: [] - clipAnimations: [] - isReadable: 0 - meshes: - lODScreenPercentages: [] - globalScale: 1 - meshCompression: 0 - addColliders: 0 - useSRGBMaterialColor: 1 - sortHierarchyByName: 1 - importPhysicalCameras: 1 - importVisibility: 1 - importBlendShapes: 1 - importCameras: 1 - importLights: 1 - nodeNameCollisionStrategy: 1 - fileIdsGeneration: 2 - swapUVChannels: 0 - generateSecondaryUV: 0 - useFileUnits: 1 - keepQuads: 0 - weldVertices: 1 - bakeAxisConversion: 0 - preserveHierarchy: 0 - skinWeightsMode: 0 - maxBonesPerVertex: 4 - minBoneWeight: 0.001 - optimizeBones: 1 - meshOptimizationFlags: -1 - indexFormat: 0 - secondaryUVAngleDistortion: 8 - secondaryUVAreaDistortion: 15.000001 - secondaryUVHardAngle: 88 - secondaryUVMarginMethod: 1 - secondaryUVMinLightmapResolution: 40 - secondaryUVMinObjectScale: 1 - secondaryUVPackMargin: 4 - useFileScale: 1 - strictVertexDataChecks: 0 - tangentSpace: - normalSmoothAngle: 60 - normalImportMode: 0 - tangentImportMode: 3 - normalCalculationMode: 4 - legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 - blendShapeNormalImportMode: 1 - normalSmoothingSource: 0 - referencedClips: [] - importAnimation: 1 - humanDescription: - serializedVersion: 3 - human: [] - skeleton: [] - armTwist: 0.5 - foreArmTwist: 0.5 - upperLegTwist: 0.5 - legTwist: 0.5 - armStretch: 0.05 - legStretch: 0.05 - feetSpacing: 0 - globalScale: 1 - rootMotionBoneName: - hasTranslationDoF: 0 - hasExtraRoot: 0 - skeletonHasParents: 1 - lastHumanDescriptionAvatarSource: {instanceID: 0} - autoGenerateAvatarMappingIfUnspecified: 1 - animationType: 2 - humanoidOversampling: 1 - avatarSetup: 0 - addHumanoidExtraRootOnlyWhenUsingAvatar: 1 - importBlendShapeDeformPercent: 1 - remapMaterialsIfMaterialImportModeIsNone: 0 - additionalBone: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab deleted file mode 100644 index eca75edac..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae351ec0f45657ddcd494552fb9f9d451df580c58853ac90f10b4bd65ebd6ac0 -size 85477 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab.meta deleted file mode 100644 index 10f7455b5..000000000 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: afbc9c9b98650e44f97662b4f503c261 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs new file mode 100644 index 000000000..68ccb32a8 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +/// +/// OptiTrack 스켈레톤의 본 매핑과 T-포즈를 에셋으로 영구 저장합니다. +/// 런타임에 Start()에서 자동 로드되며, CacheRestPose() 없이 즉시 복원이 가능합니다. +/// +[CreateAssetMenu(fileName = "OptitrackRestPoseData", menuName = "OptiTrack/Skeleton Setup")] +public class OptitrackRestPoseData : ScriptableObject +{ + // ── 본 매핑 ─────────────────────────────────────────────────────────────── + + /// + /// OptiTrack 본 이름 ↔ FBX 노드 이름 매핑 목록. + /// Transform 참조(cachedTransform)는 씬 오브젝트라 SO에 저장되지 않으며, + /// 런타임 Start()에서 자동으로 채워집니다. + /// + public List boneMappings = new List(); + + // ── T-포즈 (기준 포즈) ──────────────────────────────────────────────────── + + [Serializable] + public class RestPoseEntry + { + public string boneName; + public Vector3 localPosition; + public Quaternion localRotation; + } + + public List restPoseEntries = new List(); + + /// + /// T-포즈 데이터를 런타임 딕셔너리에 복사합니다. + /// + public void LoadRestPoseIntoRuntime( + Dictionary rotations, + Dictionary positions) + { + rotations.Clear(); + positions.Clear(); + foreach (var e in restPoseEntries) + { + rotations[e.boneName] = e.localRotation; + positions[e.boneName] = e.localPosition; + } + } +} diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs.meta new file mode 100644 index 000000000..d068c28ad --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRestPoseData.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 48d97b353e3e9b14a8b24f284c518839 \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator_Mingle.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator_Mingle.cs index 75cdbc0e7..b8e8cb6ee 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator_Mingle.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator_Mingle.cs @@ -25,12 +25,23 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour [Tooltip("Motive의 스켈레톤 에셋 이름")] public string SkeletonAssetName = "Skeleton1"; - [Header("본 매핑 (OptiTrack → FBX 노드)")] - [Tooltip("자동 매핑 후 수동 조정 가능")] + // 런타임 본 매핑 — SO(RestPoseAsset)에서 로드됨. 직접 편집하지 말고 설정 창 사용. + [HideInInspector] public List boneMappings = new List(); - [Header("디버그")] - public bool logUnmappedBones = false; + [Header("T-포즈 (기준 포즈)")] + [Tooltip("에디터에서 캡처한 T-포즈 데이터. 비어 있으면 런타임 CacheRestPose()를 사용합니다.")] + public OptitrackRestPoseData RestPoseAsset; + + [Header("본 1€ 필터 (속도 적응형 저역통과)")] + [Tooltip("활성화 시 빠른 움직임은 그대로, 정지/느린 움직임의 노이즈를 제거합니다.\n단순 EMA보다 모션 보존이 훨씬 우수합니다.")] + public bool enableBoneFilter = true; + [Tooltip("최소 차단 주파수 (Hz). 낮을수록 정지 시 노이즈 제거 강화. 권장: 1~3 Hz")] + [Range(0.1f, 10f)] + public float filterMinCutoff = 3.0f; + [Tooltip("속도 계수. 높을수록 빠른 움직임 시 지연 감소. 권장: 0.3~1.0")] + [Range(0f, 5f)] + public float filterBeta = 1.5f; private OptitrackSkeletonDefinition m_skeletonDef; private string previousSkeletonName; @@ -38,23 +49,43 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour [HideInInspector] public bool isSkeletonFound = false; - // 에디터 디버그용 — 런타임에 Motive에서 실제로 수신된 본 목록 - [HideInInspector] - public List debugReceivedBoneNames = new List(); - [HideInInspector] - public int debugReceivedBoneCount = 0; - - private float updateInterval = 0.1f; + private const float k_SkeletonCheckInterval = 0.1f; // 본 ID → 매핑 인덱스 (빠른 룩업) private Dictionary m_boneIdToMappingIndex = new Dictionary(); // 본 이름 → Transform 캐시 (전체 하이어라키) private Dictionary m_allTransforms = new Dictionary(); - // torn read 방지용 스냅샷 버퍼 + // FillBoneSnapshot 용 pre-allocated 스냅샷 버퍼 (락 내부에서 채워짐 → torn read 없음) private Dictionary m_snapshotPositions = new Dictionary(); private Dictionary m_snapshotOrientations = new Dictionary(); + // OptiTrack 본 이름 → Transform 빠른 캐시 (GetMappedTransform O(n) → O(1)) + private Dictionary m_optiNameTransformCache = new Dictionary(); + + // 스파인/넥 체인 Transform 캐시 (GetSpineChainTransforms 매 호출 List 할당 방지) + private List m_spineChainCache = new List(); + private List m_neckChainCache = new List(); + + // 힙 본 ID 캐시 (-1 = 미발견) + private int m_hipBoneId = -1; + + // NatNet 하드웨어 타임스탬프 기반 실제 프레임 간격 (렌더 프레임과 독립) + private float m_natNetDt = 1f / 120f; + private OptitrackHiResTimer.Timestamp m_lastFrameTimestamp; + private bool m_hasLastFrameTimestamp = false; + + // 1€ 필터 상태 (본 ID → 이전 프레임 필터 상태) + private struct BoneFilterState + { + public Quaternion prevOri; + public float dOriMag; // 필터된 각속도 크기 (rad/s) + public Vector3 prevPos; + public float dPosMag; // 필터된 선속도 크기 (m/s) + public bool initialized; + } + private Dictionary m_filterStates = new Dictionary(); + // OptiTrack 본 이름 → FBX 노드 접미사 기본 매핑 public static readonly Dictionary DefaultOptiToFbxSuffix = new Dictionary { @@ -140,16 +171,42 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour StreamingClient.RegisterSkeleton(this, this.SkeletonAssetName); } - // 에디터에서 세팅한 매핑의 Transform 캐시 갱신 - if (boneMappings.Count > 0) + // SO에서 본 매핑 + T-포즈 로드 + if (RestPoseAsset != null && RestPoseAsset.boneMappings.Count > 0) + { + // 본 매핑: SO → MB 런타임 복사 (cachedTransform은 아래 RefreshTransformCache에서 채워짐) + boneMappings.Clear(); + foreach (var src in RestPoseAsset.boneMappings) + { + boneMappings.Add(new OptiTrackBoneMapping + { + optiTrackBoneName = src.optiTrackBoneName, + fbxNodeName = src.fbxNodeName, + applyPosition = src.applyPosition, + applyRotation = src.applyRotation + }); + } + RefreshTransformCache(); + Debug.Log($"[OptiTrack] 본 매핑 에셋 로드 완료: {boneMappings.Count}개", this); + } + else if (boneMappings.Count > 0) { RefreshTransformCache(); } else { - Debug.LogWarning("[OptiTrack] 본 매핑이 비어있습니다. Inspector에서 'FBX 분석 → 자동 매핑 생성' 버튼을 눌러주세요.", this); + Debug.LogWarning("[OptiTrack] 본 매핑이 비어있습니다. 설정 창에서 'FBX 분석 → 자동 매핑 생성'을 눌러주세요.", this); } + // T-포즈 로드 + if (RestPoseAsset != null && RestPoseAsset.restPoseEntries.Count > 0) + { + RestPoseAsset.LoadRestPoseIntoRuntime(m_restLocalRotations, m_restLocalPositions); + m_isRestPoseCached = true; + Debug.Log($"[OptiTrack] T-포즈 에셋 로드 완료: {m_restLocalRotations.Count}개 본", this); + } + + previousSkeletonName = SkeletonAssetName; StartCoroutine(CheckSkeletonConnectionPeriodically()); } @@ -172,29 +229,24 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour return; } - if (m_skeletonDef == null) - { - m_skeletonDef = StreamingClient.GetSkeletonDefinitionByName(SkeletonAssetName); - if (m_skeletonDef == null) - return; - RebuildBoneIdMapping(); - } + if (m_skeletonDef == null) return; - // 최신 스켈레톤 상태 - OptitrackSkeletonState skelState = StreamingClient.GetLatestSkeletonState(m_skeletonDef.Id); - if (skelState == null) + // 락 보호 하에 스냅샷 복사 + NatNet 하드웨어 타임스탬프 수신 + OptitrackHiResTimer.Timestamp frameTs; + if (!StreamingClient.FillBoneSnapshot(m_skeletonDef.Id, m_snapshotPositions, m_snapshotOrientations, out frameTs)) return; - // torn read 방지 — 스냅샷 복사 - m_snapshotPositions.Clear(); - m_snapshotOrientations.Clear(); - foreach (var kvp in skelState.BonePoses) + // ── NatNet 실제 프레임 간격 계산 (하드웨어 타이머 — 렌더 프레임 등락과 완전 독립) ── + if (m_hasLastFrameTimestamp && frameTs.m_ticks != m_lastFrameTimestamp.m_ticks) { - m_snapshotPositions[kvp.Key] = kvp.Value.Position; - m_snapshotOrientations[kvp.Key] = kvp.Value.Orientation; + float measuredDt = frameTs.SecondsSince(m_lastFrameTimestamp); + if (measuredDt > 0.001f && measuredDt < 0.1f) // 1ms~100ms 범위만 신뢰 (이상값 무시) + m_natNetDt = Mathf.Lerp(m_natNetDt, measuredDt, 0.1f); } + m_lastFrameTimestamp = frameTs; + m_hasLastFrameTimestamp = true; - // 각 본 업데이트 — Transform 직접 적용 + // ── 각 본 업데이트 ─────────────────────────────────────────────────────── foreach (var bone in m_skeletonDef.Bones) { if (!m_boneIdToMappingIndex.TryGetValue(bone.Id, out int mappingIdx)) @@ -204,17 +256,26 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour if (!mapping.isMapped || mapping.cachedTransform == null) continue; - if (m_snapshotOrientations.TryGetValue(bone.Id, out Quaternion ori)) + if (mapping.applyRotation) { - if (mapping.applyPosition && m_snapshotPositions.TryGetValue(bone.Id, out Vector3 pos)) - { - mapping.cachedTransform.localPosition = SnapPosition(pos); - } + if (!m_snapshotOrientations.TryGetValue(bone.Id, out Quaternion finalOri)) + continue; - if (mapping.applyRotation) - { - mapping.cachedTransform.localRotation = SnapQuaternion(ori); - } + if (enableBoneFilter) + finalOri = ApplyOneEuroOri(bone.Id, finalOri, m_natNetDt); + + mapping.cachedTransform.localRotation = finalOri; + } + + if (mapping.applyPosition) + { + if (!m_snapshotPositions.TryGetValue(bone.Id, out Vector3 finalPos)) + continue; + + if (enableBoneFilter) + finalPos = ApplyOneEuroPos(bone.Id, finalPos, m_natNetDt); + + mapping.cachedTransform.localPosition = finalPos; } } } @@ -248,6 +309,34 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour mapping.isMapped = true; } } + RebuildOptiNameCache(); + } + + /// + /// OptiTrack 본 이름 → Transform 딕셔너리 캐시 구축 (GetMappedTransform O(n) → O(1)) + /// + private void RebuildOptiNameCache() + { + m_optiNameTransformCache.Clear(); + foreach (var mapping in boneMappings) + { + if (!string.IsNullOrEmpty(mapping.optiTrackBoneName) && mapping.isMapped && mapping.cachedTransform != null) + m_optiNameTransformCache[mapping.optiTrackBoneName] = mapping.cachedTransform; + } + RebuildChainCaches(); + } + + private void RebuildChainCaches() + { + m_spineChainCache.Clear(); + foreach (var name in SpineChainOptiNames) + if (m_optiNameTransformCache.TryGetValue(name, out Transform t)) + m_spineChainCache.Add(t); + + m_neckChainCache.Clear(); + foreach (var name in NeckChainOptiNames) + if (m_optiNameTransformCache.TryGetValue(name, out Transform t)) + m_neckChainCache.Add(t); } /// @@ -256,11 +345,10 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour private void RebuildBoneIdMapping() { m_boneIdToMappingIndex.Clear(); - debugReceivedBoneNames.Clear(); + m_filterStates.Clear(); + m_hasLastFrameTimestamp = false; if (m_skeletonDef == null) return; - debugReceivedBoneCount = m_skeletonDef.Bones.Count; - var nameToIdx = new Dictionary(); for (int i = 0; i < boneMappings.Count; i++) { @@ -269,25 +357,17 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour } int matchCount = 0; + m_hipBoneId = -1; foreach (var bone in m_skeletonDef.Bones) { string boneName = bone.Name; string optiName = boneName.Contains("_") ? boneName.Substring(boneName.IndexOf('_') + 1) : boneName; - - // 디버그: Motive에서 수신된 모든 본 기록 - string parentInfo = m_skeletonDef.BoneIdToParentIdMap.TryGetValue(bone.Id, out Int32 parentId) - ? $"parent={parentId}" : "root"; - debugReceivedBoneNames.Add($"[ID:{bone.Id}] {boneName} (suffix: {optiName}, {parentInfo})"); - if (nameToIdx.TryGetValue(optiName, out int idx)) { m_boneIdToMappingIndex[bone.Id] = idx; matchCount++; } - else if (logUnmappedBones) - { - Debug.LogWarning($"[OptiTrack] 매핑되지 않은 OptiTrack 본: {boneName} (suffix: {optiName})"); - } + if (optiName == "Hip") m_hipBoneId = bone.Id; } Debug.Log($"[OptiTrack] 본 ID 매핑 완료: {matchCount}/{m_skeletonDef.Bones.Count} 매칭"); @@ -331,31 +411,81 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour } } - yield return new WaitForSeconds(updateInterval); + yield return new WaitForSeconds(k_SkeletonCheckInterval); } } - // 소수점 4자리 이하 제거 (0.0001m = 0.1mm 미만 노이즈 제거) - private const float POS_PRECISION = 10000f; - private static Vector3 SnapPosition(Vector3 v) + // ── 1€ Filter (One Euro Filter) ────────────────────────────────────────── + // 참고: Géry Casiez et al., "1€ Filter: A Simple Speed-based Low-pass Filter", CHI 2012 + // 속도가 빠를수록 cutoff 상승 → 지연 감소, 속도가 느릴수록 cutoff = minCutoff → 노이즈 제거 + + // dt초 간격에서의 1차 LP 필터 alpha + private static float OE_Alpha(float cutoffHz, float dt) { - return new Vector3( - Mathf.Round(v.x * POS_PRECISION) / POS_PRECISION, - Mathf.Round(v.y * POS_PRECISION) / POS_PRECISION, - Mathf.Round(v.z * POS_PRECISION) / POS_PRECISION - ); + float r = 2f * Mathf.PI * cutoffHz * dt; + return r / (r + 1f); } - // 쿼터니언 소수점 5자리 이하 제거 + 정규화 - private const float ROT_PRECISION = 100000f; - private static Quaternion SnapQuaternion(Quaternion q) + private Quaternion ApplyOneEuroOri(int boneId, Quaternion raw, float dt) { - return new Quaternion( - Mathf.Round(q.x * ROT_PRECISION) / ROT_PRECISION, - Mathf.Round(q.y * ROT_PRECISION) / ROT_PRECISION, - Mathf.Round(q.z * ROT_PRECISION) / ROT_PRECISION, - Mathf.Round(q.w * ROT_PRECISION) / ROT_PRECISION - ).normalized; + const float k_DCutoff = 1f; // 도함수 필터의 고정 cutoff (Hz) + + if (!m_filterStates.TryGetValue(boneId, out BoneFilterState s) || !s.initialized) + { + m_filterStates[boneId] = new BoneFilterState + { + prevOri = raw, dOriMag = 0f, + prevPos = Vector3.zero, dPosMag = 0f, + initialized = true + }; + return raw; + } + + // 각속도(rad/s) 추정 + float angleDeg = Quaternion.Angle(s.prevOri, raw); + float speed = angleDeg * Mathf.Deg2Rad / Mathf.Max(dt, 1e-4f); + + // 도함수를 별도 LP로 스무딩 + float dAlpha = OE_Alpha(k_DCutoff, dt); + float filtDeriv = s.dOriMag + dAlpha * (speed - s.dOriMag); + + // 적응 cutoff: 빠르면 cutoff 상승 + float cutoff = filterMinCutoff + filterBeta * filtDeriv; + float alpha = OE_Alpha(cutoff, dt); + Quaternion filtered = Quaternion.Slerp(s.prevOri, raw, alpha); + + s.prevOri = filtered; + s.dOriMag = filtDeriv; + m_filterStates[boneId] = s; + return filtered; + } + + private Vector3 ApplyOneEuroPos(int boneId, Vector3 raw, float dt) + { + const float k_DCutoff = 1f; + + if (!m_filterStates.TryGetValue(boneId, out BoneFilterState s) || !s.initialized) + { + // 회전 필터가 이미 초기화했을 수 있으므로 위치만 패치 + s.prevPos = raw; + s.dPosMag = 0f; + s.initialized = true; + m_filterStates[boneId] = s; + return raw; + } + + float speed = (raw - s.prevPos).magnitude / Mathf.Max(dt, 1e-4f); + float dAlpha = OE_Alpha(k_DCutoff, dt); + float filtDeriv = s.dPosMag + dAlpha * (speed - s.dPosMag); + + float cutoff = filterMinCutoff + filterBeta * filtDeriv; + float alpha = OE_Alpha(cutoff, dt); + Vector3 filtered = Vector3.Lerp(s.prevPos, raw, alpha); + + s.prevPos = filtered; + s.dPosMag = filtDeriv; + m_filterStates[boneId] = s; + return filtered; } #region 외부 접근용 헬퍼 @@ -440,10 +570,13 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour public static readonly string[] NeckChainOptiNames = { "Neck", "Neck2" }; /// - /// OptiTrack 본 이름으로 매핑된 Transform 반환 + /// OptiTrack 본 이름으로 매핑된 Transform 반환 (캐시 O(1), 미캐시 시 선형 탐색 폴백) /// public Transform GetMappedTransform(string optiTrackBoneName) { + if (m_optiNameTransformCache.TryGetValue(optiTrackBoneName, out var cached)) + return cached; + // 캐시 미구축 상태 폴백 (Start() 전 호출 등) foreach (var mapping in boneMappings) { if (mapping.optiTrackBoneName == optiTrackBoneName && mapping.isMapped) @@ -455,32 +588,12 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour /// /// 스파인 체인의 모든 Transform을 순서대로 반환 (Ab → Spine2 → Spine3 → Spine4 → Chest) /// - public List GetSpineChainTransforms() - { - var chain = new List(); - foreach (var name in SpineChainOptiNames) - { - Transform t = GetMappedTransform(name); - if (t != null) - chain.Add(t); - } - return chain; - } + public List GetSpineChainTransforms() => m_spineChainCache; /// /// 넥 체인의 모든 Transform을 순서대로 반환 /// - public List GetNeckChainTransforms() - { - var chain = new List(); - foreach (var name in NeckChainOptiNames) - { - Transform t = GetMappedTransform(name); - if (t != null) - chain.Add(t); - } - return chain; - } + public List GetNeckChainTransforms() => m_neckChainCache; /// /// 체인의 누적 로컬 회전을 계산 (각 본의 localRotation을 순서대로 곱함) @@ -495,31 +608,49 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour return total; } - /// - /// 초기 포즈(T-포즈) 캐싱 — Humanoid가 아니므로 직접 캐싱 - /// - [HideInInspector] public Dictionary restLocalRotations = new Dictionary(); - [HideInInspector] public Dictionary restLocalPositions = new Dictionary(); - [HideInInspector] public bool isRestPoseCached = false; + // T-포즈 기준 포즈 데이터 (SO에서 로드 또는 CacheRestPose()로 캐싱) + private Dictionary m_restLocalRotations = new Dictionary(); + private Dictionary m_restLocalPositions = new Dictionary(); + private bool m_isRestPoseCached = false; /// /// 현재 포즈를 기준 포즈(T-포즈)로 캐싱 /// public void CacheRestPose() { - restLocalRotations.Clear(); - restLocalPositions.Clear(); + m_restLocalRotations.Clear(); + m_restLocalPositions.Clear(); foreach (var mapping in boneMappings) { if (mapping.isMapped && mapping.cachedTransform != null) { - restLocalRotations[mapping.optiTrackBoneName] = mapping.cachedTransform.localRotation; - restLocalPositions[mapping.optiTrackBoneName] = mapping.cachedTransform.localPosition; + m_restLocalRotations[mapping.optiTrackBoneName] = mapping.cachedTransform.localRotation; + m_restLocalPositions[mapping.optiTrackBoneName] = mapping.cachedTransform.localPosition; } } - isRestPoseCached = true; - Debug.Log($"[OptiTrack] 기준 포즈 캐싱 완료: {restLocalRotations.Count}개 본"); + m_isRestPoseCached = true; + Debug.Log($"[OptiTrack] 기준 포즈 캐싱 완료: {m_restLocalRotations.Count}개 본"); + + // SO가 연결되어 있으면 런타임 결과를 SO에도 반영 + if (RestPoseAsset != null) + { + RestPoseAsset.restPoseEntries.Clear(); + foreach (var kvp in m_restLocalRotations) + { + m_restLocalPositions.TryGetValue(kvp.Key, out Vector3 pos); + RestPoseAsset.restPoseEntries.Add(new OptitrackRestPoseData.RestPoseEntry + { + boneName = kvp.Key, + localPosition = pos, + localRotation = kvp.Value + }); + } +#if UNITY_EDITOR + UnityEditor.EditorUtility.SetDirty(RestPoseAsset); + UnityEditor.AssetDatabase.SaveAssets(); +#endif + } } /// @@ -527,15 +658,15 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour /// public void RestoreRestPose() { - if (!isRestPoseCached) return; + if (!m_isRestPoseCached) return; foreach (var mapping in boneMappings) { if (mapping.isMapped && mapping.cachedTransform != null) { - if (restLocalRotations.TryGetValue(mapping.optiTrackBoneName, out Quaternion rot)) + if (m_restLocalRotations.TryGetValue(mapping.optiTrackBoneName, out Quaternion rot)) mapping.cachedTransform.localRotation = rot; - if (restLocalPositions.TryGetValue(mapping.optiTrackBoneName, out Vector3 pos)) + if (m_restLocalPositions.TryGetValue(mapping.optiTrackBoneName, out Vector3 pos)) mapping.cachedTransform.localPosition = pos; } } @@ -546,7 +677,7 @@ public class OptitrackSkeletonAnimator_Mingle : MonoBehaviour /// public Quaternion GetRestLocalRotation(string optiTrackBoneName) { - if (restLocalRotations.TryGetValue(optiTrackBoneName, out Quaternion rot)) + if (m_restLocalRotations.TryGetValue(optiTrackBoneName, out Quaternion rot)) return rot; return Quaternion.identity; } diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs index 8b989c966..0283712c7 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs @@ -22,10 +22,6 @@ using System.Threading; using UnityEngine; using NaturalPoint; using NaturalPoint.NatNetLib; -using UnityEditor; -using UnityEditor.UIElements; -using UnityEngine.UIElements; -using static TMPro.SpriteAssetUtilities.TexturePacker_JsonArray; /// Skeleton naming conventions supported by OptiTrack Motive. @@ -79,6 +75,8 @@ public class OptitrackSkeletonState /// Maps from OptiTrack bone IDs to their corresponding bone poses. public Dictionary BonePoses; public Dictionary LocalBonePoses; + /// NatNet 프레임이 수신된 시각 (고해상도 하드웨어 타이머 기반). + public OptitrackHiResTimer.Timestamp DeliveryTimestamp; } /// Represents the state of a streamed trained markerset at an instant in time. @@ -323,6 +321,9 @@ public class OptitrackStreamingClient : MonoBehaviour [Tooltip("Skips getting data descriptions. Skeletons will not work with this feature turned on, but it will reduce network usage with a large number of rigid bodies.")] public bool SkipDataDescriptions = false; + [Tooltip("스트리밍이 끊어졌을 때 최대 5회까지 자동으로 재연결을 시도합니다.")] + public bool AutoReconnect = true; + [Tooltip("Changes to the version of Natnet used by the server")] public string ServerNatNetVersion = ""; public string ClientNatNetVersion = ""; @@ -389,6 +390,13 @@ public class OptitrackStreamingClient : MonoBehaviour /// executes on a separate thread). Note while the lock is held, any frame updates received are simply dropped. /// private object m_frameDataUpdateLock = new object(); + + // 중간에 새 스켈레톤이 생성된 경우 정의 재조회 플래그 (NatNet 스레드에서도 씀 → volatile) + private volatile bool m_pendingDefinitionRefresh = false; + private float m_definitionRefreshCooldown = 0f; + + // 자동 재연결 진행 중 여부 (중복 재연결 방지) + private bool m_isReconnecting = false; #endregion Private fields @@ -598,6 +606,15 @@ public class OptitrackStreamingClient : MonoBehaviour m_latestTMarkMarkerSpheres.Clear(); } + // 미등록 스켈레톤이 프레임에 등장했을 때 정의 자동 재조회 (Motive 중간 생성 대응) + if (m_pendingDefinitionRefresh && m_definitionRefreshCooldown <= 0f && m_client != null && !SkipDataDescriptions) + { + m_pendingDefinitionRefresh = false; + m_definitionRefreshCooldown = 5f; + try { UpdateDefinitions(); } + catch (Exception ex) { Debug.LogException(ex, this); } + } + m_definitionRefreshCooldown -= Time.deltaTime; } @@ -655,37 +672,71 @@ public class OptitrackStreamingClient : MonoBehaviour /// public void Reconnect() { - Debug.Log("OptiTrack: 재접속을 시도합니다..."); - - // 현재 연결이 있다면 먼저 해제 - if (m_client != null) + if (m_isReconnecting) { - Debug.Log("OptiTrack: 기존 연결을 해제합니다."); - OnDisable(); + Debug.LogWarning(GetType().FullName + ": 재연결이 이미 진행 중입니다.", this); + return; } - - // 잠시 대기 후 재연결 + + Debug.Log("OptiTrack: 재접속을 시도합니다..."); + + // 기존 연결 정리 (StopAllCoroutines 포함) + OnDisable(); + StartCoroutine(ReconnectCoroutine()); } /// - /// Coroutine for handling the reconnection process with a delay. + /// Coroutine for handling the reconnection process with a retry loop. + /// Attempts up to 5 times: 1s delay on first attempt, 5s on subsequent. + /// Last known pose is preserved during reconnect (m_latestSkeletonStates not cleared). /// private System.Collections.IEnumerator ReconnectCoroutine() { - // 1초 대기 후 재연결 시도 - yield return new WaitForSeconds(1.0f); - - try + m_isReconnecting = true; + const int maxAttempts = 5; + + for (int attempt = 1; attempt <= maxAttempts; attempt++) { - Debug.Log("OptiTrack: 서버에 재연결을 시도합니다."); - OnEnable(); - Debug.Log("OptiTrack: 재연결이 완료되었습니다."); - } - catch (System.Exception ex) - { - Debug.LogError("OptiTrack: 재연결 실패 - " + ex.Message); + float delay = (attempt == 1) ? 1.0f : 5.0f; + Debug.Log(string.Format("{0}: 재연결 시도 {1}/{2} — {3}초 후...", GetType().FullName, attempt, maxAttempts, delay), this); + yield return new WaitForSeconds(delay); + + // ConnectCoroutine 실행: 연결 수립 + CheckConnectionHealth 시작 + yield return StartCoroutine(ConnectCoroutine()); + + // 첫 프레임 수신까지 최대 3초 대기 + float deadline = Time.realtimeSinceStartup + 3.0f; + while (!m_receivedFrameSinceConnect && Time.realtimeSinceStartup < deadline) + yield return null; + + if (m_receivedFrameSinceConnect) + { + Debug.Log(GetType().FullName + ": 재연결 성공.", this); + m_isReconnecting = false; + yield break; + } + + Debug.LogWarning(string.Format("{0}: 재연결 시도 {1}/{2} 실패 — 데이터 수신 없음.", GetType().FullName, attempt, maxAttempts), this); + + // 다음 시도 전 부분 연결 정리 (ReconnectCoroutine 자신은 중지하지 않도록 StopCoroutine 사용) + if (m_connectionHealthCoroutine != null) + { + StopCoroutine(m_connectionHealthCoroutine); + m_connectionHealthCoroutine = null; + } + if (m_client != null) + { + if (RecordOnPlay) StopRecording(); + try { m_client.NativeFrameReceived -= OnNatNetFrameReceived; } catch (System.Exception) { } + try { m_client.Disconnect(); } catch (System.Exception) { } + try { m_client.Dispose(); } catch (System.Exception) { } + m_client = null; + } } + + Debug.LogError(string.Format("{0}: {1}회 재연결 시도 모두 실패. 수동으로 재연결하십시오.", GetType().FullName, maxAttempts), this); + m_isReconnecting = false; } /// @@ -843,6 +894,36 @@ public class OptitrackStreamingClient : MonoBehaviour return skelState; } + /// + /// 락을 유지한 채로 스켈레톤 포즈를 pre-allocated 딕셔너리에 복사. + /// GetLatestSkeletonState() 후 락 없이 BonePoses를 순회하는 torn read를 방지. + /// + /// 스켈레톤 데이터가 존재하면 true, 없으면 false. + public bool FillBoneSnapshot( Int32 skeletonId, + Dictionary posOut, + Dictionary oriOut, + out OptitrackHiResTimer.Timestamp deliveryTimestamp ) + { + deliveryTimestamp = default( OptitrackHiResTimer.Timestamp ); + lock ( m_frameDataUpdateLock ) + { + OptitrackSkeletonState state; + if ( !m_latestSkeletonStates.TryGetValue( skeletonId, out state ) || state == null ) + return false; + + deliveryTimestamp = state.DeliveryTimestamp; + posOut.Clear(); + oriOut.Clear(); + foreach ( var kvp in state.BonePoses ) + { + posOut[kvp.Key] = kvp.Value.Position; + oriOut[kvp.Key] = kvp.Value.Orientation; + } + return true; + } + } + + /// Get the most recently received state for the specified trained markerset. /// /// Taken from the corresponding field. @@ -1310,95 +1391,80 @@ public class OptitrackStreamingClient : MonoBehaviour /// /// (Re)initializes and connects to the configured streaming server. + /// 연결 초기화는 코루틴으로 위임하여 Thread.Sleep으로 메인 스레드를 블락하지 않는다. /// void OnEnable() { - IPAddress serverAddr = IPAddress.Parse( ServerAddress ); - IPAddress localAddr = IPAddress.Parse( LocalAddress ); + m_receivedFrameSinceConnect = false; + StartCoroutine( ConnectCoroutine() ); + } + private System.Collections.IEnumerator ConnectCoroutine() + { + IPAddress serverAddr; + IPAddress localAddr; NatNetConnectionType connType; - switch ( ConnectionType ) - { - case ClientConnectionType.Unicast: - connType = NatNetConnectionType.NatNetConnectionType_Unicast; - break; - case ClientConnectionType.Multicast: - default: - connType = NatNetConnectionType.NatNetConnectionType_Multicast; - break; - } try { + serverAddr = IPAddress.Parse( ServerAddress ); + localAddr = IPAddress.Parse( LocalAddress ); + connType = ConnectionType == ClientConnectionType.Unicast + ? NatNetConnectionType.NatNetConnectionType_Unicast + : NatNetConnectionType.NatNetConnectionType_Multicast; + m_client = new NatNetClient(); m_client.Connect( connType, localAddr, serverAddr ); - + // Remotely change the Skeleton Coordinate property to Global/Local - if (SkeletonCoordinates == StreamingCoordinatesValues.Global) - { + if (SkeletonCoordinates == StreamingCoordinatesValues.Global) m_client.RequestCommand("SetProperty,,Skeleton Coordinates,false"); - } else - { m_client.RequestCommand("SetProperty,,Skeleton Coordinates,true"); - } - // Remotely change the Bone Naming Convention to Motive/FBX/BVH - if(BoneNamingConvention == OptitrackBoneNameConvention.Motive) - { + // Remotely change the Bone Naming Convention to Motive/FBX/BVH + if (BoneNamingConvention == OptitrackBoneNameConvention.Motive) m_client.RequestCommand("SetProperty,,Bone Naming Convention,0"); - } else if (BoneNamingConvention == OptitrackBoneNameConvention.FBX) - { m_client.RequestCommand("SetProperty,,Bone Naming Convention,1"); - } else if (BoneNamingConvention == OptitrackBoneNameConvention.BVH) - { m_client.RequestCommand("SetProperty,,Bone Naming Convention,2"); - } - - // Make sure that remotely setting the properties has time to complete. - Thread.Sleep(100); - - if (!SkipDataDescriptions) - { - UpdateDefinitions(); - } - - if (ConnectionType == ClientConnectionType.Unicast) - { - // Clear all subscriptions - ResetStreamingSubscriptions(); - - // Re-subscribe to rigid bodies and/or skeletons in which the streaming client has data - foreach (KeyValuePair rb in m_rigidBodies) - { - SubscribeRigidBody(rb.Value, rb.Key); - } - foreach (KeyValuePair skel in m_skeletons) - { - SubscribeSkeleton(skel.Value, skel.Key); - } - foreach (KeyValuePair tmark in m_tmarkersets) // trained markerset added - { - SubscribeTMarkerset(tmark.Value, tmark.Key); - } - } - - - if ( RecordOnPlay == true ) - { - StartRecording(); - } - } catch ( Exception ex ) { Debug.LogException( ex, this ); Debug.LogError( GetType().FullName + ": Error connecting to server; check your configuration, and make sure the server is currently streaming.", this ); - this.enabled = false; - return; + if (m_client != null) { m_client.Dispose(); m_client = null; } + yield break; } + + // SetProperty 명령이 서버에 적용될 때까지 대기 (메인 스레드 블락 없이) + yield return new UnityEngine.WaitForSeconds( 0.1f ); + + try + { + if (!SkipDataDescriptions) + UpdateDefinitions(); + } + catch (Exception ex) + { + Debug.LogException(ex, this); + } + + if (ConnectionType == ClientConnectionType.Unicast) + { + ResetStreamingSubscriptions(); + foreach (KeyValuePair rb in m_rigidBodies) + SubscribeRigidBody(rb.Value, rb.Key); + foreach (KeyValuePair skel in m_skeletons) + SubscribeSkeleton(skel.Value, skel.Key); + foreach (KeyValuePair tmark in m_tmarkersets) // trained markerset added + SubscribeTMarkerset(tmark.Value, tmark.Key); + } + + if (RecordOnPlay) + StartRecording(); + byte[] NatNetVersion = m_client.ServerDescription.NatNetVersion; ServerNatNetVersion = NatNetVersion[0] + "." + NatNetVersion[1] + "." + NatNetVersion[2] + "." + NatNetVersion[3]; ClientNatNetVersion = "" + NatNetClient.NatNetLibVersion; @@ -1413,21 +1479,21 @@ public class OptitrackStreamingClient : MonoBehaviour /// void OnDisable() { - if ( m_connectionHealthCoroutine != null ) - { - StopCoroutine( m_connectionHealthCoroutine ); - m_connectionHealthCoroutine = null; - } + // ConnectCoroutine 포함 모든 코루틴 정지 + StopAllCoroutines(); + m_connectionHealthCoroutine = null; + m_isReconnecting = false; - if (RecordOnPlay == true) + if (m_client != null) { - StopRecording(); - } + if (RecordOnPlay) + StopRecording(); - m_client.NativeFrameReceived -= OnNatNetFrameReceived; - m_client.Disconnect(); - m_client.Dispose(); - m_client = null; + m_client.NativeFrameReceived -= OnNatNetFrameReceived; + try { m_client.Disconnect(); } catch { } + m_client.Dispose(); + m_client = null; + } } @@ -1480,6 +1546,12 @@ public class OptitrackStreamingClient : MonoBehaviour // Transition: Good health -> bad health. wasReceivingFrames = false; Debug.LogWarning( GetType().FullName + ": No streaming frames received from the server recently.", this ); + if ( AutoReconnect ) + { + Debug.Log( GetType().FullName + ": 자동 재연결을 시작합니다...", this ); + Reconnect(); + // OnDisable() → StopAllCoroutines() 로 이 코루틴은 다음 yield 에서 중지됨 + } continue; } } @@ -1502,9 +1574,10 @@ public class OptitrackStreamingClient : MonoBehaviour /// private void OnNatNetFrameReceived( object sender, NatNetClient.NativeFrameReceivedEventArgs eventArgs ) { - // In the event of contention, drop the frame being delivered and return immediately. - // We don't want to stall NatNetLib's internal network service thread. - if ( ! Monitor.TryEnter( m_frameDataUpdateLock ) ) + // 경합 시 최대 1ms 대기 후 드롭. + // FillBoneSnapshot의 락 보유 시간이 ~0.1ms이므로 정상 상황에서는 드롭 없음. + // GC Pause 등 1ms 초과 상황에서만 드롭 (허용 가능). + if ( ! Monitor.TryEnter( m_frameDataUpdateLock, 1 ) ) { return; } @@ -1513,7 +1586,8 @@ public class OptitrackStreamingClient : MonoBehaviour { // Update health markers. m_receivedFrameSinceConnect = true; - Interlocked.Exchange( ref m_lastFrameDeliveryTimestamp.m_ticks, OptitrackHiResTimer.Now().m_ticks ); + OptitrackHiResTimer.Timestamp frameTimestamp = OptitrackHiResTimer.Now(); + Interlocked.Exchange( ref m_lastFrameDeliveryTimestamp.m_ticks, frameTimestamp.m_ticks ); // Process received frame. IntPtr pFrame = eventArgs.NativeFramePointer; @@ -1572,6 +1646,7 @@ public class OptitrackStreamingClient : MonoBehaviour // Ensure we have a state corresponding to this skeleton ID. OptitrackSkeletonState skelState = GetOrCreateSkeletonState( skeletonId ); + skelState.DeliveryTimestamp = frameTimestamp; // Enumerate this skeleton's bone rigid bodies. Int32 skelRbCount; @@ -1612,7 +1687,10 @@ public class OptitrackStreamingClient : MonoBehaviour OptitrackSkeletonDefinition skelDef = GetSkeletonDefinitionById(skeletonId); if (skelDef == null) { - Debug.LogError(GetType().FullName + ": OnNatNetFrameReceived, no corresponding skeleton definition for received skeleton frame data.", this); + // Motive에서 중간에 스켈레톤이 생성된 경우 — 메인 스레드에서 정의 재조회 예약 + if (!m_pendingDefinitionRefresh) + Debug.LogWarning(GetType().FullName + ": 알 수 없는 스켈레톤 ID " + skeletonId + " — 정의 재조회 예약됨.", this); + m_pendingDefinitionRefresh = true; continue; } diff --git a/Assets/External/OptiTrack Unity Plugin/README.md b/Assets/External/OptiTrack Unity Plugin/README.md new file mode 100644 index 000000000..413308ac1 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/README.md @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a627e4fa19b2508cf4cd139de48b8c0e34f1eca394f1fd565785cbecf2e8b0cb +size 9496 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab.meta b/Assets/External/OptiTrack Unity Plugin/README.md.meta similarity index 62% rename from Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab.meta rename to Assets/External/OptiTrack Unity Plugin/README.md.meta index af7aad4da..d084a6149 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/BaseAvatar/Y Bot.prefab.meta +++ b/Assets/External/OptiTrack Unity Plugin/README.md.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 1a66efc1999717242b75f047a3877193 -PrefabImporter: +guid: 0e7e6625c79d3c146b42d152675716c1 +TextScriptImporter: externalObjects: {} userData: assetBundleName: diff --git a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs index 69470ce27..437dcea5f 100644 --- a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs +++ b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs @@ -987,10 +987,11 @@ namespace KindRetargeting targetHips.position = adjustedPosition; } + // 스파인/넥 분배를 먼저 실행하여 부모 계층 확정 후 자식 본(Head/Shoulder/Arm) 세팅 + ApplyOptiTrackSpineNeckDistribution(); + // 힙을 제외한 본들의 회전 동기화 SyncBoneRotations(skipBone: HumanBodyBones.Hips); - - ApplyOptiTrackSpineNeckDistribution(); } /// diff --git a/Assets/Scripts/KindRetargeting/README.md b/Assets/Scripts/KindRetargeting/README.md new file mode 100644 index 000000000..0ead25e2f --- /dev/null +++ b/Assets/Scripts/KindRetargeting/README.md @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a468d775910756cb5761bd2c4202e8ddf3a65f215153d753fc91c9711d4d868c +size 14396 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab.meta b/Assets/Scripts/KindRetargeting/README.md.meta similarity index 62% rename from Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab.meta rename to Assets/Scripts/KindRetargeting/README.md.meta index 9d4095c72..162991e50 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/BaseAvatar - OptiTrack ver 2.prefab.meta +++ b/Assets/Scripts/KindRetargeting/README.md.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ecb211056d7c61047aa8380b0b541a81 -PrefabImporter: +guid: d824776c483e7cc479af82ca17d3ac7f +TextScriptImporter: externalObjects: {} userData: assetBundleName: diff --git a/Assets/Scripts/KindRetargeting/Remote/RetargetingRemoteController.cs b/Assets/Scripts/KindRetargeting/Remote/RetargetingRemoteController.cs index cae5f77e6..9887a4b77 100644 --- a/Assets/Scripts/KindRetargeting/Remote/RetargetingRemoteController.cs +++ b/Assets/Scripts/KindRetargeting/Remote/RetargetingRemoteController.cs @@ -770,12 +770,15 @@ namespace KindRetargeting.Remote { var field = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); if (field != null) - { return (T)field.GetValue(obj); - } - } - catch (Exception) { } + // 필드를 찾지 못함 — 필드명 변경이나 오타 확인 필요 + Debug.LogWarning($"[RetargetingRemote] 필드를 찾을 수 없음: {fieldName} ({obj.GetType().Name}) — 필드명 변경 여부 확인"); + } + catch (Exception ex) + { + Debug.LogError($"[RetargetingRemote] 필드 읽기 오류 ({fieldName}): {ex.Message}"); + } return default(T); } @@ -787,7 +790,10 @@ namespace KindRetargeting.Remote if (field != null) { field.SetValue(obj, value); + return; } + // 필드를 찾지 못함 — 값이 적용되지 않음 + Debug.LogError($"[RetargetingRemote] 필드를 찾을 수 없음: {fieldName} ({obj.GetType().Name}) — 필드명 변경 여부 확인"); } catch (Exception ex) {