通过修改人体跟踪Demo源码,改变人体骨骼的初始显示位置,复制多份骨骼显示等跟踪效果,实现选择拖动人体骨骼的互动效果。
HUAWEI AR Engine 是一个用于在 Android 上构建增强现实应用的平台。BodyAR是AR Engine的子系统,允许您的应用:
一款可以在华为手机上运行的Android应用程序,可通过相机扫描人体,识别和跟踪15个人体骨骼点的位置和姿态,并渲染出虚拟的人体骨骼模型,同时可以改变人体骨骼的初始显示位置,复制多份虚拟骨骼显示等跟踪效果,实现选择拖动人体骨骼的互动效果。
准备一部华为荣耀V20或P30 Pro手机(本文以P30 Pro举例说明),一台PC和一根Type-C数据线。。
Build Settings页面
该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的能力。