2024-01-31-使用EQ-R实现手势交互
EQ-R
简介
EQ-Renderer是EQ基于sceneform(filament)扩展的一个用于安卓端的三维AR渲染器。
主要功能
它包含sceneform_v1.16.0中九成接口(剔除了如sfb资源加载等已弃用的内容),扩展了视频背景视图、解决了sceneform模型加载的内存泄漏问题、集成了AREngine和ORB-SLAM3、添加了场景坐标与地理坐标系(CGCS-2000)的转换方法。
注:由于精力有限,文档和示例都不完善。sceneform相关请直接参考谷歌官方文档,扩展部分接口说明请移步git联系。
相关链接
Git仓库
码云
EQ-R相关文档
功能实现
搭建开发环境,请参考使用EQ-Renderer创建AR加载模型
相关接口
本文介绍的功能是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",它实现了在点击位置添加标记。
关键代码如下:
- 添加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);
}
});
- 添加标记对象
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);
}
});
}
运行效果


浙公网安备 33010602011771号