如何用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对应的最大值。
开发准备
华为提供了Maven仓集成方式的AR Engine SDK包,在开始开发前,需要将AR Engine SDK集成到您的开发环境中。
Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请根据您当前的Gradle插件版本,选择对应的配置过程。
以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/" }
}
}
}
- 添加依赖 在“dependencies”中添加如下编译依赖:
dependencies {
implementation 'com.huawei.hms:arenginesdk:{version}
}
开发步骤
- 创建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;
}
}
}
}
- 创建SceneMeshDisplay类,用来渲染场景网络
Public class SceneMeshDiaplay implements SceneMeshComponenDisplay{
//需要在init中实现openGL的一些操作
Public void init(Context context){}
//在onDrawFrame方法中获取当前对应的环境Mesh
Public void onDrawFrame(ARFrame arframe){
ARSceneMesh arSceneMesh = arframe.acquireSceneMesh();
//创建一个用来更新数据的方法把arSceneMesh传入进去
updateSceneMeshData(arSceneMesh);
//arSceneMesh使用完之后需要释放
arSceneMesh.release();
}
//实现这个方法用来更新数据
Public void updateSceneMeshData(ARSceneMesh sceneMesh){
//返回当前视角下环境Mesh顶点坐标数组
FloatBuffer meshVertices = sceneMesh.getVertices();
//返回当前视角下环境Mesh三角面片顶点索引的数组
IntBuffer meshTriangleIndices = sceneMesh.getTriangleIndices();
}
}
- 创建SceneMeshRenderManager类,这个类来提供与外部场景相关的渲染管理器,
包括虚拟对象渲染管理
public class SceneMeshRenderManager implements GLSurfaceView.Render{
//初始化更新网络数据和执行渲染的类
private SceneMeshDisplay mSceneMesh = new SceneMeshDisplay();
//初始化绘制虚拟对象的类
Private HitResultDisplay mHitResultDisplay = new HitResultDisplay();
//实现onSurfaceCreated()方法
public void onSurfaceCreated(){
//需要给mSceneMesh 类和mHitResultDisplay类传入 context
mSceneMesh.init(mContext);
mHitResultDisplay.init(mContext);
}
//实现onDrawFrame()方法;
public void onDrawFrame(){
//用ARSession对象来配置camera。
mArSession.setCameraTexTureName();
ARFrame arFrame = mArSession.update();
ARCamera arCamera = arframe.getCamera();
//把SceneMeshDisplay类需要的数据传过去
mSceneMesh.onDrawFrame(arframe,viewmtxs,projmtxs);
}
}
- 创建SceneMeshActivity用来展示功能
public class SceneMeshActivity extends BaseActivity{
//提供与外部场景相关的渲染管理器,包括虚拟对象渲染管理类。
private ScemeMeshRenderManager mSceneMeshRenderManager;
//用来管理AR Engine的整个运行状态,
private ARSession mArSession;
//需要初始化一些类和对象
protected void onCreate(Bundle savedInstanceState){
mSceneMeshRenderManager = new SceneMeshRenderManager();
}
//在onResume方法中初始化ARSession
protected void onResume(){
//初始化ARSession
mArSession = new ARSession(this.getApplicationContext());
//基于session参数创建ARWorldTrackingConfig对象
ARConfigBase config = new ARWorldTrackingConfig(mArSession);
//需要把ARSession传给SceneMeshRenderManager
mSceneMeshRenderManager.setArSession(mArSession);
//需要开启mesh,用config调用setEnableItem方法
config.setEnableItem(ARConfigBase.ENABLE_MESH | ARConfigBase.ENABLE_DEPTH);
}
}
具体实现可参考示例代码
了解更多详情>>
访问华为开发者联盟官网
获取开发指导文档
华为移动服务开源仓库地址:GitHub、Gitee
关注我们,第一时间了解 HMS Core 最新技术资讯~
如何用AR Engine环境Mesh能力实现虚实遮挡的更多相关文章
- AR Engine光照估计能力,让虚拟物体在现实世界更具真实感
AR是一项现实增强技术,即在视觉层面上实现虚拟物体和现实世界的深度融合,打造沉浸式AR交互体验.而想要增强虚拟物体与现实世界的融合效果,光照估计则是关键能力之一. 人们所看到的世界外观,都是由光和物质 ...
- 如何用AR Engine开发一个虚拟形象表情包?
现如今,人们在网上聊天.发帖时越来越爱用表情包,表情包一方面是一种个性化的表达方式,另一方面更能传达出当下的心理活动,可以说在网络社交中表情包是一个不可或缺的存在.加上近年来元宇宙的兴起,3D虚拟形象 ...
- AR Engine运动跟踪能力,高精度实现沉浸式AR体验
随着电子产品的普遍应用,AR技术也开始广泛普及,在游戏.电商.家装等领域都有涉及.比如,在室内设计时,我们可以通过AR技术在实际场景中进行虚拟软装的搭配,运用华为AR Engine运动跟踪能力在实际应 ...
- HMS Core AR Engine 2D图片/3D物体跟踪技术 助力打造更智能AR交互体验
AR技术已经被广泛应用于营销.教育.游戏.展览等场景.通过2D图像跟踪技术和3D物体跟踪技术,用户只需使用一台手机进行拍摄,即可实现海报.卡牌等平面物体以及文物.手办等立体物体的AR效果.尽管近年来2 ...
- 用AR Engine手部骨骼跟踪能力实现虚拟手表试戴
AR技术的落地应用,推动着电商领域的不断升级,通过增强现实为用户带来了虚拟与现实结合的AR购物体验.如AR试衣.AR试鞋.AR试妆等功能的出现让用户在手机上就能体验产品的佩戴效果,可以让用户更直观.更 ...
- ArcGIS Engine环境下创建自定义的ArcToolbox Geoprocessing工具
在上一篇日志中介绍了自己通过几何的方法合并断开的线要素的ArcGIS插件式的应用程序.但是后来考虑到插件式的程序的配置和使用比较繁琐,也没有比较好的错误处理机制,于是我就把之前的程序封装成一个类似于A ...
- 华为在HDC2021发布全新HMS Core 6 宣布跨OS能力开放
[2021年10月22日·东莞]华为开发者大会 2021(Together)于今天正式开幕,华为在主题演讲中正式发布全新的HMS Core 6,向全球开发者开放7大领域的69个Kit和21,738个A ...
- 华为HMS Core携手超图为三维GIS注入新动能
6月30日,在2022(第五届)GIS软件技术大会GIS基础软件新技术板块论坛上,华为联合超图推出了基于HMS Core 3D Engine开发的高保真三维GIS插件,通过3D渲染技术助力三维GIS实 ...
- AR空间音频能力,打造沉浸式声音体验
随着元宇宙的兴起,3D虚拟现实广泛引用,让数字化信息和现实世界融合,目前大家的目光主要聚焦于视觉交互层面,为了在虚拟环境中更好的再现真实世界的三维空间体验,引入听觉层面必不可少,空间音频孕育而生. 空 ...
随机推荐
- Collection集合和Collection的常用功能
boolean add(E e); 向集合里添加元素 boolean remove(E e); 删除集合中的某个元素 void clear(); 清空集合的所有元素 boolean contains( ...
- React报错之Object is possibly null
正文从这开始~ 类型守卫 使用类型守卫来解决React中useRef钩子"Object is possibly null"的错误.比如说,if (inputRef.current) ...
- Java面试题(三)--虚拟机
1 内存结构 1.简述一下JVM的内存结构?(高频) JVM在执行Java程序时,会把它管理的内存划分为若干个的区域,每个区域都有自己的用途和创建销毁时间.如下图所示,可以分为两大部分,线程私有区和共 ...
- 羽夏看Linux内核——引导启动(上)
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...
- Canvas 线性图形(三):曲线
前言 画曲线要用到二次贝塞尔曲线或三次贝塞尔曲线.贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如 PhotoShop. 二次贝塞尔曲线 二次贝塞尔曲线在 ...
- java基础———break,continue
break通常用在循环语句之中用来跳出循环: continue终止某次循环过程,跳过尚未执行的语句:接着执行下次是否执行循环的判定:
- noip 2014 提高组初赛
noip 2014 提高组初赛 一. TCP协议属于哪一层协议( ) A. 应用层 B. 传输层 C. 网络层 D. 数据链路层 B TCP(传输控制协议) 若有变量int a; float: x, ...
- 【读书笔记】C#高级编程 第二十四章 文件和注册表操作
(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByR ...
- SpringMvc(四)- 下载,上传,拦截器
1.图片下载 图片下载:将服务器端的文件以流的形式写到客户端,通过浏览器保存到本地,实现下载: 1.1 图片下载步骤 1.通过session获取上下文对象(session.getServletCont ...
- docker-compose部署elastiflow
docker-compose导入导出命令 涉及的命令有export.import.save.load save 命令 docker save [options] images [images...] ...