unity3D 中关于网格八叉树的实现

      八叉树是一种3D数据结构,最适合用于根据3D位置存储对象。它们被用于许多非常酷的技术中,并成为像Voxel渲染器这样的主干。我们将致力于实现Octree的通用形式,我们可以将其用于任何解决方案。有了这个,我们将能够设计各种有趣的东西。效果如下:

 

代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum OctreeIndex
{
    BottomLeftFront = 0, //000,
    BottomRightFront = 2, //010,
    BottomRightBack = 3, //011,
    BottomLeftBack = 1, //001,
    TopLeftFront = 4, //100,
    TopRightFront = 6, //110,
    TopRightBack = 7, //111,
    TopLeftBack = 5, //101,
}

public class Octree<TType>
{
    private OctreeNode<TType> node;
    private int depth;

    public Octree(Vector3 position, float size, int depth)
    {
        node = new OctreeNode<TType>(position, size);
        node.Subdivide(depth);
    }

    public class OctreeNode<TType>
    {
        Vector3 position;
        float size;
        OctreeNode<TType>[] subNodes;
        IList<TType> value;

        public OctreeNode(Vector3 pos, float size)
        {
            position = pos;
            this.size = size;
        }

        public IEnumerable<OctreeNode<TType>> Nodes
        {
            get { return subNodes; }
        }

        public Vector3 Position
        {
            get { return position; }
        }

        public float Size
        {
            get { return size; }
        }

        public void Subdivide(int depth = 0)
        {
            subNodes = new OctreeNode<TType>[8];
            for (int i = 0; i < subNodes.Length; ++i)
            {
                Vector3 newPos = position;
                if ((i & 4) == 4)
                {
                    newPos.y += size * 0.25f;
                }
                else
                {
                    newPos.y -= size * 0.25f;
                }

                if ((i & 2) == 2)
                {
                    newPos.x += size * 0.25f;
                }
                else
                {
                    newPos.x -= size * 0.25f;
                }

                if ((i & 1) == 1)
                {
                    newPos.z += size * 0.25f;
                }
                else
                {
                    newPos.z -= size * 0.25f;
                }

                subNodes[i] = new OctreeNode<TType>(newPos, size * 0.5f);
                if (depth > 0)
                {
                    subNodes[i].Subdivide(depth - 1);
                }
            }
        }

        public bool IsLeaf()
        {
            return subNodes == null;
        }
    }

    private int GetIndexOfPosition(Vector3 lookupPosition, Vector3 nodePosition)
    {
        int index = 0;

        index |= lookupPosition.y > nodePosition.y ? 4 : 0;
        index |= lookupPosition.x > nodePosition.x ? 2 : 0;
        index |= lookupPosition.z > nodePosition.z ? 1 : 0;

        return index;
    }

    public OctreeNode<TType> GetRoot()
    {
        return node;
    }
}

 

using System.Collections;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using UnityEngine;

public class OctreeComponent : MonoBehaviour
{

    public float size = 5;
    public int depth = 2;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnDrawGizmos()
    {
        var octree = new Octree<int>(this.transform.position, size, depth);

        DrawNode(octree.GetRoot());
    }

    private Color minColor = new Color(1, 1, 1, 1f);
    private Color maxColor = new Color(0, 0.5f, 1, 0.25f);

    private void DrawNode(Octree<int>.OctreeNode<int> node, int nodeDepth = 0)
    {
        if (!node.IsLeaf())
        {
            foreach (var subnode in node.Nodes)
            {
                DrawNode(subnode, nodeDepth + 1);
            }
        }
        Gizmos.color = Color.Lerp(minColor, maxColor, nodeDepth / (float)depth);
        Gizmos.DrawWireCube(node.Position, Vector3.one * node.Size);
    }
}
 

转自:https://www.youtube.com/watch?v=m0guE7804to

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
八叉树网格划分是一种用于将三维空间划分为多个小方块的方法。它可以在计算机图形学、计算机视觉和计算机辅助设计等领域用于表示复杂的三维数据和场景。Open3D是一个开源的计算机视觉库,提供了许多用于处理三维点云和网格的功能。 在Open3D八叉树网格划分可以通过Octree类来实现。它可以将给定的三维点云数据按照一定的规则划分为多个小方块,每个小方块称为一个八叉树节点。划分过程是递归的,通过不断划分每个节点来实现对整个点云数据的划分。每个八叉树节点都存储了一定数量的点云数据,并且可以继续划分成更小的节点,直到满足某个停止条件。 八叉树网格划分在Open3D有很多应用场景,比如点云分割、点云压缩和三维重建等。通过八叉树网格划分,可以将点云数据分割成不同的部分,从而进行更精细的处理和分析。同时,通过八叉树网格划分,可以将大规模的点云数据压缩为较小的八叉树节点存储,从而节省存储空间。此外,八叉树网格划分还可以用于三维重建的体素化和表面重建,从而更方便地进行后续的处理和分析。 总之,八叉树网格划分是Open3D的一个重要功能,它可以将三维点云数据划分为多个小方块,并且可以应用于点云分割、点云压缩和三维重建等场景。通过八叉树网格划分,可以更方便地进行三维数据的处理和分析,提高计算效率和准确度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值