基于华为AR Engine与Unity3D的动作捕捉实现——骨骼点位置提取

基于华为AR Engine与Unity3D的动作捕捉实现——骨骼点位置提取

  • 简介
  • 环境搭建
  • 项目准备
  • 代码
  • 效果

简介

使用HUAWEI AR Engine(其实底层还是ARCore),在Mate 20 X设备上进行人体骨骼追踪

环境搭建

HUAWEI AR Engine可在华为开发者网站上下载到,具体步骤里面文档写的很清楚就不多说了

项目准备

基于华为AR Engine与Unity3D的动作捕捉实现——骨骼点位置提取_第1张图片
项目基于华为官方提供的BodyARSample进行修改

代码

修改文件BodyARController

namespace BodyARSample
{
    using UnityEngine;
    using System.Collections.Generic;
    using HuaweiARUnitySDK;
    using Common;
    using HuaweiARInternal;
    public class BodyARController : MonoBehaviour
    {
        [Tooltip("body prefabs")]
        public GameObject mesh;

        private List<ARBody> newBodys = new List<ARBody>();
        private List<ARBody> Bodys = new List<ARBody>();
        private Dictionary<ARBody.SkeletonPointName, ARBody.SkeletonPointEntry> skeletons = new Dictionary<ARBody.SkeletonPointName, ARBody.SkeletonPointEntry>();
        private List<GameObject> objs3D = new List<GameObject>();
        private List<GameObject> objs2D = new List<GameObject>();
        private Material m_skeletonMaterial;
        GUIStyle bb = new GUIStyle();
        private void Start()
        {
        	//用于设置Debug字体的大小颜色等
            bb.normal.background = null;
            bb.normal.textColor = new Color(1, 0, 0);
            bb.fontSize = 40;
            
            DeviceChanged.OnDeviceChange += ARSession.SetDisplayGeometry;

			//创建骨骼的材质
            m_skeletonMaterial = new Material(Shader.Find("Diffuse"));
			//生成用于描述3D空间骨骼的白色小球
            for (int i = 0; i < 15; i++)
            {
                GameObject g = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                g.transform.localScale = new Vector3(0.08f, 0.08f, 0.08f);
                g.SetActive(false);
                objs3D.Add(g);
            }
			//生成用于描述2D空间骨骼的白色小球
            for (int i = 0; i < 15; i++)
            {
                GameObject g = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                g.transform.localScale = new Vector3(0.08f, 0.08f, 0.08f);
                g.SetActive(false);
                objs2D.Add(g);
            }
        }

        public void Update()
        {
            int i = 0;
            newBodys.Clear();
            //查找是否有新的对象
            ARFrame.GetTrackables<ARBody>(newBodys, ARTrackableQueryFilter.NEW);
            //如果存在新的对象则加入到Bodys中
            foreach (var t in newBodys)
                Bodys.Add(t);

            if (Bodys.Count > 0)
            {
            	//清空骨骼
                skeletons.Clear();
                //获取对象的骨骼
                Bodys[0].GetSkeletons(skeletons);

				//遍历骨骼的每一个骨骼点
                foreach (var pair in skeletons)
                {
                    if (!pair.Value.Is3DValid)
                    {
                        continue;
                    }
                    if (!pair.Value.Is2DValid)
                    {
                        continue;
                    }
					//获取骨骼点的3D空间位置
                    Vector3 gl3DCoord = pair.Value.Coordinate3D;
                    //获取骨骼点的2D空间位置
                    Vector3 gl2DCoord = pair.Value.Coordinate2D;
                    //将2D位置转化为3D位置(伪3D)
                    Vector3 worldCoord = new Vector3((gl2DCoord.x + 1) / 2,
                        (gl2DCoord.y + 1) / 2, 3);
                    Vector3 wloc = Camera.main.ViewportToWorldPoint(worldCoord);

					//赋予对象名称
                    objs2D[i].name = pair.Key.ToString() + "2D";
                    objs3D[i].name = pair.Key.ToString() + "3D";
					//赋予对象材质
                    objs2D[i].GetComponent<MeshRenderer>().material = m_skeletonMaterial;
                    objs3D[i].GetComponent<MeshRenderer>().material = m_skeletonMaterial;
					//更新对象世界位置
                    objs2D[i].transform.position = wloc;
                    objs3D[i].transform.position = new Vector3(gl3DCoord.x * -0.2f, gl3DCoord.y * -0.2f, gl3DCoord.z * -0.2f);
					//激活对象
                    objs2D[i].SetActive(true);
                    objs3D[i].SetActive(true);
                    
                    i++;
                }
            }
        }
        //在屏幕右上角显示Debug信息
        void OnGUI()
        {
            int j = 0;
            foreach(var i in objs3D)
            {
                GUI.Label(new Rect(0, j++ * 40, 200, 200), "Location:" + i.transform.position.ToString(), bb);
            }
            if(Bodys.Count > 0)
                GUI.Label(new Rect(400, 0, 200, 200), Bodys[0].GetCoordinateSystemType().ToString(), bb);
        }
    }
}

效果


小一点的白球是2D出来的
大的白球是3D出来的

3D的看起来不是很准,不知道是不是环境问题

你可能感兴趣的:(有关Unity3D的一些东西,有关AR的一些东西,动作捕捉,ARcore,HUAWEI,AR,Engine,Unity3D,AR)