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实现相关推荐

  1. [Unity] 八叉树(四叉树、二叉树)场景划分

    什么是"八叉树"? 我们先看一幅图: 这上面只看到七个色块(仔细数一数),因为有个色块被覆盖了,所以我们看不到.我们拆分开看看(褐色框选的背面,蓝色的是前面). 这就是一个八个矩形 ...

  2. Unity性能优化 – 脚本篇

    最近开始进行Unity性能优化的工作,主要分为三类:CPU.GPU和内存.由于我们游戏的核心战斗是计算密集型,所以主要是受限于CPU.CPU的优化又分为渲染和脚本,本文将着重于脚本优化. 一般来说,优 ...

  3. 图形学/OpenGL/3D数学/Unity

    1. 场景管理的数据结构: 总结,游戏开发最常用的空间数据结构是四叉/八叉树和BVH树,而BSP树基本上只能应用于编辑器上,k-d树则只能用在特殊问题应用场景. 2. 帧同步与状态同步: https: ...

  4. Unity碰撞检测机制的原理(更新中...)

    总是碰到关于碰撞的问题,今天实在忍不住了,来把它搞懂,不然听到八叉树,BSP什么的就怕可不行. 转自:http://www.manew.com/thread-102595-1-1.html 碰撞机制 ...

  5. 【Unity】大世界实现方案

    前言 对各种形式的大世界的实现方案 1.自由视角大世界 示例: WorldStreamer插件.龙之谷2 实现核心思想: 拆分为多场景sub scene 实现细节: 拆分成多个场景,然后加载 摄像机看 ...

  6. unity 项目实践经验 和 架构体系

    GameRes游资网授权发布 文 / 吴秦(Tyler) 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: ...

  7. Unity 手游性能优化

    Unity 手游性能优化 物理 减少射线频率.长度.layer: 善用 Physics Matrix: 不要移动静态 Collider,需要移动的话加 RigidBody: 尽量使用简单的 Colli ...

  8. 基于Unity利用四叉树算法实现二维碰撞检测

    前言 在游戏制作过程中会经常遇到碰撞检测,假设在二维平面上有n个物体,那么检测每个物体的碰撞都要检测n-1次,如果要检测所有物体的碰撞,那么需要计算n*(n-1)/2次,时间复杂度为n的平方,四叉树算 ...

  9. Unity优化之 LOD 和 HLOD

    /// Shader LOD - 这个是另外一种控制细节级别的技术 - 在一个Shader当中,可以给不同的subshader指定不同的LOD属性,例如: SubShader {         LO ...

最新文章

  1. 少年自学python笔记_自学python 笔记
  2. input全选和取消全选
  3. 如何在 go 中实现一个 worker-pool?
  4. 液态渐变背景纹理,选择一个新潮的背景,为你的设计加分!
  5. BZOJ 1571: [Usaco2009 Open]滑雪课Ski
  6. verilog语法实例学习(3)
  7. 传智播客黑马 Python学习笔记之python初识
  8. 高等代数第3版下 [丘维声 著] 2015年版_微电子电路设计 第4版 电子书
  9. Abaqus学习笔记(基础)
  10. coreos mysql_Fedora CoreOS 介绍
  11. 使用element中el-tab如何改变文字样式等
  12. C# + HotKey
  13. 如何将旧电脑变成文件存储服务器,免费的NAS系统,把旧电脑改造成NAS
  14. 相邻图片之间有空白间隙的问题解决
  15. Hexo中NexT主题添加CNZZ统计
  16. 计算机英文收集(二)
  17. 如何修改ICO文件的尺寸
  18. Python 绘制五角星 【初识Python】
  19. npm install 报node-sass错误
  20. 最小覆盖模型matlab_MATLAB求解最小球覆盖问题

热门文章

  1. 2.NetWork中各种信息的意思
  2. 使用Ajax异步加载图片
  3. easyUI tree 异步加载数据
  4. 路由器配置接口IP地址和网关的配置
  5. LeetCode 二叉树路径问题 Path SUM(①②③)总结
  6. 两个聊天机器人的情话--今天打开淘宝旺旺看到聊天机器人,于是聊了两句,很有趣.........
  7. Invalid bound statement (not found)错误解决办法
  8. 数据库中左连接和右链接的区别
  9. SQL中字符串截取函数(SUBSTRING)
  10. css显示全屏背景图片