【Sceneform-EQR】使用EQ-Renderer实现手势交互

title: 使用EQ-Renderer实现手势交互
date: 2024-01-31
description: EQ-Renderer是基于sceneform(filament)扩展的一个用于安卓端的三维AR渲染器。 本文档记录如何创建一个简单的手势交互示例。

Sceneform-EQR

简介

EQ-Renderer是EQ基于sceneform(filament)扩展的一个用于安卓端的三维AR渲染器。

主要功能

它包含sceneform_v1.16.0中九成接口(剔除了如sfb资源加载等已弃用的内容),扩展了视频背景视图、解决了sceneform模型加载的内存泄漏问题、集成了AREngine和ORB-SLAM3、添加了场景坐标与地理坐标系(CGCS-2000)的转换方法。

注:由于精力有限,文档和示例都不完善。sceneform相关请直接参考谷歌官方文档,扩展部分接口说明请移步git联系。

EQ-R相关文档
  • 文档目录

相关链接

Git仓库
  • EQ-Renderer的示例工程
码云
  • EQ-Renderer的示例工程

配置环境

使用在线依赖

若使用离线依赖的方式,则跳过本节内容。

Maven配置

EQ-Renderer的maven仓库地址为:http://repo.eqgis.cn

根据AndroidSudio的版本,配置相应的AGP,这里我使用的gradle版本如下:

  • Android Gradle Plugin Version :8.1.0
  • Gradle Version:8.0

在工程目录下修改settings.gradle文件,示例如下:

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
        maven {
            allowInsecureProtocol = true
            url "http://repo.eqgis.cn"
        }
        maven {url "https://developer.huawei.com/repo" }
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            allowInsecureProtocol = true
            url "http://repo.eqgis.cn"
        }
        maven {url "https://developer.huawei.com/repo" }
    }
}

rootProject.name = "EQ-Renderer Sample"
include ':app'

注意:后面若要引入AREngine,则这里需要配置华为的maven仓库。

不同版本的Gradle配置在配置Maven仓库时,有一定差异。
Gradle 7.0版本后,需参考Android官方对于Gradle版本与Gradle插件的配套关系,把Gradle插件版本也升级到7.0及以上。

其它版本的gradle配置,请参考之前写的文档:视频地图开发文档#不同版本的Gradle

引入相关依赖

eq-renderer:三维渲染器,基于filament
eq-slam:slam算法库,当前版本(v1.0.2)使用的ORB-SLAM3,暂时仅支持arm-v8a。
opencv:图像处理
arcore:谷歌的AR服务
arengine:华为的AR服务

在模块的build.gradle文件中添加在线依赖,示例如下:

dependencies {
    //...
    
    //使用在线依赖
    implementation 'com.eqgis:eq-renderer:1.0.2'
    implementation 'com.eqgis:eq-slam:1.0.2'
    
    //引入opencv
    implementation 'org.opencv:opencv-v8a:4.5.5'

    //使用ARCore 和 AREngine (按需添加)
    implementation 'com.google.ar:core:1.39.0'
    //使用AREngine则额外添加下面依赖
    //华为仓库        maven {url "https://developer.huawei.com/repo/" }
    implementation 'com.huawei.hms:arenginesdk:3.7.0.3'
}

使用离线依赖

若已使用在线依赖的方式,则跳过本节内容。

下载AAR

EQ渲染器:
eq-renderer

SLAM算法库:
eq-slam

OpenCV(arm-v8a版本):
opencv-v8a

将相关库下载到本地,放入模块的/libs目录下,如图:

【Sceneform-EQR】使用EQ-Renderer实现手势交互_第1张图片

然后再在build.gradle文件中引入

dependencies {
    //...

    //使用离线依赖
    implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
}
引入ARCore

PS:若没有用到ARCore,可不添加这个依赖

ARCore仍采用在线依赖的方式

    //使用ARCore 和 AREngine (按需添加)
    implementation 'com.google.ar:core:1.39.0'
引入AREngine

PS:若没有用到AREngine,可不添加这个依赖

AREngine仍采用在线依赖的方式,注意:使用AREngine,需要配置华为的maven仓库。参考上面的Maven配置。

    //使用AREngine则额外添加下面依赖
    //华为仓库settings.gradle中添加“ maven {url "https://developer.huawei.com/repo/" } ”
    implementation 'com.huawei.hms:arenginesdk:3.7.0.3'

功能实现

这里以“点击模型,并在点击位置加载标记””为例。

接口说明

本文介绍的功能是sceneform已支持的,因此请直接参考谷歌sceneform API。

谷歌文档链接:https://developers.google.cn/sceneform/reference

  • Renderable

    • ModelRenderable

      • 用于渲染gltf2.0格式的模型(支持骨骼动画)
    • ViewRenderable

      • 用于渲染安卓View视图(常用于渲染文字、图片,也可渲染WebView和视频视图)
    • RenderableDefinition

      • 常用于绘制点、线、面、体
  • Node

    • 每个节点可以拥有任意数量的子节点和一个父节点
    • 通过setRenderable()方法绑定渲染对象
    • 节点对象可以设置tap\touch监听事件
  • Node.OnTapListener

    • Tap事件监听
  • Node.OnTouchListener

    • Touch事件监听

代码示例

配置开发环境以及创建场景并加载模型请参考文档:使用EQ-Renderer创建AR加载模型

手势交互参考示例源文件"InteractiveScene.java",它实现了在点击位置添加标记。

关键代码如下:

  1. 添加Tap监听事件
        modelNode.setOnTapListener(new Node.OnTapListener() {
            @Override
            public void onTap(HitTestResult hitTestResult, MotionEvent motionEvent) {
                //点击位置的节点对象
                Node node = hitTestResult.getNode();

                //获取点击对象的Node在世界坐标系下的空间位置、姿态
                Vector3 worldPosition = node.getWorldPosition();
                Quaternion worldRotation = node.getWorldRotation();
                Log.i(InteractiveScene.class.getSimpleName(), "对象节点: "+ worldRotation.toString() + "   " + worldPosition.toString());

                //点击位置与相机当前位置的距离
                float distance = hitTestResult.getDistance();
                //获取世界坐标系下的点击位置(射线检测:与点击对象包围盒的碰撞点位置)
                Vector3 point = hitTestResult.getPoint();
                Log.i(InteractiveScene.class.getSimpleName(), "点击位置与相机的距离是:" + distance + " 米" + point.toString());
                Toast.makeText(context, "碰撞点:"+ point, Toast.LENGTH_SHORT).show();

                //添加标记
                addObj(point,/*采用与父节点相同的姿态*/worldRotation);
            }
        });
  1. 添加标记对象
    public void addObj(Vector3 position,Quaternion rotation){
        //添加TextView,渲染文字
        TextView textView = new TextView(context);
        //Scenefrom默认情况下,250dp对应世界坐标系下的1m,
        textView.setTextSize(16);
        textView.setText("T");
        ViewRenderable.builder()
                .setView(context,textView)
                /*底部居中显示*/
                .setVerticalAlignment(ViewRenderable.VerticalAlignment.BOTTOM)
                .setHorizontalAlignment(ViewRenderable.HorizontalAlignment.CENTER)
                .build()
                .thenAccept(new Consumer<ViewRenderable>() {
                    @Override
                    public void accept(ViewRenderable viewRenderable) {
                        Node node = new Node();
                        node.setRenderable(viewRenderable);
                        node.setWorldScale(Vector3.one().scaled(0.25f));//比例
                        node.setWorldPosition(position);
                        node.setLocalRotation(rotation);
                        node.setParent(rootNode);
                    }
                });
    }

运行效果

在AR模式下,运行效果如下:

你可能感兴趣的:(#,Sceneform-EQR,移动端开发,ar,java)