目录

应用开发(Java/Kotlin)

本章将基于Java语言和Kotlin语言的示例代码,向您介绍如何快速使用AR Engine Java SDK开发您的应用。下图为使用AR Engine SDK开发应用的通用流程。由于AR Engine场景代码实现复杂,本章以伪代码形式提供运动跟踪场景中关键代码,详细实现请参见示例代码,您可根据需要,选择学习。

运行前验证

检查当前设备是否安装了AR Engine,若已经安装则正常运行,若没有安装,App应采用合适的方式提醒用户安装AR Engine,如主动跳转应用市场,请求安装AR Engine。具体实现代码如下(详细请参见示例代码)。

“Java”
boolean isInstallArEngineApk = AREnginesApk.isAREngineApkReady(this);

if (!isInstallArEngineApk) {
    // ConnectAppMarketActivity.class为跳转应用市场的Activity。
    startActivity(new Intent(this, com.huawei.arengine.demos.common.ConnectAppMarketActivity.class));
    isRemindInstall = true;
}
“Kotlin”
val isInstallArEngineApk = AREnginesApk.isAREngineApkReady(this)

if (!isInstallArEngineApk) {
    // ConnectAppMarketActivity::class.java为跳转应用市场的Activity。
    startActivity(Intent(this, ConnectAppMarketActivity::class.java))
    isRemindInstall = true
}

创建AR场景

AR Engine提供5种场景,包括运动跟踪(ARWorldTrackingConfig)、人脸跟踪(ARFaceTrackingConfig)、手部识别(ARHandTrackingConfig)、人体跟踪(ARBodyTrackingConfig)和图像识别(ARImageTrackingConfig)。

以下示例代码以运动跟踪场景为例。

  1. 调用ARWorldTrackingConfig接口,创建运动跟踪ARSession。
    “Java”
    // 创建ARSession。
    ARSession mArSession = new ARSession(this);
    // 根据要使用的具体场景,选用具体的Config来初始化ARSession。
    ARWorldTrackingConfig config = new ARWorldTrackingConfig(mArSession);
    “Kotlin”
    private var mArSession: ARSession? = null
    private lateinit var mArConfig: ARConfigBase
    
    // 创建ARSession。
    mArSession = ARSession(this)
    // 根据要使用的具体场景,选用具体的Config来初始化ARSession。
    mArConfig = ARWorldTrackingConfig(mArSession)
  2. 创建运动跟踪ARSession后,可通过config.setXXX方法配置场景参数,如设置对焦模式(setFocusMode)、设置需要识别的平面类型(setPlaneFindingMode)等。
    “Java”
    config.setFocusMode(ARConfigBase.FocusMode.AUTO_FOCUS);
    config.setPlaneFindingMode(ARConfigBase.PlaneFindingMode.ENABLE);
    “Kotlin”
    mArConfig.focusMode = ARConfigBase.FocusMode.AUTO_FOCUS
    mArConfig.planeFindingMode = ARConfigBase.PlaneFindingMode.ENABLE
  3. 配置完场景参数后,将配置通过ARSession.configure传入运动跟踪AR场景。
    “Java”
    mArSession.configure(config);
    “Kotlin”
    mArSession?.configure(mArconfig)
  4. 启动运动跟踪AR场景。
    “Java”
    mArSession.resume();
    “Kotlin”
    mArSession?.resume()

帧处理

  1. AR Engine的计算结果支持每帧获取,在OnDrawFrame中调用ARSession.update可获取ARFrame,通过ARSession.getAllTrackables(ARPlane.class)获取当前AR Engine捕捉到的平面(ARPlane)。
    “Java”
    // 从ARSession中获取一帧的数据。
    ARFrame arFrame = mArSession.update();
    // 可以从ARFrame中获取ARCamera,ARCamera对象可以获取相机的投影矩阵,用来渲染窗口。
    ARCamera arCamera = arFrame.getCamera();
    // 从ARSession中获取所有的可跟踪平面。
    Collection<ARPlane> arPlanes = mArSession.getAllTrackables(ARPlane.class);
    “Kotlin”
    // 从ARSession中获取一帧的数据。
    val arFrame = mArSession?.update()
    // 可以从ARFrame中获取ARCamera,ARCamera对象可以获取相机的投影矩阵,用来渲染窗口。
    val arCamera = arFrame?.camera
    // 从ARSession中获取所有的可跟踪平面。
    val planes = mArSession?.getAllTrackables(ARPlane::class.java) ?: return
  2. 在捕捉到平面后,通过设备屏幕点击平面,可触发命中检测功能(hitTest),并将hit结果新建为锚点(ARAnchor)添加到ARSession持续跟踪。
    “Java”
    private MotionEvent motionEvent;
    public void initGestureDetector(Context context, String tag, GLSurfaceView surfaceView,
        ArrayBlockingQueue<GestureEvent> queuedSingleTaps) {
        GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            ...
            @Override
            public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
                this.motionEvent = motionEvent;
                onGestureEvent(GestureEvent.createSingleTapConfirmEvent(motionEvent), tag, queuedSingleTaps);
                return true;
            }
            ...
        });
    // 向ARFrame对象传入点击事件,并生成命中检测结果。
    List<ARHitResult> hitResults = arFrame.hitTest(motionEvent);
    // 在命中检测位置创建锚点,使得AREngine持续跟踪。
    for (ARHitResult arHitResult : hitResults) {
        arHitResult.createAnchor();
    }
    “Kotlin”
    // 向ARFrame对象传入点击事件,并生成命中检测结果。
    val hitResults = arFrame.hitTest(motionEvent)
    // 在命中检测位置创建锚点,使得AREngine持续跟踪。
    for (arHitResult in hitResults) {
        arHitResult.createAnchor();
    }
  3. 可根据锚点位置来绘制所需的虚拟物体,具体实现请参见示例代码。