如何用AR Engine环境Mesh能力实现虚实遮挡

在AR应用中,用户最不希望看到不真实的穿模现象发生,如虚拟形象部分身体陷入墙壁之中,或者未碰到墙壁却已无法移动,这种不真实的交互十分影响用户体验 。那如何才能让避免虚拟物体的穿模问题呢?使用AR Engine的环境Mesh能力就能帮助开发者解决这个问题 。
效果展示实现方法AR Engine提供实时计算并输出画面环境Mesh数据的能力 。通过环境Mesh能力虚拟角色可以准确识别当前所处三维空间的情况,让虚拟物体不仅仅能放置在水平面和垂直面上,还可以放置在任意可重建的曲面上 。开发者可利用重建的环境Mesh实现虚实遮挡和碰撞检测,可以让虚拟物体藏在真实物品后,避免现实物体和虚拟物体融合现象的发生,从而实现沉浸式AR体验 。
集成步骤开发环境要求:JDK 1.8.211及以上 。
安装Android Studio 3.0及以上:
minSdkVersion 26及以上
targetSdkVersion 29(推荐)
compileSdkVersion 29(推荐)
Gradle 6.1.1及以上(推荐)
在华为终端设备上的应用市场下载AR Engine服务端APK(需在华为应用市场,搜索“华为AR Engine”)并安装到终端设备 。
测试应用的设备:参见AREngine特性软硬件依赖表中环境Mesh支持设备列表 。如果同时使用多个HMS Core的服务,则需要使用各个Kit对应的最大值 。
开发准备

  1. 在开发应用前需要在华为开发者联盟网站上注册成为开发者并完成实名认证,具体方法请参见帐号注册认证 。
  2. 华为提供了Maven仓集成方式的AR Engine SDK包,在开始开发前,需要将AR Engine SDK集成到您的开发环境中 。
  3. Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同 。请根据您当前的Gradle插件版本,选择对应的配置过程 。
  4. 以7.0为例:
打开Android Studio项目级“build.gradle”文件,添加Maven代码库 。
在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址 。
buildscript {     repositories {         google()         jcenter()         maven {url "https://developer.huawei.com/repo/" }     }}打开项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址
dependencyResolutionManagement {    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)    repositories {        repositories {             google()            jcenter()            maven {url "https://developer.huawei.com/repo/" }        }    }}
  1. 添加依赖 在“dependencies”中添加如下编译依赖:
dependencies {    implementation 'com.huawei.hms:arenginesdk:{version}}开发步骤
  1. 创建HitResultDisplay类,这个类根据指定的参数来绘制虚拟对象
Public class HitResultDisplay implements SceneMeshComponenDisplay{ //初始化VirtualObjectData VirtualObjectData mVirtualObject = new VirtualObjectData(); //在init方法中给mVirtualObject传入上下文 Public void init(Context context){mVirtualObject.init(context);//传入材质属性mVirtualObject.setMaterialProperties(); } //在onDrawFrame方法中传入ARFrame,用来获取光照估计 Public void onDrawFrame(ARFrame arframe){//获取光照估计ARLightEstimate le = arframe.getLightEstimate();//获取当前相机视野的像素强度lightIntensity = le.getPixelIntensity();//获取好之后,需要给mVirtualObject中一些方法传入数据mVirtualObject.draw(…,…,lightIntensity,…);//创建handleTap方法传入ARFrame对象来获取坐标信息handleTap(arframe); }     //实现handleTap方法     Private void handleTap(ARFrame frame){        //用ARFrame对象调用hitTest        List<ARHitResult> hitTestResults = frame.hitTest(tap);        //检测平面是否被击中,是否在平面多边形中被击中        For(int i = 0;i<hitTestResults.size();i++){            ARHitResult hitResultTemp = hitTestResults.get(i);            Trackable = hitResultTemp.getTrackable();            If(trackable instanceof ARPoint && ((ARPoint) trackable).getOrientationMode() == ARPoint.OrientationMode.ESTIMATED_SURFACE_NORMAL){                isHasHitFlag = true;                hitResult = hitResultTemp;            }        }     }}

经验总结扩展阅读