【ARFoundation学习笔记】射线检测

news/2025/2/12 14:08:39/

在这里插入图片描述


写在前面的话

本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏,更多详细内容请阅读原文以及官方文档。


文章目录

  • 射线检测
    • 射线检测概念
  • 小结


射线检测

射线检测是Unity中常见的一种物理检测方法,具体就不赘述了。除了Unity提供的Physics.Raycast()方法进行射线检测外,AR foundation还提供了AR RaycastManager组件专门用于AR中处理射线与平面、特征点的碰撞检测。

射线检测概念

射线检测通常用于在二维的屏幕上进行三维的物体检测,其简单原理就是从起始点向某一方向发射一条无限长的射线,这条射线一旦与物体的碰撞器接触就会触发检测事件。
在这里插入图片描述

假设要实现在手机屏幕上点击到AR plane之后,在对应位置产生一个小圆球(这就是第一章中使用到的案例),最好的方案就是射线检测。我们将摄像头的位置设置为初始点,而手指在屏幕上点击的位置视为基准点,构建一条穿过二点的射线,这条射线将触碰到其位置上的所有虚拟物体。往往射线检测的触发结果是从初始点开始触碰到的第一个物体。请看下述代码:

1using System.Collections.Generic;
2using UnityEngine;
3using UnityEngine.XR.ARFoundation;
4using UnityEngine.XR.ARSubsystems;
56[RequireComponent(typeof(ARRaycastManager))]
7public class AppControler : MonoBehaviour
8{
9public  GameObject spawnPrefab;
10static List<ARRaycastHit> Hits;
11private ARRaycastManager mRaycastManager;
12private GameObject spawnedObject = null;
13private void Start()
14{
15.       Hits = new List<ARRaycastHit>();
16.       mRaycastManager = GetComponent<ARRaycastManager>();
17}
1819void Update()
20{
21if (Input.touchCount == 0)
22return;
23var touch = Input.GetTouch(0);
24if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithin  Polygon | TrackableType.PlaneWithinBounds))
25{
26var hitPose = Hits[0].pose;
27if (spawnedObject == null)
28{
29.             spawnedObject = Instantiate(spawnPrefab, hitPose.position, hitPose.rotation);
30}
31else
32{
33.             spawnedObject.transform.position = hitPose.position;
34}
35}
36}
37}

在上述代码中,Hits是一个ARRaycastHitList,它保存了所有射线Hit到的物体的信息。当触发点击事件时,mRaycastManager.Raycast从摄像头发射一条向着touch.position的射线,并返回所有触碰到的虚拟物体的姿态信息给Hits,并且设置了检测的可跟踪对象为TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds(平面上的多边形或者平面带边界的平面包围盒,也就是摄像机内渲染出的可视化平面),并使用第一个检测到的平面物体的姿态信息Hits[0].pose来初始化预制体。

在ARFoundation中,目前射线检测只能用来检测平面和点云。ARFoundation中的射线检测与Unity中Physics模块使用的射线检测相似,但提供了独立的接口,在ARFoundation中使用射线检测需要ARRaycastManager组件,因为射线检测与被检测物体需要在同一个坐标空间中,所以该组件需要挂载在ARSessionOrigin对象上。
————————————————
版权声明:本文为CSDN博主「DavidWang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yolon3000/article/details/94458183

射线检测方法说明
public bool Raycast(Vector2 screenPoint, List hitResults, TrackableType trackableTypeMask = TrackableType.All)参数1为屏幕坐标点,参数2为所有与射线发生碰撞的对象列表,参数3为Trackable类型掩码(即只对该类或几类可跟踪对象进行射线检测),该方法的返回值为Bool型,true表示发生碰撞,false表示未发生碰撞。
public bool Raycast(Vector2 screenPoint, List hitResults, TrackableType trackableTypeMask = TrackableType.All)参数1为Ray类型的射线(包括位置与方向),参数2为所有与射线发生碰撞的对象列表,参数3为Trackable类型掩码(即只对该类或几类可跟踪对象进行射线检测),该方法的返回值为Bool型,true表示发生碰撞,false表示未发生碰撞。

trackableTypeMask 用来过滤需要进行碰撞检测的对象类型,Trackable类型其值可以是以下属性值的一个,也可以是几个,如果是几个,可以采用按位或,如TrackableType.PlaneWithinPolygon | TrackableType.FeaturePoint。

trackableType 属性说明
All这个值用于与放置的所有物体发生碰撞检测。如果我们填写这个值,那么在ARFoundation中,我们发射的射线将与场景中的所有平面、包围多边形、带法线的特征点进行碰撞检测。
FeaturePoint与当前帧点云中所有的特征点进行碰撞检测。
None此值用来表示trackableHit返回中没有碰撞发生,如果将此值传递给raycast,则不会得到任何碰撞结果。
PlaneWithinPolygon与已检测平面内的凸边界多边形进行碰撞检测。
PlaneWithinBounds与当前帧中已检测平面内的包围盒进行碰撞检测。
PlaneWithinInfinity与已检测到的平面进行碰撞检测,但这个检测不仅仅局限于包围盒或者多边形,而是可以与已检测到的平面的延展平面进行碰撞检测。
FeaturePointWithSurfaceNormal射线与评估平面进行碰撞检测,评估平面不一定能形成一个平面。
Planes射线与以上所有平面类型进行碰撞检测。
Image与2D图像进行射线检测。
Face与人脸进行射线检测。

ARRaycastHit类保存的是发生碰撞时检测到的碰撞体相关信息,其主要属性如下表所示。

ARRaycastHit 属性说明
Distancefloat类型,获取从射线源到命中点的距离
trackableId发生碰撞的可跟踪对象ID。
PosePose类型,获取射线击中的物体在Unity世界坐标中的姿态。
hitTypeTrackable类型,获取命中的可跟踪对象,即前文所述的七种可跟踪类型之一(实际上,目前ARFoundation只能对平面与特征点做射线检测)。
sessionRelativeDistance在Session空间中从射线起点到碰撞点的距离。
sessionRelativePose在Session空间碰撞点的姿态。

小结

使用AR RaycastHit可以用来专门处理AR空间中的射线检测信息。由于姿态信息都保存在了AR Session Rigion组件上,因此AR Raycast Manager也要挂载在该对象上。

AR RaycastHit可以获取到三维空间上所有的射线触碰到的姿态信息。我们总结了两个射线检测方法以及其参数信息,使用射线检测来实现一些基本的功能。
(作者本人的博客比官方文档写的详细多了)


http://www.ppmy.cn/news/1202038.html

相关文章

AD教程 (八)器件的复制和对齐

AD教程 &#xff08;八&#xff09;器件的复制和对齐 设置原理图工作区域 设置Sheet Size&#xff0c;将A4改为A3&#xff0c;增大原理图区域 按照原理图布局大致排布元件 框选需要复制的元件&#xff0c;按住Shift即可复制元件并拖动到合适的位置。如果元件需要对齐&#xf…

【带头学C++】----- 三、指针章 ---- 3.7 数组指针-3.8二维数组与数组指针的关系

3.7 数组指针 在C中&#xff0c;数组指针是指向数组的指针。可以使用指针来操作数组&#xff0c;例如访问数组元素或传递数组到函数。在C中&#xff0c;数组名实际上是一个指向数组第一个元素的指针。 下面是一些有关数组指针的重要概念&#xff1a; 定义数组指针&#xf…

使用Ruby编写通用爬虫程序

目录 一、引言 二、环境准备 三、爬虫程序设计 1. 抓取网页内容 2. 解析HTML内容 3. 提取特定信息 4. 数据存储 四、优化和扩展 五、结语 一、引言 网络爬虫是一种自动抓取互联网信息的程序。它们按照一定的规则和算法&#xff0c;遍历网页并提取所需的信息。使用Rub…

lightdb 普通用户拥有XMLTYPE类型的访问权限

文章目录 概述示例总结 概述 在信创移植的SQL语句中&#xff0c;有来源于Oracle数据库的SQL语句。 在Oracle中存在getClobVal函数&#xff0c;这个函数是Oracle中sys.XMLType的成员方法。 因此在LightDB23.3版本中实现了TYPE支持定义成员方法并且在新定义的XMLType类型中实现…

range-doppler图中间有一条线,是静态分量??这个静态分量,怎么理解

回复1&#xff1a; 在Range-Doppler图中&#xff0c;中间的一条线通常表示静态分量&#xff0c;也就是雷达自身或者静止目标的回波。这是因为雷达的工作原理是通过发送电磁波并接收其反射回波来检测目标。当目标相对于雷达静止或者雷达自身产生的回波时&#xff0c;由于没有相…

Web3.0的测试题

任务&#xff1a; 在前端开发一个查询UI&#xff0c;查询当前用户账户的ETH余额和指定ERC20合约中的余额 目标&#xff1a; UI框架指定使用 MUI (https://mui.com)需要查询到当前账户的ETH余额并展示在UI界面上需要输入ERC20合约地址后&#xff0c;查询到到当前账户在此ERC20…

104.c语言中的define的两个模糊点

1. define 是按照从上到下的顺序的 #define 必须先定义&#xff0c;否则报错 2.函数体内的define的影响 2.1 从定义开始的位置起&#xff0c;之后都有效 不受函数作用域的限制 #include <stdio.h>//int a[N] {0};#define N 100int a[N] {0}; //int b[X]; void abcd(v…

1.4 内网穿透与通知、查询用户订单

内网穿透与通知 文章目录 内网穿透与通知一、内网穿透1.1 工具下载 二、异步通知接收与应答2.1 支付通知2.2 签名的验证2.3 报文解密2.4 更新订单状态2.5 处理重复通知2.6 数据锁 三、处理通知完整代码3.1 接收通知Controller3.2 验签工具类3.3 处理订单Service3.4 更新订单状态…