Squashed 'UniHumanoid/' content from commit 9af6c0d
git-subtree-dir: UniHumanoid git-subtree-split: 9af6c0d3995ca8886c1ad87429dd9f28c7b4375d
21
LICENSE.md
Normal 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.
|
||||
8
LICENSE.md.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3ea85fd858590174f98cc2cd4c3e083f
|
||||
timeCreated: 1522228320
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
PoseModifier.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a90ca020c7788804ea91e172fa5efd1a
|
||||
folderAsset: yes
|
||||
timeCreated: 1524224672
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
175
PoseModifier/HandPose.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
PoseModifier/HandPose.cs.meta
Normal 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:
|
||||
100
PoseModifier/HandRig.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
PoseModifier/HandRig.cs.meta
Normal 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:
|
||||
10
PoseModifier/IPoseModifier.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public interface IPoseModifier
|
||||
{
|
||||
void Modify(ref HumanPose pose);
|
||||
}
|
||||
}
|
||||
12
PoseModifier/IPoseModifier.cs.meta
Normal 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
README.md
Normal 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
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# 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
|
||||
|
||||

|
||||
|
||||
Instanciate prefab to scene.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
These humanoids imported by [UniGLTF](https://github.com/ousttrue/UniGLTF) and created human avatar by BoneMapping.
|
||||
|
||||

|
||||
|
||||
# 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/
|
||||
|
||||
8
README.md.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: be513cfaa8530114d85f1e8e0f29708a
|
||||
timeCreated: 1517370218
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Resources.meta
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c61106d290c827b49b7a6e3f6497bd3f
|
||||
folderAsset: yes
|
||||
timeCreated: 1519379142
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
111
Resources/T-Pose.pose.asset
Normal 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
|
||||
10
Resources/T-Pose.pose.asset.meta
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 879e332f84a378c4da3b87af13da3e85
|
||||
timeCreated: 1519376738
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Scenes.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9edc7cfd64210934e817c98db16bdaea
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
149
Scenes/HumanBuilderTest.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scenes/HumanBuilderTest.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dfdcf658d2da05649974b59b849de74c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
691
Scenes/PoseTransfer.unity
Normal 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
|
||||
7
Scenes/PoseTransfer.unity.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae847f673eb3e6f4a95f61b4658b806a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
84
Scenes/RuntimeBvhLoader.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scenes/RuntimeBvhLoader.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b994e1476323bf4fbe1ae28bea164f2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
615
Scenes/RuntimeBvhLoader.unity
Normal 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
|
||||
7
Scenes/RuntimeBvhLoader.unity.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 99665560be9c32e4d9f7813b076c92ee
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
76
Scenes/target.mat
Normal 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}
|
||||
8
Scenes/target.mat.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94b4b45712e88334c9e7c5ecc53c50e6
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Scripts.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 64819743741f38e43b64a7d6add8cea9
|
||||
folderAsset: yes
|
||||
timeCreated: 1517166088
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
134
Scripts/AnimationClipUtility.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/AnimationClipUtility.cs.meta
Normal 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:
|
||||
242
Scripts/AvatarDescription.cs
Normal 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
|
||||
}
|
||||
}
|
||||
12
Scripts/AvatarDescription.cs.meta
Normal 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:
|
||||
28
Scripts/BoneGizmoDrawer.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/BoneGizmoDrawer.cs.meta
Normal 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:
|
||||
103
Scripts/BoneMapping.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/BoneMapping.cs.meta
Normal 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:
|
||||
80
Scripts/BvhBone.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scripts/BvhBone.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1a88b26726f137419428078debd253f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Scripts/Editor.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6dfa46c173ff021418df4bada32ddfe9
|
||||
folderAsset: yes
|
||||
timeCreated: 1517655448
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
419
Scripts/Editor/BoneMappingEditor.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/Editor/BoneMappingEditor.cs.meta
Normal 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:
|
||||
151
Scripts/Editor/HumanPoseTransferEditor.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/Editor/HumanPoseTransferEditor.cs.meta
Normal 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:
|
||||
352
Scripts/Editor/MuscleInspectorEditor.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/Editor/MuscleInspectorEditor.cs.meta
Normal 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:
|
||||
9
Scripts/Editor/Tests.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fcdf450ca966f85428c238046e51c2ca
|
||||
folderAsset: yes
|
||||
timeCreated: 1534750149
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1360
Scripts/Editor/Tests/BvhLoaderTests.cs
Normal file
12
Scripts/Editor/Tests/BvhLoaderTests.cs.meta
Normal 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:
|
||||
36
Scripts/Editor/bvhAssetPostprocessor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/Editor/bvhAssetPostprocessor.cs.meta
Normal 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:
|
||||
9
Scripts/Format.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fc31477377367fb48bc85f0864fe33eb
|
||||
folderAsset: yes
|
||||
timeCreated: 1517655048
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
444
Scripts/Format/Bvh.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/Format/Bvh.cs.meta
Normal 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:
|
||||
33
Scripts/HumanPoseClip.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/HumanPoseClip.cs.meta
Normal 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:
|
||||
143
Scripts/HumanPoseTransfer.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/HumanPoseTransfer.cs.meta
Normal 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:
|
||||
41
Scripts/IBone.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scripts/IBone.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c9c2e3ee9fe29a84cb902e54a90c5dec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Scripts/IO.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e07bcccfa1de56943ab8e18f8791740d
|
||||
folderAsset: yes
|
||||
timeCreated: 1517655053
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
131
Scripts/IO/BvhAnimationClip.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
12
Scripts/IO/BvhAnimationClip.cs.meta
Normal 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:
|
||||
15
Scripts/IO/BvhImporter.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/IO/BvhImporter.cs.meta
Normal 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:
|
||||
247
Scripts/IO/BvhImporterContext.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/IO/BvhImporterContext.cs.meta
Normal 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:
|
||||
9
Scripts/IO/Extensions.meta
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9f2cfbad0949d5840879540d0fce61fe
|
||||
folderAsset: yes
|
||||
timeCreated: 1517655230
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
45
Scripts/IO/Extensions/BvhExtensions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/IO/Extensions/BvhExtensions.cs.meta
Normal 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:
|
||||
49
Scripts/IO/Extensions/UnityExtensions.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Scripts/IO/Extensions/UnityExtensions.cs.meta
Normal 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:
|
||||
105
Scripts/MuscleDebug.cs
Normal 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
|
||||
}
|
||||
12
Scripts/MuscleDebug.cs.meta
Normal 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:
|
||||
11
Scripts/MuscleInspector.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniHumanoid
|
||||
{
|
||||
public class MuscleInspector : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
12
Scripts/MuscleInspector.cs.meta
Normal 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:
|
||||
92
Scripts/Skeleton.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Scripts/Skeleton.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 883d8b6e07cbda24384ce65d613d128e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
244
Scripts/SkeletonEstimator.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/SkeletonEstimator.cs.meta
Normal 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:
|
||||
232
Scripts/SkeletonMeshUtility.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Scripts/SkeletonMeshUtility.cs.meta
Normal 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
doc.meta
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bd16aca6bf957944396bb28ff3678f05
|
||||
folderAsset: yes
|
||||
timeCreated: 1517663952
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
doc/BoneMappingGizmo.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
77
doc/BoneMappingGizmo.png.meta
Normal 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:
|
||||
BIN
doc/BoneMappingInspector.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
77
doc/BoneMappingInspector.png.meta
Normal 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
doc/assets.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
68
doc/assets.png.meta
Normal 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:
|
||||
BIN
doc/bvh_bonemapping.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
77
doc/bvh_bonemapping.png.meta
Normal 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:
|
||||
BIN
doc/bvh_gameobject.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
77
doc/bvh_gameobject.png.meta
Normal 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:
|
||||
BIN
doc/bvh_prefab.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
77
doc/bvh_prefab.png.meta
Normal 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:
|
||||
BIN
doc/humanoid.gif
Normal file
|
After Width: | Height: | Size: 696 KiB |
77
doc/humanoid.gif.meta
Normal 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:
|
||||
BIN
doc/humanpose_transfer.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
77
doc/humanpose_transfer.png.meta
Normal 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:
|
||||
BIN
doc/humanpose_transfer_inspector.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
77
doc/humanpose_transfer_inspector.png.meta
Normal 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
doc/mesh.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
68
doc/mesh.png.meta
Normal 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:
|
||||