当前位置: 首页 > news >正文

【ARFoundation学习笔记】平面检测

在这里插入图片描述


写在前面的话

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


文章目录

  • 平面检测属性
    • 可视化平面
    • 平面检测的开关控制
      • 显示与隐藏已检测平面


平面检测属性

AR中检测平面的原理:AR Foundation对摄像机获取的图像进行分析处理,分离图像中的特征点(这些特征点往往是图像中明暗、强弱、颜色变化较大的点);利用VIO和IMU跟踪这些特征点的三维空间信息;在跟踪过程中,对特征点信息进行处理,并尝试用空间中位置相近或者符合一定规律的特征点构建平面,如果成功就是检测出了平面。平面有位置、方向和边界信息,AR Plane Manager负责检测平面以及管理这些检测出来的平面,但它并不负责渲染平面。

在AR Plane Manager中,我们可以设置平面检测的方式,如水平平面(Horizontal)、垂直平面(Vertical)、水平平面&垂直平面(Everything)或者不检测平面(Nothing),检测平面也是一个消耗性能的工作,而根据应用需要选择合适的检测方式可以优化应用性能。

平面本身是一个Trackable对象,因此在AR Session Origin上检测到的时候,AR Plane Manager会实例化一个平面Prefab并挂载AR Plane组件。


可视化平面

在这里插入图片描述

AR Plane Manager只负责平面的检测,并不负责平面的渲染。平面渲染通常在检测构建的Prefab上执行,预制体上的脚本如上所示:

红框中的顶点偏差阈值表示只有偏差值在阈值范围内的特征点才被归为同一平面,因此阈值越小检测越精确。AR Plane Mesh Visualizer组件主要是从边界特征点与其他特征点三角化生成一个平面网格,而这个网格由Mesh Renderer进行渲染。默认平面预制体还有一个Line Renderer用于渲染边缘。

书中示例了自定义Shader和渲染脚本以实现定制化的平面渲染。


平面检测的开关控制

15public void TogglePlaneDetection()
16{
17.       m_ARPlaneManager.enabled = !m_ARPlaneManager.enabled;
18string planeDetectionMessage = "";
19if (m_ARPlaneManager.enabled)
20{
21.          planeDetectionMessage = "禁用平面检测";
22SetAllPlanesActive(true);
23}
24else
25{
26.          planeDetectionMessage = "启用平面检测";
27SetAllPlanesActive(false);
28}34void SetAllPlanesActive(bool value)
35{
36foreach (var plane in m_ARPlaneManager.trackables)
37.          plane.gameObject.SetActive(value);
38}

对书内的代码进行了小小的裁剪。对于平面而言,我们可以通过设置平面物体的Active状态来控制平面的显示。还记得我们说平面是受Manager自动管理的,因此如果我们手动销毁平面可能会引发异常。

显示与隐藏已检测平面

直接关闭平面检测的话,那么程序后续也不会再检测新的平面。有时我们想要隐藏已检测平面的同时保留平面检测功能,以便在显示平面检测时直接显示那些新检测的平面,而不是重新开始检测。

1using System.Collections;
2using System.Collections.Generic;
3using UnityEngine;
4using UnityEngine.XR.ARFoundation;
5using UnityEngine.UI;
67public class PlaneDisplay : MonoBehaviour
8{
9public Text m_TogglePlaneDetectionText;
10private ARPlaneManager m_ARPlaneManager;
11private bool isShow = true;
12private List<ARPlane> mPlanes;
13void Start()
14{
15.       m_ARPlaneManager = GetComponent<ARPlaneManager>();
16.       mPlanes = new List<ARPlane>();
17.       m_ARPlaneManager.planesChanged += OnPlaneChanged;
18}
19void OnDisable()
20{
21.       m_ARPlaneManager.planesChanged -= OnPlaneChanged;
22}
23.    #region 显示与隐藏检测的平面
24public void TogglePlaneDisplay()
25{
26string planeDisplayMessage = "";
27if (isShow)
28{
29.          planeDisplayMessage = "隐藏平面";
30}
31else
32{
33.          planeDisplayMessage = "显示平面";
34}
35for (int i = mPlanes.Count - 1; i >= 0; i--)
36{
37if (mPlanes[i] == null || mPlanes[i].gameObject == null)
38.             mPlanes.Remove(mPlanes[i]);
39else
40.             mPlanes[i].gameObject.SetActive(isShow);
41}
42if (m_TogglePlaneDetectionText != null)
43.          m_TogglePlaneDetectionText.text = planeDisplayMessage;
4445.       isShow = !isShow;
46}
4748private void OnPlaneChanged(ARPlanesChangedEventArgs arg)
49{
50for (int i = 0; i < arg.added.Count; i++)
51{
52.          mPlanes.Add(arg.added[i]);
53.          arg.added[i].gameObject.SetActive(isShow);
54}
55}
56.    #endregion
57}

上述代码实现了在不关闭平面检测时隐藏已检测平面的功能。原理就是对平面变化的委托添加一个OnPlaneChanged的处理事件,并从附带的事件参数中获取检测到的平面信息,保存在一个私有的List<ARPlane>中。由于PanelManager中对平面的检测由Manager进行自动管理,因此附带参数Args会产生变化,例如增加新的面,更新已有的面,删除过期的面。

所以我们切换平面检测状态的时候,还需要检测参数Args回传的面是否依旧存在,若不存在,则应当移除。否则切换已经过期的面的状态会引发异常。

37if (mPlanes[i] == null || mPlanes[i].gameObject == null)
38.             mPlanes.Remove(mPlanes[i]);

事件注册与撤销一定是成双成对的,上述代码在Start()方法中进行了注册,在OnDisable()方法中撤消了注册,如果事件没有在适当的时机撤销会引发难已排查的错误。

在这里插入图片描述

相关文章:

【ARFoundation学习笔记】平面检测

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 文章目录 平面检测属性可视化平面平面检测的开关控制显示与隐藏已检测平面 平面检测属性 AR中检测平面的原理&#xff1a;AR Fou…...

Python---ljust()--左对齐、rjust()--右对齐、center()--居中对齐

作用&#xff1a;返回原字符串左对齐、右对齐以及居中对齐&#xff0c;不足的使用 指定字符 进行填充。 ljust 左对齐 rjust 右对齐 center 居中对齐 类似于Excel、Word文档中的对齐。 基本语法&#xff1a; 字符串序列.ljust(长度, 填充字符) 案例&#xff1a; …...

spdk用户态块层详解

先通过回顾内核态的通用块层来详细介绍SPDK通用块层&#xff0c;包括通用块层的架构、核心数据结构、数据流方面的考量等。最后描述基于通用块层之上的两个特性&#xff1a;一是逻辑卷的支持&#xff0c;基于通用块设备的Blobstore和各种逻辑卷的特性&#xff0c;精简配置&…...

双通道 H 桥电机驱动芯片AT8833,软硬件兼容替代DRV8833,应用玩具、打印机等应用

上期小编给大家分享了单通道 H 桥电机驱动芯片&#xff0c;现在来讲一讲双通道的驱动芯片。 双通道 H 桥电机驱动芯片能通过控制电机的正反转、速度和停止等功能&#xff0c;实现对电机的精确控制。下面介绍双通道H桥电机驱动芯片的工作原理和特点。 一、工作原理 双通道 H 桥电…...

WPF布局与控件分类

Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) Refer&#xff1a;WPF从假入门到真的入门 - 知乎 (zhihu.com) https://www.zhihu.com/column/c_1397867519101755392 https://blog.csdn.net/qq_44034384/article/details/106154954 https://www.cnblogs.com/mq0…...

复杂逻辑的开发利器—Mendix快速实现AQL质量抽检

Mendix低代码开发平台适用于复杂的业务逻辑场景&#xff0c;这句话大家早有耳闻&#xff0c;本期小编就为您打开智慧之光&#xff0c;仅从AQL小侧面&#xff0c;来管窥一二——Mendix如何形成第五代编程语言&#xff0c;来完成数据逻辑与建模、业务算法逻辑与建模的。&#xff…...

RFID系统

目录 在物联网应用中有三项关键技术 读写器 电子标签 工作原理 阅读器的组成及作用&#xff1a; 电子标签的组成及作用&#xff1a; RFID系统的组成 接口方式 在物联网应用中有三项关键技术 在物联网应用中有三项关键技术 1、传感器技术&#xff1a;这也是计算机应用中…...

Markov Chain Fingerprinting to Classify Encrypted Traffic 论文笔记

0.Abstract 在本文中&#xff0c;提出了用于SSL/TLS会话中传输的应用程序流量的随机指纹。这个指纹基于一阶齐次马尔可夫链&#xff0c;模型识别应用程序的准确率&#xff0c;并提供了检测异常对话的可能性。 1.Introduction 通过SSL/TLS会话时的头部信息创建统计指纹&#xff…...

vue 跨标签页的数据共享(即跨标签页通信)

跨标签页通信的常见方案 LocalStorage 或 SessionStorage BroadCast Channel Service Worker Shared Worker Window.postMessage() Cookies IndexedDB 什么是跨标签页通信&#xff1f; 指在同一个浏览器窗口中的多个标签页之间进行数据交流和信息传递的过程。通常情况…...

什么是拉宾-斯科特定理?

拉宾-斯科特定理(Rabin-Scott theorem )是数学上最深刻的数学结果之一。拉宾-斯科特定理是人们最喜欢的计算机科学概念之一。 当正确理解拉宾-斯科特定理时&#xff0c;它会以一种相当基本的方式改变你对现实的看法。然而&#xff0c;它典型的教科书式的呈现方式掩盖了这种深…...

Java并发编程第11讲——AQS设计思想及核心源码分析

Java并发包&#xff08;JUC&#xff09;中提供了很多并发工具&#xff0c;比如前面介绍过的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore、FutureTask等锁或者同步部件&#xff0c;它们的实现都用到了一个共同的基类——AbstractQueuedSynchronizer&…...

什么是数据库?数据库有哪些基本分类和主要特点?

数据库是以某种有组织的方式存储的数据集合。本文从数据库的基本概念出发&#xff0c;详细解读了数据库的主要类别和基本特点&#xff0c;并就大模型时代备受瞩目的数据库类型——向量数据库进行了深度剖析&#xff0c;供大家在了解数据库领域的基本概念时起到一点参考作用。 …...

flutter显示出底部控件的引导页

需求&#xff1a;同一个页面的两个不同的入口&#xff0c;同一个控件的位置有变化&#xff0c;显示引导页时对应这个控件的引导内容的位置也需要改变&#xff1b;同时半透明底部显示出真实的页面内容。 这样的需要如果切图然后再往页面上贴位置无法精确的对准。 思路&#xff1…...

常用设计模式——模板方法模式

什么是模板方法模式 模板方法模式&#xff1a;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 主要解决&#xff1a;一些方法通用&#xff0c;却要在每一个子类都重写这些方法…...

idea使用git删除本地提交(未推送)

1、找到reset head 2、打开弹窗&#xff0c;在HEAD后面输入^ 结果为HEAD^ 注释&#xff1a; Reset Type 有三种&#xff1a; Mixed&#xff08;默认方式&#xff09;&#xff0c;保留本地源码&#xff0c;回退 commit 和 index 信息&#xff0c;最常用的方式Soft 回退到某个版本…...

centos 7部署Mysql8.0主从

Mysql官网中关于部署主从的网址 环境准备&#xff1a; 搭建虚拟机和安装Mysql之前的文章中已经涉及&#xff0c;在此不再赘述。 主从IPMysql账号密码主192.168.213.4root/Root1234!从192.168.213.5root/Root1234! 1、主数据库设置 配置my.cnf 一般存放于/etc/。 主从配…...

asp.net docker-compose添加es search

打开docker-compose.yml添加 es-search:image: docker.elastic.co/elasticsearch/elasticsearch:7.17.14 打开docker-compose.override.yml添加 es-search:volumes:- data01:/usr/share/elasticsearch/dataports:- 9200:9200 docker集群中添加es search成功...

工业路由器网关的网络协议之NAT技术

在物联网通讯领域&#xff0c;NAT技术能将内网的一个私有IP转换成一个公网IP去接入互联网&#xff0c;解决组建局域网络时私有IP地址无法在公网上进行路由的问题。 NAT&#xff08;Network Address Translation&#xff09;的三种方式&#xff1a; 静态NAT 1、一个私有IP对应…...

【亲测可用】SpringBoot使用Redis的Lettuce连接池报RedisCommandTimeoutException

目录 一、问题详情 二、根本原因 三、解决方案 一、问题详情 在最近新项目的开发当中,当项目刚启动的时候访问Redis服务一切正常,但是过了几分钟后再次访问Redis就报如下错误。 Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutExcept…...

When Urban Region Profiling Meets Large Language Models

本文是LLM系列文章&#xff0c;针对《When Urban Region Profiling Meets Large Language Models》的翻译。 当城市区域轮廓遇到大型语言模型时 摘要1 引言2 前言3 方法4 实验5 结论与未来工作 摘要 基于网络数据的城市区域概况对城市规划和可持续发展至关重要。我们见证了LL…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...