如何用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虚拟现实广泛引用,让数字化信息和现实世界融合,目前大家的目光主要聚焦于视觉交互层面,为了在虚拟环境中更好的再现真实世界的三维空间体验,引入听觉层面必不可少,空间音频孕育而生. 空 ...
随机推荐
- 基于WPF重复造轮子,写一款数据库文档管理工具(一)
项目背景 公司业务历史悠久且复杂,数据库的表更是多而繁杂,每次基于老业务做功能开发都需要去翻以前的表和业务代码.需要理解旧的表的用途以及包含的字段的含义,表少还好说,但是表一多这就很浪费时间,而且留下 ...
- javascript引用奇趣
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Java学习 (六)基础篇 类型转换
类型转换 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换 字节大小(容量)-> 低--------------------------------------------- ...
- React报错之map() is not a function
正文从这开始~ 总览 当我们对一个不是数组的值调用map()方法时,就会产生"TypeError: map is not a function"错误.为了解决该错误,请将你调用ma ...
- placeholder 设置字体颜色
input::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } input:-moz-placeholder { col ...
- FreeSql 将 Saas 租户方案精简到极致[.NET ORM SAAS]
什么是多租户 维基百科:"软件多租户是指一种软件架构,在这种软件架构中,软件的一个实例运行在服务器上并且为多个租户服务".一个租户是一组共享该软件实例特定权限的用户.有了多租户架构 ...
- 解决国内不能访问github的问题
问题 最近访问GitHub总是不稳定,经常连不上, 出各种错误(OpenSSL SSL_read: Connection was reset, errno 10054, Connection refu ...
- 笃情开源:我和 Apache DolphinScheduler 社区的故事
背景 本文的主人翁是 2 次飞机参会现场交流,四天研究就把 DolphinScheduler 用上生产的来自车联网行业的大数据 boy - 黄立同学.怎么样,听起来是不是有点 crazy?下面就来看看 ...
- Luogu1769 淘汰赛制_NOI导刊2010提高(01)(概率DP)
第\(i\)次位置在\(pos_0 / 2^{i - 1}\) #include <iostream> #include <cstdio> #include <cstri ...
- 「CCO 2017」专业网络
Kevin 正在一个社区中开发他的专业网络.不幸的是,他是个外地人,还不认识社区中的任何人.但是他可以与 N 个人建立朋友关系 . 然而,社区里没几个人想与一个外地人交朋友.Kevin 想交朋友的 N ...