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是一种用于监控、控制和优化生产过程的软件系统…

python爬虫之aiohttp多任务异步爬虫

python爬虫之aiohttp多任务异步爬虫 爬取的flash服务如下&#xff1a; from flask import Flask import timeapp Flask(__name__)app.route(/bobo) def index_bobo():time.sleep(2)return Hello boboapp.route(/jay) def index_jay():time.sleep(2)return Hello jayapp.rout…

省市区下拉选择: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…

开思通智网-快讯20240617:尖端芯片给AI装上“超级引擎”

【开思通智网-快讯20240617】 【新进展】 尖端芯片给AI装上“超级引擎” https://news.sciencenet.cn/htmlnews/2024/6/524611.shtm 国内首个渔业大模型范蠡大模型1.0发布 https://tech.opensnn.com/chip/article/2775682 武汉理工大学研制出水系锌离子电池&#xff1a;安全、…

如果xml在mapper目录下,如何扫描到xml

如果xml在mapper目录下,如何扫描到xml 项目结构 src├── main│ ├── java│ │ └── com│ │ └── bg│ │ ├── Application.java│ │ ├── domain│ │ │ └── User.java│ │ …

【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;我们将探讨为什…

微信小程序请求服务器报ERR_CONNECTION_RESET

排查思路 1.域名是否配置或跳过 2.域名是否备案 3.证书是否有效 4.服务器中间件配置证书是否生效 5.服务器中间件转发配置是否生效 6.接口是否正常 本人遇到问题描述&#xff0c;通过浏览器访问本人网站&#xff0c;https&#xff0c;get请求可以通&#xff0c;小程序wx…

mac nvm的使用

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个Node.js版本的工具&#xff0c;它允许你在全局范围内安装和切换不同版本的Node.js。以下是如何在macOS上使用nvm的基本步骤&#xff1a; 安装 nvm 安装 Homebrew&#xff08;如果尚未安装&#xff09;&…

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带宽…

细节控-java删除文件

file.delete() vs Files.deleteIfExists(file.toPath()) 区别 在Java中&#xff0c;删除文件有多种方法&#xff0c;其中常见的两种方法是使用 File 类的 delete() 方法和 Files 类的 deleteIfExists() 方法。以下是这两种方法的详细比较和使用说明。 file.delete() 方法签名…

nginx配置解释

Nginx配置文件是Nginx服务器的核心&#xff0c;用于控制其行为和服务功能。下面是对Nginx配置文件和配置项的解释&#xff1a; 1. 主配置文件结构 Nginx的主配置文件通常位于/etc/nginx/nginx.conf或/usr/local/nginx/conf/nginx.conf&#xff0c;它由几个主要部分组成&#…

欧盟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;这里直接使…