Merge commit '8a35345bb0f3b60fe23552e2f04b7f9d55f86f8f' as 'UniHumanoid'

Co-authored-by: ousttrue <oustrrue@gmail.com>
Co-authored-by: ousttrue <ousttrrue@gmail.com>
Co-authored-by: ousttrue <ousttrue@gmail.com>
Co-authored-by: yutopp <yutopp@gmail.com>
This commit is contained in:
ousttrue 2018-12-28 21:08:56 +09:00
commit e115c65576
100 changed files with 8087 additions and 0 deletions

21
UniHumanoid/LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 ousttrue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ea85fd858590174f98cc2cd4c3e083f
timeCreated: 1522228320
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a90ca020c7788804ea91e172fa5efd1a
folderAsset: yes
timeCreated: 1524224672
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,175 @@
using System;
using UnityEngine;
namespace UniHumanoid
{
public class HandPoseModifier : IPoseModifier
{
public class HandPose
{
public float ThumbStrech;
public float ThumbSpread;
public float IndexStrech;
public float IndexSpread;
public float MiddleStrech;
public float MiddleSpread;
public float RingStrech;
public float RingSpread;
public float LittleStrech;
public float LittleSpread;
}
public HandPose LeftHandPose
{
get;
set;
}
public HandPose RightHandPose
{
get;
set;
}
int LeftThumb1Stretched;
int LeftThumb2Stretched;
int LeftThumb3Stretched;
int LeftIndex1Stretched;
int LeftIndex2Stretched;
int LeftIndex3Stretched;
int LeftMiddle1Stretched;
int LeftMiddle2Stretched;
int LeftMiddle3Stretched;
int LeftRing1Stretched;
int LeftRing2Stretched;
int LeftRing3Stretched;
int LeftLittle1Stretched;
int LeftLittle2Stretched;
int LeftLittle3Stretched;
int LeftThumbSpread;
int LeftIndexSpread;
int LeftMiddleSpread;
int LeftRingSpread;
int LeftLittleSpread;
int RightThumb1Stretched;
int RightThumb2Stretched;
int RightThumb3Stretched;
int RightIndex1Stretched;
int RightIndex2Stretched;
int RightIndex3Stretched;
int RightMiddle1Stretched;
int RightMiddle2Stretched;
int RightMiddle3Stretched;
int RightRing1Stretched;
int RightRing2Stretched;
int RightRing3Stretched;
int RightLittle1Stretched;
int RightLittle2Stretched;
int RightLittle3Stretched;
int RightThumbSpread;
int RightIndexSpread;
int RightMiddleSpread;
int RightRingSpread;
int RightLittleSpread;
public HandPoseModifier()
{
LeftThumb1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 1 Stretched");
LeftThumb2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 2 Stretched");
LeftThumb3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb 3 Stretched");
LeftIndex1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 1 Stretched");
LeftIndex2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 2 Stretched");
LeftIndex3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Index 3 Stretched");
LeftMiddle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 1 Stretched");
LeftMiddle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 2 Stretched");
LeftMiddle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Middle 3 Stretched");
LeftRing1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 1 Stretched");
LeftRing2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 2 Stretched");
LeftRing3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Ring 3 Stretched");
LeftLittle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 1 Stretched");
LeftLittle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 2 Stretched");
LeftLittle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Left Little 3 Stretched");
LeftThumbSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Thumb Spread");
LeftIndexSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Index Spread");
LeftMiddleSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Middle Spread");
LeftRingSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Ring Spread");
LeftLittleSpread = Array.IndexOf(HumanTrait.MuscleName, "Left Little Spread");
RightThumb1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 1 Stretched");
RightThumb2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 2 Stretched");
RightThumb3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb 3 Stretched");
RightIndex1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 1 Stretched");
RightIndex2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 2 Stretched");
RightIndex3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Index 3 Stretched");
RightMiddle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 1 Stretched");
RightMiddle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 2 Stretched");
RightMiddle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Middle 3 Stretched");
RightRing1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 1 Stretched");
RightRing2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 2 Stretched");
RightRing3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Ring 3 Stretched");
RightLittle1Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 1 Stretched");
RightLittle2Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 2 Stretched");
RightLittle3Stretched = Array.IndexOf(HumanTrait.MuscleName, "Right Little 3 Stretched");
RightThumbSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Thumb Spread");
RightIndexSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Index Spread");
RightMiddleSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Middle Spread");
RightRingSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Ring Spread");
RightLittleSpread = Array.IndexOf(HumanTrait.MuscleName, "Right Little Spread");
}
public void Modify(ref HumanPose pose)
{
if (LeftHandPose != null)
{
pose.muscles[this.LeftThumb1Stretched] = LeftHandPose.ThumbStrech;
pose.muscles[this.LeftThumb2Stretched] = LeftHandPose.ThumbStrech;
pose.muscles[this.LeftThumb3Stretched] = LeftHandPose.ThumbStrech;
pose.muscles[this.LeftIndex1Stretched] = LeftHandPose.IndexStrech;
pose.muscles[this.LeftIndex2Stretched] = LeftHandPose.IndexStrech;
pose.muscles[this.LeftIndex3Stretched] = LeftHandPose.IndexStrech;
pose.muscles[this.LeftMiddle1Stretched] = LeftHandPose.MiddleStrech;
pose.muscles[this.LeftMiddle2Stretched] = LeftHandPose.MiddleStrech;
pose.muscles[this.LeftMiddle3Stretched] = LeftHandPose.MiddleStrech;
pose.muscles[this.LeftRing1Stretched] = LeftHandPose.RingStrech;
pose.muscles[this.LeftRing2Stretched] = LeftHandPose.RingStrech;
pose.muscles[this.LeftRing3Stretched] = LeftHandPose.RingStrech;
pose.muscles[this.LeftLittle1Stretched] = LeftHandPose.LittleStrech;
pose.muscles[this.LeftLittle2Stretched] = LeftHandPose.LittleStrech;
pose.muscles[this.LeftLittle3Stretched] = LeftHandPose.LittleStrech;
pose.muscles[this.LeftThumbSpread] = LeftHandPose.ThumbSpread;
pose.muscles[this.LeftIndexSpread] = LeftHandPose.IndexSpread;
pose.muscles[this.LeftMiddleSpread] = LeftHandPose.MiddleSpread;
pose.muscles[this.LeftRingSpread] = LeftHandPose.RingSpread;
pose.muscles[this.LeftLittleSpread] = LeftHandPose.LittleSpread;
}
if (RightHandPose != null)
{
pose.muscles[this.RightThumb1Stretched] = RightHandPose.ThumbStrech;
pose.muscles[this.RightThumb2Stretched] = RightHandPose.ThumbStrech;
pose.muscles[this.RightThumb3Stretched] = RightHandPose.ThumbStrech;
pose.muscles[this.RightIndex1Stretched] = RightHandPose.IndexStrech;
pose.muscles[this.RightIndex2Stretched] = RightHandPose.IndexStrech;
pose.muscles[this.RightIndex3Stretched] = RightHandPose.IndexStrech;
pose.muscles[this.RightMiddle1Stretched] = RightHandPose.MiddleStrech;
pose.muscles[this.RightMiddle2Stretched] = RightHandPose.MiddleStrech;
pose.muscles[this.RightMiddle3Stretched] = RightHandPose.MiddleStrech;
pose.muscles[this.RightRing1Stretched] = RightHandPose.RingStrech;
pose.muscles[this.RightRing2Stretched] = RightHandPose.RingStrech;
pose.muscles[this.RightRing3Stretched] = RightHandPose.RingStrech;
pose.muscles[this.RightLittle1Stretched] = RightHandPose.LittleStrech;
pose.muscles[this.RightLittle2Stretched] = RightHandPose.LittleStrech;
pose.muscles[this.RightLittle3Stretched] = RightHandPose.LittleStrech;
pose.muscles[this.RightThumbSpread] = RightHandPose.ThumbSpread;
pose.muscles[this.RightIndexSpread] = RightHandPose.IndexSpread;
pose.muscles[this.RightMiddleSpread] = RightHandPose.MiddleSpread;
pose.muscles[this.RightRingSpread] = RightHandPose.RingSpread;
pose.muscles[this.RightLittleSpread] = RightHandPose.LittleSpread;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 14d18bc5a296a894eb7154d3f5f0e18b
timeCreated: 1523606797
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,100 @@
using UnityEngine;
namespace UniHumanoid
{
public class HandRig : MonoBehaviour
{
[SerializeField]
Animator m_animator;
public Animator Animator
{
get { return m_animator; }
}
[SerializeField, Range(-1, 1)]
public float LeftStrech;
[SerializeField, Range(-1, 1)]
public float LeftSpread;
[SerializeField, Range(-1, 1)]
public float RightStrech;
[SerializeField, Range(-1, 1)]
public float RightSpread;
private void Reset()
{
m_animator = GetComponent<Animator>();
}
HumanPoseHandler m_handler;
public static HumanPoseHandler GetHandler(Animator animator)
{
if (animator == null)
{
return null;
}
if (animator.avatar == null)
{
return null;
}
if (!animator.avatar.isValid
|| !animator.avatar.isHuman)
{
return null;
}
return new HumanPoseHandler(animator.avatar, animator.transform);
}
HandPoseModifier m_updater;
private void Awake()
{
m_handler = GetHandler(m_animator);
if (m_handler == null)
{
enabled = false;
return;
}
m_updater = new HandPoseModifier();
}
HandPoseModifier.HandPose m_leftHand = new HandPoseModifier.HandPose();
HandPoseModifier.HandPose m_rightHand = new HandPoseModifier.HandPose();
HumanPose m_pose;
private void Update()
{
m_leftHand.ThumbStrech = LeftStrech;
m_leftHand.ThumbSpread = LeftSpread;
m_leftHand.IndexStrech = LeftStrech;
m_leftHand.IndexSpread = LeftSpread;
m_leftHand.MiddleStrech = LeftStrech;
m_leftHand.MiddleSpread = LeftSpread;
m_leftHand.RingStrech = LeftStrech;
m_leftHand.RingSpread = LeftSpread;
m_leftHand.LittleStrech = LeftStrech;
m_leftHand.LittleSpread = LeftSpread;
m_rightHand.ThumbStrech = RightStrech;
m_rightHand.ThumbSpread = RightSpread;
m_rightHand.IndexStrech = RightStrech;
m_rightHand.IndexSpread = RightSpread;
m_rightHand.MiddleStrech = RightStrech;
m_rightHand.MiddleSpread = RightSpread;
m_rightHand.RingStrech = RightStrech;
m_rightHand.RingSpread = RightSpread;
m_rightHand.LittleStrech = RightStrech;
m_rightHand.LittleSpread = RightSpread;
m_updater.LeftHandPose = m_leftHand;
m_updater.RightHandPose = m_rightHand;
m_handler.GetHumanPose(ref m_pose);
m_updater.Modify(ref m_pose);
m_handler.SetHumanPose(ref m_pose);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45d55d80a64783c41ace70d5d81db454
timeCreated: 1523602613
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
using UnityEngine;
namespace UniHumanoid
{
public interface IPoseModifier
{
void Modify(ref HumanPose pose);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 973f36da309a48d4ea3c5526a51e957f
timeCreated: 1523606728
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

77
UniHumanoid/README.md Normal file
View File

@ -0,0 +1,77 @@
# UniHumanoid
Unity humanoid utility with bvh importer.
# License
* [MIT](./LICENSE.md)
# BVH runtime loader
```cs
var context = new BvhImporterContext();
context.Parse(path);
context.Load(); // create Skeleton hierarchy and mesh for visualize
GameObject root = context.Root;
```
## RuntimeLoader
* Scenes/RuntimeBvhLoader.unity
## RuntimeLoader and PoseTransfer
Load BVH and transfer pose to any model with humanoid avatar.
* Scenes/PoseTransfer.unity
![humanpose transfer target](doc/humanpose_transfer_inspector.png)
![humanpose transfer](doc/humanpose_transfer.png)
# Load bvh and create prefab with AnimationClip
Drop bvh file to Assets folder.
Then, AssetPostprocessor import bvh file.
* create a hierarchy prefab
* create a humanoid Avatar
* create a legacy mode AnimationClip
* create a skinned mesh for preview
![bvh prefab](doc/assets.png)
Instanciate prefab to scene.
![bvh gameobject](doc/mesh.png)
That object can play.
# BoneMapping
This script help create human avatar from exist GameObject hierarchy.
First, attach this script to root GameObject that has Animator.
Next, setup below.
* model position is origin
* model look at +z orientation
* model root node rotation is Quatenion.identity
* Set hips bone.
press Guess bone mapping.
If fail to guess bone mapping, you can set bones manually.
Optional, press Ensure T-Pose.
Create avatar.
![bvh bone mapping](doc/bvh_bonemapping.png)
These humanoids imported by [UniGLTF](https://github.com/ousttrue/UniGLTF) and created human avatar by BoneMapping.
![humanoid](doc/humanoid.gif)
# Download BVH files
* https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture
* http://mocapdata.com/
* http://www.thetrailerspark.com/download/Mocap/Packed/EYES-JAPAN/BVH/

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: be513cfaa8530114d85f1e8e0f29708a
timeCreated: 1517370218
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c61106d290c827b49b7a6e3f6497bd3f
folderAsset: yes
timeCreated: 1519379142
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,111 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4fdf4ef744a103a4ca01657c00d7fec2, type: 3}
m_Name: T-Pose.pose
m_EditorClassIdentifier:
bodyPosition: {x: 0.0024022944, y: 1.000028, z: 0.0019842784}
bodyRotation: {x: -0, y: 0.000000014901161, z: 0.000000014901161, w: 1}
muscles:
- -0.000000010672161
- -6.3611094e-16
- 6.3611094e-16
- -0.00000055495286
- 0.00000026851825
- -0.0000000012914859
- 0
- 0
- 0
- 0.00000029369042
- -0.0000005362765
- 0.00000026918045
- 0.00000052293626
- 0.00000012148932
- 0.0000003683441
- 0
- 0
- 0
- 0
- 0
- 0
- 0.5957687
- -0.018923696
- 0.2105892
- 1.0025908
- -0.13775763
- -0.002854546
- -0.020644147
- -0.0000060816024
- 0.5957681
- -0.01892539
- 0.2106165
- 1.0025909
- -0.13777769
- -0.0028554748
- -0.020645387
- -2.0029848e-12
- 0.0000003415094
- -0.00000011383648
- 0.39829093
- 0.3004907
- -0.030618805
- 0.999798
- 0.03679788
- -0.0025310651
- 0.00030608202
- 6.7851816e-15
- -0.00000045534588
- 0.39829168
- 0.3004914
- -0.030611247
- 0.9997984
- 0.03679079
- -0.0025303008
- 0.00030552692
- -0.68517876
- 0.4567073
- 0.64590156
- 0.6459016
- 0.66896635
- -0.40027583
- 0.8113421
- 0.81134295
- 0.66770303
- -0.62352574
- 0.8111324
- 0.811132
- 0.6683899
- -0.5698266
- 0.8116428
- 0.8116354
- 0.6692385
- -0.44004643
- 0.8082721
- 0.8082728
- -0.68401676
- 0.45769995
- 0.6457741
- 0.64577323
- 0.6689646
- -0.40025005
- 0.81134063
- 0.81134117
- 0.6677078
- -0.62352294
- 0.81113243
- 0.8111291
- 0.6683884
- -0.5698764
- 0.81164306
- 0.8116342
- 0.66924673
- -0.44011596
- 0.808278
- 0.8082771

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 879e332f84a378c4da3b87af13da3e85
timeCreated: 1519376738
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

8
UniHumanoid/Scenes.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9edc7cfd64210934e817c98db16bdaea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,149 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UniHumanoid
{
[RequireComponent(typeof(Animator))]
public class HumanBuilderTest : MonoBehaviour
{
[SerializeField]
Material m_material;
class SkeletonBuilder
{
Dictionary<HumanBodyBones, Transform> m_skeleton = new Dictionary<HumanBodyBones, Transform>();
public IDictionary<HumanBodyBones, Transform> Skeleton
{
get { return m_skeleton; }
}
Dictionary<HumanBodyBones, Vector3> m_boneTail = new Dictionary<HumanBodyBones, Vector3>();
Transform m_root;
public SkeletonBuilder(Transform root)
{
m_root = root;
}
void Add(HumanBodyBones key, Transform parent, Vector3 headPosition, Vector3 tailPosition)
{
var bone = new GameObject(key.ToString()).transform;
bone.SetParent(parent, false);
bone.localPosition = headPosition;
m_skeleton[key] = bone;
m_boneTail[key] = tailPosition;
}
void Add(HumanBodyBones key, HumanBodyBones parentKey, Vector3 tailPosition)
{
Add(key, m_skeleton[parentKey], m_boneTail[parentKey], tailPosition);
}
#region Spine
public void AddHips(float height, float len)
{
Add(HumanBodyBones.Hips, m_root, new Vector3(0, height, 0), new Vector3(0, len, 0));
}
public void AddSpine(float len)
{
Add(HumanBodyBones.Spine, HumanBodyBones.Hips, new Vector3(0, len, 0));
}
public void AddChest(float len)
{
Add(HumanBodyBones.Chest, HumanBodyBones.Spine, new Vector3(0, len, 0));
}
public void AddNeck(float len)
{
Add(HumanBodyBones.Neck, HumanBodyBones.Chest, new Vector3(0, len, 0));
}
public void AddHead(float len)
{
Add(HumanBodyBones.Head, HumanBodyBones.Neck, new Vector3(0, len, 0));
}
#endregion
public void AddArm(float shoulder, float upper, float lower, float hand)
{
Add(HumanBodyBones.LeftShoulder, HumanBodyBones.Chest, new Vector3(-shoulder, 0, 0));
Add(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftShoulder, new Vector3(-upper, 0, 0));
Add(HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftUpperArm, new Vector3(-lower, 0, 0));
Add(HumanBodyBones.LeftHand, HumanBodyBones.LeftLowerArm, new Vector3(-hand, 0, 0));
Add(HumanBodyBones.RightShoulder, HumanBodyBones.Chest, new Vector3(shoulder, 0, 0));
Add(HumanBodyBones.RightUpperArm, HumanBodyBones.RightShoulder, new Vector3(upper, 0, 0));
Add(HumanBodyBones.RightLowerArm, HumanBodyBones.RightUpperArm, new Vector3(lower, 0, 0));
Add(HumanBodyBones.RightHand, HumanBodyBones.RightLowerArm, new Vector3(hand, 0, 0));
}
public void AddLeg(float distance, float upper, float lower, float foot, float toe)
{
Add(HumanBodyBones.LeftUpperLeg, m_skeleton[HumanBodyBones.Hips], new Vector3(-distance, 0, 0), new Vector3(0, -upper, 0));
Add(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftUpperLeg, new Vector3(0, -lower, 0));
Add(HumanBodyBones.LeftFoot, HumanBodyBones.LeftLowerLeg, new Vector3(0, -foot, foot));
Add(HumanBodyBones.LeftToes, HumanBodyBones.LeftFoot, new Vector3(0, 0, toe));
Add(HumanBodyBones.RightUpperLeg, m_skeleton[HumanBodyBones.Hips], new Vector3(distance, 0, 0), new Vector3(0, -upper, 0));
Add(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightUpperLeg, new Vector3(0, -lower, 0));
Add(HumanBodyBones.RightFoot, HumanBodyBones.RightLowerLeg, new Vector3(0, -foot, foot));
Add(HumanBodyBones.RightToes, HumanBodyBones.RightFoot, new Vector3(0, 0, toe));
}
}
void OnEnable()
{
BuildSkeleton(transform);
}
private void BuildSkeleton(Transform root)
{
var position = root.position;
root.position = Vector3.zero;
try
{
// hips -> spine -> chest
var builder = new SkeletonBuilder(root);
builder.AddHips(0.8f, 0.2f);
builder.AddSpine(0.1f);
builder.AddChest(0.2f);
builder.AddNeck(0.1f);
builder.AddHead(0.2f);
builder.AddArm(0.1f, 0.3f, 0.3f, 0.1f);
builder.AddLeg(0.1f, 0.3f, 0.4f, 0.1f, 0.1f);
var description = AvatarDescription.Create(builder.Skeleton);
var animator = GetComponent<Animator>();
animator.avatar = description.CreateAvatar(root);
// create SkinnedMesh for bone visualize
var renderer = SkeletonMeshUtility.CreateRenderer(animator);
if (m_material == null)
{
m_material = new Material(Shader.Find("Standard"));
}
renderer.sharedMaterial = m_material;
//root.gameObject.AddComponent<BoneMapping>();
var transfer = GetComponent<HumanPoseTransfer>();
if (transfer != null)
{
transfer.Avatar = animator.avatar;
transfer.Setup();
}
}
finally
{
// restore position
root.position = position;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dfdcf658d2da05649974b59b849de74c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,691 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &406922205
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 406922208}
- component: {fileID: 406922207}
- component: {fileID: 406922206}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &406922206
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_Enabled: 1
--- !u!20 &406922207
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &406922208
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &540606465
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 540606468}
- component: {fileID: 540606467}
- component: {fileID: 540606466}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &540606466
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &540606467
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &540606468
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &745406201
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 745406206}
- component: {fileID: 745406205}
- component: {fileID: 745406204}
- component: {fileID: 745406203}
- component: {fileID: 745406202}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &745406202
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7b994e1476323bf4fbe1ae28bea164f2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_openButton: {fileID: 860463875}
m_dst: {fileID: 948407063}
--- !u!114 &745406203
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &745406204
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &745406205
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &745406206
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 860463874}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &860463873
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 860463874}
- component: {fileID: 860463877}
- component: {fileID: 860463876}
- component: {fileID: 860463875}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &860463874
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 2080820046}
m_Father: {fileID: 745406206}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0, y: 1}
--- !u!114 &860463875
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 860463876}
m_OnClick:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &860463876
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!222 &860463877
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_CullTransparentMesh: 0
--- !u!1 &948407059
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 948407062}
- component: {fileID: 948407061}
- component: {fileID: 948407060}
- component: {fileID: 948407063}
m_Layer: 0
m_Name: Target
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &948407060
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 948407059}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dfdcf658d2da05649974b59b849de74c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_material: {fileID: 2100000, guid: 94b4b45712e88334c9e7c5ecc53c50e6, type: 2}
--- !u!95 &948407061
Animator:
serializedVersion: 3
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 948407059}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 0}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorControllerStateOnDisable: 0
--- !u!4 &948407062
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 948407059}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -1, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &948407063
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 948407059}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e5548e4785b76854cbbf3f6d9a8e9c1d, type: 3}
m_Name:
m_EditorClassIdentifier:
SourceType: 0
Avatar: {fileID: 0}
Source: {fileID: 0}
PoseClip: {fileID: 0}
--- !u!1 &1536726113
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1536726115}
- component: {fileID: 1536726114}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1536726114
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1536726113}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1536726115
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1536726113}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &2080820045
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2080820046}
- component: {fileID: 2080820048}
- component: {fileID: 2080820047}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2080820046
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 860463874}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2080820047
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Open
--- !u!222 &2080820048
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_CullTransparentMesh: 0

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ae847f673eb3e6f4a95f61b4658b806a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UniHumanoid;
using System.IO;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniHumanoid
{
public class RuntimeBvhLoader : MonoBehaviour
{
[SerializeField]
Button m_openButton;
[SerializeField]
HumanPoseTransfer m_dst;
UnityAction m_onClick;
private void Awake()
{
m_onClick = new UnityEngine.Events.UnityAction(OnClick);
}
private void OnEnable()
{
m_openButton.onClick.AddListener(m_onClick);
}
private void OnDisable()
{
m_openButton.onClick.RemoveListener(m_onClick);
}
static string m_lastDir;
public void OnClick()
{
#if UNITY_EDITOR
var path = EditorUtility.OpenFilePanel("open bvh", m_lastDir, "bvh");
if (String.IsNullOrEmpty(path))
{
return;
}
m_lastDir = Path.GetDirectoryName(path);
#else
string path=null;
throw new NotImplementedException();
#endif
#pragma warning disable 4014
Open(path);
#pragma warning restore 4014
}
BvhImporterContext m_context;
void Open(string path)
{
Debug.LogFormat("Open: {0}", path);
if (m_context != null)
{
m_context.Destroy(true);
m_context = null;
}
m_context = new BvhImporterContext();
m_context.Parse(path);
m_context.Load();
var src = m_context.Root.AddComponent<HumanPoseTransfer>();
if (m_dst != null)
{
m_dst.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer;
m_dst.Source = src;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b994e1476323bf4fbe1ae28bea164f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,615 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &406922205
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 406922208}
- component: {fileID: 406922207}
- component: {fileID: 406922206}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &406922206
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_Enabled: 1
--- !u!20 &406922207
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &406922208
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 406922205}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &540606465
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 540606468}
- component: {fileID: 540606467}
- component: {fileID: 540606466}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &540606466
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &540606467
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &540606468
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 540606465}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &745406201
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 745406206}
- component: {fileID: 745406205}
- component: {fileID: 745406204}
- component: {fileID: 745406203}
- component: {fileID: 745406202}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &745406202
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7b994e1476323bf4fbe1ae28bea164f2, type: 3}
m_Name:
m_EditorClassIdentifier:
m_openButton: {fileID: 860463875}
m_dst: {fileID: 0}
--- !u!114 &745406203
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &745406204
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &745406205
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &745406206
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 745406201}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 860463874}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &860463873
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 860463874}
- component: {fileID: 860463877}
- component: {fileID: 860463876}
- component: {fileID: 860463875}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &860463874
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 2080820046}
m_Father: {fileID: 745406206}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0, y: 1}
--- !u!114 &860463875
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 860463876}
m_OnClick:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!114 &860463876
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!222 &860463877
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 860463873}
m_CullTransparentMesh: 0
--- !u!1 &1536726113
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1536726115}
- component: {fileID: 1536726114}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1536726114
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1536726113}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1536726115
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1536726113}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &2080820045
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2080820046}
- component: {fileID: 2080820048}
- component: {fileID: 2080820047}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2080820046
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 860463874}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2080820047
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Open
--- !u!222 &2080820048
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2080820045}
m_CullTransparentMesh: 0

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 99665560be9c32e4d9f7813b076c92ee
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,76 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: target
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _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: 0}
m_Scale: {x: 1, y: 1}
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}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 0.60773194, g: 0.8584906, b: 0.14983091, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 94b4b45712e88334c9e7c5ecc53c50e6
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

9
UniHumanoid/Scripts.meta Normal file
View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 64819743741f38e43b64a7d6add8cea9
folderAsset: yes
timeCreated: 1517166088
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,134 @@
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public static class AnimationClipUtility
{
static Dictionary<string, string> TraitPropMap = new Dictionary<string, string>
{
{"Left Thumb 1 Stretched", "LeftHand.Thumb.1 Stretched"},
{"Left Thumb Spread", "LeftHand.Thumb Spread"},
{"Left Thumb 2 Stretched", "LeftHand.Thumb.2 Stretched"},
{"Left Thumb 3 Stretched", "LeftHand.Thumb.3 Stretched"},
{"Left Index 1 Stretched", "LeftHand.Index.1 Stretched"},
{"Left Index Spread", "LeftHand.Index Spread"},
{"Left Index 2 Stretched", "LeftHand.Index.2 Stretched"},
{"Left Index 3 Stretched", "LeftHand.Index.3 Stretched"},
{"Left Middle 1 Stretched", "LeftHand.Middle.1 Stretched"},
{"Left Middle Spread", "LeftHand.Middle Spread"},
{"Left Middle 2 Stretched", "LeftHand.Middle.2 Stretched"},
{"Left Middle 3 Stretched", "LeftHand.Middle.3 Stretched"},
{"Left Ring 1 Stretched", "LeftHand.Ring.1 Stretched"},
{"Left Ring Spread", "LeftHand.Ring Spread"},
{"Left Ring 2 Stretched", "LeftHand.Ring.2 Stretched"},
{"Left Ring 3 Stretched", "LeftHand.Ring.3 Stretched"},
{"Left Little 1 Stretched", "LeftHand.Little.1 Stretched"},
{"Left Little Spread", "LeftHand.Little Spread"},
{"Left Little 2 Stretched", "LeftHand.Little.2 Stretched"},
{"Left Little 3 Stretched", "LeftHand.Little.3 Stretched"},
{"Right Thumb 1 Stretched", "RightHand.Thumb.1 Stretched"},
{"Right Thumb Spread", "RightHand.Thumb Spread"},
{"Right Thumb 2 Stretched", "RightHand.Thumb.2 Stretched"},
{"Right Thumb 3 Stretched", "RightHand.Thumb.3 Stretched"},
{"Right Index 1 Stretched", "RightHand.Index.1 Stretched"},
{"Right Index Spread", "RightHand.Index Spread"},
{"Right Index 2 Stretched", "RightHand.Index.2 Stretched"},
{"Right Index 3 Stretched", "RightHand.Index.3 Stretched"},
{"Right Middle 1 Stretched", "RightHand.Middle.1 Stretched"},
{"Right Middle Spread", "RightHand.Middle Spread"},
{"Right Middle 2 Stretched", "RightHand.Middle.2 Stretched"},
{"Right Middle 3 Stretched", "RightHand.Middle.3 Stretched"},
{"Right Ring 1 Stretched", "RightHand.Ring.1 Stretched"},
{"Right Ring Spread", "RightHand.Ring Spread"},
{"Right Ring 2 Stretched", "RightHand.Ring.2 Stretched"},
{"Right Ring 3 Stretched", "RightHand.Ring.3 Stretched"},
{"Right Little 1 Stretched", "RightHand.Little.1 Stretched"},
{"Right Little Spread", "RightHand.Little Spread"},
{"Right Little 2 Stretched", "RightHand.Little.2 Stretched"},
{"Right Little 3 Stretched", "RightHand.Little.3 Stretched"},
};
public static AnimationClip CreateAnimationClipFromHumanPose(HumanPose pose)
{
var clip = new AnimationClip();
// pos
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyPosition.x),
});
var muscle = "RootT.x";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyPosition.y),
});
var muscle = "RootT.y";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyPosition.z),
});
var muscle = "RootT.z";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
// rot
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyRotation.x),
});
var muscle = "RootQ.x";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyRotation.y),
});
var muscle = "RootQ.y";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyRotation.z),
});
var muscle = "RootQ.z";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.bodyRotation.w),
});
var muscle = "RootQ.w";
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
// muscles
for (int i = 0; i < HumanTrait.MuscleCount; ++i)
{
var curve = new AnimationCurve(new Keyframe[]
{
new Keyframe(0, pose.muscles[i]),
});
var muscle = HumanTrait.MuscleName[i];
if (TraitPropMap.ContainsKey(muscle))
{
muscle = TraitPropMap[muscle];
}
clip.SetCurve(null, typeof(Animator), muscle, curve);
}
return clip;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: e13984a5449ddb843b03e21c3409df67
timeCreated: 1516590895
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,242 @@
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
namespace UniHumanoid
{
[Serializable]
public struct BoneLimit
{
public HumanBodyBones humanBone;
public string boneName;
public bool useDefaultValues;
public Vector3 min;
public Vector3 max;
public Vector3 center;
public float axisLength;
public static BoneLimit From(HumanBone bone)
{
return new BoneLimit
{
humanBone = (HumanBodyBones)Enum.Parse(typeof(HumanBodyBones), bone.humanName.Replace(" ", ""), true),
boneName = bone.boneName,
useDefaultValues = bone.limit.useDefaultValues,
min = bone.limit.min,
max = bone.limit.max,
center = bone.limit.center,
axisLength = bone.limit.axisLength,
};
}
public static String ToHumanBoneName(HumanBodyBones b)
{
foreach (var x in HumanTrait.BoneName)
{
if (x.Replace(" ", "") == b.ToString())
{
return x;
}
}
throw new KeyNotFoundException();
}
public HumanBone ToHumanBone()
{
return new HumanBone
{
boneName = boneName,
humanName = ToHumanBoneName(humanBone),
limit = new HumanLimit
{
useDefaultValues = useDefaultValues,
axisLength = axisLength,
center = center,
max = max,
min = min
},
};
}
}
[Serializable]
public class AvatarDescription : ScriptableObject
{
public float armStretch = 0.05f;
public float legStretch = 0.05f;
public float upperArmTwist = 0.5f;
public float lowerArmTwist = 0.5f;
public float upperLegTwist = 0.5f;
public float lowerLegTwist = 0.5f;
public float feetSpacing = 0;
public bool hasTranslationDoF;
public BoneLimit[] human;
public HumanDescription ToHumanDescription(Transform root)
{
return new HumanDescription
{
skeleton = root.Traverse().Select(x => x.ToSkeletonBone()).ToArray(),
human = human.Select(x => x.ToHumanBone()).ToArray(),
armStretch = armStretch,
legStretch = legStretch,
upperArmTwist = upperArmTwist,
lowerArmTwist = lowerArmTwist,
upperLegTwist = upperLegTwist,
lowerLegTwist = lowerLegTwist,
feetSpacing = feetSpacing,
hasTranslationDoF = hasTranslationDoF,
};
}
public Avatar CreateAvatar(Transform root)
{
return AvatarBuilder.BuildHumanAvatar(root.gameObject, ToHumanDescription(root));
}
public Avatar CreateAvatarAndSetup(Transform root)
{
var avatar = CreateAvatar(root);
avatar.name = name;
var animator = root.GetComponent<Animator>();
if (animator != null)
{
var positionMap = root.Traverse().ToDictionary(x => x, x => x.position);
animator.avatar = avatar;
foreach (var x in root.Traverse())
{
x.position = positionMap[x];
}
}
var transfer = root.GetComponent<HumanPoseTransfer>();
if (transfer != null)
{
transfer.Avatar = avatar;
}
return avatar;
}
#if UNITY_EDITOR
public static AvatarDescription CreateFrom(Avatar avatar)
{
var description = default(HumanDescription);
if (!GetHumanDescription(avatar, ref description))
{
return null;
}
return CreateFrom(description);
}
#endif
public static AvatarDescription CreateFrom(HumanDescription description)
{
var avatarDescription = ScriptableObject.CreateInstance<AvatarDescription>();
avatarDescription.name = "AvatarDescription";
avatarDescription.armStretch = description.armStretch;
avatarDescription.legStretch = description.legStretch;
avatarDescription.feetSpacing = description.feetSpacing;
avatarDescription.hasTranslationDoF = description.hasTranslationDoF;
avatarDescription.lowerArmTwist = description.lowerArmTwist;
avatarDescription.lowerLegTwist = description.lowerLegTwist;
avatarDescription.upperArmTwist = description.upperArmTwist;
avatarDescription.upperLegTwist = description.upperLegTwist;
avatarDescription.human = description.human.Select(BoneLimit.From).ToArray();
return avatarDescription;
}
public static AvatarDescription Create(AvatarDescription src=null)
{
var avatarDescription = ScriptableObject.CreateInstance<AvatarDescription>();
avatarDescription.name = "AvatarDescription";
if (src != null)
{
avatarDescription.armStretch = src.armStretch;
avatarDescription.legStretch = src.legStretch;
avatarDescription.feetSpacing = src.feetSpacing;
avatarDescription.upperArmTwist = src.upperArmTwist;
avatarDescription.lowerArmTwist = src.lowerArmTwist;
avatarDescription.upperLegTwist = src.upperLegTwist;
avatarDescription.lowerLegTwist = src.lowerLegTwist;
}
else
{
avatarDescription.armStretch = 0.05f;
avatarDescription.legStretch = 0.05f;
avatarDescription.feetSpacing = 0.0f;
avatarDescription.lowerArmTwist = 0.5f;
avatarDescription.upperArmTwist = 0.5f;
avatarDescription.upperLegTwist = 0.5f;
avatarDescription.lowerLegTwist = 0.5f;
}
return avatarDescription;
}
public static AvatarDescription Create(Transform[] boneTransforms, Skeleton skeleton)
{
return Create(skeleton.Bones.Select(
x => new KeyValuePair<HumanBodyBones, Transform>(x.Key, boneTransforms[x.Value])));
}
public static AvatarDescription Create(IEnumerable<KeyValuePair<HumanBodyBones, Transform>> skeleton)
{
var description = Create();
description.SetHumanBones(skeleton);
return description;
}
public void SetHumanBones(IEnumerable<KeyValuePair<HumanBodyBones, Transform>> skeleton)
{
human = skeleton.Select(x =>
{
return new BoneLimit
{
humanBone = x.Key,
boneName = x.Value.name,
useDefaultValues = true,
};
}).ToArray();
}
#if UNITY_EDITOR
/// <summary>
/// * https://answers.unity.com/questions/612177/how-can-i-access-human-avatar-bone-and-muscle-valu.html
/// </summary>
/// <param name="target"></param>
/// <param name="des"></param>
/// <returns></returns>
public static bool GetHumanDescription(UnityEngine.Object target, ref HumanDescription des)
{
if (target != null)
{
var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(target));
if (importer != null)
{
Debug.Log("AssetImporter Type: " + importer.GetType());
ModelImporter modelImporter = importer as ModelImporter;
if (modelImporter != null)
{
des = modelImporter.humanDescription;
Debug.Log("## Cool stuff data by ModelImporter ##");
return true;
}
else
{
Debug.LogWarning("## Please Select Imported Model in Project View not prefab or other things ##");
}
}
}
return false;
}
#endif
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 976e99d37c093ce4c9b249c81c2cbdd5
timeCreated: 1520401720
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,28 @@
using UnityEngine;
namespace UniHumanoid
{
public class BoneGizmoDrawer : MonoBehaviour
{
const float size = 0.03f;
readonly Vector3 SIZE = new Vector3(size, size, size);
[SerializeField]
public bool Draw = true;
void OnDrawGizmos()
{
#if UNITY_EDITOR
if (Draw && transform.parent != null)
{
Gizmos.color = Color.yellow;
Gizmos.DrawCube(transform.position, SIZE);
Gizmos.DrawLine(transform.parent.position, transform.position);
UnityEditor.Handles.Label(transform.position, name);
}
#endif
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 677492d2843780e40aa2a6c7a6ae8fe6
timeCreated: 1517332124
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,103 @@
using UnityEngine;
using System.Linq;
using System;
namespace UniHumanoid
{
public class BoneMapping : MonoBehaviour
{
[SerializeField]
public GameObject[] Bones = new GameObject[(int)HumanBodyBones.LastBone];
[SerializeField]
public AvatarDescription Description;
private void Reset()
{
GetBones();
}
private void GetBones()
{
Bones = new GameObject[(int)HumanBodyBones.LastBone];
var animator = GetComponent<Animator>();
if (animator != null)
{
if (animator.avatar != null)
{
foreach (HumanBodyBones key in Enum.GetValues(typeof(HumanBodyBones)))
{
if (key == HumanBodyBones.LastBone)
{
break;
}
var transform = animator.GetBoneTransform(key);
if (transform != null)
{
Bones[(int)key] = transform.gameObject;
}
}
}
}
}
public void GuessBoneMapping()
{
var hips = Bones[(int)HumanBodyBones.Hips];
if (hips == null)
{
Debug.LogWarning("require hips");
return;
}
var estimater = new BvhSkeletonEstimator();
var skeleton = estimater.Detect(hips.transform);
var bones = hips.transform.Traverse().ToArray();
for (int i = 0; i < (int)HumanBodyBones.LastBone; ++i)
{
var index = skeleton.GetBoneIndex((HumanBodyBones)i);
if (index >= 0)
{
Bones[i] = bones[index].gameObject;
}
}
}
public void EnsureTPose()
{
var map = Bones
.Select((x, i) => new { i, x })
.Where(x => x.x != null)
.ToDictionary(x => (HumanBodyBones)x.i, x => x.x.transform)
;
{
var left = (map[HumanBodyBones.LeftLowerArm].position - map[HumanBodyBones.LeftUpperArm].position).normalized;
map[HumanBodyBones.LeftUpperArm].rotation = Quaternion.FromToRotation(left, Vector3.left) * map[HumanBodyBones.LeftUpperArm].rotation;
}
{
var right = (map[HumanBodyBones.RightLowerArm].position - map[HumanBodyBones.RightUpperArm].position).normalized;
map[HumanBodyBones.RightUpperArm].rotation = Quaternion.FromToRotation(right, Vector3.right) * map[HumanBodyBones.RightUpperArm].rotation;
}
}
public static void SetBonesToDescription(BoneMapping mapping, AvatarDescription description)
{
var map = mapping.Bones
.Select((x, i) => new { i, x })
.Where(x => x.x != null)
.ToDictionary(x => (HumanBodyBones)x.i, x => x.x.transform)
;
description.SetHumanBones(map);
}
private void Awake()
{
if (Bones == null
|| Bones.All(x => x==null))
{
GetBones();
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 44f5895a2095a2848ba2c9627a5c1ad9
timeCreated: 1516520420
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public class BvhBone : IBone
{
public string Name
{
private set;
get;
}
public Vector3 SkeletonLocalPosition
{
private set;
get;
}
public BvhBone(string name, Vector3 position)
{
Name = name;
SkeletonLocalPosition = position;
}
public override string ToString()
{
return string.Format("<BvhBone: {0}>", Name);
}
public IBone Parent
{
private set;
get;
}
List<IBone> _children = new List<IBone>();
public IList<IBone> Children
{
get { return _children; }
}
public void Build(Transform t)
{
foreach (Transform child in t)
{
var childBone = new BvhBone(child.name, SkeletonLocalPosition + child.localPosition);
childBone.Parent = this;
_children.Add(childBone);
childBone.Build(child);
}
}
public void Build(BvhNode node)
{
foreach (var child in node.Children)
{
var childBone = new BvhBone(child.Name, SkeletonLocalPosition + child.Offset.ToXReversedVector3());
childBone.Parent = this;
_children.Add(childBone);
childBone.Build(child);
}
}
public IEnumerable<BvhBone> Traverse()
{
yield return this;
foreach (var child in Children)
{
foreach (var x in child.Traverse())
{
yield return (BvhBone)x;
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c1a88b26726f137419428078debd253f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6dfa46c173ff021418df4bada32ddfe9
folderAsset: yes
timeCreated: 1517655448
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,419 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace UniHumanoid
{
[CustomEditor(typeof(BoneMapping))]
public class BoneMappingEditor : Editor
{
BoneMapping m_target;
void OnEnable()
{
m_target = (BoneMapping)target;
var animator = m_target.GetComponent<Animator>();
if (animator != null)
{
m_bones = EachBoneDefs.Select(x => new Bone(
animator.GetBoneTransform(x.Head), animator.GetBoneTransform(x.Tail)))
.Where(x => x.Head != null && x.Tail != null)
.ToArray();
}
}
static GameObject ObjectField(GameObject obj)
{
return (GameObject)EditorGUILayout.ObjectField(obj, typeof(GameObject), true);
}
static GameObject ObjectField(string label, GameObject obj)
{
return (GameObject)EditorGUILayout.ObjectField(label, obj, typeof(GameObject), true);
}
const int LABEL_WIDTH = 100;
static void BoneField(HumanBodyBones bone, GameObject[] bones)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(bone.ToString(), GUILayout.Width(LABEL_WIDTH));
bones[(int)bone] = ObjectField(bones[(int)bone]);
EditorGUILayout.EndHorizontal();
}
static void BoneField(HumanBodyBones left, HumanBodyBones right, GameObject[] bones)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(left.ToString().Substring(4), GUILayout.Width(LABEL_WIDTH)); // skip left
bones[(int)left] = ObjectField(bones[(int)left]);
bones[(int)right] = ObjectField(bones[(int)right]);
EditorGUILayout.EndHorizontal();
}
bool m_handFoldout;
bool m_settingsFoldout;
public override void OnInspectorGUI()
{
var bones = m_target.Bones;
if (bones == null)
{
return;
}
BoneField(HumanBodyBones.Hips, bones);
if (bones[(int)HumanBodyBones.Hips] == null)
{
EditorGUILayout.HelpBox(@"First, you set hips", MessageType.Warning);
}
else
{
if (GUILayout.Button("Guess bone mapping"))
{
m_target.GuessBoneMapping();
}
EditorGUILayout.HelpBox(@"Guess bones from hips", MessageType.Info);
if (GUILayout.Button("Ensure T-Pose"))
{
m_target.EnsureTPose();
}
EditorGUILayout.HelpBox(@"Arms to Horizontal", MessageType.Info);
if (GUILayout.Button("Create avatar"))
{
var description = AvatarDescription.Create(m_target.Description);
BoneMapping.SetBonesToDescription(m_target, description);
var avatar = description.CreateAvatarAndSetup(m_target.transform);
if (avatar != null)
{
avatar.name = "avatar";
#if UNITY_2018_2_OR_NEWER
var prefabRoot = PrefabUtility.GetCorrespondingObjectFromSource(m_target.gameObject);
#else
var prefabRoot = PrefabUtility.GetPrefabParent(m_target.gameObject);
#endif
var prefabPath = AssetDatabase.GetAssetPath(prefabRoot);
var path = (string.IsNullOrEmpty(prefabPath))
? string.Format("Assets/{0}.asset", avatar.name)
: string.Format("{0}/{1}.asset", Path.GetDirectoryName(prefabPath), Path.GetFileNameWithoutExtension(prefabPath))
;
path = EditorUtility.SaveFilePanel(
"Save avatar",
Path.GetDirectoryName(path),
string.Format("{0}.avatar.asset", serializedObject.targetObject.name),
"asset");
var assetPath = HumanPoseTransferEditor.ToAssetPath(path);
if (!string.IsNullOrEmpty(assetPath))
{
AssetDatabase.CreateAsset(description, assetPath); // overwrite
AssetDatabase.AddObjectToAsset(avatar, assetPath);
Debug.LogFormat("Create avatar {0}", path);
AssetDatabase.ImportAsset(assetPath);
Selection.activeObject = avatar;
}
else
{
Debug.LogWarning("fail to CreateAvatar");
}
}
}
EditorGUILayout.HelpBox(@"before create,
1. Model root transform should reset(origin without rotation)
2. Model forward to Z+(rotate child of model root)
3. Required bones filled
", MessageType.Info);
}
/*
m_settingsFoldout = EditorGUILayout.Foldout(m_settingsFoldout, "AvatarSettings");
if (m_settingsFoldout)
{
EditorGUILayout.FloatField("armStretch", m_target.armStretch);
EditorGUILayout.FloatField("legStretch", m_target.legStretch);
EditorGUILayout.FloatField("upperArmTwist", m_target.upperArmTwist);
EditorGUILayout.FloatField("lowerArmTwist", m_target.lowerArmTwist);
EditorGUILayout.FloatField("upperLegTwist", m_target.upperLegTwist);
EditorGUILayout.FloatField("lowerLegTwist", m_target.lowerLegTwist);
EditorGUILayout.FloatField("feetSpacing", m_target.feetSpacing);
EditorGUILayout.Toggle("hasTranslationDoF", m_target.hasTranslationDoF);
//public BoneLimit[] human;
}
*/
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Arm", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftShoulder, HumanBodyBones.RightShoulder, bones);
BoneField(HumanBodyBones.LeftUpperArm, HumanBodyBones.RightUpperArm, bones);
BoneField(HumanBodyBones.LeftLowerArm, HumanBodyBones.RightLowerArm, bones);
BoneField(HumanBodyBones.LeftHand, HumanBodyBones.RightHand, bones);
EditorGUILayout.LabelField("Body and Head", EditorStyles.boldLabel);
BoneField(HumanBodyBones.Spine, bones);
BoneField(HumanBodyBones.Chest, bones);
#if UNITY_5_6_OR_NEWER
BoneField(HumanBodyBones.UpperChest, bones);
#endif
BoneField(HumanBodyBones.Neck, bones);
BoneField(HumanBodyBones.Head, bones);
BoneField(HumanBodyBones.Jaw, bones);
BoneField(HumanBodyBones.LeftEye, HumanBodyBones.RightEye, bones);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Leg", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftUpperLeg, HumanBodyBones.RightUpperLeg, bones);
BoneField(HumanBodyBones.LeftLowerLeg, HumanBodyBones.RightLowerLeg, bones);
BoneField(HumanBodyBones.LeftFoot, HumanBodyBones.RightFoot, bones);
BoneField(HumanBodyBones.LeftToes, HumanBodyBones.RightToes, bones);
m_handFoldout = EditorGUILayout.Foldout(m_handFoldout, "Hand");
if (m_handFoldout)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Thumb", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftThumbProximal, HumanBodyBones.RightThumbProximal, bones);
BoneField(HumanBodyBones.LeftThumbIntermediate, HumanBodyBones.RightThumbIntermediate, bones);
BoneField(HumanBodyBones.LeftThumbDistal, HumanBodyBones.RightThumbDistal, bones);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Index", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftIndexProximal, HumanBodyBones.RightIndexProximal, bones);
BoneField(HumanBodyBones.LeftIndexIntermediate, HumanBodyBones.RightIndexIntermediate, bones);
BoneField(HumanBodyBones.LeftIndexDistal, HumanBodyBones.RightIndexDistal, bones);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Middle", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftMiddleProximal, HumanBodyBones.RightMiddleProximal, bones);
BoneField(HumanBodyBones.LeftMiddleIntermediate, HumanBodyBones.RightMiddleIntermediate, bones);
BoneField(HumanBodyBones.LeftMiddleDistal, HumanBodyBones.RightMiddleDistal, bones);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Ring", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftRingProximal, HumanBodyBones.RightRingProximal, bones);
BoneField(HumanBodyBones.LeftRingIntermediate, HumanBodyBones.RightRingIntermediate, bones);
BoneField(HumanBodyBones.LeftRingDistal, HumanBodyBones.RightRingDistal, bones);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Little", EditorStyles.boldLabel, GUILayout.Width(LABEL_WIDTH));
EditorGUILayout.LabelField("Left", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Right", EditorStyles.boldLabel, GUILayout.Width(40));
EditorGUILayout.EndHorizontal();
BoneField(HumanBodyBones.LeftLittleProximal, HumanBodyBones.RightLittleProximal, bones);
BoneField(HumanBodyBones.LeftLittleIntermediate, HumanBodyBones.RightLittleIntermediate, bones);
BoneField(HumanBodyBones.LeftLittleDistal, HumanBodyBones.RightLittleDistal, bones);
}
EditorUtility.SetDirty(m_target);
}
struct Bone
{
public Transform Head;
public Transform Tail;
public Bone(Transform head, Transform tail)
{
Head = head;
Tail = tail;
}
public void Draw()
{
Handles.DrawLine(Head.transform.position, Tail.transform.position);
}
}
Bone[] m_bones;
struct BoneDef
{
public HumanBodyBones Head;
public HumanBodyBones Tail;
public BoneDef(HumanBodyBones head, HumanBodyBones tail)
{
Head = head;
Tail = tail;
}
}
static readonly HumanBodyBones[][] BoneDefs =
{
new HumanBodyBones[]
{
HumanBodyBones.Hips,
HumanBodyBones.Spine,
HumanBodyBones.Chest,
HumanBodyBones.Neck,
HumanBodyBones.Head,
},
new HumanBodyBones[]
{
HumanBodyBones.Chest,
HumanBodyBones.LeftShoulder,
HumanBodyBones.LeftUpperArm,
HumanBodyBones.LeftLowerArm,
HumanBodyBones.LeftHand,
},
new HumanBodyBones[]
{
HumanBodyBones.Chest,
HumanBodyBones.RightShoulder,
HumanBodyBones.RightUpperArm,
HumanBodyBones.RightLowerArm,
HumanBodyBones.RightHand,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftThumbProximal,
HumanBodyBones.LeftThumbIntermediate,
HumanBodyBones.LeftThumbDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftIndexProximal,
HumanBodyBones.LeftIndexIntermediate,
HumanBodyBones.LeftIndexDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftMiddleProximal,
HumanBodyBones.LeftMiddleIntermediate,
HumanBodyBones.LeftMiddleDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftRingProximal,
HumanBodyBones.LeftRingIntermediate,
HumanBodyBones.LeftRingDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftLittleProximal,
HumanBodyBones.LeftLittleIntermediate,
HumanBodyBones.LeftLittleDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.RightThumbProximal,
HumanBodyBones.RightThumbIntermediate,
HumanBodyBones.RightThumbDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.RightIndexProximal,
HumanBodyBones.RightIndexIntermediate,
HumanBodyBones.RightIndexDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.RightMiddleProximal,
HumanBodyBones.RightMiddleIntermediate,
HumanBodyBones.RightMiddleDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.RightRingProximal,
HumanBodyBones.RightRingIntermediate,
HumanBodyBones.RightRingDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.RightLittleProximal,
HumanBodyBones.RightLittleIntermediate,
HumanBodyBones.RightLittleDistal,
},
new HumanBodyBones[]
{
HumanBodyBones.LeftUpperLeg,
HumanBodyBones.LeftLowerLeg,
HumanBodyBones.LeftFoot,
},
new HumanBodyBones[]
{
HumanBodyBones.RightUpperLeg,
HumanBodyBones.RightLowerLeg,
HumanBodyBones.RightFoot,
},
};
static IEnumerable<BoneDef> EachBoneDefs
{
get
{
foreach (var x in BoneDefs)
{
var count = x.Length - 1;
for (int i = 0; i < count; ++i)
{
yield return new BoneDef(x[i], x[i + 1]);
}
}
}
}
void DrawBone(HumanBodyBones bone, GameObject go)
{
if (go == null)
{
return;
}
Handles.Label(go.transform.position,
go.name + "\n(" + bone.ToString() + ")");
}
private void OnSceneGUI()
{
var bones = m_target.Bones;
if (bones != null)
{
for (int i = 0; i < bones.Length; ++i)
{
DrawBone((HumanBodyBones)i, bones[i]);
}
foreach(var x in m_bones)
{
x.Draw();
}
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 06b3418a97f8c204da34a849fa86a7c0
timeCreated: 1516520481
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,151 @@
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UniHumanoid
{
[CustomEditor(typeof(HumanPoseTransfer))]
public class HumanPoseTransferEditor : Editor
{
//HumanPoseTransfer m_target;
SerializedProperty m_avatarProp;
SerializedProperty m_typeProp;
SerializedProperty m_clipProp;
SerializedProperty m_transferProp;
static string[] SOURCE_TYPES = ((HumanPoseTransfer.HumanPoseTransferSourceType[])
Enum.GetValues(typeof(HumanPoseTransfer.HumanPoseTransferSourceType)))
.Select(x => x.ToString())
.ToArray();
private void OnEnable()
{
//m_target = (HumanPoseTransfer)target;
m_typeProp = serializedObject.FindProperty("SourceType");
m_clipProp = serializedObject.FindProperty("PoseClip");
m_avatarProp = serializedObject.FindProperty("Avatar");
m_transferProp = serializedObject.FindProperty("Source");
}
public override void OnInspectorGUI()
{
//base.OnInspectorGUI();
serializedObject.Update();
EditorGUILayout.PropertyField(m_avatarProp);
/*
m_typeProp.intValue =
GUILayout.Toolbar(m_typeProp.intValue, SOURCE_TYPES);
*/
m_typeProp.intValue =
EditorGUILayout.Popup("SourceType", m_typeProp.intValue, SOURCE_TYPES);
switch ((HumanPoseTransfer.HumanPoseTransferSourceType)m_typeProp.intValue)
{
case HumanPoseTransfer.HumanPoseTransferSourceType.None:
serializedObject.ApplyModifiedProperties();
break;
case HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseClip:
PoseClipInspector();
break;
case HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer:
PoseHandler();
break;
}
GUILayout.Space(20);
// CreatePose
if (GUILayout.Button("Pose to HumanPoseClip"))
{
var path = EditorUtility.SaveFilePanel(
"Save humanpose",
Application.dataPath,
string.Format("{0}.pose.asset", serializedObject.targetObject.name),
"asset");
var assetPath = ToAssetPath(path);
if (!string.IsNullOrEmpty(path))
{
var pose = ((HumanPoseTransfer)serializedObject.targetObject).CreatePose();
var clip = ScriptableObject.CreateInstance<HumanPoseClip>();
clip.ApplyPose(ref pose);
AssetDatabase.CreateAsset(clip, assetPath);
Selection.activeObject = clip;
}
}
// CreatePose
if (GUILayout.Button("Pose to AnimationClip"))
{
var path = EditorUtility.SaveFilePanel(
"Save animnationClip",
Application.dataPath,
string.Format("{0}.pose.anim", serializedObject.targetObject.name),
"anim");
var assetPath = ToAssetPath(path);
if (!string.IsNullOrEmpty(path))
{
var pose = ((HumanPoseTransfer)serializedObject.targetObject).CreatePose();
var clip = AnimationClipUtility.CreateAnimationClipFromHumanPose(pose);
AssetDatabase.CreateAsset(clip, assetPath);
Selection.activeObject = clip;
}
}
}
public static string ToAssetPath(string src)
{
src = src.Replace("\\", "/");
var basePath = Path.GetFullPath(Application.dataPath + "/..").Replace("\\", "/");
if (!src.StartsWith(basePath))
{
return null;
}
return src.Substring(basePath.Length + 1);
}
void PoseClipInspector()
{
var old = (HumanPoseClip)m_clipProp.objectReferenceValue;
EditorGUILayout.PropertyField(m_clipProp);
serializedObject.ApplyModifiedProperties();
var _target = (HumanPoseTransfer)target;
if (_target.PoseClip != old)
{
//Debug.Log("clip != old");
if (_target.PoseClip != null)
{
var pose = _target.PoseClip.GetPose();
_target.SetPose(pose);
}
}
#if false
if (_target.PoseClip != null)
{
if (GUILayout.Button("Apply PoseClip"))
{
Debug.Log("apply");
var pose = default(HumanPose);
_target.PoseClip.GetPose(out pose);
_target.SetPose(pose);
}
}
#endif
}
void PoseHandler()
{
EditorGUILayout.PropertyField(m_transferProp);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: d51cc8ca343beb647bc6d8e23600dd66
timeCreated: 1519366120
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,352 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace UniHumanoid
{
class BoneNode : IEnumerable<BoneNode>
{
public HumanBodyBones Bone { get; private set; }
public List<BoneNode> Children = new List<BoneNode>();
public int[] Muscles;
public BoneNode(HumanBodyBones bone, params int[] muscles)
{
Bone = bone;
Muscles = muscles;
}
public IEnumerator<BoneNode> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
public void Add(BoneNode child)
{
Children.Add(child);
}
}
class BoneTreeViewItem : TreeViewItem
{
//HumanBodyBones m_bone;
public BoneTreeViewItem(int id, int depth, HumanBodyBones bone) : base(id, depth, bone.ToString())
{
//m_bone = bone;
}
}
class MuscleTreeViewItem : TreeViewItem
{
public int Muscle
{
get;
private set;
}
public MuscleTreeViewItem(int id, int depth, int muscle) : base(id, depth, HumanTrait.MuscleName[muscle])
{
Muscle = muscle;
}
}
class BoneTreeView : TreeView
{
static BoneNode Skeleton = new BoneNode(HumanBodyBones.Hips)
{
new BoneNode(HumanBodyBones.Spine, 0, 1, 2){
new BoneNode(HumanBodyBones.Chest, 3, 4, 5){
new BoneNode(HumanBodyBones.UpperChest, 6, 7, 8){
new BoneNode(HumanBodyBones.Neck, 9, 10, 11){
new BoneNode(HumanBodyBones.Head, 12, 13, 14){
new BoneNode(HumanBodyBones.LeftEye, 15, 16),
new BoneNode(HumanBodyBones.RightEye, 17, 18)
}
},
new BoneNode(HumanBodyBones.LeftShoulder, 37, 38){
new BoneNode(HumanBodyBones.LeftUpperArm, 39, 40, 41){
new BoneNode(HumanBodyBones.LeftLowerArm, 42, 43){
new BoneNode(HumanBodyBones.LeftHand, 44, 45)
}
}
},
new BoneNode(HumanBodyBones.RightShoulder, 46, 47){
new BoneNode(HumanBodyBones.RightUpperArm, 48, 49, 50){
new BoneNode(HumanBodyBones.RightLowerArm, 51, 52){
new BoneNode(HumanBodyBones.RightHand, 53, 54)
}
}
}
}
}
},
new BoneNode(HumanBodyBones.LeftUpperLeg, 21, 22, 23){
new BoneNode(HumanBodyBones.LeftLowerLeg, 24, 25){
new BoneNode(HumanBodyBones.LeftFoot, 26, 27){
new BoneNode(HumanBodyBones.LeftToes, 28)
}
}
},
new BoneNode(HumanBodyBones.RightUpperLeg, 29, 30, 31){
new BoneNode(HumanBodyBones.RightLowerLeg, 32, 33){
new BoneNode(HumanBodyBones.RightFoot, 34, 35){
new BoneNode(HumanBodyBones.RightToes, 36)
}
}
}
};
//Animator m_animator;
HumanPoseHandler m_handler;
HumanPose m_pose;
bool m_updated;
public void Begin()
{
m_handler.GetHumanPose(ref m_pose);
}
public void End()
{
if (m_updated)
{
m_handler.SetHumanPose(ref m_pose);
}
m_updated = false;
}
public BoneTreeView(TreeViewState treeViewState, MultiColumnHeader header, HumanPoseHandler handler)
: base(treeViewState, header)
{
m_handler = handler;
Reload();
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem { id = 0, depth = -1 };
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
{
var rows = GetRows() ?? new List<TreeViewItem>(200);
// We use the GameObject instanceIDs as ids for items as we want to
// select the game objects and not the transform components.
rows.Clear();
var item = CreateTreeViewItemForBone(HumanBodyBones.Hips);
root.AddChild(item);
rows.Add(item);
if (IsExpanded(item.id))
{
AddChildrenRecursive(Skeleton, item, rows);
}
else
{
item.children = CreateChildListForCollapsedParent();
}
SetupDepthsFromParentsAndChildren(root);
return rows;
}
void AddChildrenRecursive(BoneNode bone, TreeViewItem item, IList<TreeViewItem> rows)
{
int childCount = bone.Children.Count;
item.children = new List<TreeViewItem>(childCount);
if (bone.Muscles != null)
{
foreach (var muscle in bone.Muscles)
{
var childItem = new MuscleTreeViewItem(muscle + 20000, -1, muscle);
item.AddChild(childItem);
rows.Add(childItem);
}
}
foreach (var child in bone.Children)
{
var childItem = CreateTreeViewItemForBone(child.Bone);
item.AddChild(childItem);
rows.Add(childItem);
//if (child.Children.Count > 0)
{
if (IsExpanded(childItem.id))
{
AddChildrenRecursive(child, childItem, rows);
}
else
{
childItem.children = CreateChildListForCollapsedParent();
}
}
}
}
static TreeViewItem CreateTreeViewItemForBone(HumanBodyBones bone)
{
return new TreeViewItem((int)bone, -1, Enum.GetName(typeof(HumanBodyBones), bone));
}
protected override void RowGUI(RowGUIArgs args)
{
for (int i = 0; i < args.GetNumVisibleColumns(); ++i)
{
CellGUI(args.GetCellRect(i), args.GetColumn(i), ref args);
}
}
void CellGUI(Rect cellRect, int index, ref RowGUIArgs args)
{
// Center cell rect vertically (makes it easier to place controls, icons etc in the cells)
CenterRectUsingSingleLineHeight(ref cellRect);
switch (index)
{
case 0:
{
// Default icon and label
args.rowRect = cellRect;
base.RowGUI(args);
}
break;
case 1:
{
var muscleItem = args.item as MuscleTreeViewItem;
if (muscleItem != null)
{
var muscleIndex = muscleItem.Muscle;
var muscles = m_pose.muscles;
var value = EditorGUI.Slider(cellRect, GUIContent.none, muscles[muscleIndex], -1f, 1f);
if (value != muscles[muscleIndex])
{
muscles[muscleIndex] = value;
m_updated = true;
}
}
else
{
}
}
break;
}
}
public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState()
{
var columns = new[]
{
new MultiColumnHeaderState.Column
{
headerContent = new GUIContent("Name"),
headerTextAlignment = TextAlignment.Left,
width = 250,
minWidth = 60,
autoResize = false,
allowToggleVisibility = false
},
new MultiColumnHeaderState.Column
{
headerContent = new GUIContent("Muscle value"),
headerTextAlignment = TextAlignment.Left,
width = 110,
minWidth = 60,
autoResize = true
},
};
return new MultiColumnHeaderState(columns);
}
}
[CustomEditor(typeof(MuscleInspector))]
public class MuscleInspectorEditor : Editor
{
[NonSerialized] bool m_Initialized;
[SerializeField] TreeViewState m_TreeViewState; // Serialized in the window layout file so it survives assembly reloading
//[SerializeField] MultiColumnHeaderState m_MultiColumnHeaderState;
SearchField m_SearchField;
BoneTreeView m_TreeView;
MuscleInspector m_target;
HumanPoseHandler m_handler;
MultiColumnHeader GetHeaderState()
{
//bool firstInit = m_MultiColumnHeaderState == null;
var headerState = BoneTreeView.CreateDefaultMultiColumnHeaderState();
/*
if (MultiColumnHeaderState.CanOverwriteSerializedFields(m_MultiColumnHeaderState, headerState))
{
MultiColumnHeaderState.OverwriteSerializedFields(m_MultiColumnHeaderState, headerState);
}
m_MultiColumnHeaderState = headerState;
*/
var multiColumnHeader = new MultiColumnHeader(headerState);
multiColumnHeader.ResizeToFit();
return multiColumnHeader;
}
void OnEnable()
{
var mi = this.target as MuscleInspector;
var animator = mi.GetComponent<Animator>();
if (animator != null
&& animator.avatar != null
&& animator.avatar.isValid
&& animator.avatar.isHuman
)
{
Debug.LogFormat("MuscleInspectorEditor.OnEnable");
m_handler = new HumanPoseHandler(animator.avatar, animator.transform);
m_TreeView = new BoneTreeView(new TreeViewState(), GetHeaderState(), m_handler);
}
}
void OnDisable()
{
if (m_handler != null)
{
m_handler.Dispose();
m_handler = null;
}
}
public override void OnInspectorGUI()
{
if (m_TreeView == null)
{
EditorGUILayout.HelpBox("Animator required", MessageType.Error);
return;
}
var rect = GUILayoutUtility.GetRect(0, 10000, 0, m_TreeView.totalHeight);
m_TreeView.Begin();
m_TreeView.OnGUI(rect);
m_TreeView.End();
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0d2c3401d1adf41488c19ec4d47386a0
timeCreated: 1541840728
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fcdf450ca966f85428c238046e51c2ca
folderAsset: yes
timeCreated: 1534750149
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 568764cb60017fc44ad4361d5a18b478
timeCreated: 1534750164
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace UniHumanoid
{
public class bvhAssetPostprocessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (string path in importedAssets)
{
var ext = Path.GetExtension(path).ToLower();
if (ext == ".bvh")
{
Debug.LogFormat("ImportBvh: {0}", path);
var context = new BvhImporterContext();
try
{
context.Parse(path);
context.Load();
context.SaveAsAsset();
context.Destroy(false);
}
catch(Exception ex)
{
Debug.LogError(ex);
context.Destroy(true);
}
}
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4283558adf39c194cb6c5d66d5a348de
timeCreated: 1517166107
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fc31477377367fb48bc85f0864fe33eb
folderAsset: yes
timeCreated: 1517655048
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,444 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace UniHumanoid
{
public class BvhException : Exception
{
public BvhException(string msg) : base(msg) { }
}
public enum Channel
{
Xposition,
Yposition,
Zposition,
Xrotation,
Yrotation,
Zrotation,
}
public static class ChannelExtensions
{
public static string ToProperty(this Channel ch)
{
switch (ch)
{
case Channel.Xposition: return "localPosition.x";
case Channel.Yposition: return "localPosition.y";
case Channel.Zposition: return "localPosition.z";
case Channel.Xrotation: return "localEulerAnglesBaked.x";
case Channel.Yrotation: return "localEulerAnglesBaked.y";
case Channel.Zrotation: return "localEulerAnglesBaked.z";
}
throw new BvhException("no property for " + ch);
}
public static bool IsLocation(this Channel ch)
{
switch (ch)
{
case Channel.Xposition:
case Channel.Yposition:
case Channel.Zposition: return true;
case Channel.Xrotation:
case Channel.Yrotation:
case Channel.Zrotation: return false;
}
throw new BvhException("no property for " + ch);
}
}
public struct Single3
{
public Single x;
public Single y;
public Single z;
public Single3(Single _x, Single _y, Single _z)
{
x = _x;
y = _y;
z = _z;
}
}
public class BvhNode
{
public String Name
{
get;
private set;
}
public Single3 Offset
{
get;
private set;
}
public Channel[] Channels
{
get;
private set;
}
public List<BvhNode> Children
{
get;
private set;
}
public BvhNode(string name)
{
Name = name;
Children = new List<BvhNode>();
}
public virtual void Parse(StringReader r)
{
Offset = ParseOffset(r.ReadLine());
Channels = ParseChannel(r.ReadLine());
}
static Single3 ParseOffset(string line)
{
var splited = line.Trim().Split();
if (splited[0] != "OFFSET")
{
throw new BvhException("OFFSET is not found");
}
var offset = splited.Skip(1).Where(x => !string.IsNullOrEmpty(x)).Select(x => float.Parse(x)).ToArray();
return new Single3(offset[0], offset[1], offset[2]);
}
static Channel[] ParseChannel(string line)
{
var splited = line.Trim().Split();
if (splited[0] != "CHANNELS")
{
throw new BvhException("CHANNELS is not found");
}
var count = int.Parse(splited[1]);
if (count + 2 != splited.Length)
{
throw new BvhException("channel count is not match with splited count");
}
return splited.Skip(2).Select(x => (Channel)Enum.Parse(typeof(Channel), x)).ToArray();
}
public IEnumerable<BvhNode> Traverse()
{
yield return this;
foreach (var child in Children)
{
foreach (var descentant in child.Traverse())
{
yield return descentant;
}
}
}
}
public class EndSite : BvhNode
{
public EndSite(): base("")
{
}
public override void Parse(StringReader r)
{
r.ReadLine(); // offset
}
}
public class ChannelCurve
{
public float[] Keys
{
get;
private set;
}
public ChannelCurve(int frameCount)
{
Keys = new float[frameCount];
}
public void SetKey(int frame, float value)
{
Keys[frame] = value;
}
}
public class Bvh
{
public BvhNode Root
{
get;
private set;
}
public TimeSpan FrameTime
{
get;
private set;
}
public ChannelCurve[] Channels
{
get;
private set;
}
int m_frames;
public int FrameCount
{
get { return m_frames; }
}
public struct PathWithProperty
{
public string Path;
public string Property;
public bool IsLocation;
}
public bool TryGetPathWithPropertyFromChannel(ChannelCurve channel, out PathWithProperty pathWithProp)
{
var index = Channels.ToList().IndexOf(channel);
if (index == -1)
{
pathWithProp = default(PathWithProperty);
return false;
}
foreach(var node in Root.Traverse())
{
for(int i=0; i<node.Channels.Length; ++i, --index)
{
if (index == 0)
{
pathWithProp = new PathWithProperty
{
Path=GetPath(node),
Property=node.Channels[i].ToProperty(),
IsLocation=node.Channels[i].IsLocation(),
};
return true;
}
}
}
throw new BvhException("channel is not found");
}
public string GetPath(BvhNode node)
{
var list = new List<string>() { node.Name };
var current = node;
while (current!=null)
{
current = GetParent(current);
if (current != null)
{
list.Insert(0, current.Name);
}
}
return String.Join("/", list.ToArray());
}
BvhNode GetParent(BvhNode node)
{
foreach(var x in Root.Traverse())
{
if (x.Children.Contains(node))
{
return x;
}
}
return null;
}
public ChannelCurve GetChannel(BvhNode target, Channel channel)
{
var index = 0;
foreach (var node in Root.Traverse())
{
for (int i = 0; i < node.Channels.Length; ++i, ++index)
{
if(node==target && node.Channels[i] == channel)
{
return Channels[index];
}
}
}
throw new BvhException("channel is not found");
}
public override string ToString()
{
return string.Format("{0}nodes, {1}channels, {2}frames, {3:0.00}seconds"
, Root.Traverse().Count()
, Channels.Length
, m_frames
, m_frames * FrameTime.TotalSeconds);
}
public Bvh(BvhNode root, int frames, float seconds)
{
Root = root;
FrameTime = TimeSpan.FromSeconds(seconds);
m_frames = frames;
var channelCount = Root.Traverse()
.Where(x => x.Channels!=null)
.Select(x => x.Channels.Length)
.Sum();
Channels = Enumerable.Range(0, channelCount)
.Select(x => new ChannelCurve(frames))
.ToArray()
;
}
public void ParseFrame(int frame, string line)
{
var splited = line.Trim().Split().Where(x => !string.IsNullOrEmpty(x)).ToArray();
if (splited.Length != Channels.Length)
{
throw new BvhException("frame key count is not match channel count");
}
for(int i=0; i<Channels.Length; ++i)
{
Channels[i].SetKey(frame, float.Parse(splited[i]));
}
}
public static Bvh Parse(string src)
{
using (var r = new StringReader(src))
{
if (r.ReadLine() != "HIERARCHY")
{
throw new BvhException("not start with HIERARCHY");
}
var root = ParseNode(r);
if (root == null)
{
return null;
}
var frames = 0;
var frameTime = 0.0f;
if (r.ReadLine() == "MOTION")
{
var frameSplited = r.ReadLine().Split(':');
if (frameSplited[0] != "Frames")
{
throw new BvhException("Frames is not found");
}
frames = int.Parse(frameSplited[1]);
var frameTimeSplited = r.ReadLine().Split(':');
if (frameTimeSplited[0] != "Frame Time")
{
throw new BvhException("Frame Time is not found");
}
frameTime = float.Parse(frameTimeSplited[1]);
}
var bvh = new Bvh(root, frames, frameTime);
for(int i=0; i<frames; ++i)
{
var line = r.ReadLine();
bvh.ParseFrame(i, line);
}
return bvh;
}
}
static BvhNode ParseNode(StringReader r, int level = 0)
{
var firstline = r.ReadLine().Trim();
var splited = firstline.Split();
if (splited.Length != 2)
{
if (splited.Length == 1)
{
if(splited[0] == "}")
{
return null;
}
}
throw new BvhException(String.Format("splited to {0}({1})", splited.Length, firstline));
}
BvhNode node = null;
if (splited[0] == "ROOT")
{
if (level != 0)
{
throw new BvhException("nested ROOT");
}
node = new BvhNode(splited[1]);
}
else if (splited[0] == "JOINT")
{
if (level == 0)
{
throw new BvhException("should ROOT, but JOINT");
}
node = new BvhNode(splited[1]);
}
else if (splited[0] == "End")
{
if (level == 0)
{
throw new BvhException("End in level 0");
}
node = new EndSite();
}
else
{
throw new BvhException("unknown type: " + splited[0]);
}
if(r.ReadLine().Trim() != "{")
{
throw new BvhException("'{' is not found");
}
node.Parse(r);
// child nodes
while (true)
{
var child = ParseNode(r, level + 1);
if (child == null)
{
break;
}
if(!(child is EndSite))
{
node.Children.Add(child);
}
}
return node;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2e7bf08c7b7056e4ea1f50b1e008cb7e
timeCreated: 1517166478
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,33 @@
using UnityEngine;
namespace UniHumanoid
{
public class HumanPoseClip : ScriptableObject
{
public const string TPoseResourcePath = "T-Pose.pose";
public Vector3 bodyPosition;
public Quaternion bodyRotation;
public float[] muscles;
public HumanPose GetPose()
{
return new HumanPose
{
bodyPosition = bodyPosition,
bodyRotation = bodyRotation,
muscles = muscles
};
}
public void ApplyPose(ref HumanPose pose)
{
bodyPosition = pose.bodyPosition;
bodyRotation = pose.bodyRotation;
muscles = (float[])pose.muscles.Clone();
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 4fdf4ef744a103a4ca01657c00d7fec2
timeCreated: 1517760105
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,143 @@
using UnityEngine;
namespace UniHumanoid
{
public class HumanPoseTransfer : MonoBehaviour
{
public enum HumanPoseTransferSourceType
{
None,
HumanPoseTransfer,
HumanPoseClip,
}
[SerializeField]
public HumanPoseTransferSourceType SourceType;
[SerializeField]
public Avatar Avatar;
#region Standalone
public HumanPose CreatePose()
{
var handler = new HumanPoseHandler(Avatar, transform);
var pose = default(HumanPose);
handler.GetHumanPose(ref pose);
return pose;
}
public void SetPose(HumanPose pose)
{
SetPose(Avatar, transform, pose);
}
public static void SetPose(Avatar avatar, Transform transform, HumanPose pose)
{
var handler = new HumanPoseHandler(avatar, transform);
handler.SetHumanPose(ref pose);
}
public static void SetTPose(Avatar avatar, Transform transform)
{
var humanPoseClip = Resources.Load<HumanPoseClip>(HumanPoseClip.TPoseResourcePath);
var pose = humanPoseClip.GetPose();
HumanPoseTransfer.SetPose(avatar, transform, pose);
}
#endregion
private void Reset()
{
var animator = GetComponent<Animator>();
if (animator != null)
{
Avatar = animator.avatar;
}
}
[SerializeField]
public HumanPoseTransfer Source;
[SerializeField]
public HumanPoseClip PoseClip;
[ContextMenu("Set T-Pose")]
void SetTPose()
{
if (Avatar == null) return;
SetTPose(Avatar, transform);
}
HumanPoseHandler m_handler;
public void OnEnable()
{
var animator = GetComponent<Animator>();
if (animator != null)
{
Avatar = animator.avatar;
}
Setup();
}
public void Setup()
{
if (Avatar == null)
{
return;
}
m_handler = new HumanPoseHandler(Avatar, transform);
}
HumanPose m_pose;
int m_lastFrameCount = -1;
public bool GetPose(int frameCount, ref HumanPose pose)
{
if (PoseClip != null)
{
pose = PoseClip.GetPose();
return true;
}
if (m_handler == null)
{
pose = m_pose;
return false;
}
if (frameCount != m_lastFrameCount)
{
m_handler.GetHumanPose(ref m_pose);
m_lastFrameCount = frameCount;
}
pose = m_pose;
return true;
}
private void Update()
{
switch (SourceType)
{
case HumanPoseTransferSourceType.None:
break;
case HumanPoseTransferSourceType.HumanPoseTransfer:
if (Source != null && m_handler != null)
{
if (Source.GetPose(Time.frameCount, ref m_pose))
{
m_handler.SetHumanPose(ref m_pose);
}
}
break;
case HumanPoseTransferSourceType.HumanPoseClip:
if (PoseClip != null)
{
var pose = PoseClip.GetPose();
m_handler.SetHumanPose(ref pose);
}
break;
}
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: e5548e4785b76854cbbf3f6d9a8e9c1d
timeCreated: 1517666226
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public interface IBone
{
string Name { get; }
Vector3 SkeletonLocalPosition { get; }
IBone Parent { get; }
IList<IBone> Children { get; }
}
public static class IBoneExtensions
{
public static IEnumerable<IBone> Traverse(this IBone self)
{
yield return self;
foreach (var child in self.Children)
{
foreach (var x in child.Traverse())
{
yield return x;
}
}
}
public static Vector3 CenterOfDescendant(this IBone self)
{
var sum = Vector3.zero;
int i = 0;
foreach (var x in self.Traverse())
{
sum += x.SkeletonLocalPosition;
++i;
}
return sum / i;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9c2e3ee9fe29a84cb902e54a90c5dec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e07bcccfa1de56943ab8e18f8791740d
folderAsset: yes
timeCreated: 1517655053
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public static class BvhAnimation
{
class CurveSet
{
BvhNode Node;
Func<float, float, float, Quaternion> EulerToRotation;
public CurveSet(BvhNode node)
{
Node = node;
}
public ChannelCurve PositionX;
public ChannelCurve PositionY;
public ChannelCurve PositionZ;
public Vector3 GetPosition(int i)
{
return new Vector3(
PositionX.Keys[i],
PositionY.Keys[i],
PositionZ.Keys[i]);
}
public ChannelCurve RotationX;
public ChannelCurve RotationY;
public ChannelCurve RotationZ;
public Quaternion GetRotation(int i)
{
if (EulerToRotation == null)
{
EulerToRotation = Node.GetEulerToRotation();
}
return EulerToRotation(
RotationX.Keys[i],
RotationY.Keys[i],
RotationZ.Keys[i]
);
}
static void AddCurve(Bvh bvh, AnimationClip clip, ChannelCurve ch, float scaling)
{
if (ch == null) return;
var pathWithProp = default(Bvh.PathWithProperty);
bvh.TryGetPathWithPropertyFromChannel(ch, out pathWithProp);
var curve = new AnimationCurve();
for (int i = 0; i < bvh.FrameCount; ++i)
{
var time = (float)(i * bvh.FrameTime.TotalSeconds);
var value = ch.Keys[i] * scaling;
curve.AddKey(time, value);
}
clip.SetCurve(pathWithProp.Path, typeof(Transform), pathWithProp.Property, curve);
}
public void AddCurves(Bvh bvh, AnimationClip clip, float scaling)
{
AddCurve(bvh, clip, PositionX, -scaling);
AddCurve(bvh, clip, PositionY, scaling);
AddCurve(bvh, clip, PositionZ, scaling);
var pathWithProp = default(Bvh.PathWithProperty);
bvh.TryGetPathWithPropertyFromChannel(RotationX, out pathWithProp);
// rotation
var curveX = new AnimationCurve();
var curveY = new AnimationCurve();
var curveZ = new AnimationCurve();
var curveW = new AnimationCurve();
for (int i = 0; i < bvh.FrameCount; ++i)
{
var time = (float)(i * bvh.FrameTime.TotalSeconds);
var q = GetRotation(i).ReverseX();
curveX.AddKey(time, q.x);
curveY.AddKey(time, q.y);
curveZ.AddKey(time, q.z);
curveW.AddKey(time, q.w);
}
clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.x", curveX);
clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.y", curveY);
clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.z", curveZ);
clip.SetCurve(pathWithProp.Path, typeof(Transform), "localRotation.w", curveW);
}
}
public static AnimationClip CreateAnimationClip(Bvh bvh, float scaling)
{
var clip = new AnimationClip();
clip.legacy = true;
var curveMap = new Dictionary<BvhNode, CurveSet>();
int j = 0;
foreach (var node in bvh.Root.Traverse())
{
var set = new CurveSet(node);
curveMap[node] = set;
for (int i = 0; i < node.Channels.Length; ++i, ++j)
{
var curve = bvh.Channels[j];
switch (node.Channels[i])
{
case Channel.Xposition: set.PositionX = curve; break;
case Channel.Yposition: set.PositionY = curve; break;
case Channel.Zposition: set.PositionZ = curve; break;
case Channel.Xrotation: set.RotationX = curve; break;
case Channel.Yrotation: set.RotationY = curve; break;
case Channel.Zrotation: set.RotationZ = curve; break;
default: throw new Exception();
}
}
}
foreach (var set in curveMap)
{
set.Value.AddCurves(bvh, clip, scaling);
}
clip.EnsureQuaternionContinuity();
return clip;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45951aadbd5e6b34282cd17ee163f58b
timeCreated: 1517655805
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
using System;
namespace UniHumanoid
{
public static class BvhImporter
{
[Obsolete("use BvhImporter.Parse(path), then BvhImporter.Load()")]
public static void Import(BvhImporterContext context)
{
context.Parse(context.Path);
context.Load();
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: da8ccd6cbe1692448872063195e5c71b
timeCreated: 1517655539
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,247 @@
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniHumanoid
{
[Obsolete("use BvhImporterContext")]
public class ImporterContext: BvhImporterContext
{
}
public class BvhImporterContext
{
#region Source
String m_path;
public String Path
{
get { return m_path; }
set
{
if (m_path == value) return;
m_path = value;
}
}
public String Source; // source
public Bvh Bvh;
#endregion
#region Imported
public GameObject Root;
public List<Transform> Nodes = new List<Transform>();
public AnimationClip Animation;
public AvatarDescription AvatarDescription;
public Avatar Avatar;
public Mesh Mesh;
public Material Material;
#endregion
#region Load
[Obsolete("use Load(path)")]
public void Parse()
{
Parse(Path);
}
public void Parse(string path)
{
Path = path;
Source = File.ReadAllText(Path, Encoding.UTF8);
Bvh = Bvh.Parse(Source);
}
public void Load()
{
//
// build hierarchy
//
Root = new GameObject(System.IO.Path.GetFileNameWithoutExtension(Path));
var hips = BuildHierarchy(Root.transform, Bvh.Root, 1.0f);
var skeleton = Skeleton.Estimate(hips);
var description = AvatarDescription.Create(hips.Traverse().ToArray(), skeleton);
//
// scaling. reposition
//
float scaling = 1.0f;
{
//var foot = animator.GetBoneTransform(HumanBodyBones.LeftFoot);
var foot = hips.Traverse().Skip(skeleton.GetBoneIndex(HumanBodyBones.LeftFoot)).First();
var hipHeight = hips.position.y - foot.position.y;
// hips height to a meter
scaling = 1.0f / hipHeight;
foreach (var x in Root.transform.Traverse())
{
x.localPosition *= scaling;
}
var scaledHeight = hipHeight * scaling;
hips.position = new Vector3(0, scaledHeight, 0); // foot to ground
}
//
// avatar
//
Avatar = description.CreateAvatar(Root.transform);
Avatar.name = "Avatar";
AvatarDescription = description;
var animator = Root.AddComponent<Animator>();
animator.avatar = Avatar;
//
// create AnimationClip
//
Animation = BvhAnimation.CreateAnimationClip(Bvh, scaling);
Animation.name = Root.name;
Animation.legacy = true;
Animation.wrapMode = WrapMode.Loop;
var animation = Root.AddComponent<Animation>();
animation.AddClip(Animation, Animation.name);
animation.clip = Animation;
animation.Play();
var humanPoseTransfer = Root.AddComponent<HumanPoseTransfer>();
humanPoseTransfer.Avatar = Avatar;
// create SkinnedMesh for bone visualize
var renderer = SkeletonMeshUtility.CreateRenderer(animator);
Material = new Material(Shader.Find("Standard"));
renderer.sharedMaterial = Material;
Mesh = renderer.sharedMesh;
Mesh.name = "box-man";
Root.AddComponent<BoneMapping>();
}
static Transform BuildHierarchy(Transform parent, BvhNode node, float toMeter)
{
var go = new GameObject(node.Name);
go.transform.localPosition = node.Offset.ToXReversedVector3() * toMeter;
go.transform.SetParent(parent, false);
//var gizmo = go.AddComponent<BoneGizmoDrawer>();
//gizmo.Draw = true;
foreach (var child in node.Children)
{
BuildHierarchy(go.transform, child, toMeter);
}
return go.transform;
}
#endregion
#if UNITY_EDITOR
protected virtual string GetPrefabPath()
{
var dir = System.IO.Path.GetDirectoryName(Path);
var name = System.IO.Path.GetFileNameWithoutExtension(Path);
var prefabPath = string.Format("{0}/{1}.prefab", dir, name);
if (!Application.isPlaying && File.Exists(prefabPath))
{
// already exists
if (IsOwn(prefabPath))
{
//Debug.LogFormat("already exist. own: {0}", prefabPath);
}
else
{
// but unknown prefab
var unique = AssetDatabase.GenerateUniqueAssetPath(prefabPath);
//Debug.LogFormat("already exist: {0} => {1}", prefabPath, unique);
prefabPath = unique;
}
}
return prefabPath;
}
#region Assets
IEnumerable<UnityEngine.Object> GetSubAssets(string path)
{
return AssetDatabase.LoadAllAssetsAtPath(path);
}
protected virtual bool IsOwn(string path)
{
foreach (var x in GetSubAssets(path))
{
//if (x is Transform) continue;
if (x is GameObject) continue;
if (x is Component) continue;
if (AssetDatabase.IsSubAsset(x))
{
return true;
}
}
return false;
}
IEnumerable<UnityEngine.Object> ObjectsForSubAsset()
{
if (Animation != null) yield return Animation;
if (AvatarDescription != null) yield return AvatarDescription;
if (Avatar != null) yield return Avatar;
if (Mesh != null) yield return Mesh;
if (Material != null) yield return Material;
}
public void SaveAsAsset()
{
var path = GetPrefabPath();
if (File.Exists(path))
{
// clear SubAssets
foreach (var x in GetSubAssets(path).Where(x => !(x is GameObject) && !(x is Component)))
{
GameObject.DestroyImmediate(x, true);
}
}
// Add SubAsset
foreach (var o in ObjectsForSubAsset())
{
AssetDatabase.AddObjectToAsset(o, path);
}
// Create or upate Main Asset
if (File.Exists(path))
{
Debug.LogFormat("replace prefab: {0}", path);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
PrefabUtility.ReplacePrefab(Root, prefab, ReplacePrefabOptions.ReplaceNameBased);
}
else
{
Debug.LogFormat("create prefab: {0}", path);
PrefabUtility.CreatePrefab(path, Root);
}
AssetDatabase.ImportAsset(path);
}
#endregion
#endif
public void Destroy(bool destroySubAssets)
{
if (Root != null) GameObject.DestroyImmediate(Root);
if (destroySubAssets)
{
#if UNITY_EDITOR
foreach (var o in ObjectsForSubAsset())
{
UnityEngine.Object.DestroyImmediate(o, true);
}
#endif
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6c6231d0aafc9554ca596f35e8f395c4
timeCreated: 1521112950
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9f2cfbad0949d5840879540d0fce61fe
folderAsset: yes
timeCreated: 1517655230
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
using System;
using System.Linq;
using UnityEngine;
namespace UniHumanoid
{
public static class BvhExtensions
{
public static Func<float, float, float, Quaternion> GetEulerToRotation(this BvhNode bvh)
{
var order = bvh.Channels.Where(x => x == Channel.Xrotation || x == Channel.Yrotation || x == Channel.Zrotation).ToArray();
return (x, y, z) =>
{
var xRot = Quaternion.Euler(x, 0, 0);
var yRot = Quaternion.Euler(0, y, 0);
var zRot = Quaternion.Euler(0, 0, z);
var r = Quaternion.identity;
foreach (var ch in order)
{
switch (ch)
{
case Channel.Xrotation: r = r * xRot; break;
case Channel.Yrotation: r = r * yRot; break;
case Channel.Zrotation: r = r * zRot; break;
default: throw new BvhException("no rotation");
}
}
return r;
};
}
public static Vector3 ToVector3(this Single3 s3)
{
return new Vector3(s3.x, s3.y, s3.z);
}
public static Vector3 ToXReversedVector3(this Single3 s3)
{
return new Vector3(-s3.x, s3.y, s3.z);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 30d4db9a01d6aee4db9a77d762e608f6
timeCreated: 1517655238
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,49 @@
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public static class UnityExtensions
{
public static Quaternion ReverseX(this Quaternion quaternion)
{
float angle;
Vector3 axis;
quaternion.ToAngleAxis(out angle, out axis);
return Quaternion.AngleAxis(-angle, new Vector3(-axis.x, axis.y, axis.z));
}
public static IEnumerable<Transform> GetChildren(this Transform parent)
{
foreach (Transform child in parent)
{
yield return child;
}
}
public static IEnumerable<Transform> Traverse(this Transform parent)
{
yield return parent;
foreach (Transform child in parent)
{
foreach (Transform descendant in Traverse(child))
{
yield return descendant;
}
}
}
public static SkeletonBone ToSkeletonBone(this Transform t)
{
var sb = new SkeletonBone();
sb.name = t.name;
sb.position = t.localPosition;
sb.rotation = t.localRotation;
sb.scale = t.localScale;
return sb;
}
}
}

View File

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 6c4a2b80b74e499428637f36774bbdcf
timeCreated: 1517666834
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,105 @@
using System;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniHumanoid
{
public class MuscleDebug : MonoBehaviour
{
Avatar GetAvatar()
{
var animator = GetComponent<Animator>();
if (animator != null && animator.avatar != null)
{
return animator.avatar;
}
var transfer = GetComponent<HumanPoseTransfer>();
if (transfer != null && transfer.Avatar != null)
{
return transfer.Avatar;
}
return null;
}
HumanPoseHandler m_handler;
public HumanPose m_pose;
[Serializable]
public struct Muscle
{
public int Index;
public string Name;
public float Value;
}
public Vector3 BodyPosition;
public Muscle[] Muscles;
private void OnEnable()
{
var avatar = GetAvatar();
if (avatar == null)
{
enabled = false;
return;
}
m_handler = new HumanPoseHandler(avatar, transform);
Muscles = HumanTrait.MuscleName.Select((x, i) =>
{
return new Muscle
{
Index = i,
Name = x,
};
})
.ToArray()
;
}
private void OnDisable()
{
}
private void Update()
{
m_handler.GetHumanPose(ref m_pose);
BodyPosition = m_pose.bodyPosition;
for (int i = 0; i < m_pose.muscles.Length; ++i)
{
Muscles[i].Value = m_pose.muscles[i];
}
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(MuscleDebug.Muscle))]
public class MuscleDrawer : PropertyDrawer
{
public override void OnGUI(Rect position,
SerializedProperty property, GUIContent label)
{
var nameProp = property.FindPropertyRelative("Name");
var valueProp = property.FindPropertyRelative("Value");
/*
var labl = string.Format("{0}: {1}",
nameProp.stringValue,
valueProp.floatValue
);
*/
EditorGUI.LabelField(position, nameProp.stringValue, string.Format("{0:0.00}", valueProp.floatValue));
}
}
#endif
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 14aaa52c3da53004ea85dbb38e9e4698
timeCreated: 1521114691
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
public class MuscleInspector : MonoBehaviour
{
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d2cc8a27b7978e54d9226bc91e53a502
timeCreated: 1541840537
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,92 @@
using System.Collections.Generic;
using UnityEngine;
namespace UniHumanoid
{
/// <summary>
/// Mapping HumanBodyBones to BoneIndex
/// </summary>
public struct Skeleton
{
Dictionary<HumanBodyBones, int> m_indexMap;
public Dictionary<HumanBodyBones, int> Bones
{
get { return m_indexMap; }
}
public int GetBoneIndex(HumanBodyBones bone)
{
int index;
if (m_indexMap.TryGetValue(bone, out index))
{
return index;
}
else
{
return -1;
}
}
#if UNITY_EDITOR
/// <summary>
/// For UnitTest
/// </summary>
Dictionary<HumanBodyBones, string> m_nameMap;
/// <summary>
/// ForTest
/// </summary>
/// <param name="bone"></param>
/// <returns></returns>
public string GetBoneName(HumanBodyBones bone)
{
string name;
if (m_nameMap.TryGetValue(bone, out name))
{
return name;
}
else
{
return null;
}
}
#endif
public static Skeleton Estimate(Transform hips)
{
var estimater = new BvhSkeletonEstimator();
return estimater.Detect(hips);
}
/// <summary>
/// Register bone's HumanBodyBones
/// </summary>
/// <param name="bone"></param>
/// <param name="bones"></param>
/// <param name="b"></param>
public void Set(HumanBodyBones bone, IList<IBone> bones, IBone b)
{
if (b != null)
{
Set(bone, bones.IndexOf(b), b.Name);
}
}
public void Set(HumanBodyBones bone, int index, string name)
{
if (m_indexMap == null)
{
m_indexMap = new Dictionary<HumanBodyBones, int>();
}
m_indexMap[bone] = index;
#if UNITY_EDITOR
if (m_nameMap == null)
{
m_nameMap = new Dictionary<HumanBodyBones, string>();
}
m_nameMap[bone] = name;
#endif
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 883d8b6e07cbda24384ce65d613d128e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UniHumanoid
{
public interface ISkeletonDetector
{
Skeleton Detect(IList<IBone> bones);
}
public class BvhSkeletonEstimator : ISkeletonDetector
{
static IBone GetRoot(IList<IBone> bones)
{
var hips = bones.Where(x => x.Parent == null).ToArray();
if (hips.Length != 1)
{
throw new System.Exception("Require unique root");
}
return hips[0];
}
static IBone SelectBone(Func<IBone, IBone, IBone> selector, IList<IBone> bones)
{
if (bones == null || bones.Count == 0) throw new Exception("no bones");
var current = bones[0];
for (var i = 1; i < bones.Count; ++i)
{
current = selector(current, bones[i]);
}
return current;
}
static void GetSpineAndHips(IBone hips, out IBone spine, out IBone leg_L, out IBone leg_R)
{
if (hips.Children.Count != 3) throw new System.Exception("Hips require 3 children");
spine = SelectBone((l, r) => l.CenterOfDescendant().y > r.CenterOfDescendant().y ? l : r, hips.Children);
leg_L = SelectBone((l, r) => l.CenterOfDescendant().x < r.CenterOfDescendant().x ? l : r, hips.Children);
leg_R = SelectBone((l, r) => l.CenterOfDescendant().x > r.CenterOfDescendant().x ? l : r, hips.Children);
}
static void GetNeckAndArms(IBone chest, out IBone neck, out IBone arm_L, out IBone arm_R)
{
if (chest.Children.Count != 3) throw new System.Exception("Chest require 3 children");
neck = SelectBone((l, r) => l.CenterOfDescendant().y > r.CenterOfDescendant().y ? l : r, chest.Children);
arm_L = SelectBone((l, r) => l.CenterOfDescendant().x < r.CenterOfDescendant().x ? l : r, chest.Children);
arm_R = SelectBone((l, r) => l.CenterOfDescendant().x > r.CenterOfDescendant().x ? l : r, chest.Children);
}
struct Arm
{
public IBone Shoulder;
public IBone UpperArm;
public IBone LowerArm;
public IBone Hand;
}
Arm GetArm(IBone shoulder)
{
var bones = shoulder.Traverse().ToArray();
switch (bones.Length)
{
case 0:
case 1:
case 2:
case 3:
throw new NotImplementedException();
default:
return new Arm
{
Shoulder = bones[0],
UpperArm = bones[1],
LowerArm = bones[2],
Hand = bones[3],
};
}
}
struct Leg
{
public IBone UpperLeg;
public IBone LowerLeg;
public IBone Foot;
public IBone Toes;
}
Leg GetLeg(IBone leg)
{
var bones = leg.Traverse().Where(x => !x.Name.ToLower().Contains("buttock")).ToArray();
switch (bones.Length)
{
case 0:
case 1:
case 2:
throw new NotImplementedException();
case 3:
return new Leg
{
UpperLeg = bones[0],
LowerLeg = bones[1],
Foot = bones[2],
};
default:
return new Leg
{
UpperLeg = bones[bones.Length - 4],
LowerLeg = bones[bones.Length - 3],
Foot = bones[bones.Length - 2],
Toes = bones[bones.Length - 1],
};
}
}
public Skeleton Detect(IList<IBone> bones)
{
//
// search bones
//
var root = GetRoot(bones);
var hips = root.Traverse().First(x => x.Children.Count == 3);
IBone spine, hip_L, hip_R;
GetSpineAndHips(hips, out spine, out hip_L, out hip_R);
var legLeft = GetLeg(hip_L);
var legRight = GetLeg(hip_R);
var spineToChest = new List<IBone>();
foreach(var x in spine.Traverse())
{
spineToChest.Add(x);
if (x.Children.Count == 3) break;
}
IBone neck, shoulder_L, shoulder_R;
GetNeckAndArms(spineToChest.Last(), out neck, out shoulder_L, out shoulder_R);
var armLeft = GetArm(shoulder_L);
var armRight = GetArm(shoulder_R);
var neckToHead = neck.Traverse().ToArray();
//
// set result
//
var skeleton = new Skeleton();
skeleton.Set(HumanBodyBones.Hips, bones, hips);
switch (spineToChest.Count)
{
case 0:
throw new Exception();
case 1:
skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
break;
case 2:
skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
break;
#if UNITY_5_6_OR_NEWER
case 3:
skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest[2]);
break;
#endif
default:
skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
#if UNITY_5_6_OR_NEWER
skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest.Last());
#else
skeleton.Set(HumanBodyBones.Chest, bones, spineToChest.Last());
#endif
break;
}
switch (neckToHead.Length)
{
case 0:
throw new Exception();
case 1:
skeleton.Set(HumanBodyBones.Head, bones, neckToHead[0]);
break;
case 2:
skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]);
skeleton.Set(HumanBodyBones.Head, bones, neckToHead[1]);
break;
default:
skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]);
skeleton.Set(HumanBodyBones.Head, bones, neckToHead.Where(x => x.Parent.Children.Count==1).Last());
break;
}
skeleton.Set(HumanBodyBones.LeftUpperLeg, bones, legLeft.UpperLeg);
skeleton.Set(HumanBodyBones.LeftLowerLeg, bones, legLeft.LowerLeg);
skeleton.Set(HumanBodyBones.LeftFoot, bones, legLeft.Foot);
skeleton.Set(HumanBodyBones.LeftToes, bones, legLeft.Toes);
skeleton.Set(HumanBodyBones.RightUpperLeg, bones, legRight.UpperLeg);
skeleton.Set(HumanBodyBones.RightLowerLeg, bones, legRight.LowerLeg);
skeleton.Set(HumanBodyBones.RightFoot, bones, legRight.Foot);
skeleton.Set(HumanBodyBones.RightToes, bones, legRight.Toes);
skeleton.Set(HumanBodyBones.LeftShoulder, bones, armLeft.Shoulder);
skeleton.Set(HumanBodyBones.LeftUpperArm, bones, armLeft.UpperArm);
skeleton.Set(HumanBodyBones.LeftLowerArm, bones, armLeft.LowerArm);
skeleton.Set(HumanBodyBones.LeftHand, bones, armLeft.Hand);
skeleton.Set(HumanBodyBones.RightShoulder, bones, armRight.Shoulder);
skeleton.Set(HumanBodyBones.RightUpperArm, bones, armRight.UpperArm);
skeleton.Set(HumanBodyBones.RightLowerArm, bones, armRight.LowerArm);
skeleton.Set(HumanBodyBones.RightHand, bones, armRight.Hand);
return skeleton;
}
public Skeleton Detect(Bvh bvh)
{
var root = new BvhBone(bvh.Root.Name, Vector3.zero);
root.Build(bvh.Root);
return Detect(root.Traverse().Select(x => (IBone)x).ToList());
}
public Skeleton Detect(Transform t)
{
var root = new BvhBone(t.name, Vector3.zero);
root.Build(t);
return Detect(root.Traverse().Select(x => (IBone)x).ToList());
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4f0d2728cd7343f4ab2e7f7c2b961d5c
timeCreated: 1534751085
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UniHumanoid
{
public static class SkeletonMeshUtility
{
class MeshBuilder
{
List<Vector3> m_positioins = new List<Vector3>();
List<int> m_indices = new List<int>();
List<BoneWeight> m_boneWeights = new List<BoneWeight>();
public void AddBone(Vector3 head, Vector3 tail, int boneIndex, float xWidth, float zWidth)
{
var dir = (tail - head).normalized;
Vector3 xaxis;
Vector3 zaxis;
if (Vector3.Dot(dir, Vector3.forward) >= 1.0f - float.Epsilon)
{
xaxis = Vector3.right;
zaxis = Vector3.down;
}
else
{
xaxis = Vector3.Cross(dir, Vector3.forward).normalized;
zaxis = Vector3.forward;
}
AddBox((head+tail)*0.5f,
xaxis*xWidth,
(tail-head)*0.5f,
zaxis*zWidth,
boneIndex);
}
void AddBox(Vector3 center, Vector3 xaxis, Vector3 yaxis, Vector3 zaxis, int boneIndex)
{
AddQuad(
center - yaxis - xaxis - zaxis,
center - yaxis + xaxis - zaxis,
center - yaxis + xaxis + zaxis,
center - yaxis - xaxis + zaxis,
boneIndex);
AddQuad(
center + yaxis - xaxis - zaxis,
center + yaxis + xaxis - zaxis,
center + yaxis + xaxis + zaxis,
center + yaxis - xaxis + zaxis,
boneIndex, true);
AddQuad(
center - xaxis - yaxis - zaxis,
center - xaxis + yaxis - zaxis,
center - xaxis + yaxis + zaxis,
center - xaxis - yaxis + zaxis,
boneIndex, true);
AddQuad(
center + xaxis - yaxis - zaxis,
center + xaxis + yaxis - zaxis,
center + xaxis + yaxis + zaxis,
center + xaxis - yaxis + zaxis,
boneIndex);
AddQuad(
center - zaxis - xaxis - yaxis,
center - zaxis + xaxis - yaxis,
center - zaxis + xaxis + yaxis,
center - zaxis - xaxis + yaxis,
boneIndex, true);
AddQuad(
center + zaxis - xaxis - yaxis,
center + zaxis + xaxis - yaxis,
center + zaxis + xaxis + yaxis,
center + zaxis - xaxis + yaxis,
boneIndex);
}
void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, int boneIndex, bool reverse=false)
{
var i = m_positioins.Count;
m_positioins.Add(v0);
m_positioins.Add(v1);
m_positioins.Add(v2);
m_positioins.Add(v3);
var bw = new BoneWeight
{
boneIndex0=boneIndex,
weight0=1.0f,
};
m_boneWeights.Add(bw);
m_boneWeights.Add(bw);
m_boneWeights.Add(bw);
m_boneWeights.Add(bw);
if (reverse)
{
m_indices.Add(i + 3);
m_indices.Add(i + 2);
m_indices.Add(i + 1);
m_indices.Add(i + 1);
m_indices.Add(i);
m_indices.Add(i + 3);
}
else
{
m_indices.Add(i);
m_indices.Add(i + 1);
m_indices.Add(i + 2);
m_indices.Add(i + 2);
m_indices.Add(i + 3);
m_indices.Add(i);
}
}
public Mesh CreateMesh()
{
var mesh = new Mesh();
mesh.SetVertices(m_positioins);
mesh.boneWeights = m_boneWeights.ToArray();
mesh.triangles = m_indices.ToArray();
mesh.RecalculateNormals();
mesh.RecalculateBounds();
return mesh;
}
}
struct BoneHeadTail
{
public HumanBodyBones Head;
public HumanBodyBones Tail;
public Vector3 TailOffset;
public float XWidth;
public float ZWidth;
public BoneHeadTail(HumanBodyBones head, HumanBodyBones tail, float xWidth = 0.05f, float zWidth = 0.05f)
{
Head = head;
Tail = tail;
TailOffset = Vector3.zero;
XWidth = xWidth;
ZWidth = zWidth;
}
public BoneHeadTail(HumanBodyBones head, Vector3 tailOffset, float xWidth = 0.05f, float zWidth = 0.05f)
{
Head = head;
Tail = HumanBodyBones.LastBone;
TailOffset = tailOffset;
XWidth = xWidth;
ZWidth = zWidth;
}
}
static BoneHeadTail[] Bones = new BoneHeadTail[]
{
new BoneHeadTail(HumanBodyBones.Hips, HumanBodyBones.Spine, 0.1f, 0.06f),
new BoneHeadTail(HumanBodyBones.Spine, HumanBodyBones.Chest),
new BoneHeadTail(HumanBodyBones.Chest, HumanBodyBones.Neck, 0.1f, 0.06f),
new BoneHeadTail(HumanBodyBones.Neck, HumanBodyBones.Head, 0.03f, 0.03f),
new BoneHeadTail(HumanBodyBones.Head, new Vector3(0, 0.1f, 0), 0.1f, 0.1f),
new BoneHeadTail(HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm),
new BoneHeadTail(HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm),
new BoneHeadTail(HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand),
new BoneHeadTail(HumanBodyBones.LeftHand, new Vector3(-0.1f, 0, 0)),
new BoneHeadTail(HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg),
new BoneHeadTail(HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot),
new BoneHeadTail(HumanBodyBones.LeftFoot, HumanBodyBones.LeftToes),
new BoneHeadTail(HumanBodyBones.LeftToes, new Vector3(0, 0, 0.1f)),
new BoneHeadTail(HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm),
new BoneHeadTail(HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm),
new BoneHeadTail(HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand),
new BoneHeadTail(HumanBodyBones.RightHand, new Vector3(0.1f, 0, 0)),
new BoneHeadTail(HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg),
new BoneHeadTail(HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot),
new BoneHeadTail(HumanBodyBones.RightFoot, HumanBodyBones.RightToes),
new BoneHeadTail(HumanBodyBones.RightToes, new Vector3(0, 0, 0.1f)),
};
public static SkinnedMeshRenderer CreateRenderer(Animator animator)
{
//var bodyBones = (HumanBodyBones[])Enum.GetValues(typeof(HumanBodyBones));
var bones = animator.transform.Traverse().ToList();
var builder = new MeshBuilder();
foreach(var headTail in Bones)
{
var head = animator.GetBoneTransform(headTail.Head);
if (head!=null)
{
Transform tail = null;
if(headTail.Tail!= HumanBodyBones.LastBone)
{
tail = animator.GetBoneTransform(headTail.Tail);
}
if (tail != null)
{
builder.AddBone(head.position, tail.position, bones.IndexOf(head), headTail.XWidth, headTail.ZWidth);
}
else
{
builder.AddBone(head.position, head.position + headTail.TailOffset, bones.IndexOf(head), headTail.XWidth, headTail.ZWidth);
}
}
else
{
Debug.LogWarningFormat("{0} not found", headTail.Head);
}
}
var mesh = builder.CreateMesh();
mesh.name = "box-man";
mesh.bindposes = bones.Select(x =>
x.worldToLocalMatrix * animator.transform.localToWorldMatrix).ToArray();
var renderer = animator.gameObject.AddComponent<SkinnedMeshRenderer>();
renderer.bones = bones.ToArray();
renderer.rootBone = animator.GetBoneTransform(HumanBodyBones.Hips);
renderer.sharedMesh = mesh;
//var bounds = new Bounds(Vector3.zero, mesh.bounds.size);
//renderer.localBounds = bounds;
return renderer;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 92bf6005e8d6db94b8b55c67caea9ddd
timeCreated: 1522346056
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

10
UniHumanoid/doc.meta Normal file
View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: bd16aca6bf957944396bb28ff3678f05
folderAsset: yes
timeCreated: 1517663952
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: f4993bbf703729441869ce8186574f2b
timeCreated: 1517138583
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 1e5ed0d1eaae21c46b59beeeb761a357
timeCreated: 1517138581
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
UniHumanoid/doc/assets.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,68 @@
fileFormatVersion: 2
guid: f998ebae6d907c94b87d25d0d24939d6
timeCreated: 1535601388
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 06577ef88ae5dea4189cb3022681fa9f
timeCreated: 1518017275
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 65ce8e194a35af1449cbc70c76e385ad
timeCreated: 1518016999
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 0f274a7a8cb1663479e10b9b1820156d
timeCreated: 1518016802
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 81969f93770cf844eab1f4137fefe07e
timeCreated: 1517138582
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 8dd213e4a507dac4585f174f27fcd677
timeCreated: 1518018122
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,77 @@
fileFormatVersion: 2
guid: 0091e5f38ae478b47ba5b2aec91e1598
timeCreated: 1519110272
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
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
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

BIN
UniHumanoid/doc/mesh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -0,0 +1,68 @@
fileFormatVersion: 2
guid: 7e153a45f4c3fab428c47e3d6509252d
timeCreated: 1535601388
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant: