关于android:如何用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;
            }
        }
     }
}
  1. 创立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();
     }
}
  1. 创立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);
}
}
  1. 创立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 最新技术资讯~

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理