533 lines
30 KiB
C#
533 lines
30 KiB
C#
/*
|
|
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 retargeting of streamed OptiTrack skeletal data via Mecanim.
|
|
/// Add this component to an imported model GameObject that has a properly configured humanoid Avatar definition.
|
|
/// </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 skeleton asset specified by <see cref="SkeletonAssetName"/>.
|
|
/// A source Avatar will be created automatically from the streamed skeleton definition.
|
|
/// </remarks>
|
|
public class OptitrackSkeletonAnimator : MonoBehaviour
|
|
{
|
|
/// <summary>The client object to use for receiving streamed skeletal pose data.</summary>
|
|
[Tooltip("The object containing the OptiTrackStreamingClient script.")]
|
|
public OptitrackStreamingClient StreamingClient;
|
|
|
|
/// <summary>The name of the skeleton asset in the stream that will provide retargeting source data.</summary>
|
|
[Tooltip("The name of skeleton asset in Motive.")]
|
|
public string SkeletonAssetName = "Skeleton1";
|
|
|
|
/// <summary>The humanoid avatar for this GameObject's imported model.</summary>
|
|
[Tooltip("The humanoid avatar model.")]
|
|
public Avatar DestinationAvatar;
|
|
|
|
#region Private fields
|
|
/// <summary>Used when retrieving and retargeting source pose. Cached and reused for efficiency.</summary>
|
|
private HumanPose m_humanPose = new HumanPose();
|
|
|
|
/// <summary>The streamed source skeleton definition.</summary>
|
|
private OptitrackSkeletonDefinition m_skeletonDef;
|
|
|
|
/// <summary>The root GameObject of the streamed skeletal pose transform hierarchy.</summary>
|
|
private GameObject m_rootObject;
|
|
|
|
/// <summary>Maps between OptiTrack skeleton bone IDs and corresponding GameObjects.</summary>
|
|
private Dictionary<Int32, GameObject> m_boneObjectMap;
|
|
|
|
/// <summary>
|
|
/// Maps between Mecanim anatomy bone names (keys) and streamed bone names from various naming conventions
|
|
/// supported by the OptiTrack software (values). Populated by <see cref="CacheBoneNameMap"/>.
|
|
/// </summary>
|
|
private Dictionary<string, string> m_cachedMecanimBoneNameMap = new Dictionary<string, string>();
|
|
|
|
/// <summary>Created automatically based on <see cref="m_skeletonDef"/>.</summary>
|
|
private Avatar m_srcAvatar;
|
|
|
|
/// <summary>Set up to read poses from our streamed GameObject transform hierarchy.</summary>
|
|
private HumanPoseHandler m_srcPoseHandler;
|
|
|
|
/// <summary>Set up to write poses to this GameObject using <see cref="DestinationAvatar"/>.</summary>
|
|
private HumanPoseHandler m_destPoseHandler;
|
|
#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.RegisterSkeleton(this, this.SkeletonAssetName);
|
|
|
|
// Create a lookup from Mecanim anatomy bone names to OptiTrack streaming bone names.
|
|
CacheBoneNameMap( this.StreamingClient.BoneNamingConvention, this.SkeletonAssetName );
|
|
|
|
// Retrieve the OptiTrack skeleton definition.
|
|
m_skeletonDef = this.StreamingClient.GetSkeletonDefinitionByName( this.SkeletonAssetName );
|
|
|
|
if ( m_skeletonDef == null )
|
|
{
|
|
Debug.LogError( GetType().FullName + ": Could not find skeleton definition with the name \"" + this.SkeletonAssetName + "\"", this );
|
|
this.enabled = false;
|
|
return;
|
|
}
|
|
|
|
// Create a hierarchy of GameObjects that will receive the skeletal pose data.
|
|
string rootObjectName = "OptiTrack Skeleton - " + this.SkeletonAssetName;
|
|
m_rootObject = new GameObject( rootObjectName );
|
|
|
|
m_boneObjectMap = new Dictionary<Int32, GameObject>( m_skeletonDef.Bones.Count );
|
|
|
|
for ( int boneDefIdx = 0; boneDefIdx < m_skeletonDef.Bones.Count; ++boneDefIdx )
|
|
{
|
|
OptitrackSkeletonDefinition.BoneDefinition boneDef = m_skeletonDef.Bones[boneDefIdx];
|
|
|
|
GameObject boneObject = new GameObject( boneDef.Name );
|
|
boneObject.transform.parent = boneDef.ParentId == 0 ? m_rootObject.transform : m_boneObjectMap[boneDef.ParentId].transform;
|
|
boneObject.transform.localPosition = boneDef.Offset;
|
|
m_boneObjectMap[boneDef.Id] = boneObject;
|
|
}
|
|
|
|
// Hook up retargeting between those GameObjects and the destination Avatar.
|
|
MecanimSetup( rootObjectName );
|
|
|
|
// Can't re-parent this until after Mecanim setup, or else Mecanim gets confused.
|
|
m_rootObject.transform.parent = this.StreamingClient.transform;
|
|
m_rootObject.transform.localPosition = Vector3.zero;
|
|
m_rootObject.transform.localRotation = Quaternion.identity;
|
|
}
|
|
|
|
|
|
void Update()
|
|
{
|
|
OptitrackSkeletonState skelState = StreamingClient.GetLatestSkeletonState(m_skeletonDef.Id);
|
|
if (skelState != null)
|
|
{
|
|
// Update the transforms of the bone GameObjects.
|
|
for (int i = 0; i < m_skeletonDef.Bones.Count; ++i)
|
|
{
|
|
Int32 boneId = m_skeletonDef.Bones[i].Id;
|
|
string boneName = m_skeletonDef.Bones[i].Name;
|
|
|
|
OptitrackPose bonePose;
|
|
GameObject boneObject;
|
|
|
|
bool foundPose = false;
|
|
if (StreamingClient.SkeletonCoordinates == StreamingCoordinatesValues.Global)
|
|
{
|
|
foundPose = skelState.LocalBonePoses.TryGetValue(boneId, out bonePose);
|
|
}
|
|
else
|
|
{
|
|
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)
|
|
{
|
|
m_srcPoseHandler.GetHumanPose(ref m_humanPose);
|
|
m_destPoseHandler.SetHumanPose(ref m_humanPose);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 손가락 본인지 확인하는 헬퍼 메서드
|
|
private bool IsFingerBone(string boneName)
|
|
{
|
|
return boneName.Contains("Thumb") ||
|
|
boneName.Contains("Index") ||
|
|
boneName.Contains("Middle") ||
|
|
boneName.Contains("Ring") ||
|
|
boneName.Contains("Pinky") ||
|
|
boneName.Contains("Finger");
|
|
}
|
|
|
|
#region Private methods
|
|
/// <summary>
|
|
/// Constructs the source Avatar and pose handlers for Mecanim retargeting.
|
|
/// </summary>
|
|
/// <param name="rootObjectName"></param>
|
|
private void MecanimSetup( string rootObjectName )
|
|
{
|
|
string[] humanTraitBoneNames = HumanTrait.BoneName;
|
|
|
|
// Set up the mapping between Mecanim human anatomy and OptiTrack skeleton representations.
|
|
List<HumanBone> humanBones = new List<HumanBone>( m_skeletonDef.Bones.Count );
|
|
for ( int humanBoneNameIdx = 0; humanBoneNameIdx < humanTraitBoneNames.Length; ++humanBoneNameIdx )
|
|
{
|
|
string humanBoneName = humanTraitBoneNames[humanBoneNameIdx];
|
|
if ( m_cachedMecanimBoneNameMap.ContainsKey( humanBoneName ) )
|
|
{
|
|
HumanBone humanBone = new HumanBone();
|
|
humanBone.humanName = humanBoneName;
|
|
humanBone.boneName = m_cachedMecanimBoneNameMap[humanBoneName];
|
|
humanBone.limit.useDefaultValues = true;
|
|
|
|
humanBones.Add( humanBone );
|
|
}
|
|
}
|
|
|
|
// Set up the T-pose and game object name mappings.
|
|
List<SkeletonBone> skeletonBones = new List<SkeletonBone>( m_skeletonDef.Bones.Count + 1 );
|
|
|
|
// Special case: Create the root bone.
|
|
{
|
|
SkeletonBone rootBone = new SkeletonBone();
|
|
rootBone.name = rootObjectName;
|
|
rootBone.position = Vector3.zero;
|
|
rootBone.rotation = Quaternion.identity;
|
|
rootBone.scale = Vector3.one;
|
|
|
|
skeletonBones.Add( rootBone );
|
|
}
|
|
|
|
// Create remaining re-targeted bone definitions.
|
|
for ( int boneDefIdx = 0; boneDefIdx < m_skeletonDef.Bones.Count; ++boneDefIdx )
|
|
{
|
|
OptitrackSkeletonDefinition.BoneDefinition boneDef = m_skeletonDef.Bones[boneDefIdx];
|
|
|
|
SkeletonBone skelBone = new SkeletonBone();
|
|
skelBone.name = boneDef.Name;
|
|
skelBone.position = boneDef.Offset;
|
|
skelBone.rotation = RemapBoneRotation(boneDef.Name); //Identity unless it's the thumb bone.
|
|
skelBone.scale = Vector3.one;
|
|
|
|
skeletonBones.Add( skelBone );
|
|
}
|
|
|
|
// Now set up the HumanDescription for the retargeting source Avatar.
|
|
HumanDescription humanDesc = new HumanDescription();
|
|
humanDesc.human = humanBones.ToArray();
|
|
humanDesc.skeleton = skeletonBones.ToArray();
|
|
|
|
// These all correspond to default values.
|
|
humanDesc.upperArmTwist = 0.5f;
|
|
humanDesc.lowerArmTwist = 0.5f;
|
|
humanDesc.upperLegTwist = 0.5f;
|
|
humanDesc.lowerLegTwist = 0.5f;
|
|
humanDesc.armStretch = 0.05f;
|
|
humanDesc.legStretch = 0.05f;
|
|
humanDesc.feetSpacing = 0.0f;
|
|
humanDesc.hasTranslationDoF = false;
|
|
|
|
// Finally, take the description and build the Avatar and pose handlers.
|
|
m_srcAvatar = AvatarBuilder.BuildHumanAvatar( m_rootObject, humanDesc );
|
|
|
|
if ( m_srcAvatar.isValid == false || m_srcAvatar.isHuman == false )
|
|
{
|
|
Debug.LogError( GetType().FullName + ": Unable to create source Avatar for retargeting. Check that your Skeleton Asset Name and Bone Naming Convention are configured correctly.", this );
|
|
this.enabled = false;
|
|
return;
|
|
}
|
|
|
|
m_srcPoseHandler = new HumanPoseHandler( m_srcAvatar, m_rootObject.transform );
|
|
m_destPoseHandler = new HumanPoseHandler( DestinationAvatar, this.transform );
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Adjusts default position of the proximal thumb bones.
|
|
/// The default pose between Unity and Motive differs on the thumb, this fixes that difference.
|
|
/// </summary>
|
|
/// <param name="boneName">The name of the current bone.</param>
|
|
private Quaternion RemapBoneRotation(string boneName)
|
|
{
|
|
if (this.StreamingClient.BoneNamingConvention == OptitrackBoneNameConvention.Motive)
|
|
{
|
|
if (boneName.EndsWith("_LThumb1"))
|
|
{
|
|
// 60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, 0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
if (boneName.EndsWith("_RThumb1"))
|
|
{
|
|
// -60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, -0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
}
|
|
if (this.StreamingClient.BoneNamingConvention == OptitrackBoneNameConvention.FBX)
|
|
{
|
|
if (boneName.EndsWith("_LeftHandThumb1"))
|
|
{
|
|
// 60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, 0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
if (boneName.EndsWith("_RightHandThumb1"))
|
|
{
|
|
// -60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, -0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
}
|
|
if (this.StreamingClient.BoneNamingConvention == OptitrackBoneNameConvention.BVH)
|
|
{
|
|
if (boneName.EndsWith("_LeftFinger0"))
|
|
{
|
|
// 60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, 0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
if (boneName.EndsWith("_RightFinger0"))
|
|
{
|
|
// -60 Deg Y-Axis rotation
|
|
return new Quaternion(0.0f, -0.5000011f, 0.0f, 0.8660248f);
|
|
}
|
|
}
|
|
|
|
return Quaternion.identity;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Updates the <see cref="m_cachedMecanimBoneNameMap"/> lookup to reflect the specified bone naming convention
|
|
/// and source skeleton asset name.
|
|
/// </summary>
|
|
/// <param name="convention">The bone naming convention to use. Must match the host software.</param>
|
|
/// <param name="assetName">The name of the source skeleton asset.</param>
|
|
private void CacheBoneNameMap( OptitrackBoneNameConvention convention, string assetName )
|
|
{
|
|
m_cachedMecanimBoneNameMap.Clear();
|
|
|
|
switch ( convention )
|
|
{
|
|
case OptitrackBoneNameConvention.Motive:
|
|
m_cachedMecanimBoneNameMap.Add( "Hips", assetName + "_Hip" );
|
|
m_cachedMecanimBoneNameMap.Add( "Spine", assetName + "_Ab" );
|
|
m_cachedMecanimBoneNameMap.Add( "Chest", assetName + "_Chest" );
|
|
m_cachedMecanimBoneNameMap.Add( "Neck", assetName + "_Neck" );
|
|
m_cachedMecanimBoneNameMap.Add( "Head", assetName + "_Head" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftShoulder", assetName + "_LShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperArm", assetName + "_LUArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerArm", assetName + "_LFArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftHand", assetName + "_LHand" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightShoulder", assetName + "_RShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperArm", assetName + "_RUArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerArm", assetName + "_RFArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightHand", assetName + "_RHand" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperLeg", assetName + "_LThigh" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerLeg", assetName + "_LShin" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftFoot", assetName + "_LFoot" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftToeBase", assetName + "_LToe" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperLeg", assetName + "_RThigh" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerLeg", assetName + "_RShin" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightFoot", assetName + "_RFoot" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightToeBase", assetName + "_RToe" );
|
|
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Proximal", assetName + "_LThumb1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Intermediate", assetName + "_LThumb2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Distal", assetName + "_LThumb3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Proximal", assetName + "_RThumb1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Intermediate", assetName + "_RThumb2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Distal", assetName + "_RThumb3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Proximal", assetName + "_LIndex1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Intermediate", assetName + "_LIndex2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Distal", assetName + "_LIndex3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Proximal", assetName + "_RIndex1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Intermediate", assetName + "_RIndex2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Distal", assetName + "_RIndex3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Proximal", assetName + "_LMiddle1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Intermediate", assetName + "_LMiddle2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Distal", assetName + "_LMiddle3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Proximal", assetName + "_RMiddle1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Intermediate", assetName + "_RMiddle2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Distal", assetName + "_RMiddle3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Proximal", assetName + "_LRing1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Intermediate", assetName + "_LRing2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Distal", assetName + "_LRing3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Proximal", assetName + "_RRing1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Intermediate", assetName + "_RRing2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Distal", assetName + "_RRing3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Proximal", assetName + "_LPinky1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Intermediate", assetName + "_LPinky2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Distal", assetName + "_LPinky3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Proximal", assetName + "_RPinky1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Intermediate", assetName + "_RPinky2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Distal", assetName + "_RPinky3" );
|
|
break;
|
|
case OptitrackBoneNameConvention.FBX:
|
|
m_cachedMecanimBoneNameMap.Add( "Hips", assetName + "_Hips" );
|
|
m_cachedMecanimBoneNameMap.Add( "Spine", assetName + "_Spine" );
|
|
m_cachedMecanimBoneNameMap.Add( "Chest", assetName + "_Spine1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Neck", assetName + "_Neck" );
|
|
m_cachedMecanimBoneNameMap.Add( "Head", assetName + "_Head" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftShoulder", assetName + "_LeftShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperArm", assetName + "_LeftArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerArm", assetName + "_LeftForeArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftHand", assetName + "_LeftHand" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightShoulder", assetName + "_RightShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperArm", assetName + "_RightArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerArm", assetName + "_RightForeArm" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightHand", assetName + "_RightHand" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperLeg", assetName + "_LeftUpLeg" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerLeg", assetName + "_LeftLeg" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftFoot", assetName + "_LeftFoot" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftToeBase", assetName + "_LeftToeBase" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperLeg", assetName + "_RightUpLeg" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerLeg", assetName + "_RightLeg" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightFoot", assetName + "_RightFoot" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightToeBase", assetName + "_RightToeBase" );
|
|
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Proximal", assetName + "_LeftHandThumb1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Intermediate", assetName + "_LeftHandThumb2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Distal", assetName + "_LeftHandThumb3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Proximal", assetName + "_RightHandThumb1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Intermediate", assetName + "_RightHandThumb2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Distal", assetName + "_RightHandThumb3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Proximal", assetName + "_LeftHandIndex1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Intermediate", assetName + "_LeftHandIndex2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Distal", assetName + "_LeftHandIndex3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Proximal", assetName + "_RightHandIndex1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Intermediate", assetName + "_RightHandIndex2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Distal", assetName + "_RightHandIndex3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Proximal", assetName + "_LeftHandMiddle1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Intermediate", assetName + "_LeftHandMiddle2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Distal", assetName + "_LeftHandMiddle3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Proximal", assetName + "_RightHandMiddle1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Intermediate", assetName + "_RightHandMiddle2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Distal", assetName + "_RightHandMiddle3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Proximal", assetName + "_LeftHandRing1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Intermediate", assetName + "_LeftHandRing2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Distal", assetName + "_LeftHandRing3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Proximal", assetName + "_RightHandRing1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Intermediate", assetName + "_RightHandRing2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Distal", assetName + "_RightHandRing3" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Proximal", assetName + "_LeftHandPinky1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Intermediate", assetName + "_LeftHandPinky2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Distal", assetName + "_LeftHandPinky3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Proximal", assetName + "_RightHandPinky1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Intermediate", assetName + "_RightHandPinky2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Distal", assetName + "_RightHandPinky3" );
|
|
break;
|
|
case OptitrackBoneNameConvention.BVH:
|
|
m_cachedMecanimBoneNameMap.Add( "Hips", assetName + "_Hips" );
|
|
m_cachedMecanimBoneNameMap.Add( "Spine", assetName + "_Chest" );
|
|
m_cachedMecanimBoneNameMap.Add( "Chest", assetName + "_Chest2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Neck", assetName + "_Neck" );
|
|
m_cachedMecanimBoneNameMap.Add( "Head", assetName + "_Head" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftShoulder", assetName + "_LeftCollar" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperArm", assetName + "_LeftShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerArm", assetName + "_LeftElbow" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftHand", assetName + "_LeftWrist" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightShoulder", assetName + "_RightCollar" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperArm", assetName + "_RightShoulder" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerArm", assetName + "_RightElbow" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightHand", assetName + "_RightWrist" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "LeftUpperLeg", assetName + "_LeftHip" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftLowerLeg", assetName + "_LeftKnee" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftFoot", assetName + "_LeftAnkle" );
|
|
m_cachedMecanimBoneNameMap.Add( "LeftToeBase", assetName + "_LeftToe" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "RightUpperLeg", assetName + "_RightHip" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightLowerLeg", assetName + "_RightKnee" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightFoot", assetName + "_RightAnkle" );
|
|
m_cachedMecanimBoneNameMap.Add( "RightToeBase", assetName + "_RightToe" );
|
|
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Proximal", assetName + "_LeftFinger0" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Intermediate", assetName + "_LeftFinger01" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Thumb Distal", assetName + "_LeftFinger02" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Proximal", assetName + "_RightFinger0" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Intermediate", assetName + "_RightFinger01" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Thumb Distal", assetName + "_RightFinger02" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Proximal", assetName + "_LeftFinger1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Intermediate", assetName + "_LeftFinger11" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Index Distal", assetName + "_LeftFinger12" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Proximal", assetName + "_RightFinger1" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Intermediate", assetName + "_RightFinger11" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Index Distal", assetName + "_RightFinger12" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Proximal", assetName + "_LeftFinger2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Intermediate", assetName + "_LeftFinger21" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Middle Distal", assetName + "_LeftFinger22" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Proximal", assetName + "_RightFinger2" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Intermediate", assetName + "_RightFinger21" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Middle Distal", assetName + "_RightFinger22" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Proximal", assetName + "_LeftFinger3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Intermediate", assetName + "_LeftFinger31" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Ring Distal", assetName + "_LeftFinger32" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Proximal", assetName + "_RightFinger3" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Intermediate", assetName + "_RightFinger31" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Ring Distal", assetName + "_RightFinger32" );
|
|
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Proximal", assetName + "_LeftFinger4" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Intermediate", assetName + "_LeftFinger41" );
|
|
m_cachedMecanimBoneNameMap.Add( "Left Little Distal", assetName + "_LeftFinger42" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Proximal", assetName + "_RightFinger4" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Intermediate", assetName + "_RightFinger41" );
|
|
m_cachedMecanimBoneNameMap.Add( "Right Little Distal", assetName + "_RightFinger42" );
|
|
break;
|
|
}
|
|
}
|
|
#endregion Private methods
|
|
|
|
} |