八叉树unity实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
//定义一个八叉树 二叉树对应于一维得数组(参考满二叉树)
// 那么 四叉树 对应于 二维得数组 八叉树显然对应于三维数组
// 因此我们也从1维世界转到2维世界最后来到三维.
public class OcTree
{
//程序需要定义一个最小的空间半径 下面的值可以自己指定(通过读配置==动态设置亦可)
// 但是一定要有所限制防止构建的死递归
public static float m_minRadius = 0.5f; // 比0.5还小的空间已经没有什么意义了太小了
public static float m_maxLayer = 0;
public float m_radius = 0f; // 半径
public Vector3 m_center = Vector3.zero; // 八叉树的中心
public OcTree[] m_child = new OcTree[8];
public int m_nLayer = 1;
public int m_id = 0;
public static Vector3[] releave_center_direction = new Vector3[]
{
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),// 下层第二个盒子的下面的盒子
};
public OcTree(float r, Vector3 center,int layer = 1,int id = 0)
{
m_radius = r;
m_center = center;
m_nLayer = layer;
m_id = id;
Create(); // 构造函数天生的适合做递归 这是一个感悟点
}
public void Create() //这个函数看不到递归却一直在递归似的执行 这就是编程手法
{
if(m_radius <= m_minRadius || m_nLayer > m_maxLayer)
{
return;
}
Vector3 offSet = Vector3.zero;
float halfRadius = m_radius / 2;
for(int i = 0; i < 8; i++)
{
offSet = releave_center_direction[i] * halfRadius;
int tmpId = ((m_nLayer-1) << 3) + (i+1);
m_child[i] = new OcTree(halfRadius, m_center + offSet,m_nLayer + 1, tmpId);
}
}
public void Draw()
{
if(m_radius == 0f)
{
return;
}
//一些绘制代码
DrawCube(m_radius, m_center);
for (int i = 0; i < 8; i++)
{
if (m_child[i] != null)
{
m_child[i].Draw();
}
}
}
public int IsInCube( Vector3 pos)
{
Vector3 left = m_center - m_radius * Vector3.one;
Vector3 right =m_center + m_radius * Vector3.one;
if (pos.x >= left.x && pos.x <= right.x && pos.y >= left.y && pos.y <= right.y && pos.z >= left.z &&
pos.z <= right.z)
{
return 1;
}
return -1;
}
public static int GetId(OcTree tree,Vector3 pos)
{
for(int i = 0; i < 8; i++)
{
if(tree.m_child[i] != null)
{
int nRst = tree.m_child[i].IsInCube(pos);
if (nRst > 0)
{
return GetId(tree.m_child[i], pos);
}
}
}
return tree.m_id;
}
void DrawLineFunc(Vector3 one, Vector3 two)
{
Debug.DrawLine(one, two, Color.yellow);
}
public void DrawCube(float r,Vector3 center)
{
Vector3 offSet = Vector3.zero;
Vector3[] vecArray = new Vector3[8];
for (int i = 0; i < 8;i++)
{
offSet = releave_center_direction[i] * m_radius;
vecArray[i] = m_center + offSet;
}
for(int i = 0; i < 2; i++)
{
DrawLineFunc(vecArray[4 * i ], vecArray[4 * i + 1]);
DrawLineFunc(vecArray[4 * i ], vecArray[4 * i + 2]);
DrawLineFunc(vecArray[4 * i + 2], vecArray[4 * i + 3]);
DrawLineFunc(vecArray[4 * i + 3], vecArray[4 * i + 1]);
}
DrawLineFunc(vecArray[0], vecArray[4]);
DrawLineFunc(vecArray[1], vecArray[5]);
DrawLineFunc(vecArray[2], vecArray[6]);
DrawLineFunc(vecArray[3], vecArray[7]);
}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(Game))]
public class GameEditor : Editor
{
Game self;
public void Awake()
{
self = target as Game;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if(GUILayout.Button("draw"))
{
if(self.needDraw)
{
self.CreateOcTree();
}
else
{
self.needDraw = true;
}
}
if(GUILayout.Button("nodraw"))
{
self.needDraw = false;
}
if(GUILayout.Button("找到点所在的八叉树位置"))
{
if(self.m_ocTree.IsInCube(self.findPos) > 0)
{
var id = OcTree.GetId(self.m_ocTree, self.findPos);
Debug.Log(id);
}
}
}
}
public class Game : MonoBehaviour
{
public int layer = 2;
public float minRadius = 0.5f;
[HideInInspector]
public OcTree m_ocTree = null;
public Vector3 center = Vector3.zero;
public float m_radius =10f;
public bool needDraw = false;
public static Game Instance = null;
public Vector3 findPos = new Vector3(0, 0, 0);
void Start()
{
Instance = this;
CreateOcTree();
}
public void CreateOcTree()
{
OcTree.m_maxLayer = layer;
OcTree.m_minRadius = minRadius;
m_ocTree = new OcTree(m_radius, center);
}
public void Draw()
{
if (!needDraw) return;
if(m_ocTree != null)
{
m_ocTree.Draw();
}
}
void Update()
{
Draw();
}
}
八叉树unity实现相关推荐
- [Unity] 八叉树(四叉树、二叉树)场景划分
什么是"八叉树"? 我们先看一幅图: 这上面只看到七个色块(仔细数一数),因为有个色块被覆盖了,所以我们看不到.我们拆分开看看(褐色框选的背面,蓝色的是前面). 这就是一个八个矩形 ...
- Unity性能优化 – 脚本篇
最近开始进行Unity性能优化的工作,主要分为三类:CPU.GPU和内存.由于我们游戏的核心战斗是计算密集型,所以主要是受限于CPU.CPU的优化又分为渲染和脚本,本文将着重于脚本优化. 一般来说,优 ...
- 图形学/OpenGL/3D数学/Unity
1. 场景管理的数据结构: 总结,游戏开发最常用的空间数据结构是四叉/八叉树和BVH树,而BSP树基本上只能应用于编辑器上,k-d树则只能用在特殊问题应用场景. 2. 帧同步与状态同步: https: ...
- Unity碰撞检测机制的原理(更新中...)
总是碰到关于碰撞的问题,今天实在忍不住了,来把它搞懂,不然听到八叉树,BSP什么的就怕可不行. 转自:http://www.manew.com/thread-102595-1-1.html 碰撞机制 ...
- 【Unity】大世界实现方案
前言 对各种形式的大世界的实现方案 1.自由视角大世界 示例: WorldStreamer插件.龙之谷2 实现核心思想: 拆分为多场景sub scene 实现细节: 拆分成多个场景,然后加载 摄像机看 ...
- unity 项目实践经验 和 架构体系
GameRes游资网授权发布 文 / 吴秦(Tyler) 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: ...
- Unity 手游性能优化
Unity 手游性能优化 物理 减少射线频率.长度.layer: 善用 Physics Matrix: 不要移动静态 Collider,需要移动的话加 RigidBody: 尽量使用简单的 Colli ...
- 基于Unity利用四叉树算法实现二维碰撞检测
前言 在游戏制作过程中会经常遇到碰撞检测,假设在二维平面上有n个物体,那么检测每个物体的碰撞都要检测n-1次,如果要检测所有物体的碰撞,那么需要计算n*(n-1)/2次,时间复杂度为n的平方,四叉树算 ...
- Unity优化之 LOD 和 HLOD
/// Shader LOD - 这个是另外一种控制细节级别的技术 - 在一个Shader当中,可以给不同的subshader指定不同的LOD属性,例如: SubShader { LO ...
最新文章
- 少年自学python笔记_自学python 笔记
- input全选和取消全选
- 如何在 go 中实现一个 worker-pool?
- 液态渐变背景纹理,选择一个新潮的背景,为你的设计加分!
- BZOJ 1571: [Usaco2009 Open]滑雪课Ski
- verilog语法实例学习(3)
- 传智播客黑马 Python学习笔记之python初识
- 高等代数第3版下 [丘维声 著] 2015年版_微电子电路设计 第4版 电子书
- Abaqus学习笔记(基础)
- coreos mysql_Fedora CoreOS 介绍
- 使用element中el-tab如何改变文字样式等
- C# + HotKey
- 如何将旧电脑变成文件存储服务器,免费的NAS系统,把旧电脑改造成NAS
- 相邻图片之间有空白间隙的问题解决
- Hexo中NexT主题添加CNZZ统计
- 计算机英文收集(二)
- 如何修改ICO文件的尺寸
- Python 绘制五角星 【初识Python】
- npm install 报node-sass错误
- 最小覆盖模型matlab_MATLAB求解最小球覆盖问题
热门文章
- 2.NetWork中各种信息的意思
- 使用Ajax异步加载图片
- easyUI tree 异步加载数据
- 路由器配置接口IP地址和网关的配置
- LeetCode 二叉树路径问题 Path SUM(①②③)总结
- 两个聊天机器人的情话--今天打开淘宝旺旺看到聊天机器人,于是聊了两句,很有趣.........
- Invalid bound statement (not found)错误解决办法
- 数据库中左连接和右链接的区别
- SQL中字符串截取函数(SUBSTRING)
- css显示全屏背景图片