Compare commits

...

11 Commits

Author SHA1 Message Date
ca24486eac Merge pull request 'feature-binding: 动作绑定完成' (#1) from feature-binding into master
Reviewed-on: https://rrricardo.top/git/MotionCapture/MotionCapture/pulls/1
2023-03-30 21:32:33 +08:00
9a09585f01 Merge branch 'master' into feature-binding
# Conflicts:
#	Assets/Behaviours/CameraBehaviour.cs
#	Assets/Scenes/SampleScene.unity
#	Packages/manifest.json
2023-03-30 21:30:08 +08:00
2a0047a04b feature: 基本完成绑定 2023-03-30 21:18:20 +08:00
f812a1b831 feature: 模型绑定四肢和身体 2023-03-30 14:26:38 +08:00
77bf523001 feature: 船新的基于过程的动作绑定 2023-03-29 22:58:07 +08:00
479e64907f add: 添加新的控制思路 2023-03-27 13:11:01 +08:00
d901880eea refactor: 重新规划了项目结构
删除了冗余的控制类
2023-03-27 13:10:42 +08:00
Ichirinko
4cd3bad951 add:增加了子关节与父关节的计算方法 2023-03-25 11:43:42 +08:00
b45aee859b feature: 添加z轴压缩处理类 修复了身体前倾的问题 2023-03-05 22:26:01 +08:00
e63a32b95f feature: 添加控制根骨骼胯骨的代码
但是测试发生不可理解现象
2023-03-05 19:55:37 +08:00
d9acef1e18 fix: 修复了摄像机角度位置初始化错误的问题 2023-02-13 18:09:18 +08:00
21 changed files with 1203 additions and 491 deletions

8
Assets/Behaviours.meta Normal file
View File

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

View File

@ -0,0 +1,186 @@
using System.Collections.Generic;
using Models;
using UnityEngine;
using Utils.PoseTransformHandlers;
namespace Behaviours
{
public class BallStickBehaviour : MonoBehaviour
{
private readonly GameObject[] _nodes = new GameObject[PoseLandmarkType.MaxValue];
private readonly List<Bond> _bonds = new List<Bond>();
private readonly PoseTransform[] _poseTransforms = new PoseTransform[PoseLandmarkType.MaxValue];
private readonly UdpListener _listener = new UdpListener();
private const float Scale = 0.2f;
// Start is called before the first frame update
private void Start()
{
PoseTransform.AverageLength = 3;
CreateNodes();
CreateBonds();
_listener.AddHandler(OnReceive);
_listener.Connect(5000);
}
// Update is called once per frame
private void Update()
{
var mid = _poseTransforms[PoseLandmarkType.LeftHip] + _poseTransforms[PoseLandmarkType.RightHip];
mid = mid / 2;
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
_nodes[i].transform.position = (_poseTransforms[i].ResultPosition - mid) * -5f;
}
foreach (var bond in _bonds)
{
bond.UpdateBond();
}
}
private void OnDisable()
{
_listener.DisConnect();
}
private void OnReceive(List<PoseLandmark> landmarks)
{
foreach (var landmark in landmarks)
{
PoseTransform.UpdatePosition(ref _poseTransforms[landmark.Type.Value], landmark);
}
}
private void CreateNodes()
{
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
ball.transform.localScale = new Vector3(Scale, Scale, Scale);
if (i <= 10)
{
ball.GetComponent<Renderer>().material.color = Color.red; //给头部添加颜色
}
else if (i <= 22)
{
ball.GetComponent<Renderer>().material.color = Color.blue; //给手部添加颜色
}
else if (i <= 32)
{
ball.GetComponent<Renderer>().material.color = Color.green; //给脚部添加颜色
}
_nodes[i] = ball;
_poseTransforms[i] = new PoseTransform(i, new AverageHandler());
}
}
private void CreateBonds()
{
var headBonds = new[]
{
PoseLandmarkType.RightEar,
PoseLandmarkType.RightEyeOuter,
PoseLandmarkType.RightEye,
PoseLandmarkType.RightEyeInner,
PoseLandmarkType.Nose,
PoseLandmarkType.LeftEyeInner,
PoseLandmarkType.LeftEye,
PoseLandmarkType.LeftEyeOuter,
PoseLandmarkType.LeftEar
};
_bonds.AddRange(GenerateBondsList(headBonds));
var monthBonds = new[]
{
PoseLandmarkType.MouthLeft,
PoseLandmarkType.MouthRight,
};
_bonds.AddRange(GenerateBondsList(monthBonds));
var leftArmBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftElbow,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftPinky,
PoseLandmarkType.LeftIndex,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftThumb
};
_bonds.AddRange(GenerateBondsList(leftArmBonds));
var rightArmBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightElbow,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightPinky,
PoseLandmarkType.RightIndex,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightThumb
};
_bonds.AddRange(GenerateBondsList(rightArmBonds));
var leftLegBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftHip,
PoseLandmarkType.LeftKnee,
PoseLandmarkType.LeftAnkle,
PoseLandmarkType.LeftHeel,
PoseLandmarkType.LeftFootIndex,
PoseLandmarkType.LeftAnkle
};
_bonds.AddRange(GenerateBondsList(leftLegBonds));
var rightLegBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightHip,
PoseLandmarkType.RightKnee,
PoseLandmarkType.RightAnkle,
PoseLandmarkType.RightHeel,
PoseLandmarkType.RightFootIndex,
PoseLandmarkType.RightAnkle
};
_bonds.AddRange(GenerateBondsList(rightLegBonds));
// 最后手动添加身体上的两条横线
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftShoulder],
_nodes[PoseLandmarkType.RightShoulder],
Scale));
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftHip],
_nodes[PoseLandmarkType.RightHip],
Scale));
}
/// <summary>
/// 创建棍子列表
/// </summary>
/// <param name="nodes">需要连接起来的关键点 需要按顺序设置</param>
/// <returns></returns>
private List<Bond> GenerateBondsList(int[] nodes)
{
var bonds = new List<Bond>();
for (var i = 0; i < nodes.Length - 1; i++)
{
bonds.Add(new Bond(
_nodes[nodes[i]],
_nodes[nodes[i + 1]],
Scale));
}
return bonds;
}
}
}

View File

@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using Models;
using UnityEngine;
namespace Behaviours
{
public class BoneBehaviour : MonoBehaviour
{
private readonly UdpListener _listener = new UdpListener();
private readonly GameObject[] _nodes = new GameObject[PoseLandmarkType.MaxValue];
private readonly List<Bond> _bonds = new List<Bond>();
private Dictionary<HumanBodyBones, RotationNode> _rotationNodes;
private List<PoseLandmark> _landmarks;
private Animator _animator;
private bool _isReceived;
private const float Scale = 0.2f;
private void Start()
{
_animator = GetComponent<Animator>();
CreateRotationNodes();
CreateNodes();
CreateBonds();
_listener.AddHandler(OnReceive);
_listener.Connect(5000);
}
private void Update()
{
if (_isReceived)
{
_animator.GetBoneTransform(HumanBodyBones.Hips).rotation =
_rotationNodes[HumanBodyBones.Hips].Rotation;
/*var rotation = _rotationNodes[HumanBodyBones.Hips].CalculateRotate
* Quaternion.Inverse(_rotationNodes[HumanBodyBones.RightUpperArm].CalculateRotate);
_animator.GetBoneTransform(HumanBodyBones.RightUpperArm).Rotate(rotation.eulerAngles);*/
var mid = (_landmarks[PoseLandmarkType.LeftHip].Position +
_landmarks[PoseLandmarkType.RightHip].Position) / 2;
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
_nodes[i].transform.position = (_landmarks[i].Position - mid) * 5f;
}
foreach (var bond in _bonds)
{
bond.UpdateBond();
}
_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation = _bonds[9].Rotation;
_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm).rotation = _bonds[10].Rotation;
_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.RightUpperArm).rotation = _bonds[15].Rotation;
_animator.GetBoneTransform(HumanBodyBones.RightUpperArm).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.RightLowerArm).rotation = _bonds[16].Rotation;
_animator.GetBoneTransform(HumanBodyBones.RightLowerArm).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg).rotation = _bonds[22].Rotation;
_animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg).rotation = _bonds[23].Rotation;
_animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.RightUpperLeg).rotation = _bonds[28].Rotation;
_animator.GetBoneTransform(HumanBodyBones.RightUpperLeg).Rotate(0, -180, 0,
Space.Self);
_animator.GetBoneTransform(HumanBodyBones.RightLowerLeg).rotation = _bonds[29].Rotation;
_animator.GetBoneTransform(HumanBodyBones.RightLowerLeg).Rotate(0, -180, 0,
Space.Self);
_isReceived = false;
}
}
private void OnDisable()
{
_listener.DisConnect();
}
private void OnReceive(List<PoseLandmark> landmarks)
{
// 计算腰部
var frontLeft = Vector3.Cross(
landmarks[PoseLandmarkType.RightHip].Position - landmarks[PoseLandmarkType.LeftHip].Position,
landmarks[PoseLandmarkType.RightShoulder].Position - landmarks[PoseLandmarkType.LeftHip].Position);
var frontRight = Vector3.Cross(
landmarks[PoseLandmarkType.LeftShoulder].Position - landmarks[PoseLandmarkType.RightHip].Position,
landmarks[PoseLandmarkType.LeftHip].Position - landmarks[PoseLandmarkType.LeftHip].Position);
var front = frontLeft + frontRight;
front.Normalize();
var oldRotation = _rotationNodes[HumanBodyBones.Hips];
_rotationNodes[HumanBodyBones.Hips] = new RotationNode(
oldRotation.UnityName,
oldRotation.Rotation,
Quaternion.LookRotation(front));
_landmarks = landmarks;
_isReceived = true;
}
private void CreateRotationNodes()
{
_rotationNodes = new Dictionary<HumanBodyBones, RotationNode>();
var bonesArray = new[]
{
HumanBodyBones.Hips,
HumanBodyBones.LeftUpperArm,
HumanBodyBones.LeftLowerArm,
HumanBodyBones.RightUpperArm,
HumanBodyBones.RightLowerArm,
HumanBodyBones.LeftUpperLeg,
HumanBodyBones.LeftLowerLeg,
HumanBodyBones.RightUpperLeg,
HumanBodyBones.RightLowerLeg
};
foreach (var bone in bonesArray)
{
var rotation = _animator.GetBoneTransform(bone).rotation;
_rotationNodes.Add(bone, new RotationNode(bone, rotation, rotation));
}
}
private void CreateNodes()
{
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
ball.transform.localScale = new Vector3(Scale, Scale, Scale);
if (i <= 10)
{
ball.GetComponent<Renderer>().material.color = Color.red; //给头部添加颜色
}
else if (i <= 22)
{
ball.GetComponent<Renderer>().material.color = Color.blue; //给手部添加颜色
}
else if (i <= 32)
{
ball.GetComponent<Renderer>().material.color = Color.green; //给脚部添加颜色
}
_nodes[i] = ball;
}
}
private void CreateBonds()
{
var headBonds = new[]
{
PoseLandmarkType.RightEar,
PoseLandmarkType.RightEyeOuter,
PoseLandmarkType.RightEye,
PoseLandmarkType.RightEyeInner,
PoseLandmarkType.Nose,
PoseLandmarkType.LeftEyeInner,
PoseLandmarkType.LeftEye,
PoseLandmarkType.LeftEyeOuter,
PoseLandmarkType.LeftEar
};
_bonds.AddRange(GenerateBondsList(headBonds));
var monthBonds = new[]
{
PoseLandmarkType.MouthLeft,
PoseLandmarkType.MouthRight,
};
_bonds.AddRange(GenerateBondsList(monthBonds));
var leftArmBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftElbow,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftPinky,
PoseLandmarkType.LeftIndex,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftThumb
};
_bonds.AddRange(GenerateBondsList(leftArmBonds));
var rightArmBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightElbow,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightPinky,
PoseLandmarkType.RightIndex,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightThumb
};
_bonds.AddRange(GenerateBondsList(rightArmBonds));
var leftLegBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftHip,
PoseLandmarkType.LeftKnee,
PoseLandmarkType.LeftAnkle,
PoseLandmarkType.LeftHeel,
PoseLandmarkType.LeftFootIndex,
PoseLandmarkType.LeftAnkle
};
_bonds.AddRange(GenerateBondsList(leftLegBonds));
var rightLegBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightHip,
PoseLandmarkType.RightKnee,
PoseLandmarkType.RightAnkle,
PoseLandmarkType.RightHeel,
PoseLandmarkType.RightFootIndex,
PoseLandmarkType.RightAnkle
};
_bonds.AddRange(GenerateBondsList(rightLegBonds));
// 最后手动添加身体上的两条横线
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftShoulder],
_nodes[PoseLandmarkType.RightShoulder],
Scale));
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftHip],
_nodes[PoseLandmarkType.RightHip],
Scale));
}
/// <summary>
/// 创建棍子列表
/// </summary>
/// <param name="nodes">需要连接起来的关键点 需要按顺序设置</param>
/// <returns></returns>
private List<Bond> GenerateBondsList(int[] nodes)
{
var bonds = new List<Bond>();
for (var i = 0; i < nodes.Length - 1; i++)
{
bonds.Add(new Bond(
_nodes[nodes[i]],
_nodes[nodes[i + 1]],
Scale));
}
return bonds;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a2b30b6aa6e08c4468a02e1fcabcd485
guid: a2b060336532a01bfb4593b385955175
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -7,15 +7,14 @@ public class CameraBehaviour : MonoBehaviour
private const int MouseWheelSensitivity = 1; //滚轮灵敏度设置
private const int MouseZoomMin = 1; //相机距离最小值
private const int MouseZoomMax = 20; //相机距离最大值
private const float XSpeed = 250.0f;
private const float YSpeed = 120.0f;
private const float XSpeed = 120.0f;
private const float YSpeed = 250.0f;
private const int YMinLimit = -360;
private const int YMaxLimit = 360;
private float _eulerX; //存储相机的euler角
private float _eulerY; //存储相机的euler角
private float _distance = 5; //相机和target之间的距离因为相机的Z轴总是指向target也就是相机z轴方向上的距离
private float _distance; //相机和target之间的距离因为相机的Z轴总是指向target也就是相机z轴方向上的距离
private Vector3 _targetOnScreenPosition; //目标的屏幕坐标第三个值为z轴距离
private Quaternion _cameraRotation; //存储相机的姿态四元数
private Vector3 _targetPosition; //target的位置
@ -31,11 +30,13 @@ private void Start()
{
//这里就是设置一下初始的相机视角以及一些其他变量这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
var angles = transform.eulerAngles;
_eulerX = angles.y;
_eulerY = angles.x;
_targetPosition = target.position;
//_cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0);
_cameraRotation = Quaternion.Euler(_eulerY, _eulerX, 0);
_eulerX = angles.x;
_eulerY = angles.y;
var position = target.position;
_targetPosition = position;
_cameraRotation = Quaternion.Euler(_eulerX, _eulerY, 0);
_distance = Vector3.Distance(position, transform.position);
// 引入中间变量 提高代码效率
var transform1 = transform;
//设置相机姿态
@ -52,13 +53,12 @@ private void Update()
//鼠标右键旋转功能
if (Input.GetMouseButton(1))
{
_eulerX += Input.GetAxis("Mouse X") * XSpeed * 0.02f;
_eulerY -= Input.GetAxis("Mouse Y") * YSpeed * 0.02f;
// 鼠标控制需要反转X、Y轴
_eulerX += Input.GetAxis("Mouse Y") * XSpeed * 0.02f;
_eulerX = ClampAngle(_eulerX, YMinLimit, YMaxLimit);
_eulerY -= Input.GetAxis("Mouse X") * YSpeed * 0.02f;
_eulerY = ClampAngle(_eulerY, YMinLimit, YMaxLimit);
//_cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0);
_cameraRotation = Quaternion.Euler(_eulerY, _eulerX, 0);
_cameraRotation = Quaternion.Euler(_eulerX, _eulerY, 0);
var position = _cameraRotation * new Vector3(0.0f, 0.0f, -_distance) + _targetPosition;
// 引入中间变量 提高代码效率
@ -66,7 +66,8 @@ private void Update()
transform1.rotation = _cameraRotation;
transform1.position = position;
}
else if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
{
if (_distance is >= MouseZoomMin and <= MouseZoomMax)
{

View File

@ -0,0 +1,55 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-6275755417433151442
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2b060336532a01bfb4593b385955175, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1107 &-4834836044711832442
AnimatorStateMachine:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Base Layer
m_ChildStates: []
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 0}
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BoneAnimator
serializedVersion: 5
m_AnimatorParameters: []
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: -4834836044711832442}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 1
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7406b3b3cd1a7812ca7823cf800c679b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,180 +0,0 @@
using System.Collections.Generic;
using Models;
using UnityEngine;
using Utils.PoseTransformHandlers;
public class MainBehaviour : MonoBehaviour
{
private readonly GameObject[] _nodes = new GameObject[PoseLandmarkType.MaxValue];
private readonly List<Bond> _bonds = new List<Bond>();
private readonly PoseTransform[] _poseTransforms = new PoseTransform[PoseLandmarkType.MaxValue];
private readonly UdpListener _listener = new UdpListener();
private const float Scale = 0.2f;
// Start is called before the first frame update
private void Start()
{
PoseTransform.AverageLength = 3;
CreateNodes();
CreateBonds();
_listener.AddHandler(OnReceive);
_listener.Connect(5000);
}
// Update is called once per frame
private void Update()
{
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
_nodes[i].transform.position = _poseTransforms[i].ResultPosition * -5;
}
foreach (var bond in _bonds)
{
bond.UpdateBond();
}
}
private void OnDisable()
{
_listener.DisConnect();
}
private void OnReceive(List<PoseLandmark> landmarks)
{
foreach (var landmark in landmarks)
{
PoseTransform.UpdatePosition(ref _poseTransforms[landmark.Type.Value], landmark);
}
}
private void CreateNodes()
{
for (var i = 0; i < PoseLandmarkType.MaxValue; i++)
{
var ball = GameObject.CreatePrimitive(PrimitiveType.Sphere);
ball.transform.localScale = new Vector3(Scale, Scale, Scale);
if (i <= 10)
{
ball.GetComponent<Renderer>().material.color = Color.red;//给头部添加颜色
}
else if (i <= 22)
{
ball.GetComponent<Renderer>().material.color = Color.blue;//给手部添加颜色
}
else if (i <= 32)
{
ball.GetComponent<Renderer>().material.color = Color.green;//给脚部添加颜色
}
_nodes[i] = ball;
_poseTransforms[i] = new PoseTransform(i, new AverageHandler());
}
}
private void CreateBonds()
{
var headBonds = new[]
{
PoseLandmarkType.RightEar,
PoseLandmarkType.RightEyeOuter,
PoseLandmarkType.RightEye,
PoseLandmarkType.RightEyeInner,
PoseLandmarkType.Nose,
PoseLandmarkType.LeftEyeInner,
PoseLandmarkType.LeftEye,
PoseLandmarkType.LeftEyeOuter,
PoseLandmarkType.LeftEar
};
_bonds.AddRange(GenerateBondsList(headBonds));
var monthBonds = new[]
{
PoseLandmarkType.MouthLeft,
PoseLandmarkType.MouthRight,
};
_bonds.AddRange(GenerateBondsList(monthBonds));
var leftArmBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftElbow,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftPinky,
PoseLandmarkType.LeftIndex,
PoseLandmarkType.LeftWrist,
PoseLandmarkType.LeftThumb
};
_bonds.AddRange(GenerateBondsList(leftArmBonds));
var rightArmBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightElbow,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightPinky,
PoseLandmarkType.RightIndex,
PoseLandmarkType.RightWrist,
PoseLandmarkType.RightThumb
};
_bonds.AddRange(GenerateBondsList(rightArmBonds));
var leftLegBonds = new[]
{
PoseLandmarkType.LeftShoulder,
PoseLandmarkType.LeftHip,
PoseLandmarkType.LeftKnee,
PoseLandmarkType.LeftAnkle,
PoseLandmarkType.LeftHeel,
PoseLandmarkType.LeftFootIndex,
PoseLandmarkType.LeftAnkle
};
_bonds.AddRange(GenerateBondsList(leftLegBonds));
var rightLegBonds = new[]
{
PoseLandmarkType.RightShoulder,
PoseLandmarkType.RightHip,
PoseLandmarkType.RightKnee,
PoseLandmarkType.RightAnkle,
PoseLandmarkType.RightHeel,
PoseLandmarkType.RightFootIndex,
PoseLandmarkType.RightAnkle
};
_bonds.AddRange(GenerateBondsList(rightLegBonds));
// 最后手动添加身体上的两条横线
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftShoulder],
_nodes[PoseLandmarkType.RightShoulder],
Scale));
_bonds.Add(new Bond(
_nodes[PoseLandmarkType.LeftHip],
_nodes[PoseLandmarkType.RightHip],
Scale));
}
/// <summary>
/// 创建棍子列表
/// </summary>
/// <param name="nodes">需要连接起来的关键点 需要按顺序设置</param>
/// <returns></returns>
private List<Bond> GenerateBondsList(int[] nodes)
{
var bonds = new List<Bond>();
for (var i = 0; i < nodes.Length - 1; i++)
{
bonds.Add(new Bond(
_nodes[nodes[i]],
_nodes[nodes[i + 1]],
Scale));
}
return bonds;
}
}

View File

@ -1,135 +0,0 @@
using System.Collections.Generic;
using Models;
using UnityEngine;
using Utils.PoseTransformHandlers;
public class ModelBehaviour : MonoBehaviour
{
private Animator _animator;
private readonly UdpListener _listener = new UdpListener();
private static readonly PoseTransform[] PoseTransforms = new PoseTransform[PoseLandmarkType.MaxValue];
private void Start()
{
_animator = GetComponent<Animator>(); // 获取动画控件
InitPoseTransformList();
//_listener.AddHandler(LogLandmarks);
_listener.AddHandler(RigPoint);
_listener.Connect(5000);
}
// Update is called once per frame
private void Update()
{
foreach (var landmark in PoseTransforms)
{
if (landmark.UnityName != HumanBodyBones.LastBone)
{
var transfrom = _animator.GetBoneTransform(landmark.UnityName);
var parentsum = new Vector3(0, 0, 0);
foreach (var parent in landmark.Parent)
{
parentsum += PoseTransforms[parent.Value].ResultPosition;
}
parentsum /= landmark.Parent.Count;
transfrom.rotation = Quaternion.FromToRotation(transfrom.rotation.eulerAngles,landmark.ResultPosition-parentsum);
}
}
}
private void OnDisable()
{
_listener.DisConnect();
}
private static void LogLandmarks(List<PoseLandmark> landmarks)
{
foreach (var landmark in landmarks)
{
Debug.Log(landmark.ToString());
}
}
//获取传上来的数据点坐标转换成四元数的回调函数
private static void RigPoint(List<PoseLandmark> landmarks)
{
foreach (var landmark in landmarks)
{
PoseTransform.UpdatePosition(ref PoseTransforms[landmark.Type.Value], landmark);
Debug.Log(PoseTransforms[landmark.Type.Value].UnityName+":"+PoseTransforms[landmark.Type.Value].ResultPosition);
}
}
/// <summary>
/// 初始化骨骼变化结构体列表
/// </summary>
private void InitPoseTransformList()
{
for (var type = 0; type <= PoseLandmarkType.RightFootIndex; type++)
{
var item = new PoseTransform(type, new NormalHandler());
if (item.UnityName != HumanBodyBones.LastBone)
{
item.PreviousQuaternion = _animator.GetBoneTransform(item.UnityName).rotation;
item.CurrentQuaternion = item.PreviousQuaternion;
}
PoseTransforms[type] = item;
}
// 在这里添加父节点
AddParentTransform(PoseLandmarkType.LeftShoulder, PoseLandmarkType.LeftHip);
AddParentTransform(PoseLandmarkType.LeftShoulder, PoseLandmarkType.RightHip);
AddParentTransform(PoseLandmarkType.RightShoulder, PoseLandmarkType.LeftHip);
AddParentTransform(PoseLandmarkType.RightShoulder, PoseLandmarkType.RightHip);
AddParentTransform(PoseLandmarkType.Nose, PoseLandmarkType.LeftShoulder);
AddParentTransform(PoseLandmarkType.Nose, PoseLandmarkType.RightShoulder);
AddParentTransform(PoseLandmarkType.LeftElbow, PoseLandmarkType.LeftShoulder);
AddParentTransform(PoseLandmarkType.RightElbow, PoseLandmarkType.RightShoulder);
AddParentTransform(PoseLandmarkType.LeftWrist, PoseLandmarkType.LeftElbow);
AddParentTransform(PoseLandmarkType.RightWrist, PoseLandmarkType.RightElbow);
AddParentTransform(PoseLandmarkType.LeftKnee, PoseLandmarkType.LeftHip);
AddParentTransform(PoseLandmarkType.RightKnee, PoseLandmarkType.RightHip);
AddParentTransform(PoseLandmarkType.LeftAnkle, PoseLandmarkType.LeftKnee);
AddParentTransform(PoseLandmarkType.RightAnkle, PoseLandmarkType.RightKnee);
AddParentTransform(PoseLandmarkType.LeftFootIndex, PoseLandmarkType.LeftAnkle);
AddParentTransform(PoseLandmarkType.RightFootIndex, PoseLandmarkType.RightAnkle);
}
/// <summary>
/// 给指定的骨骼变化结构体添加父节点
/// </summary>
/// <param name="target">需要添加的节点</param>
/// <param name="parent">添加的父节点</param>
private void AddParentTransform(int target, int parent)
{
var parents = PoseTransforms[target].Parent;
parents.Add(PoseTransforms[parent].MediaPipeName);
}
}

View File

@ -1,4 +1,5 @@
using UnityEngine;
using Utils;
namespace Models
{
@ -10,6 +11,9 @@ public class Bond
protected readonly GameObject Start;
protected readonly GameObject End;
private readonly GameObject _bond;
public Quaternion Rotation => _bond.transform.rotation;
public Vector3 Vector => End.transform.position - Start.transform.position;
public Bond(GameObject start,GameObject end,float scale)
{

View File

@ -1,160 +1,163 @@
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace Models
{
public class PoseLandmark
{
private const double Tolerance = 1E-6;
/// <summary>
/// 单个包的长度
/// </summary>
public const int PacketLength = 28;
/// <summary>
/// 坐标点的种类
/// </summary>
public PoseLandmarkType Type { get; }
/// <summary>
/// 真实世界x坐标
/// 以米为单位
/// 以臀部为重心 hip
/// </summary>
public float X { get; }
/// <summary>
/// 真实世界y坐标
/// 以米为单位
/// 以臀部为重心
/// </summary>
public float Y { get; }
/// <summary>
/// 真实世界z坐标
/// 以米为单位
/// 以臀部为重心
/// </summary>
public float Z { get; }
/// <summary>
/// 该坐标点估计的可见性
/// [0,1]
/// </summary>
public float Visibility { get; }
public long TimeStamp { get; }
public PoseLandmark(int type, float x, float y, float z, float visibility, long timeStamp)
{
Type = new PoseLandmarkType(type);
X = x;
Y = y;
Z = z;
Visibility = visibility;
TimeStamp = timeStamp;
}
/// <summary>
/// 单个包的长度
/// </summary>
public const int PacketLength = 28;
/// <summary>
/// 转换成字节数组
/// 便于UDP发送
/// </summary>
/// <returns></returns>
public byte[] ToByteArray()
{
var result = new byte[PacketLength];
/// <summary>
/// 坐标点的种类
/// </summary>
public PoseLandmarkType Type { get; }
BitConverter.GetBytes(Type.Value).CopyTo(result, 0);
BitConverter.GetBytes(X).CopyTo(result, 4);
BitConverter.GetBytes(Y).CopyTo(result, 8);
BitConverter.GetBytes(Z).CopyTo(result, 12);
BitConverter.GetBytes(Visibility).CopyTo(result, 16);
BitConverter.GetBytes(TimeStamp).CopyTo(result, 20);
return result;
}
/// <summary>
/// 真实世界x坐标
/// 以米为单位
/// 以臀部为重心 hip
/// </summary>
public float X { get; }
/// <summary>
/// 解析字节数组
/// </summary>
/// <param name="bytes">收到的字节数组</param>
/// <returns>字节数组中代表的坐标对象</returns>
public static PoseLandmark ValueOf(byte[] bytes)
{
var result = new PoseLandmark(
BitConverter.ToInt32(bytes, 0),
BitConverter.ToSingle(bytes, 4),
BitConverter.ToSingle(bytes, 8),
BitConverter.ToSingle(bytes, 12),
BitConverter.ToSingle(bytes, 16),
BitConverter.ToInt64(bytes, 20));
/// <summary>
/// 真实世界y坐标
/// 以米为单位
/// 以臀部为重心
/// </summary>
public float Y { get; }
return result;
}
/// <summary>
/// 真实世界z坐标
/// 以米为单位
/// 以臀部为重心
/// </summary>
public float Z { get; }
/// <summary>
/// 解析字节数组为对象列表
/// 单个
/// </summary>
/// <param name="bytes">字节数组</param>
/// <returns></returns>
public static List<PoseLandmark> ArrayOf(byte[] bytes)
{
var result = new List<PoseLandmark>();
public Vector3 Position => new Vector3(-X, -Y, -0.2f * Z);
for (var i = 0; i < bytes.Length; i = i + PacketLength)
/// <summary>
/// 该坐标点估计的可见性
/// [0,1]
/// </summary>
public float Visibility { get; }
public long TimeStamp { get; }
public PoseLandmark(int type, float x, float y, float z, float visibility, long timeStamp)
{
var landmark = new PoseLandmark(BitConverter.ToInt32(bytes, i),
BitConverter.ToSingle(bytes, i + 4),
BitConverter.ToSingle(bytes, i + 8),
BitConverter.ToSingle(bytes, i + 12),
BitConverter.ToSingle(bytes, i + 16),
BitConverter.ToInt64(bytes, i + 20));
result.Add(landmark);
Type = new PoseLandmarkType(type);
X = x;
Y = y;
Z = z;
Visibility = visibility;
TimeStamp = timeStamp;
}
return result;
}
public override bool Equals(object obj)
{
if (obj is not PoseLandmark landmark)
/// <summary>
/// 转换成字节数组
/// 便于UDP发送
/// </summary>
/// <returns></returns>
public byte[] ToByteArray()
{
return false;
var result = new byte[PacketLength];
BitConverter.GetBytes(Type.Value).CopyTo(result, 0);
BitConverter.GetBytes(X).CopyTo(result, 4);
BitConverter.GetBytes(Y).CopyTo(result, 8);
BitConverter.GetBytes(Z).CopyTo(result, 12);
BitConverter.GetBytes(Visibility).CopyTo(result, 16);
BitConverter.GetBytes(TimeStamp).CopyTo(result, 20);
return result;
}
else
/// <summary>
/// 解析字节数组
/// </summary>
/// <param name="bytes">收到的字节数组</param>
/// <returns>字节数组中代表的坐标对象</returns>
public static PoseLandmark ValueOf(byte[] bytes)
{
return Type.Value == landmark.Type.Value
&& Math.Abs(X - landmark.X) < Tolerance
&& Math.Abs(Y - landmark.Y) < Tolerance
&& Math.Abs(Z - landmark.Z) < Tolerance
&& Math.Abs(Visibility - landmark.Visibility) < Tolerance
&& TimeStamp == landmark.TimeStamp;
var result = new PoseLandmark(
BitConverter.ToInt32(bytes, 0),
BitConverter.ToSingle(bytes, 4),
BitConverter.ToSingle(bytes, 8),
BitConverter.ToSingle(bytes, 12),
BitConverter.ToSingle(bytes, 16),
BitConverter.ToInt64(bytes, 20));
return result;
}
}
public override int GetHashCode()
{
var hashCode = Type.GetHashCode();
hashCode ^= X.GetHashCode();
hashCode ^= Y.GetHashCode();
hashCode ^= Z.GetHashCode();
hashCode ^= Visibility.GetHashCode();
hashCode ^= TimeStamp.GetHashCode();
/// <summary>
/// 解析字节数组为对象列表
/// 单个
/// </summary>
/// <param name="bytes">字节数组</param>
/// <returns></returns>
public static List<PoseLandmark> ArrayOf(byte[] bytes)
{
var result = new List<PoseLandmark>();
return hashCode;
}
for (var i = 0; i < bytes.Length; i = i + PacketLength)
{
var landmark = new PoseLandmark(BitConverter.ToInt32(bytes, i),
BitConverter.ToSingle(bytes, i + 4),
BitConverter.ToSingle(bytes, i + 8),
BitConverter.ToSingle(bytes, i + 12),
BitConverter.ToSingle(bytes, i + 16),
BitConverter.ToInt64(bytes, i + 20));
public override string ToString()
{
var builder = new StringBuilder();
builder.Append($"Time: {TimeStamp}, Type: {Type}:\n");
builder.Append($"\tX:{X}, Y:{Y}, Z:{Z}, Visibility: {Visibility}\n");
result.Add(landmark);
}
return builder.ToString();
}
return result;
}
public override bool Equals(object obj)
{
if (obj is not PoseLandmark landmark)
{
return false;
}
else
{
return Type.Value == landmark.Type.Value
&& Math.Abs(X - landmark.X) < Tolerance
&& Math.Abs(Y - landmark.Y) < Tolerance
&& Math.Abs(Z - landmark.Z) < Tolerance
&& Math.Abs(Visibility - landmark.Visibility) < Tolerance
&& TimeStamp == landmark.TimeStamp;
}
}
public override int GetHashCode()
{
var hashCode = Type.GetHashCode();
hashCode ^= X.GetHashCode();
hashCode ^= Y.GetHashCode();
hashCode ^= Z.GetHashCode();
hashCode ^= Visibility.GetHashCode();
hashCode ^= TimeStamp.GetHashCode();
return hashCode;
}
public override string ToString()
{
var builder = new StringBuilder();
builder.Append($"Time: {TimeStamp}, Type: {Type}:\n");
builder.Append($"\tX:{X}, Y:{Y}, Z:{Z}, Visibility: {Visibility}\n");
return builder.ToString();
}
}
}

View File

@ -28,22 +28,11 @@ public struct PoseTransform
/// 取平均之后的结果
/// </summary>
public Vector3 ResultPosition => _transformHandler.GetResultPosition();
/// <summary>
/// 节点的父节点列表
/// </summary>
public readonly List<PoseLandmarkType> Parent;
/// <summary>
/// 骨骼节点的初始角度
/// </summary>
public Quaternion PreviousQuaternion;
/// <summary>
/// 骨骼节点的当前角度
/// </summary>
public Quaternion CurrentQuaternion;
private readonly IPoseTransformHandler _transformHandler;
public PoseTransform(
@ -54,8 +43,6 @@ IPoseTransformHandler handler
MediaPipeName = new PoseLandmarkType(type);
UnityName = GetRelatedBone(MediaPipeName);
Parent = new List<PoseLandmarkType>();
PreviousQuaternion = new Quaternion();
CurrentQuaternion = new Quaternion();
_transformHandler = handler;
}
@ -65,11 +52,6 @@ public static void UpdatePosition(ref PoseTransform pose, PoseLandmark landmark)
pose._transformHandler.ReceivePoseLandmark(landmark);
}
public static void CalculateRotation(ref PoseTransform poseTransform, PoseLandmark landmark)
{
}
public static Vector3 operator +(PoseTransform a) => a.ResultPosition;
public static Vector3 operator -(PoseTransform a) => -a.ResultPosition;

View File

@ -0,0 +1,29 @@
using UnityEngine;
namespace Models
{
public struct RotationNode
{
public readonly HumanBodyBones UnityName;
public Quaternion PreviousRotation;
public Quaternion Rotation;
public Quaternion CalculateRotate => PreviousRotation * Quaternion.Inverse(Rotation);
public RotationNode(HumanBodyBones humanBodyBone, Quaternion previousRotation, Quaternion rotation)
{
UnityName = humanBodyBone;
PreviousRotation = previousRotation;
Rotation = rotation;
}
public RotationNode(RotationNode node, PoseLandmark begin, PoseLandmark end)
{
UnityName = node.UnityName;
PreviousRotation = node.Rotation;
var forward = end.Position - begin.Position;
Rotation = Quaternion.LookRotation(forward);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 87e238cb51f34339a39945af13f43248
timeCreated: 1680090845

View File

@ -0,0 +1,441 @@
%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.18029127, g: 0.22572401, b: 0.3069303, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 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: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !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
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &306285767
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 306285770}
- component: {fileID: 306285769}
- component: {fileID: 306285768}
m_Layer: 0
m_Name: Camera
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &306285768
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 306285767}
m_Enabled: 1
--- !u!20 &306285769
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 306285767}
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_GateFitMode: 2
m_FOVAxisMode: 0
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: 0
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 &306285770
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 306285767}
m_LocalRotation: {x: 0.0016336598, y: 0.99834925, z: 0.037567556, w: -0.043414135}
m_LocalPosition: {x: -1.83, y: 6.98, z: 16.38}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: -4.31, y: 184.98, z: 0}
--- !u!1001 &670355942
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.x
value: -0.93436813
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.y
value: 0.81755877
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.z
value: -0.6021528
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_Name
value: troop
objectReference: {fileID: 0}
- target: {fileID: 5465940246521907071, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5465940246521907071, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.w
value: 0.8707891
objectReference: {fileID: 0}
- target: {fileID: 5465940246521907071, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 5465940246521907071, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.y
value: -0.49165684
objectReference: {fileID: 0}
- target: {fileID: 5465940246521907071, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: -58.899
objectReference: {fileID: 0}
- target: {fileID: 5866666021909216657, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_Controller
value:
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.x
value: -0.000114262104
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.y
value: 1.8739636
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.z
value: -0.00004636313
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.w
value: 0.9621656
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.x
value: 0.023309091
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.y
value: -0.26867148
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalRotation.z
value: -0.03885668
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 1.374
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: -31.263
objectReference: {fileID: 0}
- target: {fileID: 6502182839619065283, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: -5.01
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
--- !u!1 &670355943 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
m_PrefabInstance: {fileID: 670355942}
m_PrefabAsset: {fileID: 0}
--- !u!114 &670355944
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 670355943}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2b060336532a01bfb4593b385955175, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1059201228
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1059201230}
- component: {fileID: 1059201229}
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 &1059201229
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1059201228}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 0
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1059201230
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1059201228}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 7.33, y: 1.28, z: -4.76}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}

View File

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

View File

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 705507994}
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
m_IndirectSpecularColor: {r: 0.18029127, g: 0.22572401, b: 0.3069303, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
@ -136,11 +136,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.x
value: 0
value: -12.91
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.y
value: 0
value: -4.98
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.z
@ -178,6 +178,10 @@ PrefabInstance:
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: -464305122009946348, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_LocalPosition.x
value: -4.32
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
propertyPath: m_Name
value: troop
@ -189,7 +193,12 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
m_PrefabInstance: {fileID: 404755305}
m_PrefabAsset: {fileID: 0}
--- !u!114 &404755307
--- !u!4 &404755309 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
m_PrefabInstance: {fileID: 404755305}
m_PrefabAsset: {fileID: 0}
--- !u!114 &404755310
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -198,14 +207,9 @@ MonoBehaviour:
m_GameObject: {fileID: 404755306}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a2b30b6aa6e08c4468a02e1fcabcd485, type: 3}
m_Script: {fileID: 11500000, guid: a2b060336532a01bfb4593b385955175, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &404755309 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: c5470c9a1aff50643b6a9ff0bab4297d, type: 3}
m_PrefabInstance: {fileID: 404755305}
m_PrefabAsset: {fileID: 0}
--- !u!1 &705507993
GameObject:
m_ObjectHideFlags: 0

View File

@ -0,0 +1,21 @@
using Models;
using UnityEngine;
namespace Utils.PoseTransformHandlers
{
public class ZAxisHandler : IPoseTransformHandler
{
private Vector3 _result;
public void ReceivePoseLandmark(PoseLandmark landmark)
{
_result = new Vector3(landmark.X, landmark.Y, landmark.Z * 0.2f);
_result = _result * -1;
}
public Vector3 GetResultPosition()
{
return _result;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 12369669a7fc44eaae881f89678649b1
timeCreated: 1678024599