Android 使用Arcore 实现多点测距

已更新第二版,详情见github链接github源码 点这里 <==
主要使用了Anchor(锚点),Pose (姿势/姿态),Node(节点),Vector3(三维向量)


github源码 点这里 <==

1.准备

  • 一台支持Arcore的手机
  • 依赖arcore和sceneform
    implementation 'com.google.ar:core:1.5.0'    implementation 'com.google.ar.sceneform:core:1.5.0'    implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.5.0'

-布局文件使用sceneform提供的fragment

      
import com.blankj.utilcode.util.ToastUtils;import com.google.ar.core.exceptions.UnavailableApkTooOldException;import com.google.ar.core.exceptions.UnavailableArcoreNotInstalledException;import com.google.ar.core.exceptions.UnavailableDeviceNotCompatibleException;import com.google.ar.core.exceptions.UnavailableException;import com.google.ar.core.exceptions.UnavailableSdkTooOldException;import com.google.ar.sceneform.ux.ArFragment;//可以直接使用ArFragment   我这里为了中文提示public class MyArFragment extends ArFragment {    @Override    protected void handleSessionException(UnavailableException sessionException) {        String message;        if (sessionException instanceof UnavailableArcoreNotInstalledException) {            message = "请安装ARCore";        } else if (sessionException instanceof UnavailableApkTooOldException) {            message = "请升级ARCore";        } else if (sessionException instanceof UnavailableSdkTooOldException) {            message = "请升级app";        } else if (sessionException instanceof UnavailableDeviceNotCompatibleException) {            message = "当前设备部不支持AR";        } else {            message = "未能创建AR会话,请查看机型适配,arcore版本与系统版本";            String var3 = String.valueOf(sessionException);        }        ToastUtils.showLong(message);    }}

2.监听点击 生成锚点

  • **设置ArFragment的Tap监听 **
        (UI_ArSceneView as MyArFragment).setOnTapArPlaneListener { hitResult, plane, motionEvent ->             val currentAnchor=hitResult.createAnchor()        }

3.计算两个锚点之间的距离

val startPose = endAnchor.poseval endPose = startAnchor.poseval dx = startPose.tx() - endPose.tx()val dy = startPose.ty() - endPose.ty()val dz = startPose.tz() - endPose.tz()val length = Math.sqrt((dx * dx + dy * dy + dz * dz).toDouble())anchorInfoBean.dataText = "距离为${decimalFormat.format(length)}m"

4.UI 划线 (两个锚点在ui上连接划线)

private fun drawLine(firstAnchor: Anchor, secondAnchor: Anchor) {    val firstAnchorNode = AnchorNode(firstAnchor)    val secondAnchorNode = AnchorNode(secondAnchor)    firstAnchorNode.setParent((UI_ArSceneView as MyArFragment).arSceneView.scene)    val firstWorldPosition = firstAnchorNode.worldPosition    val secondWorldPosition = secondAnchorNode.worldPosition    val difference = Vector3.subtract(firstWorldPosition, secondWorldPosition)    val directionFromTopToBottom = difference.normalized()    val rotationFromAToB = Quaternion.lookRotation(directionFromTopToBottom, Vector3.up())    MaterialFactory.makeOpaqueWithColor(this@MainActivity, com.google.ar.sceneform.rendering.Color(0f, 191f, 255f))            .thenAccept { material ->                val lineMode = ShapeFactory.makeCube(Vector3(0.01f, 0.01f, difference.length()), Vector3.zero(), material)                val lineNode = Node()                lineNode.setParent(firstAnchorNode)                lineNode.renderable = lineMode                lineNode.worldPosition = Vector3.add(firstWorldPosition, secondWorldPosition).scaled(0.5f)                lineNode.worldRotation = rotationFromAToB            }}

5.自定义Node 始终面向相机

 override fun onUpdate(p0: FrameTime?) {        scene?.let { scene ->            val cameraPosition = scene.camera.worldPosition            val nodePosition = this@FaceToCameraNode.worldPosition            val direction = Vector3.subtract(cameraPosition, nodePosition)            this@FaceToCameraNode.worldRotation = Quaternion.lookRotation(direction, Vector3.up())        }    }

UI这里有点复杂,主要难点在Vector3(空间向量)这里.用的是数学知识了.
1.先用两个Anchor 获得 世界坐标(worldPosition)
2.使用向量计算两点空间差
3.使用起始Anchor ,生成一个Node.附加到arSceneView上
4.使用MaterialFactory 创建一个Material.再创建一个 Node使用刚才的材质,附加到之前的Node上.


github源码 点这里 <==

更多相关文章

  1. Android(安卓)studio 使用问题
  2. Android官方教程翻译(1)——创建第一个Android应用
  3. Android(安卓)调用相机和调用图库
  4. android 使用include 调用内部组件
  5. Android(安卓)SQLite数据库解析并使用两种方法实现增删改查
  6. Calling startActivity() from outside of an Activity context
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. android 开发之电子钢琴 源码
  2. android scroller用法及属性
  3. Android的事件转递机制
  4. Android实现三级联动下拉框 下拉列表spin
  5. Android(安卓)dumpstate 工具解析
  6. listview自定义背景以及item自定义背景
  7. Android权威编程指南读书笔记(1-2章)
  8. android客户端程序访问服务器端webservic
  9. 《Android开发从零开始》――10. LinearL
  10. android 实现定时器