ADD : I-pose 기능 추가 패치
This commit is contained in:
parent
0a7ae6a021
commit
e9e1c12284
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright © 2016 NaturalPoint Inc.
|
||||
Copyright <EFBFBD> 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.
|
||||
@ -19,7 +19,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace NaturalPoint.NatNetLib
|
||||
{
|
||||
@ -252,6 +252,7 @@ namespace NaturalPoint.NatNetLib
|
||||
public List<sMarkerSetDescription> MarkerSetDescriptions;
|
||||
public List<sRigidBodyDescription> RigidBodyDescriptions;
|
||||
public List<sSkeletonDescription> SkeletonDescriptions;
|
||||
public List<sAssetDescription> AssetDescriptions; // trained markerset added
|
||||
public List<sForcePlateDescription> ForcePlateDescriptions;
|
||||
public List<sCameraDescription> 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<sMarkerSetDescription>( numMarkerSetDescs ),
|
||||
RigidBodyDescriptions = new List<sRigidBodyDescription>( numRigidBodyDescs ),
|
||||
SkeletonDescriptions = new List<sSkeletonDescription>( numSkeletonDescs ),
|
||||
AssetDescriptions = new List<sAssetDescription>(numAssetDescs), // trained markerset added
|
||||
ForcePlateDescriptions = new List<sForcePlateDescription>( numForcePlateDescs ),
|
||||
CameraDescriptions = new List<sCameraDescription>( 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 );
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright © 2016 NaturalPoint Inc.
|
||||
Copyright <EFBFBD> 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
|
||||
@ -388,6 +412,10 @@ namespace NaturalPoint.NatNetLib
|
||||
[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 )]
|
||||
public sMarker[] LabeledMarkers;
|
||||
@ -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,30 +589,27 @@ 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);
|
||||
|
||||
// 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);
|
||||
|
||||
@ -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 );
|
||||
|
||||
// frame methods
|
||||
[DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)]
|
||||
public static extern NatNetError NatNet_Client_GetPredictedRigidBodyPose( IntPtr client, Int32 rigidBodyIndex, out sRigidBodyData rigidBodyData, double dt );
|
||||
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_GetTransmitTimestamp( IntPtr pFrameOfMocapData, out UInt64 pOutTransmitTimestamp );
|
||||
|
||||
public static extern NatNetError NatNet_Frame_GetTMarkersetCount(IntPtr pFrameOfMocapData, out Int32 tmarkersetCount);
|
||||
|
||||
// trained markerset added
|
||||
[DllImport(NatNetConstants.NatNetLibDllBaseName, CallingConvention = NatNetConstants.NatNetLibCallingConvention)]
|
||||
public static extern NatNetError NatNet_Frame_GetLabeledMarkerCount( IntPtr pFrameOfMocapData, out Int32 labeledMarkerCount );
|
||||
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_GetLabeledMarker( IntPtr pFrameOfMocapData, Int32 labeledMarkerIndex, out sMarker labeledMarkerData );
|
||||
public static extern NatNetError NatNet_Frame_TMarkerset_GetRigidBodyCount(IntPtr pFrameOfMocapData, Int32 tmarkersetIndex, out Int32 rigidBodyCount);
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Plugins/x86_64/NatNetLib.dll
(Stored with Git LFS)
vendored
Binary file not shown.
@ -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:
|
||||
|
||||
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Client - OptiTrack.prefab
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
107
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta
vendored
Normal file
107
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Horse_TM.fbx.meta
vendored
Normal file
@ -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:
|
||||
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Retargeted Skeleton - OptiTrack.prefab
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,8 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afbc9c9b98650e44f97662b4f503c261
|
||||
timeCreated: 1470265618
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Prefabs/Rigid Body.prefab
(Stored with Git LFS)
vendored
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e09d962f56189d46ad6bcd146c01a77
|
||||
guid: f6a3494b5f1724443a3bf3aa6741c8a4
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
||||
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/README_OptiTrack_Unity.txt
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity
(Stored with Git LFS)
vendored
BIN
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scenes/OptiTrackScene.unity
(Stored with Git LFS)
vendored
Binary file not shown.
@ -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;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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;
|
||||
Debug.LogError("OptitrackRigidBody: No OptitrackStreamingClient found in scene.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
m_streamingClient.RegisterRigidBody(this, rigidBodyId);
|
||||
}
|
||||
|
||||
// 주기적으로 RigidBody를 찾는 코루틴 시작
|
||||
StartCoroutine(CheckRigidBodyIdPeriodically());
|
||||
|
||||
#if UNITY_2017_1_OR_NEWER
|
||||
void OnEnable()
|
||||
{
|
||||
Application.onBeforeRender += OnBeforeRender;
|
||||
}
|
||||
|
||||
void Update()
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
Application.onBeforeRender -= OnBeforeRender;
|
||||
}
|
||||
|
||||
|
||||
void OnBeforeRender()
|
||||
{
|
||||
UpdatePose();
|
||||
}
|
||||
#endif
|
||||
|
||||
void UpdatePose()
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!isRigidBodyFound) return;
|
||||
if (m_streamingClient == null)
|
||||
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;
|
||||
m_isRigidBodyFound = rbState.IsTracked;
|
||||
if (m_isRigidBodyFound)
|
||||
{
|
||||
transform.position = rbState.Pose.Position;
|
||||
transform.rotation = rbState.Pose.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator CheckRigidBodyIdPeriodically()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// 현재 이름이 마지막으로 확인한 이름과 다르거나, RigidBody를 찾지 못한 상태라면 검색 수행
|
||||
if (lastCheckedName != RigidBodyName || !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}");
|
||||
m_isRigidBodyFound = false;
|
||||
}
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(updateInterval);
|
||||
|
||||
void UpdatePose()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,6 +137,7 @@ public class OptitrackSkeletonAnimator : MonoBehaviour
|
||||
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);
|
||||
|
||||
if (foundPose && foundObject)
|
||||
{
|
||||
// 손가락 본인 경우 회전 데이터는 무시하고 위치 데이터만 적용
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 손가락 본인지 확인하는 헬퍼 메서드
|
||||
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
|
||||
/// <summary>
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
/// <summary>Skeleton naming conventions supported by OptiTrack Motive.</summary>
|
||||
@ -77,6 +82,14 @@ public class OptitrackSkeletonState
|
||||
public Dictionary<Int32, OptitrackPose> LocalBonePoses;
|
||||
}
|
||||
|
||||
/// <summary>Represents the state of a streamed trained markerset at an instant in time.</summary>
|
||||
public class OptitrackTMarkersetState // trained markerset added
|
||||
{
|
||||
/// <summary>Maps from OptiTrack bone IDs to their corresponding bone poses.</summary>
|
||||
public Dictionary<Int32, OptitrackPose> BonePoses;
|
||||
public Dictionary<Int32, OptitrackPose> LocalBonePoses;
|
||||
}
|
||||
|
||||
|
||||
public class OptitrackRigidBodyDefinition
|
||||
{
|
||||
@ -125,6 +138,55 @@ public class OptitrackSkeletonDefinition
|
||||
public Dictionary<Int32, Int32> BoneIdToParentIdMap;
|
||||
}
|
||||
|
||||
|
||||
public class OptitrackTMarkersetDefinition // trained markerset added // check where this is coming from
|
||||
{
|
||||
public class BoneDefinition
|
||||
{
|
||||
/// <summary>The ID of this bone within this trained markerset.</summary>
|
||||
public Int32 Id;
|
||||
|
||||
/// <summary>The ID of this bone's parent bone. A value of 0 means that this is the root bone.</summary>
|
||||
public Int32 ParentId;
|
||||
|
||||
/// <summary>The name of this bone.</summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// This bone's position offset from its parent in the skeleton's neutral pose.
|
||||
/// (The neutral orientation is always <see cref="Quaternion.identity"/>.)
|
||||
/// </summary>
|
||||
public Vector3 Offset;
|
||||
}
|
||||
|
||||
public class MarkerDefinition
|
||||
{
|
||||
/// <summary>The name of this marker.</summary>
|
||||
public string Name;
|
||||
public Vector3 Position;
|
||||
public Int32 Id;
|
||||
|
||||
//public float Size;
|
||||
//public bool Labeled;
|
||||
//public bool IsActive;
|
||||
}
|
||||
|
||||
/// <summary>Asset ID. Used as an argument to <see cref="OptitrackStreamingClient.GetLatestTMarkersetState"/>.</summary>
|
||||
public Int32 Id;
|
||||
|
||||
/// <summary>Skeleton asset name.</summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>Bone names, hierarchy, and neutral pose position information.</summary>
|
||||
public List<BoneDefinition> Bones;
|
||||
|
||||
/// <summary>Bone hierarchy information</summary>
|
||||
public Dictionary<Int32, Int32> BoneIdToParentIdMap;
|
||||
|
||||
public List<MarkerDefinition> Markers;
|
||||
}
|
||||
|
||||
|
||||
public class OptitrackMarkersDefinition
|
||||
{
|
||||
/// <summary>The name of this bone.</summary>
|
||||
@ -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<OptitrackRigidBodyDefinition> m_rigidBodyDefinitions = new List<OptitrackRigidBodyDefinition>();
|
||||
private List<OptitrackSkeletonDefinition> m_skeletonDefinitions = new List<OptitrackSkeletonDefinition>();
|
||||
private List<OptitrackTMarkersetDefinition> m_tmarkersetDefinitions = new List<OptitrackTMarkersetDefinition>(); // trained markerset added
|
||||
private List<OptitrackMarkersDefinition> m_tmarkmarkersDefinitions = new List<OptitrackMarkersDefinition>(); // trained markerset added
|
||||
private List<OptitrackMarkersDefinition> m_markersDefinitions = new List<OptitrackMarkersDefinition>();
|
||||
private List<OptitrackCameraDefinition> m_cameraDefinitions = new List<OptitrackCameraDefinition>();
|
||||
private List<OptitrackForcePlateDefinition> m_forcePlateDefinitions = new List<OptitrackForcePlateDefinition>();
|
||||
@ -284,18 +362,30 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
/// <summary>Maps from a streamed skeleton's ID to its most recent available pose data.</summary>
|
||||
private Dictionary<Int32, OptitrackSkeletonState> m_latestSkeletonStates = new Dictionary<Int32, OptitrackSkeletonState>();
|
||||
|
||||
/// <summary>Maps from a streamed trained markerset's ID to its most recent available pose data.</summary>
|
||||
private Dictionary<Int32, OptitrackTMarkersetState> m_latestTMarkersetStates = new Dictionary<Int32, OptitrackTMarkersetState>(); // trained markerset added
|
||||
|
||||
/// <summary>Maps from a streamed marker's ID to its most recent available position.</summary>
|
||||
private Dictionary<Int32, OptitrackMarkerState> m_latestMarkerStates = new Dictionary<Int32, OptitrackMarkerState>();
|
||||
|
||||
/// <summary>Maps from a streamed trained markerset marker's ID to its most recent available position.</summary>
|
||||
private Dictionary<Int32, OptitrackMarkerState> m_latestTMarkMarkerStates = new Dictionary<Int32, OptitrackMarkerState>(); // trained markerset added
|
||||
|
||||
/// <summary>Maps from a streamed rigid body's ID to its component.</summary>
|
||||
private Dictionary<Int32, MonoBehaviour> m_rigidBodies = new Dictionary<Int32, MonoBehaviour>();
|
||||
|
||||
/// <summary>Maps from a streamed skeleton names to its component.</summary>
|
||||
private Dictionary<string, MonoBehaviour> m_skeletons = new Dictionary<string, MonoBehaviour>();
|
||||
|
||||
/// <summary>Maps from a streamed trained markerset names to its component.</summary>
|
||||
private Dictionary<string, MonoBehaviour> m_tmarkersets = new Dictionary<string, MonoBehaviour>(); // trained markerset added
|
||||
|
||||
/// <summary>Maps from a streamed marker's ID to its sphere game object. Used for drawing markers.</summary>
|
||||
private Dictionary<Int32, GameObject> m_latestMarkerSpheres = new Dictionary<Int32, GameObject>();
|
||||
|
||||
/// <summary>Maps from a streamed trained markerset marker's ID to its sphere game object. Used for drawing markers.</summary>
|
||||
private Dictionary<Int32, GameObject> m_latestTMarkMarkerSpheres = new Dictionary<Int32, GameObject>(); // trained markerset added
|
||||
|
||||
/// <summary>
|
||||
/// Lock held during access to fields which are potentially modified by <see cref="OnNatNetFrameReceived"/> (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<Int32> markerIds = new List<Int32>();
|
||||
//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<Int32> tmarkmarkerIds = new List<Int32>();
|
||||
//Debug.Log("tmark states: " + m_latestTMarkMarkerStates.Count);
|
||||
lock (m_frameDataUpdateLock)
|
||||
{
|
||||
// Move existing spheres and create new ones if necessary
|
||||
foreach (KeyValuePair<Int32, OptitrackMarkerState> 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<Renderer>().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<Int32> markerCubeIdsToDelete = new List<Int32>();
|
||||
foreach (KeyValuePair<Int32, GameObject> 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<Int32, GameObject> markerCubeEntry in m_latestTMarkMarkerSpheres)
|
||||
{
|
||||
Destroy(m_latestTMarkMarkerSpheres[markerCubeEntry.Key]);
|
||||
}
|
||||
m_latestTMarkMarkerSpheres.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -449,7 +611,7 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
/// <returns>An arbitrary OptitrackClient from the scene, or null if none are found.</returns>
|
||||
public static OptitrackStreamingClient FindDefaultClient()
|
||||
{
|
||||
OptitrackStreamingClient[] allClients = FindObjectsByType<OptitrackStreamingClient>(FindObjectsSortMode.None);
|
||||
OptitrackStreamingClient[] allClients = FindObjectsOfType<OptitrackStreamingClient>();
|
||||
|
||||
if ( allClients.Length == 0 )
|
||||
{
|
||||
@ -519,23 +681,6 @@ 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;
|
||||
}
|
||||
|
||||
/// <summary>Get the most recently received state for the specified skeleton.</summary>
|
||||
/// <param name="skeletonId">
|
||||
@ -555,6 +700,25 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
return skelState;
|
||||
}
|
||||
|
||||
/// <summary>Get the most recently received state for the specified trained markerset.</summary>
|
||||
/// <param name="tmarkersetId">
|
||||
/// Taken from the corresponding <see cref="OptitrackTMarkersetDefinition.Id"/> field.
|
||||
/// To find the appropriate skeleton definition, use <see cref="GetTMarkersetDefinitionByName"/>.
|
||||
/// </param>
|
||||
/// <returns>The most recent available state, or null if none available.</returns>
|
||||
public OptitrackTMarkersetState GetLatestTMarkersetState(Int32 tmarkersetId)
|
||||
{
|
||||
OptitrackTMarkersetState tmarState;
|
||||
|
||||
lock (m_frameDataUpdateLock)
|
||||
{
|
||||
m_latestTMarkersetStates.TryGetValue(tmarkersetId, out tmarState);
|
||||
}
|
||||
|
||||
return tmarState;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Get the most recently received state for streamed markers.</summary>
|
||||
/// <returns>The most recent available marker states, or null if none available.</returns>
|
||||
public List<OptitrackMarkerState> GetLatestMarkerStates()
|
||||
@ -635,6 +799,68 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Retrieves the definition of the tmarkerset with the specified asset name.</summary>
|
||||
/// <param name="TMarkersetName">The name of the tmarkerset for which to retrieve the definition.</param>
|
||||
/// <returns>The specified tmarkerset definition, or null if not found.</returns> // 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;
|
||||
}
|
||||
|
||||
/// <summary>Retrieves the definition of the tmarkerset with the specified tmarkerset id.</summary>
|
||||
/// <param name="tmarkersetId">The id of the tmarkerset for which to retrieve the definition.</param>
|
||||
/// <returns>The specified tmarkerset definition, or null if not found.</returns> // 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;
|
||||
}
|
||||
|
||||
/// <summary>Get the most recently received state for streamed trained markerset markers.</summary>
|
||||
/// <returns>The most recent available trained markerset marker states, or null if none available.</returns>
|
||||
public List<OptitrackMarkerState> GetLatestTMarkMarkerStates() // trained markerset added
|
||||
{
|
||||
List<OptitrackMarkerState> tmarkmarkerStates = new List<OptitrackMarkerState>();
|
||||
Debug.Log("GetLatestTMarkMarker: " + m_latestTMarkMarkerStates.Count);
|
||||
|
||||
lock (m_frameDataUpdateLock)
|
||||
{
|
||||
foreach (KeyValuePair<Int32, OptitrackMarkerState> 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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Request data descriptions from the host, then update our definitions.</summary>
|
||||
/// <exception cref="NatNetException">
|
||||
/// Thrown by <see cref="NatNetClient.GetDataDescriptions"/> 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<OptitrackTMarkersetDefinition.BoneDefinition>(nativeTmark.RigidBodyCount),
|
||||
BoneIdToParentIdMap = new Dictionary<int, int>(),
|
||||
Markers = new List<OptitrackTMarkersetDefinition.MarkerDefinition>(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<int, int> 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);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// (Re)initializes <see cref="m_client"/> and connects to the configured streaming server.
|
||||
@ -934,6 +1236,10 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
{
|
||||
SubscribeSkeleton(skel.Value, skel.Key);
|
||||
}
|
||||
foreach (KeyValuePair<string, MonoBehaviour> 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)
|
||||
{
|
||||
@ -1221,6 +1627,7 @@ public class OptitrackStreamingClient : MonoBehaviour
|
||||
string assetName = "";
|
||||
OptitrackRigidBodyDefinition rigidBodyDef = GetRigidBodyDefinitionById( 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<Int32, OptitrackPose>(),
|
||||
LocalBonePoses = new Dictionary<int, OptitrackPose>(),
|
||||
};
|
||||
|
||||
m_latestTMarkersetStates[tmarkersetId] = newTMarkersetState;
|
||||
|
||||
returnedState = newTMarkersetState;
|
||||
}
|
||||
|
||||
return returnedState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="OptitrackMarkerState"/> corresponding to the provided <paramref name="markerId"/>.
|
||||
/// If the requested state object does not exist yet, it will initialize and return a newly-created one.
|
||||
/// </summary>
|
||||
/// <remarks>Makes the assumption that the lock on <see cref="m_frameDataUpdateLock"/> is already held.</remarks>
|
||||
/// <param name="markerId">The ID of the bone in trained markerset for which to retrieve the corresponding state.</param>
|
||||
/// <returns>The existing state object, or a newly created one if necessary.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="OptitrackMarkerState"/> corresponding to the provided <paramref name="markerId"/>.
|
||||
|
||||
190
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs
vendored
Normal file
190
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs
vendored
Normal file
@ -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;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Implements live tracking of streamed OptiTrack trained markerset data onto an asset in Unity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A hierarchy of GameObjects (see <see cref="m_rootObject"/> and <see cref="m_boneObjectMap"/>) will be created to
|
||||
/// receive the streaming pose data for the tmarkerset asset specified by <see cref="TMarkersetAssetName"/>.
|
||||
/// </remarks>
|
||||
|
||||
public class OptitrackTrainedMarkerset : MonoBehaviour
|
||||
{
|
||||
/// <summary>The client object to use for receiving streamed TMarkerset pose data.</summary>
|
||||
[Tooltip("The object containing the OptiTrackStreamingClient script.")]
|
||||
public OptitrackStreamingClient StreamingClient;
|
||||
|
||||
/// <summary>The name of the TMarkerset asset in the stream that will provide retargeting source data.</summary>
|
||||
[Tooltip("The name of markerset asset in Motive.")]
|
||||
public string TMarkersetAssetName = "TMarkerset1";
|
||||
|
||||
#region Private fields
|
||||
/// <summary>The streamed source tmarkerset definition.</summary>
|
||||
private OptitrackTMarkersetDefinition m_tmarkersetDef;
|
||||
|
||||
/// <summary>The root GameObject of the streamed tmarkerset pose transform hierarchy.</summary>
|
||||
private GameObject m_rootObject;
|
||||
|
||||
/// <summary>Maps between OptiTrack tmarkerset bone IDs and corresponding GameObjects.</summary>
|
||||
private Dictionary<Int32, GameObject> m_boneObjectMap;
|
||||
|
||||
/// <summary>
|
||||
/// Maps between game object's bone names (keys) and streamed bone names from OptiTrack software (values).
|
||||
/// </summary>
|
||||
private Dictionary<string, Transform> m_cachedBoneNameMap = new Dictionary<string, Transform>(); // Optitrack's skeleton's bone names
|
||||
|
||||
private Dictionary<Transform, Transform> m_transformMap = new Dictionary<Transform, Transform>();
|
||||
|
||||
#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<Int32, GameObject>( 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
|
||||
/// <summary>
|
||||
/// Constructs the source to target mapping of the bones
|
||||
/// </summary>
|
||||
/// <param name="rootObjectName"></param>
|
||||
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<Transform>(); // source
|
||||
|
||||
Transform[] tarObjectBones = this.GetComponentsInChildren<Transform>(); // 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
|
||||
}
|
||||
2
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta
vendored
Normal file
2
Assets/External/OptiTrack Unity Plugin/OptiTrack/Scripts/OptitrackTrainedMarkerset.cs.meta
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07333194d9e70e74692863bb8b2c148a
|
||||
@ -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}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset
(Stored with Git LFS)
vendored
Normal file
BIN
Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
8
Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta
vendored
Normal file
8
Assets/External/UniGLTF/Runtime/Resources/I-Pose.pose.asset.meta
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4b8a69c9f45e384d92846d5b5081c1a
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,8 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d2617171adc40b41ac50228f101e178
|
||||
timeCreated: 1546851178
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyA_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_eyepatch_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/bodyB_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionA_NoOutline_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/emissionB_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeGuruguru_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eyeKakusei_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/eye_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/face_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowA_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/glowB_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/hair_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/skinB_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.Materials/thunder_mtoon.asset
(Stored with Git LFS)
Binary file not shown.
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab
(Stored with Git LFS)
BIN
Assets/ResourcesData/Character/00.R&D/TestVRM/Zonko_VRM.prefab
(Stored with Git LFS)
Binary file not shown.
8
Assets/ResourcesData/Etc.meta
Normal file
8
Assets/ResourcesData/Etc.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c50d1706d9c5fce43b5f9ee9bd3c1d59
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ResourcesData/Etc/Plane UV.meta
Normal file
8
Assets/ResourcesData/Etc/Plane UV.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 872de359ed282b846ba8b1d2ffd14aac
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
136
Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat
Normal file
136
Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat
Normal file
@ -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
|
||||
8
Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta
Normal file
8
Assets/ResourcesData/Etc/Plane UV/PlaneUV.mat.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1452bd3d60b905d4499a8e9c99d5b488
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/ResourcesData/Etc/Plane UV/PlaneUV.png
(Stored with Git LFS)
Normal file
BIN
Assets/ResourcesData/Etc/Plane UV/PlaneUV.png
(Stored with Git LFS)
Normal file
Binary file not shown.
115
Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta
Normal file
115
Assets/ResourcesData/Etc/Plane UV/PlaneUV.png.meta
Normal file
@ -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:
|
||||
BIN
Assets/Scenes/Development scene.unity
(Stored with Git LFS)
BIN
Assets/Scenes/Development scene.unity
(Stored with Git LFS)
Binary file not shown.
8
Assets/Scripts/Editor.meta
Normal file
8
Assets/Scripts/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d987f2b028376dc4a9e670318498ddca
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
138
Assets/Scripts/Editor/HumanPoseClipApplier.cs
Normal file
138
Assets/Scripts/Editor/HumanPoseClipApplier.cs
Normal file
@ -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<HumanPoseClipApplier>("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<HumanPoseData>(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");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta
Normal file
2
Assets/Scripts/Editor/HumanPoseClipApplier.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1fa397be4544444b859d065a7aa33b3
|
||||
119
Assets/Scripts/Editor/HumanPoseClipCreator.cs
Normal file
119
Assets/Scripts/Editor/HumanPoseClipCreator.cs
Normal file
@ -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<HumanPoseClipCreator>("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<HumanPoseClip>();
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta
Normal file
2
Assets/Scripts/Editor/HumanPoseClipCreator.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56ea0fa3ec6bb174f85a1ba2d080d85b
|
||||
@ -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>(HumanPoseClip.IPoseResourcePath);
|
||||
if (humanPoseClip != null)
|
||||
@ -981,7 +983,6 @@ namespace KindRetargeting
|
||||
{
|
||||
Debug.LogWarning("I-Pose 데이터가 존재하지 않습니다.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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": {
|
||||
|
||||
BIN
Packages/manifest.json
(Stored with Git LFS)
BIN
Packages/manifest.json
(Stored with Git LFS)
Binary file not shown.
BIN
Packages/packages-lock.json
(Stored with Git LFS)
BIN
Packages/packages-lock.json
(Stored with Git LFS)
Binary file not shown.
BIN
ProjectSettings/TagManager.asset
(Stored with Git LFS)
BIN
ProjectSettings/TagManager.asset
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user