【ARFoundation学习笔记】射线检测

在这里插入图片描述


写在前面的话

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


文章目录

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


射线检测

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

射线检测概念

射线检测通常用于在二维的屏幕上进行三维的物体检测,其简单原理就是从起始点向某一方向发射一条无限长的射线,这条射线一旦与物体的碰撞器接触就会触发检测事件。
【ARFoundation学习笔记】射线检测_第1张图片

假设要实现在手机屏幕上点击到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 属性 说明
Distance float类型,获取从射线源到命中点的距离
trackableId 发生碰撞的可跟踪对象ID。
Pose Pose类型,获取射线击中的物体在Unity世界坐标中的姿态。
hitType Trackable类型,获取命中的可跟踪对象,即前文所述的七种可跟踪类型之一(实际上,目前ARFoundation只能对平面与特征点做射线检测)。
sessionRelativeDistance 在Session空间中从射线起点到碰撞点的距离。
sessionRelativePose 在Session空间碰撞点的姿态。

小结

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

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

你可能感兴趣的:(学习,笔记,AR)