Unity3D 八叉树划分空间和可视化

也许更好的阅读体验

成果展示

所有层
第一层

第二层

代码

OctreeNode
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OctreeNode
{//空间内包含的物体public List<GameObject> areaObjects;//空间中心public Vector3 center;//空间大小public float size;//子节点个数 private int kidCount = 8;//子节点public OctreeNode[] kids;//构造函数public OctreeNode (Vector3 center, float size){this.center = center;this.size = size;kids = new OctreeNode[kidCount];areaObjects = new List<GameObject>();}#region 八个子节点中心对应的偏移方向public static Vector3[] centerOffset = new Vector3[8] {new Vector3 (-1, 1, -1),new Vector3 (1, 1, -1),new Vector3 (-1, 1, 1),new Vector3 (1, 1, 1),new Vector3 (-1, -1, -1),new Vector3 (1, -1, -1),new Vector3 (-1, -1, 1),new Vector3 (1, -1, 1)};#endregion#region 空间和内部物体管理//空间内物体树public int objectCount => areaObjects.Count;//把该空间画出来public void DrawGizmos (){Gizmos.DrawWireCube(center, Vector3.one * size);}//判断是否包含某个点public bool Contains (Vector3 position){float halfSize = size / 2.0f;return Mathf.Abs(position.x - center.x) <= halfSize &&Mathf.Abs(position.y - center.y) <= halfSize &&Mathf.Abs(position.z - center.z) <= halfSize;}//清理空间内物体public void Clear (){areaObjects.Clear();}//添加物体public void AddGameObject (GameObject obj){areaObjects.Add(obj);}#endregion}
Orctree
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using Unity.VisualScripting;
using UnityEngine;//可视化模式
public enum OctreeDebugMode
{AllDepth,TargetDepth
}
public class Octree : MonoBehaviour
{#region 物体生成和构建八叉树//生成物体数[Range(0, 500)]public int genCount = 500;//物体生成范围[Range(1, 300)]public float range = 100;//生成的物体public List<GameObject> sceneObjects;//Octree最大层数[Range(1, 8)]public int maxDepth = 3;//Octree的根节点public OctreeNode root;// Start is called before the first frame updatevoid Start(){GenObjects();OctreePartition();}//随机生成一些cubeprivate void GenObjects(){float genRange = range * 0.5f;sceneObjects = new List<GameObject>();for (int i = 0; i < genCount; ++i){GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);obj.transform.position = new Vector3(Random.Range(-genRange, genRange),Random.Range(-genRange, genRange),Random.Range(-genRange, genRange));obj.hideFlags = HideFlags.HideInHierarchy;sceneObjects.Add(obj);}}//进行八叉树划分private void OctreePartition (){//设定根节点Vector3 origin = Vector3.one;root = new OctreeNode(Vector3.zero, range);root.areaObjects = sceneObjects;//往下生成八叉树 根节点层数为1GenerateOcetree(root, range, 2);}//递归往下生成八叉树private void GenerateOcetree (OctreeNode root, float range, int depth){//depth是当前生成的层数if (depth > maxDepth) return;//下一层的大小float halfRange = range / 2.0f;//根节点偏移量float rootOffset = halfRange / 2.0f;for (int i = 0; i < 8; ++i){Vector3 origin = root.center + OctreeNode.centerOffset[i] * rootOffset;root.kids[i] = new OctreeNode(origin, halfRange);}PartitionSceneObjects(root);for (int i = 0; i < 8; ++i){if (root.kids[i].objectCount >= 2) GenerateOcetree(root.kids[i], halfRange, depth + 1);}}//把空间内物体划分给子节点private void PartitionSceneObjects(OctreeNode root){foreach (GameObject obj in root.areaObjects){foreach (OctreeNode kid in root.kids){if (kid.Contains(obj.transform.position)){kid.AddGameObject(obj);}}}}#endregion#region 可视化//是否显示八叉树public bool showOctree = true;//可视化类型public OctreeDebugMode octreeDebugMode;//可视化层数[Range(0, 8)]public int displayDepth = 3;//不同深度的可视化颜色public Color[] displayColor;private void OnDrawGizmos(){if (root == null) return;if (showOctree && displayDepth <= maxDepth){//显示所有深度的空间范围if (octreeDebugMode == OctreeDebugMode.AllDepth){DrawNode(root, 1);}//显示指定深度的空间范围(第displayDepth层)else if (octreeDebugMode == OctreeDebugMode.TargetDepth){if (displayDepth > 0 && displayColor.Length >= displayDepth) {Color color = displayColor[displayDepth - 1];color.a = 0.5f;Gizmos.color = color;DrawTargetDepth(root, displayDepth);}}}}//绘制所有节点 当前深度为depthprivate void DrawNode(OctreeNode root, int depth){if (root == null || depth > maxDepth) return;Color color = displayColor[depth - 1];color.a = 0.5f;Gizmos.color = color;root.DrawGizmos();foreach (OctreeNode kid in root.kids){DrawNode(kid, depth + 1);}}//绘制指定层private void DrawTargetDepth (OctreeNode root, int targetDepth){--targetDepth;if (root == null || targetDepth < 0) return;Debug.Log(targetDepth);if (targetDepth == 0){root.DrawGizmos();return;}foreach (OctreeNode kid in root.kids){DrawTargetDepth(kid, targetDepth);}}#endregion
}

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

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

相关文章

Sqlite3入门和c/c++下使用

1. SQLite3基本介绍 1.1 数据库的数据类型 1.2 基本语法 1. 创建数据表格 create table 表名(字段名 数据类型&#xff0c; 字段名 数据类型)&#xff1b; create table student(id int, name varchar(256), address text, QQ char(32)); 2. 插入数据 insert into 表名 valu…

工业制造领涉及的8大常见管理系统,如mes、scada、aps、wms等

在工业生产和制造领域有一些常见的管理系统&#xff0c;很多小伙伴分不清&#xff0c;这次大美B端工场带领大家了解清楚。 MES&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;&#xff1a; MES是一种用于监控、控制和优化生产过程的软件系统…

省市区下拉选择:3个el-select(附完整代码+json)

目录 直接上做出的效果&#xff1a; 页面代码&#xff1a; 使用click.native&#xff1a; data及引入&#xff1a; 初始化&#xff1a; methods&#xff1a; JSON: 示例结构&#xff1a; 1.code.json 2.pca-code.json 回显&#xff1a; 视频效果&#xff1a; 直接上做出…

安装jfrog container registry(jcr)

1、下载软件 下载地址,本案例下载的是jfrog-artifactory-jcr-7.59.11-linux.tar.gz: https://releases.jfrog.io/artifactory/bintray-artifactory/org/artifactory/jcr/jfrog-artifactory-jcr/ 2、解压下载下来的压缩包 tar zxf jfrog-artifactory-jcr-7.59.11-linux.tar…

【Linux】Xshell和Xftp简介_安装_VMware虚拟机使用

1、简介 Xshell简介 Xshell是一款强大的安全终端模拟软件支持SSH1、SSH2以及Microsoft Windows平台的TELNET协议。该软件通过互联网实现到远程主机的安全连接&#xff0c;并通过其创新性的设计和特色帮助用户在复杂的网络环境中高效工作。Xshell可以在Windows界面下访问远端不…

电脑怎么卸载软件?多个方法合集(2024年新版)

在电脑的日常使用中&#xff0c;我们经常需要安装各种软件来满足不同的需求&#xff0c;但随着时间的推移&#xff0c;可能会出现一些软件不再需要或需要更换的情况。此时&#xff0c;及时从电脑上卸载这些不必要的软件是非常重要的。它不仅可以释放硬盘空间&#xff0c;还可以…

顶级管理者的新视角:管理状态而非时间

在快节奏的商业环境中&#xff0c;时间管理常被看作是提升效率和效果的关键因素。然而&#xff0c;对于顶级管理者来说&#xff0c;仅仅管理时间可能并不足够。一个更深层、更全面的管理方式——管理状态&#xff0c;正在成为新的趋势。在这篇文章中&#xff0c;我们将探讨为什…

MPLS TE简介

定义 MPLS TE&#xff08;MPLS Traffic Engineering&#xff09;&#xff0c;即MPLS流量工程。MPLS流量工程通过建立基于一定约束条件的LSP隧道&#xff0c;并将流量引入到这些隧道中进行转发&#xff0c;使网络流量按照指定的路径进行传输&#xff0c;达到流量工程的目的。 …

泰克DPO4104示波器

特色&#xff1a; Inspector智能存储管理 2.串行触发和分析 3.10.4”较大的显示器, 板上USB和CompactFlash端口, 及TekVPI?改善的探头接口, 较强的操作渐 变性 商品名称 &#xff1a;DPO4104数字荧光示波器 商品型号 &#xff1a;泰克DPO4104 商品简介 &#xff1a;1GHz带宽…

欧盟CE认证 包过亚马逊 方华快捷办理 价格三位数

什么是CE证书 CE证书是欧洲共同体&#xff08;European Community&#xff09;规定的产品合格性认证&#xff0c;全称为“Conformit Europene”&#xff0c;意为“欧洲合格性”。在欧洲经济区内销售的产品&#xff0c;必须符合欧洲的相关法律法规和标准&#xff0c;而获得CE证…

剪画小程序:音频混音攻略:从新手到高手的必备方法!

在我们欣赏他人发布的视频时&#xff0c;常常会留意到除了清晰的人声&#xff0c;还有相得益彰的背景音乐。 这些背景音乐并非录制时同步播放&#xff0c;而是后期添加而成。那究竟怎样给音频添加背景音乐呢&#xff1f; 今天&#xff0c;小编为大家整理了几种实用方法&#xf…

【Docker安装】Ubuntu系统下部署Docker环境

【Docker安装】Ubuntu系统下部署Docker环境 前言一、本次实践介绍1.1 本次实践规划1.2 本次实践简介二、检查本地环境2.1 检查操作系统版本2.2 检查内核版本2.3 更新软件源三、卸载Docker四、部署Docker环境4.1 安装Docker4.2 检查Docker版本4.3 配置Docker镜像加速4.4 启动Doc…

【Unity】实现分屏开发

前言&#xff1a; 最近有个项目二期需要做分屏开发&#xff0c;今天恰好研究一下为后续的项目做个准备。 原理 整体的实现还是蛮简单的&#xff0c;主要是通过camera的一个targetDisplay属性进行设置 可以看到unity支持最多八个分屏 实现 场景搭建 &#xff0c;这里直接使…

ArrayDeque详解(含动画演示)

目录 ArrayDeque详解1、 ArrayDeque的继承体系2、Queue和Deque接口的区别3、 ArrayDeque的数据结构4、ArrayDeque的构造方法5、 ArrayDeque的addFirst方法6、 ArrayDeque的addLast方法7、 ArrayDeque的如何利用head和tail索引实现环形数组8、 ArrayDeque的doubleCapacity方法&a…

20. mediasoup服务器的布署与使用

Mediasoup Demo部署 架构服务分析 服务端提供3个服务&#xff1a; 1.www服务&#xff0c;浏览器通过访问服务器目录获取客户端代码&#xff0c;通过V8引擎&#xff0c;启动底层WebRTC 2.nodejs提供websocket服务和http服务&#xff0c;用于信令交互 3.Mediasoup C提供的流媒体…

BL104应用在智慧零售多协议采集监控远程实时查看

在智慧零售领域&#xff0c;如今的市场竞争日益激烈&#xff0c;传统的零售模式已经难以满足消费者对服务和体验的高需求。智能化技术的引入&#xff0c;尤其是基于物联网的解决方案&#xff0c;成为提升零售业务效率和服务质量的关键。钡铼BL104 Modbus转MQTT网关作为一种先进…

同时使用磁吸充电器和Lightning时,iPhone充电速度会变快吗?

在智能手机的世界里&#xff0c;续航能力一直是用户关注的焦点。苹果公司以其创新的MagSafe技术和传统的Lightning接口&#xff0c;为iPhone用户提供了多样化的充电解决方案。 然而&#xff0c;当这两种技术同时使用时&#xff0c;它们能否带来更快的充电速度&#xff1f;本文…

Talk|新加坡国立大学贾鑫宇:适用于高自由度机器人的运动控制器

本期为TechBeat人工智能社区第600期线上Talk。 北京时间6月13日(周四)20:00&#xff0c;新加坡国立大学博士生—贾鑫宇的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “适用于高自由度机器人的运动控制器”&#xff0c;向大家系统地介绍了如何通…

千脑计划:模拟人类大脑皮层,开启AI新纪元

随着科技的飞速发展&#xff0c;人工智能已成为当今时代的热门话题。然而&#xff0c;目前主流的深度神经网络虽然取得了显著成就&#xff0c;但也面临着能耗高、稳定性差等问题。为了解决这些挑战&#xff0c;一项名为“千脑计划”的宏伟项目应运而生&#xff0c;旨在通过模仿…

数据结构:4.1.1二叉搜素树及查找

静态查找&#xff1a;要找的集合的元素是不动的&#xff0c;主要是find操作&#xff0c;没有delete操作 动态查找&#xff1a;要查找的集合会经常发生插入删除的操作 静态查找的一个很好的方法就是二分查找 把数据直接放在树上 结点右子树的值>结点的值>结点左子树的…