ARCore:ARCore开发的起步

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/p106786860/article/details/78620542

已经是第7章节了,终于可以开始正式接触到我们梦寐以求的ARCore了,相信大家应该都有一点点小激动了吧。那么下面我们就开始讲解如何进行ARCore的开发。

一、Session简介


初看到Session,大家都摸不到头脑。最直接的解释,它是ARCore API的一个类com.google.ar.core.Session。它管理了AR系统的状态,有自己的生命周期,开始和停止访问摄像头图像帧的获取。

所管理AR系统状态,包含跟踪的Anchor信息、通过session.add(Pose)和session.removeAnchor(anchors)保存和删除。session.getAllPlanes()返回被检测到的平面、当前投影矩阵等。

当ARCore App退至后台,Activity调用onPause()方法时,也需要通过session.pause()暂停Session,来停止摄像机的图像获取并获取资源。在App呈现在前台的时候,onResume()方法中调用session.resume(Config)可以重新启用Session,获取摄像机图像等。

有了平面和虚拟内容位置等信息进行渲染。但是当手机的位置移动的时候,我们是如何保持绘制内容的“位置不变”的呢?这都是基于ARCore系统不断返回的图像帧、设备位置和朝向等信息。调用session.update()方法来获取最新的相机帧,更新设备的位置,更新被跟踪的Anchor信息,更新被检查的平面。

二、Config简介


Config,即ARCore API中com.google.ar.core.Config,保存了用于配置Session的设置。那么这个配置中都包含了什么呢?

  1. 光线评估子系统的行为Config.LightingMode,包含开启或者禁止光线评估。
  2. 平面检测子系统的行为Config.PlaneFindingMode,包含开启和禁止平面检测。
  3. update()的行为Config.UpdateMode。在大多数设备中,摄像头被配置每秒捕捉30帧。当调用update()从摄像机获取帧的时,没有新的相机图片包含两种行为:立即分会和阻塞等待。

另外前面提到过目前并不是所有设备都支持ARCore,session.isSupport(config)方法就能完成当前设备是否支持该ARCore的配置。

三、ARCore开发起步


了解了Config和Session的意义之后,正式开始ARCore开发。我们需要处理这么几件事情:

  1. ARCore设备支持检测:自定义或者创建默认Config,然后通过Session来检测当前设备是否支持当前ARCore配置。
  2. 处理Session生命周期和视图变化:

    • 在Activity的onPause()和onResume()生命周期回调中,处理Session生命周期。正确的开始和暂停相机获取图像,释放资源等。
    • 当手机屏幕变化等情况发生,导致GLSurfaceView大小变化。需要适当调整透视图矩阵和背景,设置纵横比和坐标缩放,用于UV坐标系和投影矩阵生成。保证变化后虚拟内容的正常渲染。

四、案例源码分析


了解了基本的概念和步骤后,我们来看看在Google的ARCore Demo中是如何处理的。
1. ARCore设备支持检测
com\google\ar\core\examples\java\helloar\HelloArActivity.java

public class HelloArActivity extends AppCompatActivity implements GLSurfaceView.Renderer {
    ... ...
    private Session mSession;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ... ... 
        //Sessoin类是ARCore API的主要入口,管理AR系统状态和处理Session生命周期,接收帧允许访问摄像头的图片和设备的Pose
        mSession = new Session(/this);
        //创建默认的Config,平面检测,光线评估被启动,并且阻塞更新被选中。检查当前的设备是否支持ARCore,从这个Config创建Session
        mDefaultConfig = Config.createDefaultConfig();
        if (!mSession.isSupported(mDefaultConfig)) {
            Toast.makeText(this, "This device does not support AR", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        ... ...
    }
}

2.处理Session生命周期和视图变化
com\google\ar\core\examples\java\helloar\HelloArActivity.java

public class HelloArActivity extends AppCompatActivity implements GLSurfaceView.Renderer {
    ... ...
    private Session mSession;

    @Override
    protected void onResume() {
        super.onResume();
        //ARCore需要摄像机权限来操作。如果我们还没有Android M及以上得到运行时的权限,现在是一个向用户请求它的好时机
        if (CameraPermissionHelper.hasCameraPermission(this)) {
            showLoadingMessage();

            //使用默认配置恢复Session,如果Session没有开始或者被暂停,这个方法必须在App的UI线程中被调用。它将会启动Session,初始化相机和运动跟踪,当update()被调用的时候,将会产生帧。注意这个顺序很重要 - 在onPause()中看到该说明,相反的在这里也同样适用。
            mSession.resume(mDefaultConfig);

            //恢复渲染线程,如果有必要的话重新创建OpenGL上下文,它和onPause对应
            mSurfaceView.onResume();
        } else {
            CameraPermissionHelper.requestCameraPermission(this);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        //注意这个顺序很重要 - GLSurfaceView首先暂停所以它不会再尝试查询Session。如果Session在GLSurfaceView。前被暂停,GLSurfaceView可能一直调用mSession.update()并且获取一个SessionPauseException
        mSurfaceView.onPause();

        //暂停当前Session,这个方法将会停止相机反馈和释放资源
        mSession.pause();
    } 

        @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        //通知ARCore Session视图大小被改变,所以透视矩阵和视频背景可以适当的调整。设置纵横比和坐标缩放,这个数据将会被使用UV坐标系,生成投影矩阵
        mSession.setDisplayGeometry(width, height);
    }
}

1.新技术,新未来!尽在1024工场。时刻关注最前沿技术资讯,发布最棒技术博文!(甭客气!尽情的扫描或者长按!)
1024工场服务号

2.完整和持续更新的《使用Android打开AR的开发大门—ARCore》文档,欢迎大家阅读!
https://www.kancloud.cn/p3243986735/arcore_develop/457951
这里写图片描述

猜你喜欢

转载自blog.csdn.net/p106786860/article/details/78620542
今日推荐