通过修改人体跟踪Demo源码,改变人体骨骼的初始显示位置,复制多份骨骼显示等跟踪效果,实现选择拖动人体骨骼的互动效果。

什么是BodyAR?

HUAWEI AR Engine 是一个用于在 Android 上构建增强现实应用的平台。BodyAR是AR Engine的子系统,允许您的应用:

要了解更多信息,请参阅我们的开发人员文档(JavaUnity)。

一款可以在华为手机上运行的Android应用程序,可通过相机扫描人体,识别和跟踪15个人体骨骼点的位置和姿态,并渲染出虚拟的人体骨骼模型,同时可以改变人体骨骼的初始显示位置,复制多份虚拟骨骼显示等跟踪效果,实现选择拖动人体骨骼的互动效果。

硬件要求

准备一部华为荣耀V20或P30 Pro手机(本文以P30 Pro举例说明),一台PC和一根Type-C数据线。。

软件要求

  1. 解压缩下载的HUAWEI_AR_Engine_SDK.zip文件。
  2. 启动Unity,新建一个工程,导入步骤1解压出的文件路径下unity目录中的HUAWEI AR Engine Unity SDK_vx.x.x.unitypackage,然后打开Examples/BodyARSample下的worldBodyAR场景,如图1所示:

构建并运行示例应用程序

  1. 设置Build Settings,选择场景和Android平台,如下图所示(Gradle构建失败时,可以选择Internal构建):

Build Settings页面

  1. 点击File->Build And Run, Unity将自动编译安装。

该demo程序将运行在P30 Pro手机上,确认相机权限后,后置相机对准人体,Demo将识别出该人体的骨骼点,效果如图:

修改人体骨骼渲染位置

在此步骤中,您将需要实现修改人体骨骼渲染位置,使其能够渲染在指的的位置(非人体位置),并可以支持复制多份骨骼显示。

首先,此demo程序已有场景运行的是world + body的AR场景,AREngine可以同时跟踪现实世界中的位姿(可以监测识别出各种类型的平面(桌面,墙面等)的大小和位置,并支持命中检测,详细请参考AREngine功能说明)和人体骨骼。因此可以利用命中检测获取现实世界空间中的锚点,从而控制人体骨骼显示在锚点上。

修改BodySkeletonVisualizer.cs文件,增加保存已有锚点的变量。
public static List <ARAnchor> addedAnchors = new List ();

修改WorldBodyARController.cs文件,在_DrawARLogo方法添加锚点时,修改BodySkeletonVisualizer.cs的锚点变量

BodySkeletonVisualizer.addedAnchors = addedAnchors;

修改BodySkeletonVisualizer.cs类中privatevoid_Draw3DBody()方法,当识别3Dbody并渲染骨骼模型时,如果以有现实世界中的锚点,则调整渲染位置到锚点上。

m_body.GetSkeletons(m_bodySkeletons); Matrix4x4 camera2WorldMatrix = m_skeletonCamera.cameraToWorldMatrix; ARBody.SkeletonPointEntry pointRightAnkle = m_bodySkeletons[ARBody.SkeletonPointName.Right_Ankle]; Vector3 pointRightAnkleInWorldSpace = camera2WorldMatrix.MultiplyPoint(pointRightAnkle.Coordinate3D); foreach (var pair in m_bodySkeletons) { if (!pair.Value.Is3DValid) { continue; } m_skeletonPointObject[(int)pair.Key].name = pair.Key.ToString(); Vector3 positionInCameraSpace = pair.Value.Coordinate3D; Vector3 positionInWorldSpace = camera2WorldMatrix.MultiplyPoint(positionInCameraSpace); if (addedAnchors.Count != 0) { Matrix4x4 matrixMove = Matrix4x4.identity; //根据Right_Ankle的位置到锚点位置得到平移矩阵做平移 Vector3 posFromRightAnkle = positionInWorldSpace - pointRightAnkleInWorldSpace; matrixMove.m03 = posFromRightAnkle.x; //x轴平移量 matrixMove.m13 = posFromRightAnkle.y; //y轴平移量 matrixMove.m23 = posFromRightAnkle.z; //z轴平移量 // 每个锚点复制一份 for (int i = 0; i < addedAnchors.Count; i++) { Vector4 startPos = new Vector4(addedAnchors[i].GetPose().position.x, addedAnchors[i].GetPose().position.y, addedAnchors[i].GetPose().position.z, 1); Vector4 pointMoved = matrixMove * startPos; m_skeletonPointObject[(int)pair.Key + (int)ARBody.SkeletonPointName.SKELETON_LENGTH * i].transform.position = new Vector3(pointMoved.x, pointMoved.y, pointMoved.z); m_skeletonPointObject[(int)pair.Key + (int)ARBody.SkeletonPointName.SKELETON_LENGTH * i].GetComponent<MeshRenderer>().material = m_skeletonMaterial; m_skeletonPointObject[(int)pair.Key + (int)ARBody.SkeletonPointName.SKELETON_LENGTH * i].SetActive(true); } } else { m_skeletonPointObject[(int)pair.Key].transform.position = positionInWorldSpace; m_skeletonPointObject[(int)pair.Key].GetComponent<MeshRenderer>().material = m_skeletonMaterial; m_skeletonPointObject[(int)pair.Key].SetActive(true); } }

运行修改后的程序,得到如下效果:

干得好,你已经成功完成了codelab并学到了:

您还可以查看示例中的其他demo程序以了解更多的AREngine的能力。

已复制代码