游戏空间划分技术

【前言】

空间划分主要是为了降低搜索比较量,如果不采用空间划分,暴力遍历也是可以求解的,但耗时过长。通过空间划分将全局搜索简化为为局部搜索,大大降低搜索量。

搜索出来后最终还要是一一比较,比较的是距离(这里的距离通常指欧式距离),将当前点和目标点做距离计算。

在游戏中,存在静态和动态物体,动态物体可能会更改空间划分

【均匀网格(Uniform Grid)】

原理:将空间划分为固定大小的网格单元,每个单元记录其中的物体

划分方式:3D空间中可以去掉y方向,只按照xz方向做划分,xz一般等长;如果y方向高度差很大,也可以考虑增加y方向上的空间划分。

特点

  • 知道某个物体的位置,可以直接通过(x/xcellsize,z/zcellsize)计算出该物体所在的网格单元Id,继而可以得到单元各内的所有物体或者该物体的邻近物体
  • 可以得到物体相对于网格单元中心点的位置
  • 固定空间划分是不考虑物体的,因此,不同网格单元可能包含相同的多个物体
  • 如果某一网格单元内的物体密集,仍需要遍历非常多的物体,效率降低
  • 预先划分好空间后,不可以在运行时重新划分

应用:场景流式加载区域划分、地图特色区域划分、寻路网格划分

对存在动态物体的应用场景

一是网格单元较大,动态物体始终在网格单元内;二是根据物体位置每帧动态计算所在网格单元Id,如果Id改变,做移除和添加操作

优点:实现简单,查询速度快

缺点:密集时效率低,无法动态调整空间、

拓展:层次网格划分

【四叉树(Quadtree)与八叉树(Octree)】

原理:递归细分空间(四叉树为2D四等分,八叉树为3D八等分),直到满足终止条件(如物体数量或深度限制)

划分方式:与二叉树作为对比,四叉树有四个子节点,八叉树有八个子节点,通常四叉树用于二维,八叉树用于三维

四叉树每次将空间四等分,根节点对应整个空间,第二层节点对应四分之一空间,第三层对应16分之一的空间,以此递归细分,当某个子空间满足终止条件时,将不再继续细分该子空间

特点与对比

  • 四叉树只有叶子节点才会存储所包含的物体,中间节点不包含
  • 同样的,由于等分空间,必然存在一个物体会同时处于多个子空间的情况
  • 查询确定物体处于哪个空间时(即区域查询),每次都需要从根节点依次往下寻找到叶子节点。显而易见,比均匀网格的查询速度不是一个量级的
  • 以数量作为终止条件时,可以保证物体密集时的搜索效率,对比而言,均匀网格在物体密集时效率低
  • 四叉树叶子节点的空间大小与物体分布有关,物体分布密集,会有多个小空间,物体分布稀疏,会有一个大空间。在某些情景下,需要设置小的空间,对均匀网格而言,可能会存在非常多的没有任何物体的网格,这会导致内存浪费

应用:开放世界地形管理(四叉树)、3D场景的碰撞检测优化(八叉树)、视锥裁剪

四叉树的基本操作

  • 插入:根据物体的位置,从根节点找到叶子节点,极为该物体所在的子空间,将物体插入该节点。在静态构建时,可以继续分割该节点。动态插入时,可以不分割,或该节点物体到一定数量再分割
  • 删除:找到物体所在的节点,从节点中删除该物体。如果节点没有任何物体了,也可以删除该节点
  • 查询:输入一个位置或区域,获取位置所属的子空间内的所有物体;或者查询某个区域内是否存在该物体
  • 更新(修改):动态物体的位置改变时,可以检查动态物体是否超出了当前子空间的范围,如果超出了,先删除,再重新插入

对动态物体:需要根据物体的所处的叶子节点做删除和添加操作,按照预先构建时的标准,可能导致叶子节点物体数量超过限制或过少,必须重新对子空间做划分或合并。

存在多个动态物体时,可能会导致四叉树部分节点不断重新构建,影响性能。

为了避免频繁的重建树结构,在运行时可采用松散的树结构:即调整叶子节点的划分和合并上下限,或扩散叶子节点的空间,允许重叠,以降低重建的频率

优点:动态适应物体分布,减少冗余计算

缺点:树结构维护成本较高,频繁更新可能影响性能

拓展:同二叉树一样,死叉树保持树的平衡,四叉树的查询效率才会更高。因此,在构建四叉树时,不必完全等分,可以根据空间内物体分布情况自适应划分,保证每个子空间内物体数量均等,以确保树的平衡。

开源实现

https://github.com/Nition/UnityOctree

https://github.com/marijnz/NativeQuadtree

https://github.com/splitice/QuadTrees

【KD树(k-dimensional Tree)】

原理:沿不同维度轴递归分割空间,交替选择分割维度

划分方式:KDTree的最终目的是构建一个二叉树,每次选择维度是相当于将所有数据点划分为左右两部分,成为二叉树当前节点的足有子树。如果数据点是三维的,通常最简单的划分方式是按照xyz交替取中位数做分割点和分割方向:

  1. 将所有数据点先按照x轴坐标做排序,找到中位数,其所在的点是根节点Root,将数据分为左右两部分Left、Right,整体待分数据-1
  2. 分别对左右两个部分,按照y轴坐标排序,找到中位数据,其所在的点就是根节点的左右子节点,此后左边部分Left又可以被分为两个部分,右边部分Right也可以被分为两个部分,整体待分数据-2
  3. 对剩余的四个部分,按照z轴坐标排序,找到中位数,得到根据y轴排序找到的节点的左右子节点,整体待分数据-4。如果剩余部分只剩下一个数据,说明其就是子节点,不必再分。如果剩下部分没有数据,表明子节点为空。
  4. 循环按照xyz轴进行划分,直到待分数据为0

特点和对比

  • 因为是按照维度轴划分的,维度轴是互相垂直的,分割出来的是方形空间,如果是二维的,那么分割出来的空间就是矩形
  • 可以高效查询多维数据
  • KDTree是以数据点为界限划分空间的,已知的数据点都位于空间边缘分割线上,二叉树的节点会包含数据点,而四叉树是以固定的间隔做空间划分的,只有叶子节点才会包含数据点。
  • KDTree的空间是所有数据点构成的空间,而四叉树是在现有空间再有数据
  • KDTree中任意数据点位置改为可能会导致重建,而四叉树允许部分数据点位置改变,也即KDTree重建成本更高
  • KDTree搜索到最后可以得到邻近的点,而四叉树得到的一堆点

应用:最近邻搜索和范围搜索;群体动态避障中搜索邻近会可能会发生碰撞的对象;AI获取周围一定范围内的可拾取物品;

对动态物体:动态物体位置改变需要重建

优点:高效的多维数据查询

缺点:动态场景中重构成本高

拓展:在二叉树中,左右子树尽可能平衡,高度尽可能低,搜索效率就越高。因此,在建立KDTree时,要尽可能保证树的平衡,其关键在与每个划分时选择哪个轴。不一定xyz的交替顺序,可以根据数据的聚合程度选择分隔轴

开源实现

https://github.com/codeandcats/KdTree

https://github.com/mathnet/mathnet-spatial

https://github.com/jlblancoc/nanoflann

https://github.com/mariusmuja/flann

SciPy库的 cKDTree

【层次包围盒(BVH)】

原理:基于物体包围盒构建树结构,上层节点包围下层节点的体积

划分方式:BVH最终也是构建一个二叉树,包含所有物体的包围盒是根节点,随后根据某种依据将所有物体分为两组,分别求出包含每组的所有物体的包围盒,作为跟节点的左右子节点,再依次迭代划分,直到满足某种终止条件,例如迭代到一定深度或者包围盒内的物体小于一定数量

特点和对比

  • 只有叶子节点存放物体,与四叉树相同;非叶子节点会存放包围盒数据,表示空间区域,与四叉树相同
  • BVH的空间是根据物体来确定的,与KDTree相同,但BVH不适合确定距离
  • BVH的空间会重叠,而四叉树、KDTree不会
  • BVH的空间不规整,与四叉树、KDTree有区别
  • BVH可以支持部分动态更新,同四叉树一样,但还额外涉及包围盒的重新计算,重构成本比四叉树高

应用:物理引擎碰撞粗检测用 BVH 快速筛选可能发生碰撞的物体对、光线追踪中将场景中的所有三角形组织成 BVH 树加速光线和三角面相交计算、光照烘焙中将静态场景的几何体组织成BVH加速找到相交表面

优点:支持动态更新,平衡查询与更新效率

缺点:包围盒可能重叠,影响查询精度

拓展:通常物体会有一个包围盒,但在物体内部仍可以更具三角面构建BVH;包围盒内部可以进一步做均匀网格划分

开源实现

https://github.com/rossborchers/UnityBoundingVolumeHeirachy

https://github.com/bepu/bepuphysics2

https://github.com/embree/embree

https://github.com/bulletphysics/bullet3

【 二叉空间划分树(BSP Tree)】

可以被视为kd树的推广,不再像kd树中按照轴向划分空间,可以按照任意轴向使得子树尽可能平衡的划分。

在3D空间中,划分空间的是平面,节点代表平面,其代表的平面将当前空间划分为前向和背向两个子空间,分别对应左右子树。可以用于可见性判断,不过这种渲染优化技术已经过时了。

此外,其动态构建成本过高,基本只能用于静态场景。

【空间哈希(Spatial Hashing)】

原理:将物体位置映射到哈希表的网格单元,快速定位附近物体

划分方式:在均匀网格的基础上,用空间的小块的位置为Key值,物体的集合为Value值,使用哈希表将每个空间小块中的物体存储起来,通常通过如下方式计算hash值,hash表的大小是单元格数量,而一般将单元格的大小设置为物体的两倍

    uint hashFunc(uint3 key)
    {
        uint p1 = 73856093 * key.x;
        uint p2 = 19349663 * key.y;
        uint p3 = 83492791 * key.z;
        return p1 ^ p2 ^ p3;
    }

特点和对比

  • 当网格内没有物体时,内存中就不会存在该网格的数据,如果物体稀疏分布,相比均匀网格可以节省大量内存
  • 空间哈希更适合物体大小较为均匀的情况
  • 空间哈希划分的空间通常较小,可以更为快速的查询,邻近搜索只需要遍历周围3*3*3共27个空间
  • 相比均匀网格,空间哈希可以根据物体分布情况,动态调整网格大小
  • 哈希表的结构支持动态插入删除,更新成本低,适合物体高频更新

应用:大量高速移动物体(如子弹、爆炸碎片)的实时碰撞检测;数万粒子的相互作用(如相互排斥、聚合)流体、烟雾

优点:插入和查询速度快,适合高频更新的场景

缺点:哈希冲突可能影响效率,需合理选择网格大小

【混合结构】

原理:将多种技术结合,如网格+四叉树,或BVH+空间哈希

优点:灵活适应不同场景需求

缺点:实现复杂度高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96958.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C#】观察者模式 + UI 线程调度、委托讲解

“观察者模式 UI 线程调度”的典型应用A. 涉及的知识点(抽象)观察者模式(Observer Pattern) 发布者:DemoDeviceService.cs 内部生成一帧数据 ScopeFrame,通过 OnScopeFrame?.Invoke(frame) 发布事件。订阅…

Linux应用软件编程---网络编程(TCP:[ 其他机制、头部标志位、应用示例 ]、 HTTP:[ 万维网、概念、格式、报文、应用示例 ]

一、TCP 网络协议补充内容1、TCP 的其他机制1)TCP 头部的标志位TCP 头部可用抓包工具 (wireshark) 来查看。头部标志位用途SYN请求建立连接标志位ACK响应报文标志位PSH携带数据标志位,通知接收方该从缓冲区读数据FIN请求断开连接标志位RST复位标志位URG紧…

基于开源飞控pix的无人机装调与测试

文章目录 前言资源下载1、地面站软件独家汉化版QGC地面站(推荐)原版QGC地面站Mission Planner地面站 2、安装好环境的虚拟机安装虚拟机打开虚拟机文件 3、完整的各版本PX4、QGC源码PX4QGC 一、无人机基本常识/预备知识(1)无人机飞…

Ubuntu解决makefile交叉编译的问题

问题1:/usr/lib/gcc-cross/aarch64-linux-gnu/11/../../../../aarch64-linux-gnu/bin/ld: cannot find -lwiringpi: No such file or directory 找不到-lwiringpi库路径,其实在3rd/usr/lib/aarch64-linux-gnu下没有libwiringPi.so.2 …

ExcelUtils实现 设置内容 插入行 复制行列格式

ExcelUtils实现:1.实现输入 例如 2 A 的excel格式,自动填充对应excel单元格;2.实现复制并新增下一行;3.实现控制复制上一行相同列的格式;4.实现控制复制同一行上一列的格式;/*** 在指定行下方插入新行并复…

SQLBot 智能问数、数据洞察逻辑拆解

* 基于 SQLBot v1.0.2* 使用 AI Gateway 抓取模型调用记录SQLBot 通过融入 LLM 能力实现了非常优秀的问数体验,这里记录一下产品中如何引入 AI 能力,顺便探究一下调用大模型的数据安全的问题(是否会向模型提供真实数据)。结论&…

实现统一门户登录跳转免登录

统一门户所有应用页面&#xff0c;点击跳转对应业务系统&#xff0c;实现业务系统免登录//获取所有业务系统项&#xff08;获取并存储到仓库) //用于页面展示 let appSubjectVoList ref<any>([]) appSubjectVoList.value userStore.getAppSubjectVoList || [] //登陆后…

卓伊凡的开源战略与PHP-SG16加密技术深度解析-sg加密技术详解-卓伊凡

卓伊凡的开源战略与PHP-SG16加密技术深度解析-sg加密技术详解-卓伊凡引言&#xff1a;在理想与现实间寻求平衡的开源之路近日&#xff0c;技术创业者卓伊凡先生宣布了一项重大决策&#xff1a;将于明日将其公司旗下的优雅草商城、项目管理系统等众多成熟商业产品正式开源。这一…

回溯 算法常见面试问题

1. 全排列(无重复元素) 核心思想:交换法避免额外空间 def permute(nums):def backtrack(first=0):if first == len(nums):res.append(nums.copy())returnfor i in range(first, len(nums)):nums[first], nums[i] = nums[i], nums[first]backtrack(first + 1)nums[first], …

营销专业人员核心能力构建与发展路径

CDA数据分析师证书含金量高&#xff0c;适应了未来数字化经济和AI发展趋势&#xff0c;难度不高&#xff0c;行业认可度高&#xff0c;对于找工作很有帮助。一、营销人员五维能力模型能力维度核心技能要素工具与方法论产出成果数据驱动决策指标监控、归因分析、效果优化Google …

Android系统学习2——Android.Utils.Log模块讨论

Android系统学习2——Android.Utils.Log模块讨论 ​ 打日志是一个很好的习惯&#xff0c;有的时候我们可以通过这里排查我们的程序的问题。在这里&#xff0c;我们可以从Android的日志机制入手讨论我们的Log模块。 android.util.Log 类的作用 Android 中最常用的日志工具是 and…

使用 YAML 文件,如何优雅地删除 k8s 资源?

在 Kubernetes 中&#xff0c;删除资源是日常运维中不可避免的操作。如果你习惯了使用 kubectl create 和 kubectl apply 来创建和更新资源&#xff0c;那么你可能也会想知道如何用同样基于文件的方式来删除它们。 虽然你总是可以用 kubectl delete deployment <name> 这…

如何将游戏和软件移动到另一个驱动器或外部磁盘中

您的C盘存储空间是否不足&#xff0c;或者您不小心在错误的驱动器中安装了游戏或应用程序。那么使用这个简单的技巧&#xff0c;您可以轻松的将游戏或应用程序移动到另一个分区或磁盘中。1、找到准备移动的软件&#xff0c;选择路径并复制&#xff1a;2、打开记事本&#xff0c…

赋能汽车电子智造:全星QMS打造品质检验、稽核与客诉管理闭环​——全星质量管理软件系统

全星QMS&#xff1a;驱动汽车电子质量卓越与商业成功的核心引擎 在智能汽车时代&#xff0c;汽车电子的质量已成为产品安全、性能与品牌信誉的核心。面对复杂的供应链、严苛的IATF 16949/ISO 26262标准及降本增效的压力&#xff0c;您的企业需要一位数字化战略伙伴。全星质量管…

【数据结构C语言】顺序表

1. 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线…

AI 学习路径-记录分享

目录推荐学习资源延申阅读推荐学习资源 3Blue1Brown的个人空间-3Blue1Brown个人主页-哔哩哔哩视频 这个简短的课程有助于了解AI的本质&#xff0c;迈入学习AI的第一步。 欢迎加入 &#x1f917; AI Agents 课程 - Hugging Face Agents Course AI Agent&#xff0c;当前火爆…

Windows Server 2019 上安装 Ubuntu 20.04 的几种方式

docker desktop不支持Windows server 2019&#xff0c;所以Windows Server 2019 上安装 Ubuntu 20.04 变成一种可行的途径。记录一下其中可用的几种方式&#xff1a;&#x1f5c2; 常见安装方式对比方式原理难度适用场景优点缺点Hyper‑V 虚拟机&#xff08;推荐&#xff09;利…

当Trae遇上高德MCP:一次国庆武汉之旅的AI技术实践

当Trae遇上高德MCP&#xff1a;一次国庆武汉之旅的AI技术实践 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个特性都是我…

设计模式:抽象工厂模式

简介 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种封装一组具有共同主题或相关依赖关系的独立工厂的方式,而无需指定它们的具体类。核心思想是创建一系列相关或相互依赖的对象家族(产品族),可以将客户端与具体产品的创建过程解耦,使得客…

知行——同为科技24周年庆典

在宜人的金秋时节&#xff0c;北京同为科技有限公司于2025年8月23日&#xff0c;天津基地与江西同时隆重举办了以“知行”为主题的周年庆祝活动&#xff0c;回顾企业24年来的奋斗历程&#xff0c;凝聚“同为人”力量&#xff0c;展望更加光明的未来。当天&#xff0c;创始人周慧…