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

八叉树,分裂空间的魔法师【Unity】

八叉树,分裂空间的魔法师

前往我的博客阅读,享受免费无广告的体验

诞生

当我们要做物理碰撞检测的时候,例如一枚子弹射了出去,我们或许会选择遍历所有的物体,通过运算判断是否相交,是否发生碰撞,但这不理想,尤其是面对成千上万物体的时候,计算量极其恐怖。
同样的,在面对光线计算,遮挡关系计算中也有这个问题。
事实上,如果让我们也这样做,即从头看到尾,依次遍历,寻找碰撞,也未必迅速。但是我们能很快发现发生碰撞的物品,为什么?

因为我们会进行一个潜在的分区,只看可能会碰撞的位置

这就是我们的思路,尝试进行分区,然后遍历分区内的物体;
八叉树就这样诞生了

原理

先看个图片:
在这里插入图片描述

这个图片是李恒老师的图片,很直观的展示了八叉树根本的原理。
即通过预划分,将其分类,当需要检测东西的时候,只需要对其空间内的进行遍历

从Octree到BVH,对空间划分的理解

最近在看games104,也算是学了游戏引擎的毛毛皮。
其最大的意义,我认为是让游戏引擎变聪明了,可以借助技巧减少运算了。

  • 例如生化危机8:村庄中,也可以说绝大数生化危机中,都对房间进行划分,进入某个房间后,激活僵尸AI,做相关处理。
  • 再例如僵尸毁灭工程我的世界,就对引入区块的概念,重点渲染,处理区块内的内容。

总之,核心并不难理解,其底层就是划分,然后分开处理。

使用

有了最最最浅显的理解,可以写一下最基本的数据结构了

public class OctreeNode  
{  // 空间大小与其内的物体  public List<GameObject> areaObjects;  public Vector3 center;  public float size;  private const int kidCount = 8;  private OctreeNode[] kids;  public OctreeNode(Vector3 center, float size)  {        kids = new OctreeNode[kidCount];  this.center = center;  this.size = size;  areaObjects = new List<GameObject>();  }    //四个上面的节点public OctreeNode top0  {  get { return kids[0];}  set { kids[0] = value; }  }  // 省略//四个下面的节点public OctreeNode bottom0  {  get{ return kids[4];}  set { kids[4] = value; }  }  // 省略public int objectCount => areaObjects.Count;  public void DrawGizmos()  {        Gizmos.DrawWireCube(center, Vector3.one * size);  }  public bool Contains(Vector3 position)  {        var halfSize = size * 0.5f;  return Mathf.Abs(position.x - center.x) <= halfSize &&  Mathf.Abs(position.y - center.y) <= halfSize &&  Mathf.Abs(position.z - center.z) <= halfSize;  }          public void AddGameobject(GameObject go)  {        areaObjects.Add(go);  }          
}

很容易理解,即定义了一个OctreeNode,其拥有一个位置与大小,其包含八个OctreeNode;

接下来是八叉树控制代码

public class OctreeNodeCon : MonoBehaviour  
{  public OctreeNode root;  private List<GameObject> sceneObjects;  [Range(0, 500)] public int genCount = 100;  [Range(1, 8)] public int buildDepth;  [Range(1, 300)] public float range = 100;  [Range(0, 8)] public int displayDepth = 3;  public bool showOctree = true;  public OctreeDebugMode octreeDebugMode;  public Color[] displayColor;  // 检测信息  public bool showQueryResult = true;  public GameObject checkTarget;  private List<GameObject> queryObjects

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【开发环境搭建】Macbook M1搭建Java开发环境
  • 二维背包问题(C++)
  • C++入门9——list的使用
  • vue增加长时间无操作退出登录功能
  • C# 数组定义和常用方法
  • AI 浪潮中的一体化数据库|外滩大会之OceanBase实录
  • P1308 [NOIP2011 普及组] 统计单词数
  • aliyun图片存储OSS工具类
  • Cesium 问题:视角漫游时添加的无人机模型飞行时有抖动
  • 【软考】设计模式之责任链模式
  • Tube Qualify三维弯管测量系统用于弯管机修正弯管回弹参数
  • 一维数组的概念和应用
  • Excel单元格操作:读写单元格数据、格式设置与条件格式详解
  • 1.C_数据结构_基本知识
  • 第4章-03-用WebDriver获取页面Cookie
  • ➹使用webpack配置多页面应用(MPA)
  • 2019.2.20 c++ 知识梳理
  • Bootstrap JS插件Alert源码分析
  • E-HPC支持多队列管理和自动伸缩
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Git的一些常用操作
  • java多线程
  • Python socket服务器端、客户端传送信息
  • SQLServer之创建数据库快照
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 排序算法之--选择排序
  • 原生Ajax
  • 找一份好的前端工作,起点很重要
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • #565. 查找之大编号
  • $(function(){})与(function($){....})(jQuery)的区别
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (javaweb)Http协议
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (三)模仿学习-Action数据的模仿
  • (十)T检验-第一部分
  • (四)进入MySQL 【事务】
  • (转)详解PHP处理密码的几种方式
  • .bashrc在哪里,alias妙用
  • .NET 8.0 发布到 IIS
  • .net framework profiles /.net framework 配置
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET编程C#线程之旅:十种开启线程的方式以及各自使用场景和优缺点
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • .net中的Queue和Stack
  • [2019红帽杯]Snake
  • [Algorithm][综合训练][kotori和气球][体操队形][二叉树中的最大路径和]详细讲解
  • [Android View] 可绘制形状 (Shape Xml)
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [BUG]vscode插件live server无法自动打开浏览器
  • [C#]猫叫人醒老鼠跑 C#的委托及事件
  • [C++]四种方式求解最大子序列求和问题