From e9e1c1228428d6963798a9c602a8fd84a6cbe250 Mon Sep 17 00:00:00 2001 From: "DESKTOP-S4BOTN2\\user" Date: Sat, 3 May 2025 16:30:57 +0900 Subject: [PATCH] =?UTF-8?q?ADD=20:=20I-pose=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=ED=8C=A8=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Plugins/Managed/NatNetLib/Client.cs | 18 +- .../Plugins/Managed/NatNetLib/Native.cs | 116 +- .../OptiTrack/Plugins/x86_64/NatNetLib.dll | 4 +- .../Plugins/x86_64/NatNetLib.dll.meta | 52 +- .../Prefabs/Client - OptiTrack.prefab | 4 +- .../OptiTrack/Prefabs/Horse_TM.fbx | 3 + .../OptiTrack/Prefabs/Horse_TM.fbx.meta | 107 + .../Retargeted Skeleton - OptiTrack.prefab | 4 +- ...etargeted Skeleton - OptiTrack.prefab.meta | 5 +- .../OptiTrack/Prefabs/Rigid Body.prefab | 4 +- .../OptiTrack/Prefabs/Rigid Body.prefab.meta | 2 +- .../OptiTrack/README_OptiTrack_Unity.txt | 4 +- .../OptiTrack/Scenes/OptiTrackScene.unity | 4 +- .../OptiTrack/Scripts/OptitrackRigidBody.cs | 141 +- .../Scripts/OptitrackSkeletonAnimator.cs | 46 +- .../Scripts/OptitrackStreamingClient.cs | 586 ++++- .../Scripts/OptitrackTrainedMarkerset.cs | 190 ++ .../Scripts/OptitrackTrainedMarkerset.cs.meta | 2 + .../Materials/EthanWhite.mat | 13 +- .../Models/Ethan.fbx.meta | 2153 ++++++----------- .../Runtime/Resources/I-Pose.pose.asset | 3 + .../Runtime/Resources/I-Pose.pose.asset.meta | 8 + .../Runtime/Resources/test_motion.txt.meta | 5 +- .../Runtime/UniHumanoid/HumanPoseClip.cs | 1 + .../Zonko_VRM.Materials/bodyA_mtoon.asset | 4 +- .../bodyB_eyepatch_mtoon.asset | 4 +- .../Zonko_VRM.Materials/bodyB_mtoon.asset | 4 +- .../emissionA_NoOutline_mtoon.asset | 4 +- .../Zonko_VRM.Materials/emissionB_mtoon.asset | 4 +- .../eyeGuruguru_mtoon.asset | 4 +- .../eyeKakusei_mtoon.asset | 4 +- .../Zonko_VRM.Materials/eye_mtoon.asset | 4 +- .../Zonko_VRM.Materials/face_mtoon.asset | 4 +- .../Zonko_VRM.Materials/glowA_mtoon.asset | 4 +- .../Zonko_VRM.Materials/glowB_mtoon.asset | 4 +- .../Zonko_VRM.Materials/hair_mtoon.asset | 4 +- .../Zonko_VRM.Materials/skinB_mtoon.asset | 4 +- .../Zonko_VRM.Materials/thunder_mtoon.asset | 4 +- .../Character/00.R&D/TestVRM/Zonko_VRM.prefab | 4 +- Assets/ResourcesData/Etc.meta | 8 + Assets/ResourcesData/Etc/Plane UV.meta | 8 + Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat | 136 ++ .../Etc/Plane UV/PlaneUV.mat.meta | 8 + Assets/ResourcesData/Etc/Plane UV/PlaneUV.png | 3 + .../Etc/Plane UV/PlaneUV.png.meta | 115 + Assets/Scenes/Development scene.unity | 4 +- Assets/Scripts/Editor.meta | 8 + Assets/Scripts/Editor/HumanPoseClipApplier.cs | 138 ++ .../Editor/HumanPoseClipApplier.cs.meta | 2 + Assets/Scripts/Editor/HumanPoseClipCreator.cs | 119 + .../Editor/HumanPoseClipCreator.cs.meta | 2 + .../CustomRetargetingScript.cs | 11 +- .../SpoutOutputScript/FinalOutputShader.mat | 2 +- .../FinalOutputShader.shadergraph | 14 - Packages/manifest.json | 4 +- Packages/packages-lock.json | 4 +- ProjectSettings/TagManager.asset | 4 +- 57 files changed, 2402 insertions(+), 1723 deletions(-) create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs create mode 100644 Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta create mode 100644 Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset create mode 100644 Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta create mode 100644 Assets/ResourcesData/Etc.meta create mode 100644 Assets/ResourcesData/Etc/Plane UV.meta create mode 100644 Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat create mode 100644 Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta create mode 100644 Assets/ResourcesData/Etc/Plane UV/PlaneUV.png create mode 100644 Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta create mode 100644 Assets/Scripts/Editor.meta create mode 100644 Assets/Scripts/Editor/HumanPoseClipApplier.cs create mode 100644 Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta create mode 100644 Assets/Scripts/Editor/HumanPoseClipCreator.cs create mode 100644 Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Client.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Client.cs index 0e6a321d..3a2c02cc 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Client.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Client.cs @@ -1,5 +1,5 @@ - /* -Copyright 2016 NaturalPoint Inc. +/* +Copyright � 2016 NaturalPoint Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,8 +18,8 @@ limitations under the License. using System; using System.Collections.Generic; using System.Net; -using System.Runtime.InteropServices; - +using System.Runtime.InteropServices; +using UnityEngine; namespace NaturalPoint.NatNetLib { @@ -252,6 +252,7 @@ namespace NaturalPoint.NatNetLib public List MarkerSetDescriptions; public List RigidBodyDescriptions; public List SkeletonDescriptions; + public List AssetDescriptions; // trained markerset added public List ForcePlateDescriptions; public List CameraDescriptions; } @@ -472,6 +473,7 @@ namespace NaturalPoint.NatNetLib Int32 numMarkerSetDescs = 0; Int32 numRigidBodyDescs = 0; Int32 numSkeletonDescs = 0; + Int32 numAssetDescs = 0; // trained markerset added Int32 numForcePlateDescs = 0; Int32 numCameraDescs = 0; @@ -490,6 +492,9 @@ namespace NaturalPoint.NatNetLib case (Int32)NatNetDataDescriptionType.NatNetDataDescriptionType_Skeleton: ++numSkeletonDescs; break; + case (Int32)NatNetDataDescriptionType.NatNetDataDescriptionType_Asset: + ++numAssetDescs; // trained markerset added + break; case (Int32)NatNetDataDescriptionType.NatNetDataDescriptionType_ForcePlate: ++numForcePlateDescs; break; @@ -504,6 +509,7 @@ namespace NaturalPoint.NatNetLib MarkerSetDescriptions = new List( numMarkerSetDescs ), RigidBodyDescriptions = new List( numRigidBodyDescs ), SkeletonDescriptions = new List( numSkeletonDescs ), + AssetDescriptions = new List(numAssetDescs), // trained markerset added ForcePlateDescriptions = new List( numForcePlateDescs ), CameraDescriptions = new List( numCameraDescs ), }; @@ -527,6 +533,10 @@ namespace NaturalPoint.NatNetLib sSkeletonDescription skeletonDesc = (sSkeletonDescription)Marshal.PtrToStructure( desc.Description, typeof( sSkeletonDescription ) ); retDescriptions.SkeletonDescriptions.Add( skeletonDesc ); break; + case (Int32)NatNetDataDescriptionType.NatNetDataDescriptionType_Asset: // trained markerset added + sAssetDescription assetDesc = (sAssetDescription)Marshal.PtrToStructure(desc.Description, typeof(sAssetDescription)); + retDescriptions.AssetDescriptions.Add( assetDesc ); + break; case (Int32)NatNetDataDescriptionType.NatNetDataDescriptionType_ForcePlate: sForcePlateDescription forcePlateDesc = (sForcePlateDescription)Marshal.PtrToStructure( desc.Description, typeof( sForcePlateDescription ) ); retDescriptions.ForcePlateDescriptions.Add( forcePlateDesc ); diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Native.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Native.cs index 88f1e454..fe219ab9 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Native.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/Managed/NatNetLib/Native.cs @@ -1,5 +1,5 @@ /* -Copyright 2016 NaturalPoint Inc. +Copyright � 2016 NaturalPoint Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ using NaturalPoint.NatNetLib; // Found in NatNetTypes.h + // NOTE: These native structure representations are in some places incomplete // (e.g. IntPtr to unspecified data) or untested (e.g. the force plate data // types have not received any testing). See NatNetTypes.h for more info. @@ -40,6 +41,7 @@ namespace NaturalPoint.NatNetLib public const int MaxModels = 2000; public const int MaxMarkerSets = 1000; public const int MaxRigidBodies = 1000; + // Add Assets public const int MaxAssets = 1000; @@ -65,6 +67,7 @@ namespace NaturalPoint.NatNetLib // where is client/server msg ids ?? + #region Enumerations internal enum NatNetError { @@ -93,9 +96,11 @@ namespace NaturalPoint.NatNetLib NatNetDataDescriptionType_ForcePlate, NatNetDataDescriptionType_Device, NatNetDataDescriptionType_Camera, + NatNetDataDescriptionType_Asset, }; + internal enum NatNetVerbosity { None = 0, @@ -105,6 +110,7 @@ namespace NaturalPoint.NatNetLib Error, }; + internal enum AssetTypes { Undefined = 0, @@ -118,7 +124,10 @@ namespace NaturalPoint.NatNetLib // Sender_Server ?? // Packet ?? + + #region Definition types + // Defns : From MarkerData to CameraDesc [StructLayout( LayoutKind.Sequential )] // control physical layout of class in memory // Sequential : laid out in order they are defined @@ -129,9 +138,10 @@ namespace NaturalPoint.NatNetLib } + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Ansi )] - // strings in structure are marshaled as ANSI default - internal struct sServerDescription // following sequence in NatNetTypes.h + + internal struct sServerDescription { [MarshalAs( UnmanagedType.U1 )] // bool - 1-byte unsigned int, particular reason to // choose this way of boolean? @@ -141,6 +151,7 @@ namespace NaturalPoint.NatNetLib // always use SizeConst, character type used with ByValTStr is determined by CharSet public string HostComputerName; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 4 )] // SizeConst in this case is # elements in the array public byte[] HostComputerAddress; @@ -148,6 +159,7 @@ namespace NaturalPoint.NatNetLib [MarshalAs( UnmanagedType.ByValTStr, SizeConst = NatNetConstants.MaxNameLength )] public string HostApp; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 4 )] public byte[] HostAppVersion; @@ -165,11 +177,13 @@ namespace NaturalPoint.NatNetLib [MarshalAs( UnmanagedType.U1 )] public bool ConnectionMulticast; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 4 )] public byte[] ConnectionMulticastAddress; } + [StructLayout( LayoutKind.Sequential )] internal struct sDataDescriptions // Array of data descs { @@ -180,6 +194,7 @@ namespace NaturalPoint.NatNetLib } + [StructLayout( LayoutKind.Sequential )] internal struct sDataDescription { @@ -188,6 +203,7 @@ namespace NaturalPoint.NatNetLib } + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Ansi )] internal struct sMarkerSetDescription { @@ -202,6 +218,7 @@ namespace NaturalPoint.NatNetLib } + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Ansi )] internal struct sRigidBodyDescription { @@ -213,6 +230,12 @@ namespace NaturalPoint.NatNetLib public float OffsetX; public float OffsetY; public float OffsetZ; + + public float OffsetQX; + public float OffsetQY; + public float OffsetQZ; + public float OffsetQW; + public Int32 MarkerCount; public IntPtr MarkerPositions; // Pointer to float[MarkerCount][3] public IntPtr MarkerRequiredLabels; // Pointer to int32_t[MarkerCount] @@ -336,6 +359,7 @@ namespace NaturalPoint.NatNetLib public float Size; // marker size public Int16 Params; // Host defined parameters. Bit values: // 0 : Active + } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] @@ -346,13 +370,12 @@ namespace NaturalPoint.NatNetLib public Int32 AssetType; public Int32 AssetID; - public Int32 RigidBodyCount; + public Int32 RigidBodyCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxSkeletonRigidBodies)] public sRigidBodyDescription[] RigidBodies; public Int32 MarkerCount; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxMarkers)] // check public sMarkerDescription[] Markers; } @@ -362,6 +385,7 @@ namespace NaturalPoint.NatNetLib // AssetDescription ? - done // MarkerDescription ? - done + #region Data types [StructLayout( LayoutKind.Sequential )] internal struct sFrameOfMocapData @@ -387,6 +411,10 @@ namespace NaturalPoint.NatNetLib public Int32 AssetCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxAssets)] public sAssetData[] Assets; + + public Int32 TMarkersetMarkerCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxLabeledMarkers)] + public sMarker[] TMarkersetMarkers; public Int32 LabeledMarkerCount; [MarshalAs( UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxLabeledMarkers )] @@ -406,7 +434,7 @@ namespace NaturalPoint.NatNetLib public UInt64 CameraMidExposureTimestamp; public UInt64 CameraDataReceivedTimestamp; public UInt64 TransmitTimestamp; - // what about PrecisionTimestamps ?? + public Int16 Params; // [b0: recording] // [b1: model list changed] // [b2: Live/Edit mode (0=Live, 1=Edit)] @@ -490,6 +518,7 @@ namespace NaturalPoint.NatNetLib [MarshalAs( UnmanagedType.ByValArray, SizeConst = NatNetConstants.MaxAnalogChannels )] public sAnalogChannelData[] ChannelData; public Int16 Params; + } @@ -514,8 +543,7 @@ namespace NaturalPoint.NatNetLib public string ServerAddress; public string LocalAddress; public string MulticastAddress; - // subcribed Data ?? - // BitstreamVersion ?? + }; @@ -561,32 +589,29 @@ namespace NaturalPoint.NatNetLib internal static class NativeMethods { - // NatNetCAPI.cpp + + // Helper methods [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern void NatNet_GetVersion( [In, Out, MarshalAs( UnmanagedType.LPArray, SizeConst=4 )] byte[] version ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern void NatNet_SetLogCallback(NatNetLogCallback pfnCallback); + [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern void NatNet_DecodeID( Int32 compositeId, out Int32 entityId, out Int32 memberId ); [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] public static extern void NatNet_DecodeTimecode(UInt32 compositeId, UInt32 timecodeSubframe, out Int32 pOutHour, out Int32 pOutMinute, out Int32 pOutSecond, out Int32 pOutFrame, out Int32 pOutSubFrame); - // TimecodeStringify ?? - - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern void NatNet_SetLogCallback( NatNetLogCallback pfnCallback ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_CreateAsyncServerDiscovery(out IntPtr discoveryHandle, NatNetServerDiscoveryCallback pfnCallback, IntPtr pUserContext = default(IntPtr), [MarshalAs(UnmanagedType.U1)] bool startImmediately = true); - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_CreateAsyncServerDiscovery( out IntPtr discoveryHandle, NatNetServerDiscoveryCallback pfnCallback, IntPtr pUserContext = default(IntPtr), [MarshalAs( UnmanagedType.U1 )] bool startImmediately = true ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)] + public static extern NatNetError NatNet_AddDirectServerToAsyncDiscovery(IntPtr discoveryHandle, string serverAddress); - // Not in NatNet - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true )] - public static extern NatNetError NatNet_AddDirectServerToAsyncDiscovery( IntPtr discoveryHandle, string serverAddress ); - - // Not in NatNet - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_StartAsyncDiscovery( IntPtr discoveryHandle ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_StartAsyncDiscovery(IntPtr discoveryHandle); [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_FreeAsyncServerDiscovery( IntPtr discoveryHandle ); @@ -596,6 +621,7 @@ namespace NaturalPoint.NatNetLib // These functions are not a supported part of the public API, and are // subject to change without notice. + // client methods [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_Client_Create( out IntPtr clientHandle ); @@ -623,8 +649,9 @@ namespace NaturalPoint.NatNetLib [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_Client_SecondsSinceHostTimestamp( IntPtr clientHandle, UInt64 inTimestamp, out double pOutTimeElapsed ); - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_Client_GetPredictedRigidBodyPose( IntPtr client, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData, double dt ); + // frame methods + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_GetTransmitTimestamp(IntPtr pFrameOfMocapData, out UInt64 pOutTransmitTimestamp); [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] public static extern NatNetError NatNet_Frame_GetTimecode(IntPtr pFrameOfMocapData, out UInt32 timecode, out UInt32 timecodeSubframe); @@ -635,6 +662,14 @@ namespace NaturalPoint.NatNetLib [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_Frame_GetRigidBody( IntPtr pFrameOfMocapData, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Client_GetPredictedRigidBodyPose(IntPtr client, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData, double dt); + + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_GetLabeledMarkerCount(IntPtr pFrameOfMocapData, out Int32 labeledMarkerCount); + + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_GetLabeledMarker(IntPtr pFrameOfMocapData, Int32 labeledMarkerIndex, out sMarker labeledMarkerData); [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_Frame_GetSkeletonCount( IntPtr pFrameOfMocapData, out Int32 skeletonCount ); @@ -648,15 +683,36 @@ namespace NaturalPoint.NatNetLib [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] public static extern NatNetError NatNet_Frame_Skeleton_GetRigidBody( IntPtr pFrameOfMocapData, Int32 skeletonIndex, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData ); + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_GetTMarkersetCount(IntPtr pFrameOfMocapData, out Int32 tmarkersetCount); - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_Frame_GetTransmitTimestamp( IntPtr pFrameOfMocapData, out UInt64 pOutTransmitTimestamp ); + // trained markerset added + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_TMarkerset_GetId(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, out Int32 tmarkersetId); + // trained markerset added + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_TMarkerset_GetRigidBodyCount(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, out Int32 rigidBodyCount); - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_Frame_GetLabeledMarkerCount( IntPtr pFrameOfMocapData, out Int32 labeledMarkerCount ); + // trained markerset added + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_TMarkerset_GetRigidBody(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData); + + // trained markerset added + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_TMarkerset_GetMarkerCount(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, out Int32 assetMarkerCount); + + // trained markerset added + [DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + public static extern NatNetError NatNet_Frame_TMarkerset_GetMarker(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, Int32 markerIndex, out sMarker markerData); + + //// trained markerset added + //[DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + //public static extern NatNetError NatNet_Frame_TMarkerset_GetMarkerCount(IntPtr pFrameOfMocapData, out Int32 tmarkMarkerCount); + + //// trained markerset added + //[DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)] + //public static extern NatNetError NatNet_Frame_TMarkerset_GetMarker(IntPtr pFrameOfMocapData, Int32 tmarkMarkerIdx, out sMarker markerData); - [DllImport( NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention )] - public static extern NatNetError NatNet_Frame_GetLabeledMarker( IntPtr pFrameOfMocapData, Int32 labeledMarkerIndex, out sMarker labeledMarkerData ); } } diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll index 5bb72641..7f77fd2b 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dce3d5bca185ff7241a0dab86bf33f79c50731f85e5d4b342cfd112d55ba858 -size 136192 +oid sha256:d1c63719ccbf7c2010f64d3bdd6e54ca816de301baff85a658f0d9363728c829 +size 137216 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll.meta index b4cc8ccb..47f86b1c 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll.meta +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll.meta @@ -1,52 +1,2 @@ fileFormatVersion: 2 -guid: 90a37dc4ae5b35a45876059d687031bc -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 0 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - Any: - second: - enabled: 1 - settings: {} - - first: - Editor: Editor - second: - enabled: 0 - settings: - CPU: x86_64 - DefaultValueInitialized: true - - first: - Standalone: Linux64 - second: - enabled: 1 - settings: - CPU: x86_64 - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: x86_64 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 1 - settings: - CPU: x86_64 - userData: - assetBundleName: - assetBundleVariant: +guid: 90a37dc4ae5b35a45876059d687031bc \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab index 7395f747..c7636c5c 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d7e3e9e3ae8f6c381473c5a2b1e13617b44ae0c6c5eca8cf607af7b77abf1eb -size 1559 +oid sha256:cf165614d7c436093115e79a170efced6bbbd80dbaedadbbd1fa909e2edb06fb +size 1688 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx new file mode 100644 index 00000000..eaebe14d --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx @@ -0,0 +1,3 @@ +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 new file mode 100644 index 00000000..ea3dd8f2 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta @@ -0,0 +1,107 @@ +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 index 4f33438d..eca75eda 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee9fa8de0b50befb135ddc90faa35503f4b5dad6d72c437ae6625771254e0665 -size 81831 +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 index 3463c69d..10f7455b 100644 --- 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 @@ -1,8 +1,7 @@ fileFormatVersion: 2 guid: afbc9c9b98650e44f97662b4f503c261 -timeCreated: 1470265618 -licenseType: Free -NativeFormatImporter: +PrefabImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab index 73757857..308adf5e 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:631446346c5ccc77014278a4cc564c742f4b37f5bcc9f884c5a39fd464863a68 -size 3371 +oid sha256:f5ca816ee920573ed3be88d69c78bf22036e65fe69c995d3bc5f34d990790125 +size 3730 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab.meta index f265c1a7..6dfbbb58 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab.meta +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1e09d962f56189d46ad6bcd146c01a77 +guid: f6a3494b5f1724443a3bf3aa6741c8a4 PrefabImporter: externalObjects: {} userData: diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt b/Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt index c1069df8..c449fc24 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9c4c7316f1f228cc5593001a92607e7ba7962d485fd1b700445adcfe762cc0f -size 4819 +oid sha256:fbd5eb5af17461fce6630487443a5ccb38b390e0e67d4d8f03723494ef244986 +size 5193 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity index 62b14848..7f832f8f 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:014f3772b9eabdb86408044aa6124bb4b96a3eff8144e818fae94734557fdc7a -size 3747 +oid sha256:40caa227e0779f0ede687714db64266ceaaa41c1339c7eaea14923455b1a5f52 +size 20422 diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRigidBody.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRigidBody.cs index c7d509bb..da6ea31c 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRigidBody.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackRigidBody.cs @@ -1,93 +1,108 @@ -using System; -using System.Collections; +/* +Copyright © 2016 NaturalPoint Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +using System; using UnityEngine; + /// -/// Implements live tracking of streamed OptiTrack rigid body data onto an object using Rigid Body Name instead of ID, -/// and periodically rechecks the ID. +/// Implements live tracking of streamed OptiTrack rigid body data onto an object. /// public class OptitrackRigidBody : MonoBehaviour { - [Tooltip("The object containing the OptiTrackStreamingClient script.")] - public OptitrackStreamingClient StreamingClient; + [Tooltip("The ID of the rigid body to track.")] + public int rigidBodyId; - [Tooltip("The name of the rigid body in Motive.")] - public string RigidBodyName; + [Tooltip("Whether to use network compensation for this rigid body.")] + public bool useNetworkCompensation = true; - private float updateInterval = 0.1f; + private OptitrackStreamingClient m_streamingClient; + private bool m_isRigidBodyFound = false; - private int RigidBodyId = -1; - private string lastCheckedName; // 마지막으로 확인한 이름을 저장 - - [HideInInspector] - public bool isRigidBodyFound = false; + public bool isRigidBodyFound + { + get { return m_isRigidBodyFound; } + } void Start() { - // StreamingClient를 찾습니다. - if (this.StreamingClient == null) + m_streamingClient = OptitrackStreamingClient.FindDefaultClient(); + if (m_streamingClient == null) { - this.StreamingClient = OptitrackStreamingClient.FindDefaultClient(); - - if (this.StreamingClient == null) - { - Debug.LogError(GetType().FullName + ": Streaming client not set, and no " + typeof(OptitrackStreamingClient).FullName + " components found in scene; disabling this component.", this); - this.enabled = false; - return; - } + Debug.LogError("OptitrackRigidBody: No OptitrackStreamingClient found in scene.", this); + return; } - // 주기적으로 RigidBody를 찾는 코루틴 시작 - StartCoroutine(CheckRigidBodyIdPeriodically()); + m_streamingClient.RegisterRigidBody(this, rigidBodyId); } - void Update() + +#if UNITY_2017_1_OR_NEWER + void OnEnable() + { + Application.onBeforeRender += OnBeforeRender; + } + + + void OnDisable() + { + Application.onBeforeRender -= OnBeforeRender; + } + + + void OnBeforeRender() { UpdatePose(); } +#endif + + + void Update() + { + if (m_streamingClient == null) + return; + + OptitrackRigidBodyState rbState = m_streamingClient.GetLatestRigidBodyState(rigidBodyId, useNetworkCompensation); + if (rbState != null) + { + m_isRigidBodyFound = rbState.IsTracked; + if (m_isRigidBodyFound) + { + transform.position = rbState.Pose.Position; + transform.rotation = rbState.Pose.Orientation; + } + } + else + { + m_isRigidBodyFound = false; + } + } + void UpdatePose() { - if (!isRigidBodyFound) return; - - OptitrackRigidBodyState rbState = StreamingClient.GetLatestRigidBodyState(RigidBodyId); + OptitrackRigidBodyState rbState = m_streamingClient.GetLatestRigidBodyState(rigidBodyId, useNetworkCompensation); if (rbState != null) { - this.transform.localPosition = rbState.Pose.Position; - this.transform.localRotation = rbState.Pose.Orientation; - } - } - - private IEnumerator CheckRigidBodyIdPeriodically() - { - while (true) - { - // 현재 이름이 마지막으로 확인한 이름과 다르거나, RigidBody를 찾지 못한 상태라면 검색 수행 - if (lastCheckedName != RigidBodyName || !isRigidBodyFound) + m_isRigidBodyFound = rbState.IsTracked; + if (m_isRigidBodyFound) { - int newRigidBodyId = StreamingClient.GetRigidBodyIdByName(RigidBodyName); - - if (newRigidBodyId != -1) - { - if (newRigidBodyId != RigidBodyId) - { - // 새로운 RigidBody 발견 - RigidBodyId = newRigidBodyId; - this.StreamingClient.RegisterRigidBody(this, RigidBodyId); - Debug.Log($"RigidBody 재연결 성공: {RigidBodyName} (ID: {RigidBodyId})"); - } - isRigidBodyFound = true; - lastCheckedName = RigidBodyName; - } - else - { - // RigidBody를 찾지 못함 - isRigidBodyFound = false; - //Debug.LogWarning($"RigidBody를 찾을 수 없음: {RigidBodyName}"); - } + transform.position = rbState.Pose.Position; + transform.rotation = rbState.Pose.Orientation; } - - yield return new WaitForSeconds(updateInterval); } } } diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator.cs index b2c57263..470f6c1e 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackSkeletonAnimator.cs @@ -130,13 +130,14 @@ public class OptitrackSkeletonAnimator : MonoBehaviour void Update() { - OptitrackSkeletonState skelState = StreamingClient.GetLatestSkeletonState( m_skeletonDef.Id ); - if ( skelState != null ) + OptitrackSkeletonState skelState = StreamingClient.GetLatestSkeletonState(m_skeletonDef.Id); + if (skelState != null) { // Update the transforms of the bone GameObjects. - for ( int i = 0; i < m_skeletonDef.Bones.Count; ++i ) + for (int i = 0; i < m_skeletonDef.Bones.Count; ++i) { Int32 boneId = m_skeletonDef.Bones[i].Id; + string boneName = m_skeletonDef.Bones[i].Name; OptitrackPose bonePose; GameObject boneObject; @@ -144,36 +145,51 @@ public class OptitrackSkeletonAnimator : MonoBehaviour bool foundPose = false; if (StreamingClient.SkeletonCoordinates == StreamingCoordinatesValues.Global) { - // Use global skeleton coordinates foundPose = skelState.LocalBonePoses.TryGetValue(boneId, out bonePose); } else { - // Use local skeleton coordinates foundPose = skelState.BonePoses.TryGetValue(boneId, out bonePose); } - bool foundObject = m_boneObjectMap.TryGetValue( boneId, out boneObject ); - + bool foundObject = m_boneObjectMap.TryGetValue(boneId, out boneObject); if (foundPose && foundObject) { - boneObject.transform.localPosition = bonePose.Position; - boneObject.transform.localRotation = bonePose.Orientation; + // 손가락 본인 경우 회전 데이터는 무시하고 위치 데이터만 적용 + if (IsFingerBone(boneName)) + { + boneObject.transform.localPosition = bonePose.Position; + // 회전은 기본값 유지 + boneObject.transform.localRotation = Quaternion.identity; + } + else + { + // 손가락이 아닌 다른 본들은 모든 데이터 적용 + boneObject.transform.localPosition = bonePose.Position; + boneObject.transform.localRotation = bonePose.Orientation; + } } } // Perform Mecanim retargeting. - if ( m_srcPoseHandler != null && m_destPoseHandler != null ) + if (m_srcPoseHandler != null && m_destPoseHandler != null) { - // Interpret the streamed pose into Mecanim muscle space representation. - m_srcPoseHandler.GetHumanPose( ref m_humanPose ); - - // Re-target that muscle space pose to the destination avatar. - m_destPoseHandler.SetHumanPose( ref m_humanPose ); + m_srcPoseHandler.GetHumanPose(ref m_humanPose); + m_destPoseHandler.SetHumanPose(ref m_humanPose); } } } + // 손가락 본인지 확인하는 헬퍼 메서드 + private bool IsFingerBone(string boneName) + { + return boneName.Contains("Thumb") || + boneName.Contains("Index") || + boneName.Contains("Middle") || + boneName.Contains("Ring") || + boneName.Contains("Pinky") || + boneName.Contains("Finger"); + } #region Private methods /// diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs index 05ebc91b..d3184793 100644 --- a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackStreamingClient.cs @@ -22,6 +22,11 @@ using System.Threading; using UnityEngine; using NaturalPoint; using NaturalPoint.NatNetLib; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; +using static TMPro.SpriteAssetUtilities.TexturePacker_JsonArray; /// Skeleton naming conventions supported by OptiTrack Motive. @@ -77,6 +82,14 @@ public class OptitrackSkeletonState public Dictionary LocalBonePoses; } +/// Represents the state of a streamed trained markerset at an instant in time. +public class OptitrackTMarkersetState // trained markerset added +{ + /// Maps from OptiTrack bone IDs to their corresponding bone poses. + public Dictionary BonePoses; + public Dictionary LocalBonePoses; +} + public class OptitrackRigidBodyDefinition { @@ -125,6 +138,55 @@ public class OptitrackSkeletonDefinition public Dictionary BoneIdToParentIdMap; } + +public class OptitrackTMarkersetDefinition // trained markerset added // check where this is coming from +{ + public class BoneDefinition + { + /// The ID of this bone within this trained markerset. + public Int32 Id; + + /// The ID of this bone's parent bone. A value of 0 means that this is the root bone. + public Int32 ParentId; + + /// The name of this bone. + public string Name; + + /// + /// This bone's position offset from its parent in the skeleton's neutral pose. + /// (The neutral orientation is always .) + /// + public Vector3 Offset; + } + + public class MarkerDefinition + { + /// The name of this marker. + public string Name; + public Vector3 Position; + public Int32 Id; + + //public float Size; + //public bool Labeled; + //public bool IsActive; + } + + /// Asset ID. Used as an argument to . + public Int32 Id; + + /// Skeleton asset name. + public string Name; + + /// Bone names, hierarchy, and neutral pose position information. + public List Bones; + + /// Bone hierarchy information + public Dictionary BoneIdToParentIdMap; + + public List Markers; +} + + public class OptitrackMarkersDefinition { /// The name of this bone. @@ -236,6 +298,9 @@ public class OptitrackStreamingClient : MonoBehaviour [Tooltip("Controls whether skeleton data is streamed with local or global coordinates.")] public StreamingCoordinatesValues SkeletonCoordinates = StreamingCoordinatesValues.Local; + [Tooltip("Controls whether tmarkerset data is streamed with local or global coordinates.")] + public StreamingCoordinatesValues TMarkersetCoordinates = StreamingCoordinatesValues.Local; + [Tooltip("Controls the Bone Naming Convention in the streamed data.")] public OptitrackBoneNameConvention BoneNamingConvention = OptitrackBoneNameConvention.Motive; @@ -244,6 +309,9 @@ public class OptitrackStreamingClient : MonoBehaviour [Tooltip("Draws marker visuals in the viewport for debugging and other uses. Using this will increase the data rate in Unicast mode.")] public bool DrawMarkers = false; + [Tooltip("Draws trained markerset marker visuals in the viewport for debugging and other uses. Using this will increase the data rate in Unicast mode.")] + public bool DrawTMarkersetMarkers = false; // trained markerset added + [Tooltip("Draws camera visuals in the viewport for debugging and other uses. Motive 3.0+ only.")] public bool DrawCameras = false; @@ -256,6 +324,13 @@ 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("Changes to the version of Natnet used by the server")] + public string ServerNatNetVersion = ""; + public string ClientNatNetVersion = ""; + + //[Tooltip("Timecode Provider")] + //public bool TimecodeProvider = false; + #region Private fields //private UInt16 ServerCommandPort = NatNetConstants.DefaultCommandPort; @@ -266,6 +341,7 @@ public class OptitrackStreamingClient : MonoBehaviour private bool m_hasDrawnCameras = false; private bool m_hasDrawnForcePlates = false; private bool m_subscribedToMarkers = false; + private bool m_subscribedToTMarkMarkers = false; // trained markerset added private OptitrackHiResTimer.Timestamp m_lastFrameDeliveryTimestamp; private Coroutine m_connectionHealthCoroutine = null; @@ -274,6 +350,8 @@ public class OptitrackStreamingClient : MonoBehaviour private NatNetClient.DataDescriptions m_dataDescs; private List m_rigidBodyDefinitions = new List(); private List m_skeletonDefinitions = new List(); + private List m_tmarkersetDefinitions = new List(); // trained markerset added + private List m_tmarkmarkersDefinitions = new List(); // trained markerset added private List m_markersDefinitions = new List(); private List m_cameraDefinitions = new List(); private List m_forcePlateDefinitions = new List(); @@ -284,18 +362,30 @@ public class OptitrackStreamingClient : MonoBehaviour /// Maps from a streamed skeleton's ID to its most recent available pose data. private Dictionary m_latestSkeletonStates = new Dictionary(); + /// Maps from a streamed trained markerset's ID to its most recent available pose data. + private Dictionary m_latestTMarkersetStates = new Dictionary(); // trained markerset added + /// Maps from a streamed marker's ID to its most recent available position. private Dictionary m_latestMarkerStates = new Dictionary(); + /// Maps from a streamed trained markerset marker's ID to its most recent available position. + private Dictionary m_latestTMarkMarkerStates = new Dictionary(); // trained markerset added + /// Maps from a streamed rigid body's ID to its component. private Dictionary m_rigidBodies = new Dictionary(); /// Maps from a streamed skeleton names to its component. private Dictionary m_skeletons = new Dictionary(); + /// Maps from a streamed trained markerset names to its component. + private Dictionary m_tmarkersets = new Dictionary(); // trained markerset added + /// Maps from a streamed marker's ID to its sphere game object. Used for drawing markers. private Dictionary m_latestMarkerSpheres = new Dictionary(); + /// Maps from a streamed trained markerset marker's ID to its sphere game object. Used for drawing markers. + private Dictionary m_latestTMarkMarkerSpheres = new Dictionary(); // trained markerset added + /// /// Lock held during access to fields which are potentially modified by (which /// executes on a separate thread). Note while the lock is held, any frame updates received are simply dropped. @@ -314,6 +404,7 @@ public class OptitrackStreamingClient : MonoBehaviour } List markerIds = new List(); + //Debug.Log("markers: " + m_latestMarkerStates.Count); lock (m_frameDataUpdateLock) { // Move existing spheres and create new ones if necessary @@ -325,7 +416,7 @@ public class OptitrackStreamingClient : MonoBehaviour } else { - var sphere = GameObject.CreatePrimitive( PrimitiveType.Sphere ); + var sphere = GameObject.CreatePrimitive( PrimitiveType.Cube ); sphere.transform.parent = this.transform; sphere.transform.localScale = new Vector3( markerEntry.Value.Size, markerEntry.Value.Size, markerEntry.Value.Size ); sphere.transform.position = markerEntry.Value.Position; @@ -438,6 +529,77 @@ public class OptitrackStreamingClient : MonoBehaviour } + //if (TimecodeProvider) + //{ + // Debug.Log(""); + //} + + // Trained Markerset Markers if requested to draw // trained markerset added + if (DrawTMarkersetMarkers) + { + //if (m_client != null && ConnectionType == ClientConnectionType.Unicast && !m_subscribedToTMarkMarkers) + //{ + // SubscribeTMarkMarkers(); + //} + + List tmarkmarkerIds = new List(); + //Debug.Log("tmark states: " + m_latestTMarkMarkerStates.Count); + lock (m_frameDataUpdateLock) + { + // Move existing spheres and create new ones if necessary + foreach (KeyValuePair markerEntry in m_latestTMarkMarkerStates) + { + if (m_latestTMarkMarkerSpheres.ContainsKey(markerEntry.Key)) + { + m_latestTMarkMarkerSpheres[markerEntry.Key].transform.position = markerEntry.Value.Position; + } + else + { + var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); + cube.transform.parent = this.transform; + cube.transform.localScale = new Vector3(markerEntry.Value.Size, markerEntry.Value.Size, markerEntry.Value.Size); + cube.transform.position = markerEntry.Value.Position; + cube.name = markerEntry.Value.Name; + if (markerEntry.Value.IsActive) + { + // Make active markers cyan colored + cube.GetComponent().material.SetColor("_Color", Color.cyan); + } + m_latestTMarkMarkerSpheres[markerEntry.Key] = cube; + } + tmarkmarkerIds.Add(markerEntry.Key); + } + // find spheres to remove that weren't in the previous frame + List markerCubeIdsToDelete = new List(); + foreach (KeyValuePair markerCubeEntry in m_latestTMarkMarkerSpheres) + { + if (!tmarkmarkerIds.Contains(markerCubeEntry.Key)) + { + // stale marker, tag for removal + markerCubeIdsToDelete.Add(markerCubeEntry.Key); + } + } + // remove stale spheres + foreach (Int32 markerId in markerCubeIdsToDelete) + { + if (m_latestTMarkMarkerSpheres.ContainsKey(markerId)) + { + Destroy(m_latestTMarkMarkerSpheres[markerId]); + m_latestTMarkMarkerSpheres.Remove(markerId); + } + } + } + } + else + { + // not drawing markers, remove all marker spheres + foreach (KeyValuePair markerCubeEntry in m_latestTMarkMarkerSpheres) + { + Destroy(m_latestTMarkMarkerSpheres[markerCubeEntry.Key]); + } + m_latestTMarkMarkerSpheres.Clear(); + } + } @@ -449,7 +611,7 @@ public class OptitrackStreamingClient : MonoBehaviour /// An arbitrary OptitrackClient from the scene, or null if none are found. public static OptitrackStreamingClient FindDefaultClient() { - OptitrackStreamingClient[] allClients = FindObjectsByType(FindObjectsSortMode.None); + OptitrackStreamingClient[] allClients = FindObjectsOfType(); if ( allClients.Length == 0 ) { @@ -517,26 +679,9 @@ public class OptitrackStreamingClient : MonoBehaviour } return rbState; - } - - public int GetRigidBodyIdByName(string name) - { - // 먼저 정의 목록을 업데이트 - UpdateDefinitions(); - - // 정의 목록에서 이름으로 Rigid Body ID를 찾음 - foreach (var rbDef in m_rigidBodyDefinitions) - { - if (rbDef.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) - { - return rbDef.Id; - } - } - - // 이름이 없으면 -1 반환 - return -1; } + /// Get the most recently received state for the specified skeleton. /// /// Taken from the corresponding field. @@ -555,6 +700,25 @@ public class OptitrackStreamingClient : MonoBehaviour return skelState; } + /// Get the most recently received state for the specified trained markerset. + /// + /// Taken from the corresponding field. + /// To find the appropriate skeleton definition, use . + /// + /// The most recent available state, or null if none available. + public OptitrackTMarkersetState GetLatestTMarkersetState(Int32 tmarkersetId) + { + OptitrackTMarkersetState tmarState; + + lock (m_frameDataUpdateLock) + { + m_latestTMarkersetStates.TryGetValue(tmarkersetId, out tmarState); + } + + return tmarState; + } + + /// Get the most recently received state for streamed markers. /// The most recent available marker states, or null if none available. public List GetLatestMarkerStates() @@ -635,6 +799,68 @@ public class OptitrackStreamingClient : MonoBehaviour return null; } + /// Retrieves the definition of the tmarkerset with the specified asset name. + /// The name of the tmarkerset for which to retrieve the definition. + /// The specified tmarkerset definition, or null if not found. // trained markerset added + public OptitrackTMarkersetDefinition GetTMarkersetDefinitionByName(string TMarkersetName) + { + for (int i = 0; i < m_tmarkersetDefinitions.Count; i++) + { + OptitrackTMarkersetDefinition tmarDef = m_tmarkersetDefinitions[i]; + + if (tmarDef.Name.Equals(TMarkersetName, StringComparison.InvariantCultureIgnoreCase)) + { + return tmarDef; + } + } + + return null; + } + + /// Retrieves the definition of the tmarkerset with the specified tmarkerset id. + /// The id of the tmarkerset for which to retrieve the definition. + /// The specified tmarkerset definition, or null if not found. // trained markerset added + public OptitrackTMarkersetDefinition GetTMarkersetDefinitionById(Int32 tmarkersetId) + { + for (int i = 0; i < m_tmarkersetDefinitions.Count; ++i) + { + OptitrackTMarkersetDefinition tmarDef = m_tmarkersetDefinitions[i]; + + if (tmarDef.Id == tmarkersetId) + { + return tmarDef; + } + } + + return null; + } + + /// Get the most recently received state for streamed trained markerset markers. + /// The most recent available trained markerset marker states, or null if none available. + public List GetLatestTMarkMarkerStates() // trained markerset added + { + List tmarkmarkerStates = new List(); + Debug.Log("GetLatestTMarkMarker: " + m_latestTMarkMarkerStates.Count); + + lock (m_frameDataUpdateLock) + { + foreach (KeyValuePair markerEntry in m_latestTMarkMarkerStates) + { + OptitrackMarkerState newMarkerState = new OptitrackMarkerState + { + Position = markerEntry.Value.Position, + Labeled = markerEntry.Value.Labeled, + Size = markerEntry.Value.Size, + Id = markerEntry.Value.Id + }; + tmarkmarkerStates.Add(newMarkerState); + } + } + + return tmarkmarkerStates; + } + + /// Request data descriptions from the host, then update our definitions. /// /// Thrown by if the request to the server fails. @@ -645,6 +871,7 @@ public class OptitrackStreamingClient : MonoBehaviour UInt32 descriptionTypeMask = 0; descriptionTypeMask |= (1 << (int)NatNetDataDescriptionType.NatNetDataDescriptionType_RigidBody); descriptionTypeMask |= (1 << (int)NatNetDataDescriptionType.NatNetDataDescriptionType_Skeleton); + descriptionTypeMask |= (1 << (int)NatNetDataDescriptionType.NatNetDataDescriptionType_Asset); // trained markerset added if (DrawMarkers) { descriptionTypeMask |= (1 << (int)NatNetDataDescriptionType.NatNetDataDescriptionType_MarkerSet); @@ -661,6 +888,7 @@ public class OptitrackStreamingClient : MonoBehaviour m_rigidBodyDefinitions.Clear(); m_skeletonDefinitions.Clear(); + m_tmarkersetDefinitions.Clear(); // ---------------------------------- // - Translate Rigid Body Definitions @@ -735,6 +963,68 @@ public class OptitrackStreamingClient : MonoBehaviour m_skeletonDefinitions.Add( skelDef ); } + // -------------------------------------------------------------------- + // - Translate Trained Markerset Definitions // trained markerset added + // -------------------------------------------------------------------- + for (int nativeTmarkDescIdx = 0; nativeTmarkDescIdx < m_dataDescs.AssetDescriptions.Count; ++nativeTmarkDescIdx) + { + sAssetDescription nativeTmark = m_dataDescs.AssetDescriptions[nativeTmarkDescIdx]; + // Debug.Log("#rbs: " + nativeTmark.RigidBodyCount); // correct + + OptitrackTMarkersetDefinition tmarkDef = new OptitrackTMarkersetDefinition + { + Id = nativeTmark.AssetID, + Name = nativeTmark.Name, + Bones = new List(nativeTmark.RigidBodyCount), + BoneIdToParentIdMap = new Dictionary(), + Markers = new List(nativeTmark.MarkerCount), + }; + + // Populate nested bone definitions. + for (int nativeBoneIdx = 0; nativeBoneIdx < nativeTmark.RigidBodyCount; ++nativeBoneIdx) + { + sRigidBodyDescription nativeBone = nativeTmark.RigidBodies[nativeBoneIdx]; + + OptitrackTMarkersetDefinition.BoneDefinition boneDef = + new OptitrackTMarkersetDefinition.BoneDefinition + { + Id = nativeBone.Id, + ParentId = nativeBone.ParentId, + Name = nativeBone.Name, + Offset = new Vector3(-nativeBone.OffsetX, nativeBone.OffsetY, nativeBone.OffsetZ), + }; + + tmarkDef.Bones.Add(boneDef); + tmarkDef.BoneIdToParentIdMap[boneDef.Id] = boneDef.ParentId; + } + + // Populate nested marker definitions + for (int nativeMarkerIdx = 0; nativeMarkerIdx < nativeTmark.MarkerCount; ++nativeMarkerIdx) + { + sMarkerDescription nativeMarker = nativeTmark.Markers[nativeMarkerIdx]; + //Debug.Log("TMarkerset (X, Y, Z): " + nativeMarker.X + " " + nativeMarker.Y + " " + nativeMarker.Z); + //Debug.Log(nativeMarker.Id + " " + nativeMarker.Name); + + OptitrackTMarkersetDefinition.MarkerDefinition markerDef = + new OptitrackTMarkersetDefinition.MarkerDefinition + { + Name = nativeMarker.Name, + Id = nativeMarker.Id, + Position = new Vector3(-nativeMarker.X, nativeMarker.Y, nativeMarker.Z), + }; + tmarkDef.Markers.Add(markerDef); + + } + + //foreach (KeyValuePair kvp in tmarkDef.BoneIdToParentIdMap) + //{ + // Debug.Log("Key: " + kvp.Key + "Value: " + kvp.Value); + //} // correct + + m_tmarkersetDefinitions.Add(tmarkDef); + } + + // ---------------------------------- // - Get Marker Definitions (ToDo) // ---------------------------------- @@ -862,6 +1152,18 @@ public class OptitrackStreamingClient : MonoBehaviour SubscribeSkeleton(component, name); } + public void RegisterTMarkerset(MonoBehaviour component, string name) // trained markerset added + { + if (m_tmarkersets.ContainsKey(name)) + { + return; + } + + m_tmarkersets[name] = component; + + SubscribeTMarkerset(component, name); + } + /// /// (Re)initializes and connects to the configured streaming server. @@ -934,6 +1236,10 @@ public class OptitrackStreamingClient : MonoBehaviour { SubscribeSkeleton(skel.Value, skel.Key); } + foreach (KeyValuePair tmark in m_tmarkersets) // trained markerset added + { + SubscribeTMarkerset(tmark.Value, tmark.Key); + } } @@ -950,6 +1256,9 @@ public class OptitrackStreamingClient : MonoBehaviour this.enabled = false; return; } + byte[] NatNetVersion = m_client.ServerDescription.NatNetVersion; + ServerNatNetVersion = NatNetVersion[0] + "." + NatNetVersion[1] + "." + NatNetVersion[2] + "." + NatNetVersion[3]; + ClientNatNetVersion = "" + NatNetClient.NatNetLibVersion; m_client.NativeFrameReceived += OnNatNetFrameReceived; m_connectionHealthCoroutine = StartCoroutine( CheckConnectionHealth() ); @@ -1077,6 +1386,7 @@ public class OptitrackStreamingClient : MonoBehaviour result = NaturalPoint.NatNetLib.NativeMethods.NatNet_Frame_GetTimecode(pFrame, out timecode, out timecodeSubframe); Int32 hour, minute, second, frameNumber, subframeNumber; NaturalPoint.NatNetLib.NativeMethods.NatNet_DecodeTimecode(timecode, timecodeSubframe, out hour, out minute, out second, out frameNumber, out subframeNumber); + //Debug.Log(hour + "......" + minute + second + frameNumber + subframeNumber); // ---------------------- // - Update rigid bodies @@ -1174,6 +1484,100 @@ public class OptitrackStreamingClient : MonoBehaviour } } + // ----------------------------------------------------- + // - Update trained markerset // trained markerset added + // ---------------------------------------------------- + //Int32 frameTMarkersetCount = m_dataDescs.AssetDescriptions.Count; + /*result = NaturalPoint.NatNetLib.NativeMethods.NatNet_Frame_GetTMarkersetCount(pFrame, out frameTMarkersetCount); + NatNetException.ThrowIfNotOK(result, "NatNet_Frame_GetTMarkersetCount failed.");*/ + + for (int tmarkIdx = 0; tmarkIdx < m_dataDescs.AssetDescriptions.Count; ++tmarkIdx) + { + Int32 tmarkersetId = m_dataDescs.AssetDescriptions[tmarkIdx].AssetID; + + // Ensure we have a state corresponding to this tmarkerset ID. + OptitrackTMarkersetState tmarkState = GetOrCreateTMarkersetState(tmarkersetId); + + // Enumerate this tmarkerset's bone rigid bodies. + Int32 tmarkRbCount = m_dataDescs.AssetDescriptions[tmarkIdx].RigidBodyCount; + + for (int boneIdx = 0; boneIdx < tmarkRbCount; ++boneIdx) + { + sRigidBodyData boneData = new sRigidBodyData(); + result = NaturalPoint.NatNetLib.NativeMethods.NatNet_Frame_TMarkerset_GetRigidBody(pFrame, tmarkIdx, boneIdx, out boneData); + NatNetException.ThrowIfNotOK(result, "NatNet_Frame_TMarkerset_GetRigidBody failed."); + + // In the context of frame data (unlike in the definition data), this ID value is a + // packed composite of both the asset/entity (tmarkerset) ID and member (bone) ID. + Int32 boneTMarkId, boneId; + NaturalPoint.NatNetLib.NativeMethods.NatNet_DecodeID(boneData.Id, out boneTMarkId, out boneId); + + // TODO: Could pre-populate this map when the definitions are retrieved. + // Should never allocate after the first frame, at least. + if (tmarkState.BonePoses.ContainsKey(boneId) == false) + { + tmarkState.BonePoses[boneId] = new OptitrackPose(); + } + if (tmarkState.LocalBonePoses.ContainsKey(boneId) == false) + { + tmarkState.LocalBonePoses[boneId] = new OptitrackPose(); + } + + // Flip coordinate handedness from right to left by inverting X and W. + Vector3 bonePos = new Vector3(-boneData.X, boneData.Y, boneData.Z); + Quaternion boneOri = new Quaternion(-boneData.QX, boneData.QY, boneData.QZ, -boneData.QW); + tmarkState.BonePoses[boneId].Position = bonePos; + tmarkState.BonePoses[boneId].Orientation = boneOri; + + Vector3 parentBonePos = new Vector3(0, 0, 0); + Quaternion parentBoneOri = new Quaternion(0, 0, 0, 1); + + OptitrackTMarkersetDefinition tmarkDef = GetTMarkersetDefinitionById(tmarkersetId); + if (tmarkDef == null) + { + Debug.LogError(GetType().FullName + ": OnNatNetFrameReceived, no corresponding tmarkerset definition for received tmarkerset frame data.", this); + continue; + } + + Int32 pId = tmarkDef.BoneIdToParentIdMap[boneId]; + if (pId != -1) + { + parentBonePos = tmarkState.BonePoses[pId].Position; + parentBoneOri = tmarkState.BonePoses[pId].Orientation; + } + tmarkState.LocalBonePoses[boneId].Position = bonePos - parentBonePos; + tmarkState.LocalBonePoses[boneId].Orientation = Quaternion.Inverse(parentBoneOri) * boneOri; + } + + // -------------------------------------------- + // - Update trained markerset markers + // -------------------------------------------- + Int32 tmarkMarkerCount = m_dataDescs.AssetDescriptions[tmarkIdx].MarkerCount; + /*result = NaturalPoint.NatNetLib.NativeMethods.NatNet_Frame_TMarkerset_GetMarkerCount(pFrame, tmarkIdx, out tmarkMarkerCount); + NatNetException.ThrowIfNotOK(result, "NatNet_Frame_TMarkerset_GetMarkerCount failed.");*/ + //Debug.Log("tmark marker count: " + tmarkMarkerCount); // working finally + + m_latestTMarkMarkerStates.Clear(); + + // Update Trained Markerset Marker data + for (int markerIdx = 0; markerIdx < tmarkMarkerCount; ++markerIdx) + { + sMarker tmarker = new sMarker(); // markerData + result = NaturalPoint.NatNetLib.NativeMethods.NatNet_Frame_TMarkerset_GetMarker(pFrame, tmarkIdx, markerIdx, out tmarker); + NatNetException.ThrowIfNotOK(result, "NatNet_Frame_TMarkerset_GetMarker failed."); + //Debug.Log("result: " + result); + + // Flip coordinate handedness + OptitrackMarkerState tmarkerState = GetOrCreateTMarkMarkerState(tmarker.Id); + tmarkerState.Name = GetMarkerName(tmarker); + tmarkerState.Position = new Vector3(-tmarker.X, tmarker.Y, tmarker.Z); + tmarkerState.Size = tmarker.Size; + tmarkerState.Labeled = (tmarker.Params & 0x10) == 0; + tmarkerState.Id = tmarker.Id; + tmarkerState.IsActive = (tmarker.Params & 0x20) != 0; + } + + } // ---------------------- // - Update markers @@ -1183,6 +1587,7 @@ public class OptitrackStreamingClient : MonoBehaviour NatNetException.ThrowIfNotOK( result, "NatNet_Frame_GetLabeledMarkerCount failed."); m_latestMarkerStates.Clear(); + //Debug.Log("marker count: " + MarkerCount); for (int markerIdx = 0; markerIdx < MarkerCount; ++markerIdx) { @@ -1199,6 +1604,7 @@ public class OptitrackStreamingClient : MonoBehaviour markerState.Id = marker.Id; markerState.IsActive = (marker.Params & 0x20) != 0; } + } catch (Exception ex) { @@ -1220,7 +1626,8 @@ public class OptitrackStreamingClient : MonoBehaviour // Figure out the asset name if it exists. string assetName = ""; OptitrackRigidBodyDefinition rigidBodyDef = GetRigidBodyDefinitionById( assetID ); - OptitrackSkeletonDefinition skeletonDef = GetSkeletonDefinitionById(assetID); + OptitrackSkeletonDefinition skeletonDef = GetSkeletonDefinitionById( assetID ); + OptitrackTMarkersetDefinition tmarkersetDef = GetTMarkersetDefinitionById( assetID ); if (rigidBodyDef != null) { @@ -1230,6 +1637,10 @@ public class OptitrackStreamingClient : MonoBehaviour { assetName = skeletonDef.Name; } + else if (tmarkersetDef != null) + { + assetName = tmarkersetDef.Name; + } // Figure out if the marker is labeled or active bool IsLabeled = (marker.Params & 0x10) == 0; @@ -1348,6 +1759,81 @@ public class OptitrackStreamingClient : MonoBehaviour } } + private void SubscribeTMarkerset(MonoBehaviour component, string name) // check the version numbers // trained markerset added + { + if (m_client != null && ConnectionType == ClientConnectionType.Unicast) + { + if (m_client.ServerAppVersion >= new Version(2, 2, 1)) + { + // Try subscribing up to 3 times with a 2000 ms timeout before giving up. + bool subscribeSucceeded = m_client.RequestCommand("SubscribeToData,TrainedMarkersets," + name, 2000, 3); + + // Log a warning on the first failure. + if (!subscribeSucceeded && !m_doneSubscriptionNotice) + { + Debug.LogError("Failed to subscribe to trained markerset streaming data for component", component); + m_doneSubscriptionNotice = true; + } + } + + else if (m_client.ServerAppVersion == new Version(2, 2, 0, 0)) + { + // Motive 2.2.0 has a bug were Motive says it subscribes successfully, but doesn't. + // Subscribing to all skeletons still works, so for this version that is done instead. + + // Try subscribing up to 3 times with a 2000 ms timeout before giving up. + bool subscribeSucceeded = m_client.RequestCommand("SubscribeToData,TrainedMarkersets,All" + name, 2000, 3); + + if (!subscribeSucceeded && !m_doneSubscriptionNotice) + { + Debug.LogError("Failed to subscribe to all trained markersets streaming data some unknown reason.", component); + m_doneSubscriptionNotice = true; + } + } + + else + { + Debug.LogWarning("Your version of Motive is too old to support NatNet skeleton data subscription; streaming bandwidth consumption may be higher than necessary. This feature works in Motive 2.2.1+."); + m_doneSubscriptionNotice = true; + } + } + + } + + private void SubscribeTMarkMarkers() + { + if (m_client != null && ConnectionType == ClientConnectionType.Unicast) + { + bool subscribeSucceeded4 = m_client.RequestCommand("SubscribeToData, TrainedMarkersetMarkers,All", 2000, 3); + //Debug.Log("TMMarkers: " + subscribeSucceeded4); + + // Log a warning on the first failure. + if (!subscribeSucceeded4 && !m_doneSubscriptionNotice) + { + if (m_client.ServerDescription.HostApp == "Motive") + { + // Host app is Motive: If new enough to support subscription, failure is an error. + // Otherwise, warn them that they may want to update Motive to reduce bandwidth consumption. + if (m_client.ServerAppVersion >= new Version(2, 2, 0)) + { + Debug.LogError("Failed to subscribe to tmark marker streaming data"); + } + else + { + Debug.LogWarning("Your version of Motive is too old to support NatNet tmark marker data subscription; streaming bandwidth consumption may be higher than necessary. This feature works in Motive 2.2.0+."); + } + } + else + { + // Not Motive, we don't know whether it "should" support this. Warning instead of error. + Debug.LogWarning("Failed to subscribe to tmark marker streaming data"); + } + + m_doneSubscriptionNotice = true; + } + } + } + private void SubscribeMarkers( ) { if (m_client != null && ConnectionType == ClientConnectionType.Unicast) @@ -1356,6 +1842,8 @@ public class OptitrackStreamingClient : MonoBehaviour bool subscribeSucceeded = m_client.RequestCommand("SubscribeToData,MarkerSetMarkers,All", 2000, 3); bool subscribeSucceeded2 = m_client.RequestCommand("SubscribeToData,LabeledMarkers,All", 2000, 3); bool subscribeSucceeded3 = m_client.RequestCommand("SubscribeToData,LegacyUnlabeledMarkers,All", 2000, 3); + //bool subscribeSucceeded4 = m_client.RequestCommand("SubscribeToData, TrainedMarkersetMarkers,All", 2000, 3); + //bool allSubscribeSucceeded = subscribeSucceeded4; bool allSubscribeSucceeded = subscribeSucceeded && subscribeSucceeded2 && subscribeSucceeded3; m_subscribedToMarkers = allSubscribeSucceeded; @@ -1447,6 +1935,60 @@ public class OptitrackStreamingClient : MonoBehaviour return returnedState; } + private OptitrackTMarkersetState GetOrCreateTMarkersetState(Int32 tmarkersetId) + { + OptitrackTMarkersetState returnedState = null; + + if (m_latestTMarkersetStates.ContainsKey(tmarkersetId)) + { + returnedState = m_latestTMarkersetStates[tmarkersetId]; + } + else + { + OptitrackTMarkersetState newTMarkersetState = new OptitrackTMarkersetState + { + BonePoses = new Dictionary(), + LocalBonePoses = new Dictionary(), + }; + + m_latestTMarkersetStates[tmarkersetId] = newTMarkersetState; + + returnedState = newTMarkersetState; + } + + return returnedState; + } + + /// + /// Returns the corresponding to the provided . + /// If the requested state object does not exist yet, it will initialize and return a newly-created one. + /// + /// Makes the assumption that the lock on is already held. + /// The ID of the bone in trained markerset for which to retrieve the corresponding state. + /// The existing state object, or a newly created one if necessary. + private OptitrackMarkerState GetOrCreateTMarkMarkerState(Int32 markerId) + { + OptitrackMarkerState returnedState = null; + + if (m_latestTMarkMarkerStates.ContainsKey(markerId)) + { + returnedState = m_latestTMarkMarkerStates[markerId]; + } + else + { + OptitrackMarkerState newMarkerState = new OptitrackMarkerState + { + Position = new Vector3(), + }; + + m_latestTMarkMarkerStates[markerId] = newMarkerState; + + returnedState = newMarkerState; + } + + //Debug.Log(returnedState); + return returnedState; + } /// /// Returns the corresponding to the provided . @@ -1490,4 +2032,4 @@ public class OptitrackStreamingClient : MonoBehaviour Monitor.Exit( m_frameDataUpdateLock ); } #endregion Private methods -} +} \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs new file mode 100644 index 00000000..e4ce9bd3 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs @@ -0,0 +1,190 @@ +/* +Copyright 2016 NaturalPoint Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +using System; +using System.Collections.Generic; +using UnityEngine; + + +/// +/// Implements live tracking of streamed OptiTrack trained markerset data onto an asset in Unity. +/// +/// +/// A hierarchy of GameObjects (see and ) will be created to +/// receive the streaming pose data for the tmarkerset asset specified by . +/// + +public class OptitrackTrainedMarkerset : MonoBehaviour +{ + /// The client object to use for receiving streamed TMarkerset pose data. + [Tooltip("The object containing the OptiTrackStreamingClient script.")] + public OptitrackStreamingClient StreamingClient; + + /// The name of the TMarkerset asset in the stream that will provide retargeting source data. + [Tooltip("The name of markerset asset in Motive.")] + public string TMarkersetAssetName = "TMarkerset1"; + + #region Private fields + /// The streamed source tmarkerset definition. + private OptitrackTMarkersetDefinition m_tmarkersetDef; + + /// The root GameObject of the streamed tmarkerset pose transform hierarchy. + private GameObject m_rootObject; + + /// Maps between OptiTrack tmarkerset bone IDs and corresponding GameObjects. + private Dictionary m_boneObjectMap; + + /// + /// Maps between game object's bone names (keys) and streamed bone names from OptiTrack software (values). + /// + private Dictionary m_cachedBoneNameMap = new Dictionary(); // Optitrack's skeleton's bone names + + private Dictionary m_transformMap = new Dictionary(); + + #endregion Private fields + + + void Start() + { + // If the user didn't explicitly associate a client, find a suitable default. + if (this.StreamingClient == null) + { + this.StreamingClient = OptitrackStreamingClient.FindDefaultClient(); + + // If we still couldn't find one, disable this component. + if (this.StreamingClient == null) + { + Debug.LogError(GetType().FullName + ": Streaming client not set, and no " + typeof(OptitrackStreamingClient).FullName + " components found in scene; disabling this component.", this); + this.enabled = false; + return; + } + } + + this.StreamingClient.RegisterTMarkerset(this, this.TMarkersetAssetName); + + // Retrieve the OptiTrack tmarkerset definition. + m_tmarkersetDef = this.StreamingClient.GetTMarkersetDefinitionByName(this.TMarkersetAssetName); + + if (m_tmarkersetDef == null) + { + Debug.LogError(GetType().FullName + ": Could not find trained markerset definition with the name \"" + this.TMarkersetAssetName + "\"", this); + this.enabled = false; + return; + } + + + // Create a hierarchy of GameObjects that will receive the tmarkerset pose data + string rootObjectName = "OptiTrack TMarkerset - " + this.TMarkersetAssetName; + m_rootObject = new GameObject( rootObjectName ); + + m_boneObjectMap = new Dictionary( m_tmarkersetDef.Bones.Count ); + + for (int boneDefIdx = 0; boneDefIdx < m_tmarkersetDef.Bones.Count; boneDefIdx++) + { + OptitrackTMarkersetDefinition.BoneDefinition boneDef = m_tmarkersetDef.Bones[boneDefIdx]; + + GameObject boneObject = new GameObject(boneDef.Name); + if (boneDef.ParentId == -1) { boneObject.name = "Root"; } // set the parent name to 'Root' to match the naming in dictionary + + boneObject.transform.parent = boneDef.ParentId == -1 ? m_rootObject.transform : m_boneObjectMap[boneDef.ParentId].transform; // parent ID starts at -1 in TM + boneObject.transform.localPosition = boneDef.Offset; + m_boneObjectMap[boneDef.Id] = boneObject; + //Debug.Log("boneDef: " + boneObject.name + " " + boneObject.transform.name); // exact same + m_cachedBoneNameMap[boneObject.transform.name] = boneObject.transform; + } + + Setup(rootObjectName); + + m_rootObject.transform.parent = this.StreamingClient.transform; + m_rootObject.transform.localPosition = Vector3.zero; + m_rootObject.transform.localRotation = Quaternion.identity; + } + + private void Update() + { + OptitrackTMarkersetState tmarState = StreamingClient.GetLatestTMarkersetState( m_tmarkersetDef.Id ); + if (tmarState != null) + { + // Update the transforms of the bone GameObjects. + for (int i = 0; i < m_tmarkersetDef.Bones.Count; ++i) + { + Int32 boneId = m_tmarkersetDef.Bones[i].Id; + + OptitrackPose bonePose; + GameObject boneObject; + + bool foundPose = false; + if (StreamingClient.TMarkersetCoordinates == StreamingCoordinatesValues.Global) + { + // Use global tmarkerset coordinates + foundPose = tmarState.LocalBonePoses.TryGetValue(boneId, out bonePose); + } + else + { + // Use local tmarkerset coordinates + foundPose = tmarState.BonePoses.TryGetValue(boneId, out bonePose); + } + + bool foundObject = m_boneObjectMap.TryGetValue(boneId, out boneObject); + if (foundPose && foundObject) + { + boneObject.transform.localPosition = bonePose.Position; + boneObject.transform.localRotation = bonePose.Orientation; + m_transformMap[boneObject.transform].transform.localPosition = bonePose.Position; + m_transformMap[boneObject.transform].transform.localRotation = bonePose.Orientation; + } + } + } + } + + #region Private methods + /// + /// Constructs the source to target mapping of the bones + /// + /// + private void Setup(string rootObjectName) + { + // Set up the mapping between destination Game Object and hierarchy of GameObjects we created with the source streamed data + //Debug.Log("name of gameobject: " + gameObject.name); + + GameObject srcObject = GameObject.Find(rootObjectName); + Transform[] srcObjectBones = srcObject.GetComponentsInChildren(); // source + + Transform[] tarObjectBones = this.GetComponentsInChildren(); // target + + // Iterate through the bones in source and map onto the destination + foreach (var bone in tarObjectBones) + { + if (bone.name.EndsWith("End")) + { + ; + } + else + { + if (m_cachedBoneNameMap.ContainsKey(bone.name) == false) + { + Debug.Log(bone.name + " name exists in target, but does not exist in the source."); + } + else + { + m_transformMap[m_cachedBoneNameMap[bone.name]] = bone; + } + } + + } + } + #endregion Private methods +} \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta new file mode 100644 index 00000000..5534f588 --- /dev/null +++ b/Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 07333194d9e70e74692863bb8b2c148a \ No newline at end of file diff --git a/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Materials/EthanWhite.mat b/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Materials/EthanWhite.mat index 797421f7..289ea712 100644 --- a/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Materials/EthanWhite.mat +++ b/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Materials/EthanWhite.mat @@ -1,6 +1,6 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: ---- !u!114 &-1324386466927670935 +--- !u!114 &-6543920408461200634 MonoBehaviour: m_ObjectHideFlags: 11 m_CorrespondingSourceObject: {fileID: 0} @@ -28,11 +28,7 @@ Material: - _EMISSION - _NORMALMAP - _OCCLUSIONMAP - - _SPECULAR_SETUP - m_InvalidKeywords: - - _LIGHTMAPPING_STATIC_LIGHTMAPS - - _UVPRIM_UV1 - - _UVSEC_UV1 + m_InvalidKeywords: [] m_LightmapFlags: 0 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -111,6 +107,7 @@ Material: m_Offset: {x: 0, y: 0} m_Ints: [] m_Floats: + - _AddPrecomputedVelocity: 0 - _AlphaClip: 0 - _AlphaTestRef: 0.5 - _AlphaToMask: 0 @@ -141,7 +138,7 @@ Material: - _QueueOffset: 0 - _ReceiveShadows: 1 - _Shininess: 0.41313845 - - _Smoothness: 0.15 + - _Smoothness: 0.5 - _SmoothnessTextureChannel: 0 - _SpecularHighlights: 1 - _SrcBlend: 1 @@ -149,7 +146,7 @@ Material: - _Surface: 0 - _UVPrim: 0 - _UVSec: 0 - - _WorkflowMode: 0 + - _WorkflowMode: 1 - _ZWrite: 1 m_Colors: - _BaseColor: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Models/Ethan.fbx.meta b/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Models/Ethan.fbx.meta index 0126e059..00ae0f7b 100644 --- a/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Models/Ethan.fbx.meta +++ b/Assets/External/OptiTrack Unity Plugin/Standard Assets/Characters/ThirdPersonCharacter/Models/Ethan.fbx.meta @@ -1,1094 +1,382 @@ fileFormatVersion: 2 guid: b235179bd2a63d1468dd430670338c55 +timeCreated: 1467401728 +licenseType: Free ModelImporter: - serializedVersion: 22200 - internalIDToNameTable: - - first: - 1: 100000 - second: char_cyberKid_Badge - - first: - 1: 100002 - second: char_ethan_body - - first: - 1: 100004 - second: char_ethan_glasses - - first: - 1: 100006 - second: char_ethan_Head - - first: - 1: 100008 - second: char_ethan_Head1 - - first: - 1: 100010 - second: char_ethan_Hips - - first: - 1: 100012 - second: char_ethan_Jaw - - first: - 1: 100014 - second: char_ethan_LeftArm - - first: - 1: 100016 - second: char_ethan_LeftBlink - - first: - 1: 100018 - second: char_ethan_LeftBrow - - first: - 1: 100020 - second: char_ethan_LeftCorner - - first: - 1: 100022 - second: char_ethan_LeftEye - - first: - 1: 100024 - second: char_ethan_LeftFoot - - first: - 1: 100026 - second: char_ethan_LeftForeArm - - first: - 1: 100028 - second: char_ethan_LeftHand - - first: - 1: 100030 - second: char_ethan_LeftHandIndex1 - - first: - 1: 100032 - second: char_ethan_LeftHandIndex2 - - first: - 1: 100034 - second: char_ethan_LeftHandIndex3 - - first: - 1: 100036 - second: char_ethan_LeftHandIndex4 - - first: - 1: 100038 - second: char_ethan_LeftHandMiddle1 - - first: - 1: 100040 - second: char_ethan_LeftHandMiddle2 - - first: - 1: 100042 - second: char_ethan_LeftHandMiddle3 - - first: - 1: 100044 - second: char_ethan_LeftHandMiddle4 - - first: - 1: 100046 - second: char_ethan_LeftHandPinky1 - - first: - 1: 100048 - second: char_ethan_LeftHandPinky2 - - first: - 1: 100050 - second: char_ethan_LeftHandPinky3 - - first: - 1: 100052 - second: char_ethan_LeftHandPinky4 - - first: - 1: 100054 - second: char_ethan_LeftHandRing1 - - first: - 1: 100056 - second: char_ethan_LeftHandRing2 - - first: - 1: 100058 - second: char_ethan_LeftHandRing3 - - first: - 1: 100060 - second: char_ethan_LeftHandRing4 - - first: - 1: 100062 - second: char_ethan_LeftHandThumb1 - - first: - 1: 100064 - second: char_ethan_LeftHandThumb2 - - first: - 1: 100066 - second: char_ethan_LeftHandThumb3 - - first: - 1: 100068 - second: char_ethan_LeftHandThumb4 - - first: - 1: 100070 - second: char_ethan_LeftLeg - - first: - 1: 100072 - second: char_ethan_LeftLowerLip - - first: - 1: 100074 - second: char_ethan_LeftShoulder - - first: - 1: 100076 - second: char_ethan_LeftToe1 - - first: - 1: 100078 - second: char_ethan_LeftToe2 - - first: - 1: 100080 - second: char_ethan_LeftUpLeg - - first: - 1: 100082 - second: char_ethan_LeftUpperLip - - first: - 1: 100084 - second: char_ethan_LowerLip - - first: - 1: 100086 - second: char_ethan_Neck - - first: - 1: 100088 - second: char_ethan_RightArm - - first: - 1: 100090 - second: char_ethan_RightBlink - - first: - 1: 100092 - second: char_ethan_RightBrow - - first: - 1: 100094 - second: char_ethan_RightCorner - - first: - 1: 100096 - second: char_ethan_RightEye - - first: - 1: 100098 - second: char_ethan_RightFoot - - first: - 1: 100100 - second: char_ethan_RightForeArm - - first: - 1: 100102 - second: char_ethan_RightHand - - first: - 1: 100104 - second: char_ethan_RightHandIndex1 - - first: - 1: 100106 - second: char_ethan_RightHandIndex2 - - first: - 1: 100108 - second: char_ethan_RightHandIndex3 - - first: - 1: 100110 - second: char_ethan_RightHandIndex4 - - first: - 1: 100112 - second: char_ethan_RightHandMiddle1 - - first: - 1: 100114 - second: char_ethan_RightHandMiddle2 - - first: - 1: 100116 - second: char_ethan_RightHandMiddle3 - - first: - 1: 100118 - second: char_ethan_RightHandMiddle4 - - first: - 1: 100120 - second: char_ethan_RightHandPinky1 - - first: - 1: 100122 - second: char_ethan_RightHandPinky2 - - first: - 1: 100124 - second: char_ethan_RightHandPinky3 - - first: - 1: 100126 - second: char_ethan_RightHandPinky4 - - first: - 1: 100128 - second: char_ethan_RightHandRing1 - - first: - 1: 100130 - second: char_ethan_RightHandRing2 - - first: - 1: 100132 - second: char_ethan_RightHandRing3 - - first: - 1: 100134 - second: char_ethan_RightHandRing4 - - first: - 1: 100136 - second: char_ethan_RightHandThumb1 - - first: - 1: 100138 - second: char_ethan_RightHandThumb2 - - first: - 1: 100140 - second: char_ethan_RightHandThumb3 - - first: - 1: 100142 - second: char_ethan_RightHandThumb4 - - first: - 1: 100144 - second: char_ethan_RightLeg - - first: - 1: 100146 - second: char_ethan_RightLowerLip - - first: - 1: 100148 - second: char_ethan_RightShoulder - - first: - 1: 100150 - second: char_ethan_RightToe1 - - first: - 1: 100152 - second: char_ethan_RightToe2 - - first: - 1: 100154 - second: char_ethan_RightUpLeg - - first: - 1: 100156 - second: char_ethan_RightUpperLip - - first: - 1: 100158 - second: char_ethan_skeleton - - first: - 1: 100160 - second: char_ethan_Spine - - first: - 1: 100162 - second: char_ethan_Spine1 - - first: - 1: 100164 - second: char_ethan_Spine2 - - first: - 1: 100166 - second: char_ethan_UpperLip - - first: - 1: 100168 - second: //RootNode - - first: - 1: 100170 - second: EthanBody - - first: - 1: 100172 - second: EthanGlasses - - first: - 1: 100174 - second: EthanHead - - first: - 1: 100176 - second: EthanHead1 - - first: - 1: 100178 - second: EthanHips - - first: - 1: 100180 - second: EthanJaw - - first: - 1: 100182 - second: EthanLeftArm - - first: - 1: 100184 - second: EthanLeftBlink - - first: - 1: 100186 - second: EthanLeftBrow - - first: - 1: 100188 - second: EthanLeftCorner - - first: - 1: 100190 - second: EthanLeftEye - - first: - 1: 100192 - second: EthanLeftFoot - - first: - 1: 100194 - second: EthanLeftForeArm - - first: - 1: 100196 - second: EthanLeftHand - - first: - 1: 100198 - second: EthanLeftHandIndex1 - - first: - 1: 100200 - second: EthanLeftHandIndex2 - - first: - 1: 100202 - second: EthanLeftHandIndex3 - - first: - 1: 100204 - second: EthanLeftHandIndex4 - - first: - 1: 100206 - second: EthanLeftHandMiddle1 - - first: - 1: 100208 - second: EthanLeftHandMiddle2 - - first: - 1: 100210 - second: EthanLeftHandMiddle3 - - first: - 1: 100212 - second: EthanLeftHandMiddle4 - - first: - 1: 100214 - second: EthanLeftHandPinky1 - - first: - 1: 100216 - second: EthanLeftHandPinky2 - - first: - 1: 100218 - second: EthanLeftHandPinky3 - - first: - 1: 100220 - second: EthanLeftHandPinky4 - - first: - 1: 100222 - second: EthanLeftHandRing1 - - first: - 1: 100224 - second: EthanLeftHandRing2 - - first: - 1: 100226 - second: EthanLeftHandRing3 - - first: - 1: 100228 - second: EthanLeftHandRing4 - - first: - 1: 100230 - second: EthanLeftHandThumb1 - - first: - 1: 100232 - second: EthanLeftHandThumb2 - - first: - 1: 100234 - second: EthanLeftHandThumb3 - - first: - 1: 100236 - second: EthanLeftHandThumb4 - - first: - 1: 100238 - second: EthanLeftLeg - - first: - 1: 100240 - second: EthanLeftLowerLip - - first: - 1: 100242 - second: EthanLeftShoulder - - first: - 1: 100244 - second: EthanLeftToe1 - - first: - 1: 100246 - second: EthanLeftToe2 - - first: - 1: 100248 - second: EthanLeftUpLeg - - first: - 1: 100250 - second: EthanLeftUpperLip - - first: - 1: 100252 - second: EthanLowerLip - - first: - 1: 100254 - second: EthanNeck - - first: - 1: 100256 - second: EthanRightArm - - first: - 1: 100258 - second: EthanRightBlink - - first: - 1: 100260 - second: EthanRightBrow - - first: - 1: 100262 - second: EthanRightCorner - - first: - 1: 100264 - second: EthanRightEye - - first: - 1: 100266 - second: EthanRightFoot - - first: - 1: 100268 - second: EthanRightForeArm - - first: - 1: 100270 - second: EthanRightHand - - first: - 1: 100272 - second: EthanRightHandIndex1 - - first: - 1: 100274 - second: EthanRightHandIndex2 - - first: - 1: 100276 - second: EthanRightHandIndex3 - - first: - 1: 100278 - second: EthanRightHandIndex4 - - first: - 1: 100280 - second: EthanRightHandMiddle1 - - first: - 1: 100282 - second: EthanRightHandMiddle2 - - first: - 1: 100284 - second: EthanRightHandMiddle3 - - first: - 1: 100286 - second: EthanRightHandMiddle4 - - first: - 1: 100288 - second: EthanRightHandPinky1 - - first: - 1: 100290 - second: EthanRightHandPinky2 - - first: - 1: 100292 - second: EthanRightHandPinky3 - - first: - 1: 100294 - second: EthanRightHandPinky4 - - first: - 1: 100296 - second: EthanRightHandRing1 - - first: - 1: 100298 - second: EthanRightHandRing2 - - first: - 1: 100300 - second: EthanRightHandRing3 - - first: - 1: 100302 - second: EthanRightHandRing4 - - first: - 1: 100304 - second: EthanRightHandThumb1 - - first: - 1: 100306 - second: EthanRightHandThumb2 - - first: - 1: 100308 - second: EthanRightHandThumb3 - - first: - 1: 100310 - second: EthanRightHandThumb4 - - first: - 1: 100312 - second: EthanRightLeg - - first: - 1: 100314 - second: EthanRightLowerLip - - first: - 1: 100316 - second: EthanRightShoulder - - first: - 1: 100318 - second: EthanRightToe1 - - first: - 1: 100320 - second: EthanRightToe2 - - first: - 1: 100322 - second: EthanRightUpLeg - - first: - 1: 100324 - second: EthanRightUpperLip - - first: - 1: 100326 - second: EthanSkeleton - - first: - 1: 100328 - second: EthanSpine - - first: - 1: 100330 - second: EthanSpine1 - - first: - 1: 100332 - second: EthanSpine2 - - first: - 1: 100334 - second: EthanUpperLip - - first: - 1: 100336 - second: EthanBody1 - - first: - 1: 100338 - second: EthanSkeleton1 - - first: - 4: 400000 - second: char_cyberKid_Badge - - first: - 4: 400002 - second: char_ethan_body - - first: - 4: 400004 - second: char_ethan_glasses - - first: - 4: 400006 - second: char_ethan_Head - - first: - 4: 400008 - second: char_ethan_Head1 - - first: - 4: 400010 - second: char_ethan_Hips - - first: - 4: 400012 - second: char_ethan_Jaw - - first: - 4: 400014 - second: char_ethan_LeftArm - - first: - 4: 400016 - second: char_ethan_LeftBlink - - first: - 4: 400018 - second: char_ethan_LeftBrow - - first: - 4: 400020 - second: char_ethan_LeftCorner - - first: - 4: 400022 - second: char_ethan_LeftEye - - first: - 4: 400024 - second: char_ethan_LeftFoot - - first: - 4: 400026 - second: char_ethan_LeftForeArm - - first: - 4: 400028 - second: char_ethan_LeftHand - - first: - 4: 400030 - second: char_ethan_LeftHandIndex1 - - first: - 4: 400032 - second: char_ethan_LeftHandIndex2 - - first: - 4: 400034 - second: char_ethan_LeftHandIndex3 - - first: - 4: 400036 - second: char_ethan_LeftHandIndex4 - - first: - 4: 400038 - second: char_ethan_LeftHandMiddle1 - - first: - 4: 400040 - second: char_ethan_LeftHandMiddle2 - - first: - 4: 400042 - second: char_ethan_LeftHandMiddle3 - - first: - 4: 400044 - second: char_ethan_LeftHandMiddle4 - - first: - 4: 400046 - second: char_ethan_LeftHandPinky1 - - first: - 4: 400048 - second: char_ethan_LeftHandPinky2 - - first: - 4: 400050 - second: char_ethan_LeftHandPinky3 - - first: - 4: 400052 - second: char_ethan_LeftHandPinky4 - - first: - 4: 400054 - second: char_ethan_LeftHandRing1 - - first: - 4: 400056 - second: char_ethan_LeftHandRing2 - - first: - 4: 400058 - second: char_ethan_LeftHandRing3 - - first: - 4: 400060 - second: char_ethan_LeftHandRing4 - - first: - 4: 400062 - second: char_ethan_LeftHandThumb1 - - first: - 4: 400064 - second: char_ethan_LeftHandThumb2 - - first: - 4: 400066 - second: char_ethan_LeftHandThumb3 - - first: - 4: 400068 - second: char_ethan_LeftHandThumb4 - - first: - 4: 400070 - second: char_ethan_LeftLeg - - first: - 4: 400072 - second: char_ethan_LeftLowerLip - - first: - 4: 400074 - second: char_ethan_LeftShoulder - - first: - 4: 400076 - second: char_ethan_LeftToe1 - - first: - 4: 400078 - second: char_ethan_LeftToe2 - - first: - 4: 400080 - second: char_ethan_LeftUpLeg - - first: - 4: 400082 - second: char_ethan_LeftUpperLip - - first: - 4: 400084 - second: char_ethan_LowerLip - - first: - 4: 400086 - second: char_ethan_Neck - - first: - 4: 400088 - second: char_ethan_RightArm - - first: - 4: 400090 - second: char_ethan_RightBlink - - first: - 4: 400092 - second: char_ethan_RightBrow - - first: - 4: 400094 - second: char_ethan_RightCorner - - first: - 4: 400096 - second: char_ethan_RightEye - - first: - 4: 400098 - second: char_ethan_RightFoot - - first: - 4: 400100 - second: char_ethan_RightForeArm - - first: - 4: 400102 - second: char_ethan_RightHand - - first: - 4: 400104 - second: char_ethan_RightHandIndex1 - - first: - 4: 400106 - second: char_ethan_RightHandIndex2 - - first: - 4: 400108 - second: char_ethan_RightHandIndex3 - - first: - 4: 400110 - second: char_ethan_RightHandIndex4 - - first: - 4: 400112 - second: char_ethan_RightHandMiddle1 - - first: - 4: 400114 - second: char_ethan_RightHandMiddle2 - - first: - 4: 400116 - second: char_ethan_RightHandMiddle3 - - first: - 4: 400118 - second: char_ethan_RightHandMiddle4 - - first: - 4: 400120 - second: char_ethan_RightHandPinky1 - - first: - 4: 400122 - second: char_ethan_RightHandPinky2 - - first: - 4: 400124 - second: char_ethan_RightHandPinky3 - - first: - 4: 400126 - second: char_ethan_RightHandPinky4 - - first: - 4: 400128 - second: char_ethan_RightHandRing1 - - first: - 4: 400130 - second: char_ethan_RightHandRing2 - - first: - 4: 400132 - second: char_ethan_RightHandRing3 - - first: - 4: 400134 - second: char_ethan_RightHandRing4 - - first: - 4: 400136 - second: char_ethan_RightHandThumb1 - - first: - 4: 400138 - second: char_ethan_RightHandThumb2 - - first: - 4: 400140 - second: char_ethan_RightHandThumb3 - - first: - 4: 400142 - second: char_ethan_RightHandThumb4 - - first: - 4: 400144 - second: char_ethan_RightLeg - - first: - 4: 400146 - second: char_ethan_RightLowerLip - - first: - 4: 400148 - second: char_ethan_RightShoulder - - first: - 4: 400150 - second: char_ethan_RightToe1 - - first: - 4: 400152 - second: char_ethan_RightToe2 - - first: - 4: 400154 - second: char_ethan_RightUpLeg - - first: - 4: 400156 - second: char_ethan_RightUpperLip - - first: - 4: 400158 - second: char_ethan_skeleton - - first: - 4: 400160 - second: char_ethan_Spine - - first: - 4: 400162 - second: char_ethan_Spine1 - - first: - 4: 400164 - second: char_ethan_Spine2 - - first: - 4: 400166 - second: char_ethan_UpperLip - - first: - 4: 400168 - second: //RootNode - - first: - 4: 400170 - second: EthanBody - - first: - 4: 400172 - second: EthanGlasses - - first: - 4: 400174 - second: EthanHead - - first: - 4: 400176 - second: EthanHead1 - - first: - 4: 400178 - second: EthanHips - - first: - 4: 400180 - second: EthanJaw - - first: - 4: 400182 - second: EthanLeftArm - - first: - 4: 400184 - second: EthanLeftBlink - - first: - 4: 400186 - second: EthanLeftBrow - - first: - 4: 400188 - second: EthanLeftCorner - - first: - 4: 400190 - second: EthanLeftEye - - first: - 4: 400192 - second: EthanLeftFoot - - first: - 4: 400194 - second: EthanLeftForeArm - - first: - 4: 400196 - second: EthanLeftHand - - first: - 4: 400198 - second: EthanLeftHandIndex1 - - first: - 4: 400200 - second: EthanLeftHandIndex2 - - first: - 4: 400202 - second: EthanLeftHandIndex3 - - first: - 4: 400204 - second: EthanLeftHandIndex4 - - first: - 4: 400206 - second: EthanLeftHandMiddle1 - - first: - 4: 400208 - second: EthanLeftHandMiddle2 - - first: - 4: 400210 - second: EthanLeftHandMiddle3 - - first: - 4: 400212 - second: EthanLeftHandMiddle4 - - first: - 4: 400214 - second: EthanLeftHandPinky1 - - first: - 4: 400216 - second: EthanLeftHandPinky2 - - first: - 4: 400218 - second: EthanLeftHandPinky3 - - first: - 4: 400220 - second: EthanLeftHandPinky4 - - first: - 4: 400222 - second: EthanLeftHandRing1 - - first: - 4: 400224 - second: EthanLeftHandRing2 - - first: - 4: 400226 - second: EthanLeftHandRing3 - - first: - 4: 400228 - second: EthanLeftHandRing4 - - first: - 4: 400230 - second: EthanLeftHandThumb1 - - first: - 4: 400232 - second: EthanLeftHandThumb2 - - first: - 4: 400234 - second: EthanLeftHandThumb3 - - first: - 4: 400236 - second: EthanLeftHandThumb4 - - first: - 4: 400238 - second: EthanLeftLeg - - first: - 4: 400240 - second: EthanLeftLowerLip - - first: - 4: 400242 - second: EthanLeftShoulder - - first: - 4: 400244 - second: EthanLeftToe1 - - first: - 4: 400246 - second: EthanLeftToe2 - - first: - 4: 400248 - second: EthanLeftUpLeg - - first: - 4: 400250 - second: EthanLeftUpperLip - - first: - 4: 400252 - second: EthanLowerLip - - first: - 4: 400254 - second: EthanNeck - - first: - 4: 400256 - second: EthanRightArm - - first: - 4: 400258 - second: EthanRightBlink - - first: - 4: 400260 - second: EthanRightBrow - - first: - 4: 400262 - second: EthanRightCorner - - first: - 4: 400264 - second: EthanRightEye - - first: - 4: 400266 - second: EthanRightFoot - - first: - 4: 400268 - second: EthanRightForeArm - - first: - 4: 400270 - second: EthanRightHand - - first: - 4: 400272 - second: EthanRightHandIndex1 - - first: - 4: 400274 - second: EthanRightHandIndex2 - - first: - 4: 400276 - second: EthanRightHandIndex3 - - first: - 4: 400278 - second: EthanRightHandIndex4 - - first: - 4: 400280 - second: EthanRightHandMiddle1 - - first: - 4: 400282 - second: EthanRightHandMiddle2 - - first: - 4: 400284 - second: EthanRightHandMiddle3 - - first: - 4: 400286 - second: EthanRightHandMiddle4 - - first: - 4: 400288 - second: EthanRightHandPinky1 - - first: - 4: 400290 - second: EthanRightHandPinky2 - - first: - 4: 400292 - second: EthanRightHandPinky3 - - first: - 4: 400294 - second: EthanRightHandPinky4 - - first: - 4: 400296 - second: EthanRightHandRing1 - - first: - 4: 400298 - second: EthanRightHandRing2 - - first: - 4: 400300 - second: EthanRightHandRing3 - - first: - 4: 400302 - second: EthanRightHandRing4 - - first: - 4: 400304 - second: EthanRightHandThumb1 - - first: - 4: 400306 - second: EthanRightHandThumb2 - - first: - 4: 400308 - second: EthanRightHandThumb3 - - first: - 4: 400310 - second: EthanRightHandThumb4 - - first: - 4: 400312 - second: EthanRightLeg - - first: - 4: 400314 - second: EthanRightLowerLip - - first: - 4: 400316 - second: EthanRightShoulder - - first: - 4: 400318 - second: EthanRightToe1 - - first: - 4: 400320 - second: EthanRightToe2 - - first: - 4: 400322 - second: EthanRightUpLeg - - first: - 4: 400324 - second: EthanRightUpperLip - - first: - 4: 400326 - second: EthanSkeleton - - first: - 4: 400328 - second: EthanSpine - - first: - 4: 400330 - second: EthanSpine1 - - first: - 4: 400332 - second: EthanSpine2 - - first: - 4: 400334 - second: EthanUpperLip - - first: - 4: 400336 - second: EthanBody1 - - first: - 4: 400338 - second: EthanSkeleton1 - - first: - 43: 4300000 - second: char_ethan_glasses - - first: - 43: 4300002 - second: char_ethan_body - - first: - 43: 4300004 - second: EthanGlasses - - first: - 43: 4300006 - second: EthanBody - - first: - 43: 4300008 - second: EthanBody1 - - first: - 74: 7400000 - second: Take 001 - - first: - 95: 9500000 - second: //RootNode - - first: - 137: 13700000 - second: char_ethan_body - - first: - 137: 13700002 - second: char_ethan_glasses - - first: - 137: 13700004 - second: EthanBody - - first: - 137: 13700006 - second: EthanGlasses - - first: - 137: 13700008 - second: EthanBody1 - externalObjects: {} + serializedVersion: 19 + fileIDToRecycleName: + 100000: char_cyberKid_Badge + 100002: char_ethan_body + 100004: char_ethan_glasses + 100006: char_ethan_Head + 100008: char_ethan_Head1 + 100010: char_ethan_Hips + 100012: char_ethan_Jaw + 100014: char_ethan_LeftArm + 100016: char_ethan_LeftBlink + 100018: char_ethan_LeftBrow + 100020: char_ethan_LeftCorner + 100022: char_ethan_LeftEye + 100024: char_ethan_LeftFoot + 100026: char_ethan_LeftForeArm + 100028: char_ethan_LeftHand + 100030: char_ethan_LeftHandIndex1 + 100032: char_ethan_LeftHandIndex2 + 100034: char_ethan_LeftHandIndex3 + 100036: char_ethan_LeftHandIndex4 + 100038: char_ethan_LeftHandMiddle1 + 100040: char_ethan_LeftHandMiddle2 + 100042: char_ethan_LeftHandMiddle3 + 100044: char_ethan_LeftHandMiddle4 + 100046: char_ethan_LeftHandPinky1 + 100048: char_ethan_LeftHandPinky2 + 100050: char_ethan_LeftHandPinky3 + 100052: char_ethan_LeftHandPinky4 + 100054: char_ethan_LeftHandRing1 + 100056: char_ethan_LeftHandRing2 + 100058: char_ethan_LeftHandRing3 + 100060: char_ethan_LeftHandRing4 + 100062: char_ethan_LeftHandThumb1 + 100064: char_ethan_LeftHandThumb2 + 100066: char_ethan_LeftHandThumb3 + 100068: char_ethan_LeftHandThumb4 + 100070: char_ethan_LeftLeg + 100072: char_ethan_LeftLowerLip + 100074: char_ethan_LeftShoulder + 100076: char_ethan_LeftToe1 + 100078: char_ethan_LeftToe2 + 100080: char_ethan_LeftUpLeg + 100082: char_ethan_LeftUpperLip + 100084: char_ethan_LowerLip + 100086: char_ethan_Neck + 100088: char_ethan_RightArm + 100090: char_ethan_RightBlink + 100092: char_ethan_RightBrow + 100094: char_ethan_RightCorner + 100096: char_ethan_RightEye + 100098: char_ethan_RightFoot + 100100: char_ethan_RightForeArm + 100102: char_ethan_RightHand + 100104: char_ethan_RightHandIndex1 + 100106: char_ethan_RightHandIndex2 + 100108: char_ethan_RightHandIndex3 + 100110: char_ethan_RightHandIndex4 + 100112: char_ethan_RightHandMiddle1 + 100114: char_ethan_RightHandMiddle2 + 100116: char_ethan_RightHandMiddle3 + 100118: char_ethan_RightHandMiddle4 + 100120: char_ethan_RightHandPinky1 + 100122: char_ethan_RightHandPinky2 + 100124: char_ethan_RightHandPinky3 + 100126: char_ethan_RightHandPinky4 + 100128: char_ethan_RightHandRing1 + 100130: char_ethan_RightHandRing2 + 100132: char_ethan_RightHandRing3 + 100134: char_ethan_RightHandRing4 + 100136: char_ethan_RightHandThumb1 + 100138: char_ethan_RightHandThumb2 + 100140: char_ethan_RightHandThumb3 + 100142: char_ethan_RightHandThumb4 + 100144: char_ethan_RightLeg + 100146: char_ethan_RightLowerLip + 100148: char_ethan_RightShoulder + 100150: char_ethan_RightToe1 + 100152: char_ethan_RightToe2 + 100154: char_ethan_RightUpLeg + 100156: char_ethan_RightUpperLip + 100158: char_ethan_skeleton + 100160: char_ethan_Spine + 100162: char_ethan_Spine1 + 100164: char_ethan_Spine2 + 100166: char_ethan_UpperLip + 100168: //RootNode + 100170: EthanBody + 100172: EthanGlasses + 100174: EthanHead + 100176: EthanHead1 + 100178: EthanHips + 100180: EthanJaw + 100182: EthanLeftArm + 100184: EthanLeftBlink + 100186: EthanLeftBrow + 100188: EthanLeftCorner + 100190: EthanLeftEye + 100192: EthanLeftFoot + 100194: EthanLeftForeArm + 100196: EthanLeftHand + 100198: EthanLeftHandIndex1 + 100200: EthanLeftHandIndex2 + 100202: EthanLeftHandIndex3 + 100204: EthanLeftHandIndex4 + 100206: EthanLeftHandMiddle1 + 100208: EthanLeftHandMiddle2 + 100210: EthanLeftHandMiddle3 + 100212: EthanLeftHandMiddle4 + 100214: EthanLeftHandPinky1 + 100216: EthanLeftHandPinky2 + 100218: EthanLeftHandPinky3 + 100220: EthanLeftHandPinky4 + 100222: EthanLeftHandRing1 + 100224: EthanLeftHandRing2 + 100226: EthanLeftHandRing3 + 100228: EthanLeftHandRing4 + 100230: EthanLeftHandThumb1 + 100232: EthanLeftHandThumb2 + 100234: EthanLeftHandThumb3 + 100236: EthanLeftHandThumb4 + 100238: EthanLeftLeg + 100240: EthanLeftLowerLip + 100242: EthanLeftShoulder + 100244: EthanLeftToe1 + 100246: EthanLeftToe2 + 100248: EthanLeftUpLeg + 100250: EthanLeftUpperLip + 100252: EthanLowerLip + 100254: EthanNeck + 100256: EthanRightArm + 100258: EthanRightBlink + 100260: EthanRightBrow + 100262: EthanRightCorner + 100264: EthanRightEye + 100266: EthanRightFoot + 100268: EthanRightForeArm + 100270: EthanRightHand + 100272: EthanRightHandIndex1 + 100274: EthanRightHandIndex2 + 100276: EthanRightHandIndex3 + 100278: EthanRightHandIndex4 + 100280: EthanRightHandMiddle1 + 100282: EthanRightHandMiddle2 + 100284: EthanRightHandMiddle3 + 100286: EthanRightHandMiddle4 + 100288: EthanRightHandPinky1 + 100290: EthanRightHandPinky2 + 100292: EthanRightHandPinky3 + 100294: EthanRightHandPinky4 + 100296: EthanRightHandRing1 + 100298: EthanRightHandRing2 + 100300: EthanRightHandRing3 + 100302: EthanRightHandRing4 + 100304: EthanRightHandThumb1 + 100306: EthanRightHandThumb2 + 100308: EthanRightHandThumb3 + 100310: EthanRightHandThumb4 + 100312: EthanRightLeg + 100314: EthanRightLowerLip + 100316: EthanRightShoulder + 100318: EthanRightToe1 + 100320: EthanRightToe2 + 100322: EthanRightUpLeg + 100324: EthanRightUpperLip + 100326: EthanSkeleton + 100328: EthanSpine + 100330: EthanSpine1 + 100332: EthanSpine2 + 100334: EthanUpperLip + 100336: EthanBody1 + 100338: EthanSkeleton1 + 400000: char_cyberKid_Badge + 400002: char_ethan_body + 400004: char_ethan_glasses + 400006: char_ethan_Head + 400008: char_ethan_Head1 + 400010: char_ethan_Hips + 400012: char_ethan_Jaw + 400014: char_ethan_LeftArm + 400016: char_ethan_LeftBlink + 400018: char_ethan_LeftBrow + 400020: char_ethan_LeftCorner + 400022: char_ethan_LeftEye + 400024: char_ethan_LeftFoot + 400026: char_ethan_LeftForeArm + 400028: char_ethan_LeftHand + 400030: char_ethan_LeftHandIndex1 + 400032: char_ethan_LeftHandIndex2 + 400034: char_ethan_LeftHandIndex3 + 400036: char_ethan_LeftHandIndex4 + 400038: char_ethan_LeftHandMiddle1 + 400040: char_ethan_LeftHandMiddle2 + 400042: char_ethan_LeftHandMiddle3 + 400044: char_ethan_LeftHandMiddle4 + 400046: char_ethan_LeftHandPinky1 + 400048: char_ethan_LeftHandPinky2 + 400050: char_ethan_LeftHandPinky3 + 400052: char_ethan_LeftHandPinky4 + 400054: char_ethan_LeftHandRing1 + 400056: char_ethan_LeftHandRing2 + 400058: char_ethan_LeftHandRing3 + 400060: char_ethan_LeftHandRing4 + 400062: char_ethan_LeftHandThumb1 + 400064: char_ethan_LeftHandThumb2 + 400066: char_ethan_LeftHandThumb3 + 400068: char_ethan_LeftHandThumb4 + 400070: char_ethan_LeftLeg + 400072: char_ethan_LeftLowerLip + 400074: char_ethan_LeftShoulder + 400076: char_ethan_LeftToe1 + 400078: char_ethan_LeftToe2 + 400080: char_ethan_LeftUpLeg + 400082: char_ethan_LeftUpperLip + 400084: char_ethan_LowerLip + 400086: char_ethan_Neck + 400088: char_ethan_RightArm + 400090: char_ethan_RightBlink + 400092: char_ethan_RightBrow + 400094: char_ethan_RightCorner + 400096: char_ethan_RightEye + 400098: char_ethan_RightFoot + 400100: char_ethan_RightForeArm + 400102: char_ethan_RightHand + 400104: char_ethan_RightHandIndex1 + 400106: char_ethan_RightHandIndex2 + 400108: char_ethan_RightHandIndex3 + 400110: char_ethan_RightHandIndex4 + 400112: char_ethan_RightHandMiddle1 + 400114: char_ethan_RightHandMiddle2 + 400116: char_ethan_RightHandMiddle3 + 400118: char_ethan_RightHandMiddle4 + 400120: char_ethan_RightHandPinky1 + 400122: char_ethan_RightHandPinky2 + 400124: char_ethan_RightHandPinky3 + 400126: char_ethan_RightHandPinky4 + 400128: char_ethan_RightHandRing1 + 400130: char_ethan_RightHandRing2 + 400132: char_ethan_RightHandRing3 + 400134: char_ethan_RightHandRing4 + 400136: char_ethan_RightHandThumb1 + 400138: char_ethan_RightHandThumb2 + 400140: char_ethan_RightHandThumb3 + 400142: char_ethan_RightHandThumb4 + 400144: char_ethan_RightLeg + 400146: char_ethan_RightLowerLip + 400148: char_ethan_RightShoulder + 400150: char_ethan_RightToe1 + 400152: char_ethan_RightToe2 + 400154: char_ethan_RightUpLeg + 400156: char_ethan_RightUpperLip + 400158: char_ethan_skeleton + 400160: char_ethan_Spine + 400162: char_ethan_Spine1 + 400164: char_ethan_Spine2 + 400166: char_ethan_UpperLip + 400168: //RootNode + 400170: EthanBody + 400172: EthanGlasses + 400174: EthanHead + 400176: EthanHead1 + 400178: EthanHips + 400180: EthanJaw + 400182: EthanLeftArm + 400184: EthanLeftBlink + 400186: EthanLeftBrow + 400188: EthanLeftCorner + 400190: EthanLeftEye + 400192: EthanLeftFoot + 400194: EthanLeftForeArm + 400196: EthanLeftHand + 400198: EthanLeftHandIndex1 + 400200: EthanLeftHandIndex2 + 400202: EthanLeftHandIndex3 + 400204: EthanLeftHandIndex4 + 400206: EthanLeftHandMiddle1 + 400208: EthanLeftHandMiddle2 + 400210: EthanLeftHandMiddle3 + 400212: EthanLeftHandMiddle4 + 400214: EthanLeftHandPinky1 + 400216: EthanLeftHandPinky2 + 400218: EthanLeftHandPinky3 + 400220: EthanLeftHandPinky4 + 400222: EthanLeftHandRing1 + 400224: EthanLeftHandRing2 + 400226: EthanLeftHandRing3 + 400228: EthanLeftHandRing4 + 400230: EthanLeftHandThumb1 + 400232: EthanLeftHandThumb2 + 400234: EthanLeftHandThumb3 + 400236: EthanLeftHandThumb4 + 400238: EthanLeftLeg + 400240: EthanLeftLowerLip + 400242: EthanLeftShoulder + 400244: EthanLeftToe1 + 400246: EthanLeftToe2 + 400248: EthanLeftUpLeg + 400250: EthanLeftUpperLip + 400252: EthanLowerLip + 400254: EthanNeck + 400256: EthanRightArm + 400258: EthanRightBlink + 400260: EthanRightBrow + 400262: EthanRightCorner + 400264: EthanRightEye + 400266: EthanRightFoot + 400268: EthanRightForeArm + 400270: EthanRightHand + 400272: EthanRightHandIndex1 + 400274: EthanRightHandIndex2 + 400276: EthanRightHandIndex3 + 400278: EthanRightHandIndex4 + 400280: EthanRightHandMiddle1 + 400282: EthanRightHandMiddle2 + 400284: EthanRightHandMiddle3 + 400286: EthanRightHandMiddle4 + 400288: EthanRightHandPinky1 + 400290: EthanRightHandPinky2 + 400292: EthanRightHandPinky3 + 400294: EthanRightHandPinky4 + 400296: EthanRightHandRing1 + 400298: EthanRightHandRing2 + 400300: EthanRightHandRing3 + 400302: EthanRightHandRing4 + 400304: EthanRightHandThumb1 + 400306: EthanRightHandThumb2 + 400308: EthanRightHandThumb3 + 400310: EthanRightHandThumb4 + 400312: EthanRightLeg + 400314: EthanRightLowerLip + 400316: EthanRightShoulder + 400318: EthanRightToe1 + 400320: EthanRightToe2 + 400322: EthanRightUpLeg + 400324: EthanRightUpperLip + 400326: EthanSkeleton + 400328: EthanSpine + 400330: EthanSpine1 + 400332: EthanSpine2 + 400334: EthanUpperLip + 400336: EthanBody1 + 400338: EthanSkeleton1 + 4300000: char_ethan_glasses + 4300002: char_ethan_body + 4300004: EthanGlasses + 4300006: EthanBody + 4300008: EthanBody1 + 7400000: Take 001 + 9500000: //RootNode + 13700000: char_ethan_body + 13700002: char_ethan_glasses + 13700004: EthanBody + 13700006: EthanGlasses + 13700008: EthanBody1 materials: - materialImportMode: 1 + importMaterials: 1 materialName: 1 materialSearch: 2 - materialLocation: 0 animations: legacyGenerateAnimations: 4 bakeSimulation: 0 - resampleCurves: 1 + resampleRotations: 1 optimizeGameObjects: 0 - removeConstantScaleCurves: 0 motionNodeName: - rigImportErrors: - rigImportWarnings: "Avatar Rig Configuration mis-match. Bone length in configuration - does not match position in animation file:\n\t'EthanLeftLeg' : position error - = 3.271898 mm\n" 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: 1 meshes: @@ -1096,49 +384,25 @@ ModelImporter: globalScale: 0.01 meshCompression: 0 addColliders: 0 - useSRGBMaterialColor: 1 - sortHierarchyByName: 1 - importPhysicalCameras: 0 - importVisibility: 0 importBlendShapes: 1 - importCameras: 0 - importLights: 0 - nodeNameCollisionStrategy: 0 - fileIdsGeneration: 1 swapUVChannels: 0 generateSecondaryUV: 0 useFileUnits: 0 + optimizeMeshForGPU: 1 keepQuads: 0 weldVertices: 1 - bakeAxisConversion: 0 - preserveHierarchy: 0 - skinWeightsMode: 0 - maxBonesPerVertex: 4 - minBoneWeight: 0.001 - optimizeBones: 1 - meshOptimizationFlags: -1 - indexFormat: 1 secondaryUVAngleDistortion: 8 secondaryUVAreaDistortion: 15.000001 secondaryUVHardAngle: 88 - secondaryUVMarginMethod: 0 - secondaryUVMinLightmapResolution: 40 - secondaryUVMinObjectScale: 1 secondaryUVPackMargin: 4 useFileScale: 0 - strictVertexDataChecks: 0 tangentSpace: normalSmoothAngle: 60 normalImportMode: 0 tangentImportMode: 4 - normalCalculationMode: 0 - legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 1 - blendShapeNormalImportMode: 1 - normalSmoothingSource: 0 - referencedClips: [] importAnimation: 0 + copyAvatar: 0 humanDescription: - serializedVersion: 3 human: - boneName: EthanHips humanName: Hips @@ -1196,14 +460,6 @@ ModelImporter: value: {x: 0, y: 0, z: 0} length: 0 modified: 0 - - boneName: EthanNeck - humanName: UpperChest - 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: EthanRightShoulder humanName: RightShoulder limit: @@ -1574,425 +830,424 @@ ModelImporter: modified: 0 skeleton: - name: Ethan(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} + transformModified: 1 - name: EthanBody - parentName: Ethan(Clone) - position: {x: -0, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanGlasses - parentName: Ethan(Clone) - position: {x: -0, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} + position: {x: 0, y: 0, z: 0} + rotation: {x: 0, y: 0, z: 0, w: 1} scale: {x: 1, y: 1, z: 1} + transformModified: 1 - name: EthanSkeleton - parentName: Ethan(Clone) - position: {x: -0, y: 0, z: 0} - rotation: {x: 0, y: -0, z: -0, w: 1} + position: {x: 0, y: 0, z: 0} + rotation: {x: 0, y: 0, z: 0, w: 1} scale: {x: 1, y: 1, z: 1} + transformModified: 1 - name: EthanHips - parentName: EthanSkeleton position: {x: 0.00000042162256, y: 0.7787106, z: -0.033025585} rotation: {x: -0.49999934, y: 0.49999934, z: -0.50000066, w: 0.50000066} scale: {x: 1, y: 1, z: 1} + transformModified: 1 - name: EthanSpine - parentName: EthanHips position: {x: -0.044983033, y: 0.00011812973, z: -0.000000026061407} - rotation: {x: -0.0000020492112, y: 0.0000006409474, z: 0.043222737, w: 0.99906546} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftUpLeg - parentName: EthanSpine - position: {x: 0.044804916, y: -0.00400244, z: -0.07436281} - rotation: {x: 0.009854246, y: 0.9996559, z: -0.0031334888, w: 0.024108019} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftLeg - parentName: EthanLeftUpLeg - position: {x: -0.3529785, y: -0.047479518, z: 0.03461981} - rotation: {x: 0, y: 0, z: 0.16876774, w: 0.98565584} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftFoot - parentName: EthanLeftLeg - position: {x: -0.2827789, y: 0.1718791, z: 0.031038838} - rotation: {x: -0.08430487, y: 0.035964992, z: -0.13311164, w: 0.9868539} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftToe1 - parentName: EthanLeftFoot - position: {x: -0.085517354, y: -0.11005712, z: -0.0000006698085} - rotation: {x: 7.3885096e-18, y: -8.589314e-17, z: -0.7071068, w: 0.7071068} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftToe2 - parentName: EthanLeftToe1 - position: {x: 0.08174267, y: -0.000000009601407, z: -0.00000029316797} - rotation: {x: 1, y: -5.6351963e-23, z: 1.110223e-16, w: -0.00000068451953} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightUpLeg - parentName: EthanSpine - position: {x: 0.044804532, y: -0.004002823, z: 0.07436302} - rotation: {x: 0.0098541705, y: 0.9996559, z: 0.0031362663, w: -0.024108129} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightLeg - parentName: EthanRightUpLeg - position: {x: -0.3529783, y: -0.04747951, z: -0.034621846} - rotation: {x: 0, y: 0, z: 0.16876684, w: 0.985656} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightFoot - parentName: EthanRightLeg - position: {x: -0.282779, y: 0.17187855, z: -0.031040668} - rotation: {x: 0.08430424, y: -0.03596484, z: -0.13311061, w: 0.9868541} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightToe1 - parentName: EthanRightFoot - position: {x: -0.08551728, y: -0.11005718, z: 0.000000062032285} - rotation: {x: -1.3899192e-17, y: 3.352535e-17, z: -0.7071068, w: 0.7071068} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightToe2 - parentName: EthanRightToe1 - position: {x: 0.08174264, y: 0.000000049485, z: 0.00000019218783} - rotation: {x: -1.6724651e-16, y: 4.9321447e-33, z: -2.949027e-17, w: 1} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.000002026558, y: 0.00000064074993, z: 0.04322271, w: 0.9990655} + scale: {x: 1, y: 0.99999994, z: 1} + transformModified: 1 - name: EthanSpine1 - parentName: EthanSpine position: {x: -0.14667831, y: 0.025727088, z: -0.0000003282363} - rotation: {x: -1.0587912e-22, y: -7.34684e-40, z: 6.938894e-18, w: 1} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.000000059604638, y: 0.000000014901159, z: 0, w: 1} + scale: {x: 1.0000004, y: 1.0000001, z: 1.0000002} + transformModified: 1 - name: EthanSpine2 - parentName: EthanSpine1 position: {x: -0.12695539, y: 0.022281736, z: -0.0000002830808} - rotation: {x: -1.0587912e-22, y: -7.34684e-40, z: 6.938894e-18, w: 1} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.000000014901159, y: 0.000000014901159, z: -0.000000014901159, + w: 1} + scale: {x: 0.9999998, y: 0.9999998, z: 0.99999976} + transformModified: 1 - name: EthanNeck - parentName: EthanSpine2 position: {x: -0.12697862, y: 0.02224573, z: -0.00000028315998} - rotation: {x: -7.318979e-17, y: 1.4170987e-17, z: -0.13052638, w: 0.9914448} - scale: {x: 1, y: 1, z: 1} - - name: EthanHead - parentName: EthanNeck - position: {x: -0.090649985, y: -0.041122116, z: 0.000000058975164} - rotation: {x: 1.3487235e-18, y: -1.7102821e-17, z: 0.087552026, w: 0.99616} - scale: {x: 1, y: 1, z: 1} - - name: EthanHead1 - parentName: EthanHead - position: {x: -0.17475267, y: 0.00000045072835, z: 0.00000009431633} - rotation: {x: 1.0587912e-22, y: 4.646893e-23, z: -2.7755576e-17, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftCorner - parentName: EthanHead1 - position: {x: 0.14939941, y: -0.06769698, z: -0.024466591} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftUpperLip - parentName: EthanHead1 - position: {x: 0.14274777, y: -0.075114705, z: -0.014378637} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightCorner - parentName: EthanHead1 - position: {x: 0.14939931, y: -0.06769704, z: 0.02431402} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightUpperLip - parentName: EthanHead1 - position: {x: 0.14274772, y: -0.07511473, z: 0.014226249} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanUpperLip - parentName: EthanHead1 - position: {x: 0.14274773, y: -0.087347545, z: -0.00007465846} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanJaw - parentName: EthanHead - position: {x: -0.03240739, y: -0.029785074, z: -0.00000007152633} - rotation: {x: -0.49673736, y: 0.5032417, z: 0.5032421, w: -0.49673653} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftLowerLip - parentName: EthanJaw - position: {x: 0.044976283, y: -0.009381128, z: -0.014150948} - rotation: {x: 5.54211e-23, y: 0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLowerLip - parentName: EthanJaw - position: {x: 0.057204966, y: 0.0049228696, z: -0.014469165} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightLowerLip - parentName: EthanJaw - position: {x: 0.044976283, y: 0.019223755, z: -0.014150911} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftBlink - parentName: EthanHead - position: {x: -0.08582658, y: -0.07248985, z: -0.023909489} - rotation: {x: -0.43938157, y: 0.5540251, z: 0.55402577, w: -0.4393808} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftBrow - parentName: EthanHead - position: {x: -0.09988994, y: -0.08062434, z: -0.028973255} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftEye - parentName: EthanHead - position: {x: -0.0817658, y: -0.058895037, z: -0.027851813} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightBlink - parentName: EthanHead - position: {x: -0.08582671, y: -0.07248995, z: 0.033750787} - rotation: {x: -0.44628233, y: 0.55759704, z: 0.54723495, w: -0.43640757} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightBrow - parentName: EthanHead - position: {x: -0.09989007, y: -0.08062444, z: 0.02868702} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightEye - parentName: EthanHead - position: {x: -0.0817396, y: -0.05880309, z: 0.027845075} - rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.00000004470348, y: 0, z: 0.13052633, w: -0.9914448} + scale: {x: 1, y: 0.99999994, z: 0.9999999} + transformModified: 1 - name: EthanLeftShoulder - parentName: EthanNeck position: {x: 0.00002230769, y: -0.00006137982, z: -0.026027031} - rotation: {x: -0.48608947, y: -0.0722202, z: 0.8640734, w: -0.10898846} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.4860895, y: 0.07222023, z: -0.86407334, w: 0.10898842} + scale: {x: 0.99999994, y: 0.9999999, z: 0.99999994} + transformModified: 1 - name: EthanLeftArm - parentName: EthanLeftShoulder position: {x: 0.08180639, y: 0.009300345, z: -0.09634663} - rotation: {x: 0.06292434, y: -0.29547754, z: -0.011793284, w: 0.95320225} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.062924355, y: -0.29547742, z: -0.011793196, w: 0.9532023} + scale: {x: 0.99999994, y: 1, z: 1.0000001} + transformModified: 1 - name: EthanLeftForeArm - parentName: EthanLeftArm position: {x: 0.08794441, y: -0.014121806, z: -0.22941957} - rotation: {x: -0.18687433, y: 0.0007973312, z: 0.14583053, w: 0.97149926} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.18687439, y: 0.00079712254, z: 0.14583057, w: 0.97149926} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999998} + transformModified: 1 - name: EthanLeftHand - parentName: EthanLeftForeArm position: {x: 0.070799686, y: 0.035503525, z: -0.14085448} - rotation: {x: -0.70413613, y: -0.061654028, z: -0.061605077, w: 0.7046956} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandIndex1 - parentName: EthanLeftHand - position: {x: 0.018482484, y: 0.08044448, z: 0.051040206} - rotation: {x: 0.0015112518, y: -0.043594275, z: -0.043560736, w: 0.9980981} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandIndex2 - parentName: EthanLeftHandIndex1 - position: {x: 0.00022275507, y: 0.025879132, z: 0.010385311} - rotation: {x: -0.052662343, y: 0.035397545, z: -0.2640296, w: 0.9624251} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandIndex3 - parentName: EthanLeftHandIndex2 - position: {x: -0.012793984, y: 0.016905012, z: 0.011081521} - rotation: {x: -0.02921515, y: 0.08614237, z: -0.2737419, w: 0.9574922} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandIndex4 - parentName: EthanLeftHandIndex3 - position: {x: -0.020055601, y: 0.0045873905, z: 0.007730915} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandMiddle1 - parentName: EthanLeftHand - position: {x: 0.013394796, y: 0.084405266, z: 0.03165157} - rotation: {x: -0.044011682, y: 2.8034074e-17, z: -5.7106006e-18, w: 0.999031} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandMiddle2 - parentName: EthanLeftHandMiddle1 - position: {x: 0.0037795054, y: 0.030145722, z: 0.0116361305} - rotation: {x: -0.091909915, y: 0.05467633, z: -0.42002133, w: 0.90119106} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandMiddle3 - parentName: EthanLeftHandMiddle2 - position: {x: -0.017910194, y: 0.014384004, z: 0.013012275} - rotation: {x: -0.040044915, y: 0.008001845, z: -0.18298166, w: 0.9822679} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandMiddle4 - parentName: EthanLeftHandMiddle3 - position: {x: -0.020049915, y: 0.0035380095, z: 0.012281134} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandPinky1 - parentName: EthanLeftHand - position: {x: -0.0067506824, y: 0.09838339, z: -0.0051224125} - rotation: {x: -0.15040894, y: 0.08822873, z: -0.33158392, w: 0.92717046} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandPinky2 - parentName: EthanLeftHandPinky1 - position: {x: -0.010750259, y: 0.009622569, z: 0.009467701} - rotation: {x: -0.044671368, y: 0.009720898, z: -0.17979467, w: 0.9826413} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandPinky3 - parentName: EthanLeftHandPinky2 - position: {x: -0.0155973025, y: 0.0034428125, z: 0.0112945065} - rotation: {x: -0.045708735, y: -0.0008739185, z: -0.17979562, w: 0.98264116} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandPinky4 - parentName: EthanLeftHandPinky3 - position: {x: -0.009463298, y: -0.002946482, z: 0.006961719} - rotation: {x: 8.326673e-17, y: 1.3877788e-17, z: -6.938894e-18, w: 1} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandRing1 - parentName: EthanLeftHand - position: {x: 0.011634815, y: 0.097086444, z: 0.00849549} - rotation: {x: -0.04750495, y: -0.02680468, z: -0.21266928, w: 0.9756006} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandRing2 - parentName: EthanLeftHandRing1 - position: {x: -0.009746879, y: 0.022168977, z: 0.013826583} - rotation: {x: -0.06670461, y: 0.026029166, z: -0.25883004, w: 0.9632653} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandRing3 - parentName: EthanLeftHandRing2 - position: {x: -0.015402557, y: 0.007800675, z: 0.011749413} - rotation: {x: -0.01883299, y: 0.002628695, z: -0.09988077, w: 0.9948177} - scale: {x: 1, y: 1, z: 1} - - name: EthanLeftHandRing4 - parentName: EthanLeftHandRing3 - position: {x: -0.01707594, y: 0.0025099975, z: 0.012105394} - rotation: {x: 0, y: -0, z: -0, w: 1} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.70413613, y: -0.061654136, z: -0.061605126, w: 0.7046955} + scale: {x: 1.0000001, y: 1.0000004, z: 1} + transformModified: 1 - name: EthanLeftHandThumb1 - parentName: EthanLeftHand position: {x: -0.004633863, y: 0.028035661, z: 0.048953336} - rotation: {x: 0.6603434, y: -0.2809301, z: -0.23108192, w: 0.6569824} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.6603427, y: -0.28092977, z: -0.23108095, w: 0.65698373} + scale: {x: 0.9999998, y: 0.99999994, z: 1} + transformModified: 1 - name: EthanLeftHandThumb2 - parentName: EthanLeftHandThumb1 position: {x: -0.0031383773, y: 0.025515735, z: -0.014984593} - rotation: {x: 0.042990893, y: -0.025952533, z: -0.17635348, w: 0.98304516} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.042994235, y: -0.025951888, z: -0.17635398, w: 0.983045} + scale: {x: 1, y: 1.0000004, z: 1.0000001} + transformModified: 1 - name: EthanLeftHandThumb3 - parentName: EthanLeftHandThumb2 position: {x: -0.010219031, y: 0.014567392, z: -0.012677365} - rotation: {x: 0.047834244, y: -0.015308736, z: -0.17635654, w: 0.9830442} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.047831908, y: -0.015310384, z: -0.17635532, w: 0.98304456} + scale: {x: 0.9999998, y: 1, z: 0.99999976} + transformModified: 1 - name: EthanLeftHandThumb4 - parentName: EthanLeftHandThumb3 position: {x: -0.016609639, y: 0.007850524, z: -0.014726918} - rotation: {x: 2.220446e-16, y: 0, z: -0, w: 1} + rotation: {x: 0.00000020861623, y: 0.000000029802319, z: -0.000000059604638, + w: 1} scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftHandIndex1 + position: {x: 0.018482484, y: 0.08044448, z: 0.051040206} + rotation: {x: 0.0015113147, y: -0.043594163, z: -0.043560673, w: 0.99809813} + scale: {x: 0.9999996, y: 0.9999995, z: 1} + transformModified: 1 + - name: EthanLeftHandIndex2 + position: {x: 0.00022275507, y: 0.025879132, z: 0.010385311} + rotation: {x: -0.05266091, y: 0.035396505, z: -0.26402727, w: 0.9624258} + scale: {x: 1.0000001, y: 1.0000005, z: 1} + transformModified: 1 + - name: EthanLeftHandIndex3 + position: {x: -0.012793984, y: 0.016905012, z: 0.011081521} + rotation: {x: -0.029213775, y: 0.08614278, z: -0.2737399, w: 0.9574928} + scale: {x: 0.99999994, y: 1.0000002, z: 1} + transformModified: 1 + - name: EthanLeftHandIndex4 + position: {x: -0.020055601, y: 0.0045873905, z: 0.007730915} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftHandMiddle1 + position: {x: 0.013394796, y: 0.084405266, z: 0.03165157} + rotation: {x: -0.044011593, y: 0.00000013411042, z: 0.00000008777713, w: 0.999031} + scale: {x: 0.9999999, y: 0.9999998, z: 1} + transformModified: 1 + - name: EthanLeftHandMiddle2 + position: {x: 0.0037795054, y: 0.030145722, z: 0.0116361305} + rotation: {x: -0.09190983, y: 0.054676782, z: -0.420022, w: 0.9011906} + scale: {x: 1, y: 1.0000004, z: 0.99999994} + transformModified: 1 + - name: EthanLeftHandMiddle3 + position: {x: -0.017910194, y: 0.014384004, z: 0.013012275} + rotation: {x: -0.040044125, y: 0.008001473, z: -0.18298012, w: 0.9822682} + scale: {x: 1, y: 1.0000001, z: 1.0000001} + transformModified: 1 + - name: EthanLeftHandMiddle4 + position: {x: -0.020049915, y: 0.0035380095, z: 0.012281134} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftHandRing1 + position: {x: 0.011634815, y: 0.097086444, z: 0.00849549} + rotation: {x: -0.047505103, y: -0.026804648, z: -0.21266912, w: 0.97560066} + scale: {x: 0.9999998, y: 1.0000001, z: 1.0000001} + transformModified: 1 + - name: EthanLeftHandRing2 + position: {x: -0.009746879, y: 0.022168977, z: 0.013826583} + rotation: {x: -0.06670468, y: 0.0260291, z: -0.2588301, w: 0.9632653} + scale: {x: 0.99999994, y: 0.9999999, z: 1} + transformModified: 1 + - name: EthanLeftHandRing3 + position: {x: -0.015402557, y: 0.007800675, z: 0.011749413} + rotation: {x: -0.018833177, y: 0.0026289748, z: -0.099881686, w: 0.9948176} + scale: {x: 1, y: 0.9999999, z: 0.99999994} + transformModified: 1 + - name: EthanLeftHandRing4 + position: {x: -0.01707594, y: 0.0025099975, z: 0.012105394} + rotation: {x: 0, y: 0, z: 0, w: 1} + scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftHandPinky1 + position: {x: -0.0067506824, y: 0.09838339, z: -0.0051224125} + rotation: {x: -0.15041116, y: 0.088230126, z: -0.33158657, w: 0.92716897} + scale: {x: 0.99999946, y: 0.99999994, z: 0.9999998} + transformModified: 1 + - name: EthanLeftHandPinky2 + position: {x: -0.010750259, y: 0.009622569, z: 0.009467701} + rotation: {x: -0.044669047, y: 0.009719333, z: -0.1797906, w: 0.9826422} + scale: {x: 1, y: 1.0000001, z: 1} + transformModified: 1 + - name: EthanLeftHandPinky3 + position: {x: -0.0155973025, y: 0.0034428125, z: 0.0112945065} + rotation: {x: -0.045708567, y: -0.0008701785, z: -0.17979488, w: 0.9826412} + scale: {x: 1, y: 1.0000004, z: 1.0000001} + transformModified: 1 + - name: EthanLeftHandPinky4 + position: {x: -0.009463298, y: -0.002946482, z: 0.006961719} + rotation: {x: -0.000000042840824, y: -0.000000059604623, z: -0.000000017229462, + w: 1} + scale: {x: 0.9999999, y: 1.0000001, z: 1} + transformModified: 1 - name: EthanRightShoulder - parentName: EthanNeck position: {x: 0.000022271464, y: -0.00006150465, z: 0.026027026} - rotation: {x: 0.48609114, y: 0.07221765, z: 0.86407244, w: -0.10898975} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.48609093, y: -0.072217636, z: -0.8640726, w: 0.10898978} + scale: {x: 1.0000001, y: 1.0000001, z: 0.99999994} + transformModified: 1 - name: EthanRightArm - parentName: EthanRightShoulder position: {x: 0.081806876, y: 0.009300272, z: 0.096346125} - rotation: {x: -0.06292416, y: 0.29547858, z: -0.011792945, w: 0.95320195} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.06292414, y: 0.2954782, z: -0.011793, w: 0.953202} + scale: {x: 1.0000002, y: 1.0000001, z: 1.0000001} + transformModified: 1 - name: EthanRightForeArm - parentName: EthanRightArm position: {x: 0.087945335, y: -0.014121898, z: 0.22941919} - rotation: {x: 0.18687426, y: -0.00079792744, z: 0.14582933, w: 0.97149944} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.18687394, y: -0.0007980613, z: 0.1458295, w: 0.97149944} + scale: {x: 1.0000001, y: 1.0000002, z: 1.0000001} + transformModified: 1 - name: EthanRightHand - parentName: EthanRightForeArm position: {x: 0.07080024, y: 0.03550319, z: 0.14085418} - rotation: {x: 0.70413506, y: 0.061653953, z: -0.061604813, w: 0.7046967} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.704135, y: 0.061653838, z: -0.061604835, w: 0.7046967} + scale: {x: 0.99999964, y: 0.9999997, z: 0.99999946} + transformModified: 1 + - name: EthanRightHandThumb1 + position: {x: -0.0046337163, y: 0.028035993, z: -0.04895318} + rotation: {x: -0.6603439, y: 0.28093216, z: -0.23107955, w: 0.656982} + scale: {x: 1.0000004, y: 1.0000001, z: 1.0000005} + transformModified: 1 + - name: EthanRightHandThumb2 + position: {x: -0.0031383634, y: 0.025515651, z: 0.014984788} + rotation: {x: -0.04299632, y: 0.025953326, z: -0.17635515, w: 0.98304456} + scale: {x: 0.9999998, y: 1.0000001, z: 0.9999999} + transformModified: 1 + - name: EthanRightHandThumb3 + position: {x: -0.010218882, y: 0.014567167, z: 0.012677433} + rotation: {x: -0.0478321, y: 0.015310019, z: -0.17635414, w: 0.98304474} + scale: {x: 0.99999994, y: 1.0000001, z: 0.99999994} + transformModified: 1 + - name: EthanRightHandThumb4 + position: {x: -0.016609553, y: 0.007850429, z: 0.0147271305} + rotation: {x: -0.8654032, y: 0.000000059604638, z: 0, w: 0.5010763} + scale: {x: 0.99999994, y: 0.99999976, z: 0.99999976} + transformModified: 1 - name: EthanRightHandIndex1 - parentName: EthanRightHand position: {x: 0.018482815, y: 0.08044467, z: -0.05103978} - rotation: {x: -0.0015103403, y: 0.04359434, z: -0.04356065, w: 0.9980981} - scale: {x: 1, y: 1, z: 1} + rotation: {x: -0.001510277, y: 0.04359444, z: -0.043560643, w: 0.998098} + scale: {x: 1, y: 1.0000006, z: 1.0000006} + transformModified: 1 - name: EthanRightHandIndex2 - parentName: EthanRightHandIndex1 position: {x: 0.0002228482, y: 0.025879227, z: -0.0103851855} - rotation: {x: 0.052665275, y: -0.03539689, z: -0.2640311, w: 0.9624246} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.052665427, y: -0.03539806, z: -0.26403317, w: 0.9624239} + scale: {x: 0.9999997, y: 0.99999964, z: 0.9999995} + transformModified: 1 - name: EthanRightHandIndex3 - parentName: EthanRightHandIndex2 position: {x: -0.012793941, y: 0.01690497, z: -0.01108144} - rotation: {x: 0.029212933, y: -0.086144, z: -0.27374128, w: 0.95749235} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.029213933, y: -0.086143054, z: -0.27374178, w: 0.95749223} + scale: {x: 0.99999994, y: 0.9999999, z: 1.0000001} + transformModified: 1 - name: EthanRightHandIndex4 - parentName: EthanRightHandIndex3 position: {x: -0.020055542, y: 0.0045875087, z: -0.007730851} rotation: {x: 0.48288566, y: 0, z: -0, w: 0.8756834} scale: {x: 1, y: 1, z: 1} + transformModified: 1 - name: EthanRightHandMiddle1 - parentName: EthanRightHand position: {x: 0.013395289, y: 0.08440544, z: -0.031651095} - rotation: {x: 0.044012643, y: 6.003835e-17, z: 1.01539365e-16, w: 0.999031} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.044012684, y: 0.000000089406946, z: -0.00000005960463, w: 0.99903095} + scale: {x: 0.9999999, y: 0.9999998, z: 1} + transformModified: 1 - name: EthanRightHandMiddle2 - parentName: EthanRightHandMiddle1 position: {x: 0.0037796986, y: 0.030145705, z: -0.011636003} - rotation: {x: 0.094236314, y: -0.059271846, z: -0.4174624, w: 0.9018489} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.09423573, y: -0.059270926, z: -0.41746053, w: 0.9018499} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + transformModified: 1 - name: EthanRightHandMiddle3 - parentName: EthanRightHandMiddle2 position: {x: -0.017910058, y: 0.01438411, z: -0.013012125} - rotation: {x: 0.04004537, y: -0.008000995, z: -0.182982, w: 0.98226786} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.040044833, y: -0.008001883, z: -0.18298179, w: 0.98226786} + scale: {x: 1.0000004, y: 0.9999999, z: 1.0000001} + transformModified: 1 - name: EthanRightHandMiddle4 - parentName: EthanRightHandMiddle3 position: {x: -0.020049982, y: 0.003538114, z: -0.012281116} rotation: {x: 0.37079856, y: 0, z: -0, w: 0.9287133} scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandPinky1 - parentName: EthanRightHand - position: {x: -0.006750106, y: 0.09838347, z: 0.005122984} - rotation: {x: 0.1463402, y: -0.08530397, z: -0.3388866, w: 0.9254532} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandPinky2 - parentName: EthanRightHandPinky1 - position: {x: -0.010876534, y: 0.00954607, z: -0.009400739} - rotation: {x: 0.035175603, y: -0.014915591, z: -0.1534898, w: 0.98741126} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandPinky3 - parentName: EthanRightHandPinky2 - position: {x: -0.015650306, y: 0.004325165, z: -0.010911368} - rotation: {x: 0.04428527, y: -0.00024321023, z: -0.18078291, w: 0.98252547} - scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandPinky4 - parentName: EthanRightHandPinky3 - position: {x: -0.009746457, y: -0.002438951, z: -0.006764462} - rotation: {x: 0.1938353, y: 4.4878757e-17, z: 1.2351859e-17, w: 0.9810341} - scale: {x: 1, y: 1, z: 1} + transformModified: 1 - name: EthanRightHandRing1 - parentName: EthanRightHand position: {x: 0.011635365, y: 0.09708646, z: -0.008494926} - rotation: {x: 0.060691163, y: 0.019897887, z: -0.24453539, w: 0.9675346} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.06069146, y: 0.019897364, z: -0.24453661, w: 0.9675343} + scale: {x: 1.0000002, y: 1.0000001, z: 0.9999999} + transformModified: 1 - name: EthanRightHandRing2 - parentName: EthanRightHandRing1 position: {x: -0.011261935, y: 0.021090085, z: -0.014353217} - rotation: {x: 0.06872561, y: -0.023836197, z: -0.258021, w: 0.963397} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.06872784, y: -0.023836557, z: -0.25802362, w: 0.96339613} + scale: {x: 1.0000002, y: 1, z: 1.0000001} + transformModified: 1 - name: EthanRightHandRing3 - parentName: EthanRightHandRing2 position: {x: -0.015814971, y: 0.0064337812, z: -0.012026324} - rotation: {x: 0.019225024, y: -0.0019389626, z: -0.09967033, w: 0.9948329} - scale: {x: 1, y: 1, z: 1} + rotation: {x: 0.019220976, y: -0.0019377263, z: -0.099664316, w: 0.9948335} + scale: {x: 1.0000001, y: 0.99999994, z: 1} + transformModified: 1 - name: EthanRightHandRing4 - parentName: EthanRightHandRing3 position: {x: -0.017074374, y: 0.0010487483, z: -0.012320689} rotation: {x: 0.4587139, y: 0, z: -0, w: 0.888584} scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandThumb1 - parentName: EthanRightHand - position: {x: -0.0046337163, y: 0.028035993, z: -0.04895318} - rotation: {x: -0.6603426, y: 0.28093094, z: -0.23108082, w: 0.65698344} + transformModified: 1 + - name: EthanRightHandPinky1 + position: {x: -0.006750106, y: 0.09838347, z: 0.005122984} + rotation: {x: 0.1463391, y: -0.08530413, z: -0.3388866, w: 0.9254534} + scale: {x: 1, y: 1.0000004, z: 1.0000001} + transformModified: 1 + - name: EthanRightHandPinky2 + position: {x: -0.010876534, y: 0.00954607, z: -0.009400739} + rotation: {x: 0.03517469, y: -0.014915802, z: -0.15348929, w: 0.98741144} + scale: {x: 1.0000001, y: 0.99999976, z: 0.9999999} + transformModified: 1 + - name: EthanRightHandPinky3 + position: {x: -0.015650306, y: 0.004325165, z: -0.010911368} + rotation: {x: 0.044283934, y: -0.00024359577, z: -0.18078029, w: 0.98252606} + scale: {x: 1.0000001, y: 0.99999994, z: 1.0000002} + transformModified: 1 + - name: EthanRightHandPinky4 + position: {x: -0.009746457, y: -0.002438951, z: -0.006764462} + rotation: {x: 0.19383506, y: -0.000000048428767, z: -0.000000029802319, w: 0.98103416} + scale: {x: 1, y: 0.99999994, z: 0.9999998} + transformModified: 1 + - name: EthanHead + position: {x: -0.090649985, y: -0.041122116, z: 0.000000058975164} + rotation: {x: 0.000000029802322, y: 0.000000059604645, z: -0.08755198, w: -0.99616} + scale: {x: 1, y: 1.0000002, z: 1.0000002} + transformModified: 1 + - name: EthanLeftBrow + position: {x: -0.09988994, y: -0.08062434, z: -0.028973255} + rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandThumb2 - parentName: EthanRightHandThumb1 - position: {x: -0.0031383634, y: 0.025515651, z: 0.014984788} - rotation: {x: -0.04299569, y: 0.025953516, z: -0.17635538, w: 0.98304456} + transformModified: 1 + - name: EthanRightBrow + position: {x: -0.09989007, y: -0.08062444, z: 0.02868702} + rotation: {x: -0.5, y: 0.5, z: 0.5000007, w: -0.49999928} scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandThumb3 - parentName: EthanRightHandThumb2 - position: {x: -0.010218882, y: 0.014567167, z: 0.012677433} - rotation: {x: -0.047832713, y: 0.015309883, z: -0.17635481, w: 0.98304456} + transformModified: 1 + - name: EthanHead1 + position: {x: -0.17475267, y: 0.00000045072835, z: 0.00000009431633} + rotation: {x: 0.000000059604645, y: 0, z: 0, w: 1} + scale: {x: 0.9999999, y: 0.99999994, z: 0.9999999} + transformModified: 1 + - name: EthanUpperLip + position: {x: 0.14274773, y: -0.087347545, z: -0.00007465846} + rotation: {x: -0.5000001, y: 0.5, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanRightUpperLip + position: {x: 0.14274772, y: -0.07511473, z: 0.014226249} + rotation: {x: -0.5000001, y: 0.5, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanLeftUpperLip + position: {x: 0.14274777, y: -0.075114705, z: -0.014378637} + rotation: {x: -0.5000001, y: 0.5, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanRightCorner + position: {x: 0.14939931, y: -0.06769704, z: 0.02431402} + rotation: {x: -0.5000001, y: 0.5, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanLeftCorner + position: {x: 0.14939941, y: -0.06769698, z: -0.024466591} + rotation: {x: -0.5000001, y: 0.5, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanJaw + position: {x: -0.03240739, y: -0.029785074, z: -0.00000007152633} + rotation: {x: -0.49673745, y: 0.5032417, z: 0.5032422, w: -0.49673647} + scale: {x: 0.9999998, y: 0.99999964, z: 0.99999964} + transformModified: 1 + - name: EthanLowerLip + position: {x: 0.057204966, y: 0.0049228696, z: -0.014469165} + rotation: {x: 0, y: 0, z: 0, w: 1} scale: {x: 1, y: 1, z: 1} - - name: EthanRightHandThumb4 - parentName: EthanRightHandThumb3 - position: {x: -0.016609553, y: 0.007850429, z: 0.0147271305} - rotation: {x: -0.8654032, y: 0, z: 0, w: 0.5010762} + transformModified: 1 + - name: EthanRightLowerLip + position: {x: 0.044976283, y: 0.019223755, z: -0.014150911} + rotation: {x: 0, y: 0, z: 0, w: 1} scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftLowerLip + position: {x: 0.044976283, y: -0.009381128, z: -0.014150948} + rotation: {x: -0.00000011920926, y: 0.000000089406946, z: -0.00000005960463, + w: 1} + scale: {x: 1.0000001, y: 1, z: 0.99999994} + transformModified: 1 + - name: EthanRightBlink + position: {x: -0.08582671, y: -0.07248995, z: 0.033750787} + rotation: {x: -0.44628236, y: 0.55759704, z: 0.547235, w: -0.43640754} + scale: {x: 0.99999976, y: 0.99999976, z: 0.9999997} + transformModified: 1 + - name: EthanLeftBlink + position: {x: -0.08582658, y: -0.07248985, z: -0.023909489} + rotation: {x: -0.4393816, y: 0.5540251, z: 0.55402577, w: -0.43938076} + scale: {x: 1, y: 0.9999999, z: 0.9999999} + transformModified: 1 + - name: EthanLeftEye + position: {x: -0.0817658, y: -0.058895037, z: -0.027851813} + rotation: {x: -0.5000001, y: 0.49999997, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.99999976} + transformModified: 1 + - name: EthanRightEye + position: {x: -0.0817396, y: -0.05880309, z: 0.027845075} + rotation: {x: -0.5000001, y: 0.49999997, z: 0.5000007, w: -0.49999928} + scale: {x: 0.99999994, y: 0.9999999, z: 0.99999976} + transformModified: 1 + - name: EthanLeftUpLeg + position: {x: 0.044804916, y: -0.00400244, z: -0.07436281} + rotation: {x: -0.009854168, y: -0.9996559, z: 0.0031335354, w: -0.024108008} + scale: {x: 1.0000001, y: 1.0000002, z: 0.9999998} + transformModified: 1 + - name: EthanLeftLeg + position: {x: -0.3547823, y: -0.048040718, z: 0.036754183} + rotation: {x: 0.000000014901161, y: 0.000000029802322, z: 0.16876784, w: 0.9856559} + scale: {x: 1, y: 1, z: 1} + transformModified: 1 + - name: EthanLeftFoot + position: {x: -0.2827789, y: 0.1718791, z: 0.031038838} + rotation: {x: 0.0843049, y: -0.035965025, z: 0.1331117, w: -0.9868539} + scale: {x: 0.99999976, y: 0.9999997, z: 0.99999976} + transformModified: 1 + - name: EthanLeftToe1 + position: {x: -0.085517354, y: -0.11005712, z: -0.0000006698085} + rotation: {x: -0.00000005960463, y: 0.00000003888532, z: 0.7071068, w: -0.7071068} + scale: {x: 1.0000005, y: 1.0000001, z: 1.0000005} + transformModified: 1 + - name: EthanLeftToe2 + position: {x: 0.08174267, y: -0.000000009601407, z: -0.00000029316797} + rotation: {x: 1, y: 0.0000000342361, z: 0.00000008940694, w: -0.00000070150384} + scale: {x: 1, y: 1, z: 0.9999999} + transformModified: 1 + - name: EthanRightUpLeg + position: {x: 0.044804532, y: -0.004002823, z: 0.07436302} + rotation: {x: -0.009854078, y: -0.99965596, z: -0.003136307, w: 0.024108097} + scale: {x: 1, y: 1.0000002, z: 0.99999976} + transformModified: 1 + - name: EthanRightLeg + position: {x: -0.3529783, y: -0.04747951, z: -0.034621846} + rotation: {x: -0.000000044703473, y: -0.00000005960463, z: -0.16876689, w: -0.98565596} + scale: {x: 0.99999976, y: 0.99999976, z: 0.99999976} + transformModified: 1 + - name: EthanRightFoot + position: {x: -0.282779, y: 0.17187855, z: -0.031040668} + rotation: {x: -0.08430425, y: 0.0359649, z: 0.13311061, w: -0.986854} + scale: {x: 1.0000001, y: 1.0000001, z: 1} + transformModified: 1 + - name: EthanRightToe1 + position: {x: -0.08551728, y: -0.11005718, z: 0.000000062032285} + rotation: {x: -0.00000008940697, y: 0.000000017728667, z: -0.7071068, w: 0.7071068} + scale: {x: 0.9999999, y: 1, z: 0.9999999} + transformModified: 1 + - name: EthanRightToe2 + position: {x: 0.08174264, y: 0.000000049485, z: 0.00000019218783} + rotation: {x: 0.000000022965732, y: -6.64365e-14, z: 0.00000011919623, w: 1} + scale: {x: 1, y: 1, z: 1} + transformModified: 1 armTwist: 0.5 foreArmTwist: 0.5 upperLegTwist: 0.5 @@ -2000,19 +1255,11 @@ ModelImporter: armStretch: 1 legStretch: 1 feetSpacing: 0 - globalScale: 0.01 rootMotionBoneName: hasTranslationDoF: 0 - hasExtraRoot: 0 - skeletonHasParents: 0 lastHumanDescriptionAvatarSource: {instanceID: 0} - autoGenerateAvatarMappingIfUnspecified: 0 animationType: 3 humanoidOversampling: 1 - avatarSetup: 1 - addHumanoidExtraRootOnlyWhenUsingAvatar: 0 - importBlendShapeDeformPercent: 0 - remapMaterialsIfMaterialImportModeIsNone: 1 additionalBone: 0 userData: assetBundleName: diff --git a/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset b/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset new file mode 100644 index 00000000..e87dc2c7 --- /dev/null +++ b/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f7d87fe14c4d6657f4e6bb187c8516091c66d24fe726314f40446ea29a23de7 +size 1944 diff --git a/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta b/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta new file mode 100644 index 00000000..d6275c95 --- /dev/null +++ b/Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c4b8a69c9f45e384d92846d5b5081c1a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/UniGLTF/Runtime/Resources/test_motion.txt.meta b/Assets/External/UniGLTF/Runtime/Resources/test_motion.txt.meta index a514100b..b77c0c6f 100644 --- a/Assets/External/UniGLTF/Runtime/Resources/test_motion.txt.meta +++ b/Assets/External/UniGLTF/Runtime/Resources/test_motion.txt.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 guid: 7d2617171adc40b41ac50228f101e178 -timeCreated: 1546851178 -licenseType: Pro -DefaultImporter: +TextScriptImporter: + externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/External/UniGLTF/Runtime/UniHumanoid/HumanPoseClip.cs b/Assets/External/UniGLTF/Runtime/UniHumanoid/HumanPoseClip.cs index bed31795..9de44649 100644 --- a/Assets/External/UniGLTF/Runtime/UniHumanoid/HumanPoseClip.cs +++ b/Assets/External/UniGLTF/Runtime/UniHumanoid/HumanPoseClip.cs @@ -6,6 +6,7 @@ namespace UniHumanoid public class HumanPoseClip : ScriptableObject { public const string TPoseResourcePath = "T-Pose.pose"; + public const string IPoseResourcePath = "I-Pose.pose"; public Vector3 bodyPosition; diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset index 19426ddf..c7727149 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8af94026c132aa2108f30b901c35ed0138c9b9cf2222c5dad916251c765a43e -size 47904 +oid sha256:c9dc9a7cbc45c9514fbaf093777c757b142dd3f3405a5bc110223214ed98a06b +size 46925 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset index 1c8238e2..0cc72db0 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6161d414165ca5d83175e8f445dd49e3b5d87e87b07e3e666c08dfc7768122d1 -size 47997 +oid sha256:392d4824f52d148f4e47e33e43ad351181691c8714af5ce2d5d07520274fc838 +size 47037 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset index 3e89b934..ab433444 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72833bc88329a329f99e5c1369987d8837ef4182b08f9811aaa95dffb2f72708 -size 47959 +oid sha256:491a120b182d613c65dec10623cfb90eb76a7db9919dae67fc9060c48bcc26eb +size 47006 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset index cfdaece3..8e1ad312 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5df535c161f2b1e85476f93da472d56d01a7f1a136a7a404b1c5bf6b0eb178d -size 47953 +oid sha256:e9d64b2d097d99358cc6b36e78f2b14fc9dd1f4672d3bb9f4990d262d30d4012 +size 46999 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset index 2b3f3ef3..d22682e9 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a92dfe60e6357baca526a9b5a0d84ea84d9faa58d829ef2df6d0f77be78ce9d7 -size 48001 +oid sha256:87d504c94cab419c862e4f4c32515945df282f15680845a15d916a5f069bf539 +size 47029 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset index c8f856b4..b1049db5 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:476db73d0702814f77a10590ff9b5223f260b1d35619b4409f58c8fb0bf33eaf -size 47881 +oid sha256:b1983b716328cc5e3f614c400d43a88fbf43da82c742bb66c35ba039c6aae064 +size 46910 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset index 868b2476..38db3984 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e6c03ff75fc360a403616ce7947f6660f0b73003d2b222d7486ed171896f953 -size 47880 +oid sha256:a5c7f2f412b1b426f740d8b244646efeb5e91b78023c7ac9342c241963073045 +size 46909 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset index 99249bd8..137081f6 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9869f6209d381760e8682b4e6e0bdbb5864f686f56775849166643f9945b30d8 -size 47873 +oid sha256:d631a81fcc9b856167a196333c02498289fca3ed4be8ee27386b9830c69c83e4 +size 46902 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset index dc524c58..60cfe18c 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6d9e87b17826778c95e85748890cac28787f5a9bfd33c17f49b6d45bc84d9b7 -size 47970 +oid sha256:a7ee233224b24449f9b7a5cd5948b83819be606ff70280d0ba9ff760366c2cd8 +size 47074 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset index aa5737ec..7836a63c 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6307b84dee3227890074294b33bebb78c352de3e9928477b90f36bdfdb109eec -size 47997 +oid sha256:9f70412c7be66bccba70cf071caa7b2ddef5360ea003f8c3f4042d8a95dd7327 +size 47025 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset index d5981914..88387393 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95f2bbc59a54de0d4c4453a00393e1fa727db1ce07105cdaa9481d795e312e83 -size 47997 +oid sha256:652f462df6eed6cc37363b51defd01438d0b5292ffa08421ce0309673035b5b8 +size 47025 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset index 03de9e55..a39a11f8 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:919526cb3b9a7cb68a5877052a6e927ef2f0a415c4eba24b4167b8841e18328b -size 47957 +oid sha256:3f6b6b830a9a140ed4d594d182524b0fd1c37bad31dfa89de41c070678510d6b +size 47062 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset index 6a743d4a..ce95ea69 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04268000a372b1e4123e115a3e3301e8f0fadd9524528f27f72e8cf1d89b160a -size 47958 +oid sha256:8614230d1693001e22d65d06ebf68305ecf5319b581487cc5f66f1462095f6c2 +size 47063 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset index cb04666b..8093a6c7 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75d58c9915b48c06d6ad268563af0f61f585eafb7591ee82d7e515e9d775c0b8 -size 47848 +oid sha256:f9a3fcbc7410597e4db70f19d25992823f3d143a97c26879731caab4eeebf86d +size 46894 diff --git a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab index 92f1f36c..8d68ff1f 100644 --- a/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab +++ b/Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4388fc5a64b876a71f265f9447680497e6044c2c947b5fbf9e9bdf83ec13226e -size 284295 +oid sha256:779ff71ae6b21d154b32ea13bcbc4b5c697c9dc47301ce6ef422aac44f91bd8e +size 283240 diff --git a/Assets/ResourcesData/Etc.meta b/Assets/ResourcesData/Etc.meta new file mode 100644 index 00000000..9ffc785e --- /dev/null +++ b/Assets/ResourcesData/Etc.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c50d1706d9c5fce43b5f9ee9bd3c1d59 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ResourcesData/Etc/Plane UV.meta b/Assets/ResourcesData/Etc/Plane UV.meta new file mode 100644 index 00000000..eea16b7d --- /dev/null +++ b/Assets/ResourcesData/Etc/Plane UV.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 872de359ed282b846ba8b1d2ffd14aac +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat new file mode 100644 index 00000000..357a757b --- /dev/null +++ b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-7164037998396398279 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 9 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: PlaneUV + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 2800000, guid: fb1c6a42d195a80488bb37ada228ebfa, type: 3} + m_Scale: {x: 80, y: 80} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 2800000, guid: fb1c6a42d195a80488bb37ada228ebfa, type: 3} + m_Scale: {x: 80, y: 80} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta new file mode 100644 index 00000000..1f5b4cb4 --- /dev/null +++ b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1452bd3d60b905d4499a8e9c99d5b488 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png new file mode 100644 index 00000000..d8433982 --- /dev/null +++ b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e93a579aac6450cd6e93addb36e9cea11996c3341809cf219740e63d2c573b5 +size 15440 diff --git a/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta new file mode 100644 index 00000000..d4cb63b5 --- /dev/null +++ b/Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta @@ -0,0 +1,115 @@ +fileFormatVersion: 2 +guid: fb1c6a42d195a80488bb37ada228ebfa +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Development scene.unity b/Assets/Scenes/Development scene.unity index fd94335e..1b2bfaf6 100644 --- a/Assets/Scenes/Development scene.unity +++ b/Assets/Scenes/Development scene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:989f93f79f3c54f303f1eb678fcb12349e01017a54ae6dc0f57b1bc0929051a8 -size 56503 +oid sha256:a37a2f545bf68167adafe3210bb4671b8b324f97a2880c7e9d4977ec852dc58e +size 79247 diff --git a/Assets/Scripts/Editor.meta b/Assets/Scripts/Editor.meta new file mode 100644 index 00000000..5d7c05e5 --- /dev/null +++ b/Assets/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d987f2b028376dc4a9e670318498ddca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/HumanPoseClipApplier.cs b/Assets/Scripts/Editor/HumanPoseClipApplier.cs new file mode 100644 index 00000000..5be1d580 --- /dev/null +++ b/Assets/Scripts/Editor/HumanPoseClipApplier.cs @@ -0,0 +1,138 @@ +using UnityEngine; +using UnityEditor; +using System.IO; +using UniHumanoid; +using UniGLTF; + +[System.Serializable] +public class HumanPoseData +{ + public Vector3 bodyPosition; + public Quaternion bodyRotation; + public float[] muscles; +} + +public class HumanPoseClipApplier : EditorWindow +{ + private Animator targetAnimator; + private HumanPoseClip poseClip; + private string jsonPath; + private bool useJsonFile = false; + + [MenuItem("Tools/Animation/Apply Human Pose Clip")] + public static void ShowWindow() + { + GetWindow("Human Pose Clip Applier"); + } + + private void OnGUI() + { + GUILayout.Label("Apply Human Pose Clip to Animator", EditorStyles.boldLabel); + + EditorGUILayout.Space(); + + targetAnimator = (Animator)EditorGUILayout.ObjectField("Target Animator", targetAnimator, typeof(Animator), true); + + EditorGUILayout.Space(); + + useJsonFile = EditorGUILayout.Toggle("Use JSON File", useJsonFile); + + if (useJsonFile) + { + EditorGUILayout.BeginHorizontal(); + jsonPath = EditorGUILayout.TextField("JSON File Path", jsonPath); + if (GUILayout.Button("Browse", GUILayout.Width(60))) + { + string path = EditorUtility.OpenFilePanel("Select JSON File", "", "json"); + if (!string.IsNullOrEmpty(path)) + { + jsonPath = path; + } + } + EditorGUILayout.EndHorizontal(); + } + else + { + poseClip = (HumanPoseClip)EditorGUILayout.ObjectField("Pose Clip", poseClip, typeof(HumanPoseClip), false); + } + + EditorGUILayout.Space(); + + bool canApply = targetAnimator != null && + ((useJsonFile && !string.IsNullOrEmpty(jsonPath)) || (!useJsonFile && poseClip != null)); + GUI.enabled = canApply; + if (GUILayout.Button("Apply Pose Clip")) + { + ApplyPoseClip(); + } + GUI.enabled = true; + } + + private void ApplyPoseClip() + { + if (targetAnimator == null) + { + EditorUtility.DisplayDialog("Error", "Please select an Animator!", "OK"); + return; + } + + HumanPose pose; + if (useJsonFile) + { + if (string.IsNullOrEmpty(jsonPath) || !File.Exists(jsonPath)) + { + EditorUtility.DisplayDialog("Error", "Please select a valid JSON file!", "OK"); + return; + } + // JSON 파일에서 데이터 로드 + string jsonContent = File.ReadAllText(jsonPath); + HumanPoseData poseData = JsonUtility.FromJson(jsonContent); + + // HumanPose로 변환 + pose = new HumanPose + { + bodyPosition = poseData.bodyPosition, + bodyRotation = poseData.bodyRotation, + muscles = poseData.muscles + }; + } + else if (poseClip != null) + { + pose = poseClip.GetPose(); + } + else + { + EditorUtility.DisplayDialog("Error", "Please select a Pose Clip!", "OK"); + return; + } + + var animator = targetAnimator; + var avatar = animator.avatar; + + if (avatar == null || !avatar.isHuman) + { + EditorUtility.DisplayDialog("Error", "Selected Animator must have a Humanoid Avatar!", "OK"); + return; + } + + try + { + // HumanPoseHandler를 사용하여 포즈 데이터 적용 + var handler = new HumanPoseHandler(avatar, animator.transform); + + // 포즈 적용 + handler.SetHumanPose(ref pose); + + // 변경사항 저장 + EditorUtility.SetDirty(animator); + + Debug.Log("Pose clip has been applied to the Animator"); + EditorUtility.DisplayDialog("Success", "Pose clip has been applied to the Animator", "OK"); + } + catch (System.Exception e) + { + Debug.LogError($"Error applying pose clip: {e.Message}"); + EditorUtility.DisplayDialog("Error", $"Failed to apply pose clip: {e.Message}", "OK"); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta b/Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta new file mode 100644 index 00000000..56c0d12e --- /dev/null +++ b/Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a1fa397be4544444b859d065a7aa33b3 \ No newline at end of file diff --git a/Assets/Scripts/Editor/HumanPoseClipCreator.cs b/Assets/Scripts/Editor/HumanPoseClipCreator.cs new file mode 100644 index 00000000..0a9ae420 --- /dev/null +++ b/Assets/Scripts/Editor/HumanPoseClipCreator.cs @@ -0,0 +1,119 @@ +using UnityEngine; +using UnityEditor; +using System.IO; +using UniHumanoid; + +public class HumanPoseClipCreator : EditorWindow +{ + private Animator selectedAnimator; + private string assetName = "NewPoseClip"; + private string savePath = "Assets/Resources"; + + [MenuItem("Tools/Animation/Create Human Pose Clip")] + public static void ShowWindow() + { + GetWindow("Human Pose Clip Creator"); + } + + private void OnGUI() + { + GUILayout.Label("Create Human Pose Clip", EditorStyles.boldLabel); + + EditorGUILayout.Space(); + + selectedAnimator = (Animator)EditorGUILayout.ObjectField("Target Animator", selectedAnimator, typeof(Animator), true); + + EditorGUILayout.Space(); + + assetName = EditorGUILayout.TextField("Asset Name", assetName); + + EditorGUILayout.BeginHorizontal(); + savePath = EditorGUILayout.TextField("Save Path", savePath); + if (GUILayout.Button("Browse", GUILayout.Width(60))) + { + string path = EditorUtility.SaveFolderPanel("Select Save Location", "Assets", ""); + if (!string.IsNullOrEmpty(path)) + { + string projectPath = Application.dataPath; + if (path.StartsWith(projectPath)) + { + savePath = "Assets" + path.Substring(projectPath.Length); + } + else + { + EditorUtility.DisplayDialog("Error", "Please select a folder inside the Assets directory!", "OK"); + } + } + } + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.Space(); + + GUI.enabled = selectedAnimator != null; + if (GUILayout.Button("Create Pose Clip")) + { + CreatePoseClip(); + } + GUI.enabled = true; + } + + private void CreatePoseClip() + { + if (selectedAnimator == null) + { + EditorUtility.DisplayDialog("Error", "Please select an Animator first!", "OK"); + return; + } + + // 경로가 Assets로 시작하는지 확인 + if (!savePath.StartsWith("Assets/")) + { + EditorUtility.DisplayDialog("Error", "Save path must start with 'Assets/'!", "OK"); + return; + } + + var animator = selectedAnimator; + var avatar = animator.avatar; + + if (avatar == null || !avatar.isHuman) + { + EditorUtility.DisplayDialog("Error", "Selected Animator must have a Humanoid Avatar!", "OK"); + return; + } + + try + { + // HumanPoseHandler를 사용하여 현재 포즈 가져오기 + var handler = new HumanPoseHandler(avatar, animator.transform); + HumanPose pose = new HumanPose(); + handler.GetHumanPose(ref pose); + + // 새로운 HumanPoseClip 생성 + HumanPoseClip poseClip = ScriptableObject.CreateInstance(); + poseClip.ApplyPose(ref pose); + + // 저장 경로 생성 + string fullPath = Path.Combine(savePath, $"{assetName}.pose.asset"); + string directory = Path.GetDirectoryName(fullPath); + + // 디렉토리가 없으면 생성 + if (!Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + // 에셋 저장 + AssetDatabase.CreateAsset(poseClip, fullPath); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + + Debug.Log($"Pose clip has been created at: {fullPath}"); + EditorUtility.DisplayDialog("Success", $"Pose clip has been created at: {fullPath}", "OK"); + } + catch (System.Exception e) + { + Debug.LogError($"Error creating pose clip: {e.Message}"); + EditorUtility.DisplayDialog("Error", $"Failed to create pose clip: {e.Message}", "OK"); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta b/Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta new file mode 100644 index 00000000..00b9514f --- /dev/null +++ b/Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 56ea0fa3ec6bb174f85a1ba2d080d85b \ No newline at end of file diff --git a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs index 1f386f5a..ebecf14a 100644 --- a/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs +++ b/Assets/Scripts/KindRetargeting/CustomRetargetingScript.cs @@ -580,16 +580,20 @@ namespace KindRetargeting for (int i = 0; i < 40; i++) { int muscleIndex = 55 + i; + string muscleName = HumanTrait.MuscleName[muscleIndex]; + + // "Spread"가 포함된 머슬만 스킵 (손가락 벌리기 동작) + if (muscleName.Contains("Spread")) + continue; + float targetValue = sourcePose.muscles[muscleIndex]; float currentValue = targetPose.muscles[muscleIndex]; - // 모션 필터 적용 (값을 직접 필터링) if (useMotionFilter) { targetValue = ApplyFilter(targetValue, i); } - // 러프 모션을 Lerp로 적용 if (useFingerRoughMotion && roughMotions.TryGetValue(HumanBodyBones.LeftHand, out RoughMotion rough)) { float smoothSpeed = 50f - (fingerRoughness * 49f); @@ -968,8 +972,6 @@ namespace KindRetargeting Avatar avatar = animator.avatar; Transform transform = animator.transform; - // I포즈 기능 개발해야함 밍글 스튜디오 참고 - /* // HumanPoseClip에 저장된 T-포즈 데이터를 로드하여 적용 var humanPoseClip = Resources.Load(HumanPoseClip.IPoseResourcePath); if (humanPoseClip != null) @@ -981,7 +983,6 @@ namespace KindRetargeting { Debug.LogWarning("I-Pose 데이터가 존재하지 않습니다."); } - */ } #endregion diff --git a/Assets/Scripts/SpoutOutputScript/FinalOutputShader.mat b/Assets/Scripts/SpoutOutputScript/FinalOutputShader.mat index 7f9bec96..03182bd2 100644 --- a/Assets/Scripts/SpoutOutputScript/FinalOutputShader.mat +++ b/Assets/Scripts/SpoutOutputScript/FinalOutputShader.mat @@ -147,7 +147,7 @@ Material: - _BaseColor: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 1, g: 1, b: 1, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - - _Resolution: {r: 3840, g: 2160, b: 0, a: 0} + - _Resolution: {r: 1920, g: 1080, b: 0, a: 0} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} m_BuildTextureStacks: [] m_AllowLocking: 1 diff --git a/Assets/Scripts/SpoutOutputScript/FinalOutputShader.shadergraph b/Assets/Scripts/SpoutOutputScript/FinalOutputShader.shadergraph index 47ab44f1..e45f8220 100644 --- a/Assets/Scripts/SpoutOutputScript/FinalOutputShader.shadergraph +++ b/Assets/Scripts/SpoutOutputScript/FinalOutputShader.shadergraph @@ -157,20 +157,6 @@ "m_SlotId": 1 } }, - { - "m_OutputSlot": { - "m_Node": { - "m_Id": "af4e86cdd63b47428691d8c7cf6fd511" - }, - "m_SlotId": 3 - }, - "m_InputSlot": { - "m_Node": { - "m_Id": "ad863a97e6f14704b6137da83d1dba35" - }, - "m_SlotId": 0 - } - }, { "m_OutputSlot": { "m_Node": { diff --git a/Packages/manifest.json b/Packages/manifest.json index 5d16269c..a0e24e5b 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76bd0b5631a9d2fa887599f83a1e84c70083360d6e25914a77a172780d82fd2c -size 2325 +oid sha256:0484a82face991d71f810636ba025c7171520043dc23f8c5d2fdcc129cffedf5 +size 2328 diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 14923b91..55e115d3 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d07f0ed99b80bb3c59d23c6e13fd0576830c050422712014b27158343b85051 -size 13864 +oid sha256:5d052547d34d2f4f8f332de4c7da68e4613eb7ba7a1493754098e1e3c241029a +size 13867 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 6d49bef5..8d34c663 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:23fc56b484aa3d7edf5914cd3591f7a823ccef5e3f3496f8a51f30388ead63dc -size 657 +oid sha256:cd1cf5fdde17db286153290bee0482ef83d46a04a4118f537b346ade5847d333 +size 545