Ejemplo n.º 1
0
    //Recursively search the tree and for each leaf node at the bottom depth populate it's
    //SDF structure by raycasting to all Scene Geometry and find the closest Surface Point
    void PopulateTree(Octree.OctreeNode node)
    {
        if (!node.IsLeaf())
        {
            var subNodes = node.Nodes;
            foreach (var subNode in subNodes)
            {
                PopulateTree(subNode);
            }
        }
        else
        {
            if (node.IsLowestNode())
            {
                //find the closest Surface Point to this Mesh
                //Unity 5.7 has Physics.ClosestPoint(Vec3 p)

                //This is my version of it
                //Vector3 surfacePoint_old = ClosesPointOnCollider(node.Position);
                Vector3 surfacePoint = ClosesPointOnColliders(node.Position);
                if (surfacePoint == node.Position)
                {
                    node.InsideMesh = true;
                }
                else
                {
                    node.InsideMesh    = false;
                    node.SDF.mPoint    = surfacePoint;
                    node.SDF.mDistance = (surfacePoint - node.Position).magnitude;
                }
            }
        }
    }
Ejemplo n.º 2
0
    //=====================================================================================================================
    //This initializes this Octree
    //=====================================================================================================================
    void Build_Octree()
    {
        RayDirs = PointsOnSphere.GetPoints((float)RayDirections);

        //First step all Scene geometry send their Meshes to the Octree class
        if (Octree.All_OBBs == null)
        {
            Octree.All_OBBs = new List <Octree.OBB>();
        }

        if (Unpacked_Tree == null)
        {
            Unpacked_Tree = new List <TreeNode>();
        }

        //send all scene Geometry(AABBs) to the Octree class
        StreamGeometry();

        //Create a new Octree only ONCE this is not a dynamic scene!!!!
        OCTREE = new Octree(transform.position, VoxelSize, TreeDepth);

        Octree.OctreeNode root = OCTREE.GetRootNode();

        //Now for each Leaf node at the bottom of the Tree populate it
        //ie. Find the closest Surface geometry to it and populate its SDF structure
        PopulateTree(root);

        //Structure the Octree into a single list of tree nodes
        UnpackTree(root);

        //Finaly Step: Store the UnpackedOctree into a linear Array(ComputeBuffer)
        PackTree();

        Initialized = true;
    }
Ejemplo n.º 3
0
 /// <summary>
 /// Renders node gizmos
 /// </summary>
 private void OnDrawGizmos()
 {
     if (!renderGizmos)
     {
         return;
     }
     foreach (GameObject g in gameObjectPoints)
     {
         Vector3           coordinate = octree.GetRoot().FindCoordinateOnOctree(g.transform.position - globalOffset);
         Octree.OctreeNode oc         = octree.GetRoot().GetNodeAtCoordinate(coordinate);
         int distance = Distance(lastCoordinatePosition, coordinate);
         if (distance == 0)
         {
             Gizmos.color = new Color(1, 0, 0, 1f);
         }
         else if (distance == 1)
         {
             Gizmos.color = new Color(0, 1, 0, 1f);
         }
         else
         {
             Gizmos.color = new Color(0, 0, 1, 1f);
         }
         Gizmos.DrawWireCube(oc.Position + globalOffset, new Vector3(octree.smallestTile, octree.smallestTile, octree.smallestTile));
     }
     //Gizmos.DrawWireCube(origin, max - min);
 }
Ejemplo n.º 4
0
    //Linearly search the Unpacked Tree to find this nodes index
    int FindIndex(Octree.OctreeNode node, ref List <TreeNode> tree)
    {
        int index = -1;

        for (index = 0; index < tree.Count; ++index)
        {
            if (tree[index].mNode == node)
            {
                return(index);
            }
        }

        return(-1);
    }
Ejemplo n.º 5
0
    //recursively go through the Octree and convert them into a simple structure
    void UnpackTree(Octree.OctreeNode node)
    {
        TreeNode current = new TreeNode();

        var subNodes = node.Nodes;

        //set this up
        current.mParent = node.Parent;
        current.mNode   = node;
        int i = 0;

        if (subNodes != null)
        {
            current.mChildren = new Octree.OctreeNode[8];
            foreach (var subNode in subNodes)
            {
                current.mChildren[i] = subNode;
                ++i;
            }
        }
        else
        {
            current.mChildren = null;
        }

        //assign this node to our array only if It's not inside a mesh
        if (!current.mNode.InsideMesh)
        {
            Unpacked_Tree.Add(current);
        }

        //if this Node has children recurse
        if (!node.IsLeaf())
        {
            foreach (var subNode in subNodes)
            {
                UnpackTree(subNode);
            }
        }
    }
Ejemplo n.º 6
0
    //Final step Get the Unpacked tree and then pack it into a linear Buffer
    void PackTree()
    {
        //the unpacked Tree is recursively built so we have to turn it into a linear list here before we copy it with proper
        //indexing into the final LinearList below
        List <TreeNode> LinearUnpackedTree = new List <TreeNode>();

        for (int i = 0; i < Unpacked_Tree.Count - 1; ++i) //ignore last node some reason the recursion f***s up when adding an extra garbage node
        {
            LinearUnpackedTree.Add(Unpacked_Tree[i]);
        }
        Unpacked_Tree.Clear();

        //Go through the unpacked tree and build it linearly
        List <SDF_Node> LinearList = new List <SDF_Node>();

        for (int i = 0; i < LinearUnpackedTree.Count; ++i)
        {
            SDF_Node current = new SDF_Node();

            Octree.OctreeNode node = LinearUnpackedTree[i].mNode;
            Vector3           p    = node.Position;
            float             s    = node.SDF.mSize;

            current.Min.x = p.x - s;
            current.Min.y = p.y - s;
            current.Min.z = p.z - s;

            current.Max.x = p.x + s;
            current.Max.y = p.y + s;
            current.Max.z = p.z + s;

            current.index        = i;
            current.SurfacePoint = node.SDF.mPoint;
            if (LinearUnpackedTree[i].mChildren != null)
            {
                current.c0 = FindIndex(LinearUnpackedTree[i].mChildren[0], ref LinearUnpackedTree);
                current.c1 = FindIndex(LinearUnpackedTree[i].mChildren[1], ref LinearUnpackedTree);
                current.c2 = FindIndex(LinearUnpackedTree[i].mChildren[2], ref LinearUnpackedTree);
                current.c3 = FindIndex(LinearUnpackedTree[i].mChildren[3], ref LinearUnpackedTree);
                current.c4 = FindIndex(LinearUnpackedTree[i].mChildren[4], ref LinearUnpackedTree);
                current.c5 = FindIndex(LinearUnpackedTree[i].mChildren[5], ref LinearUnpackedTree);
                current.c6 = FindIndex(LinearUnpackedTree[i].mChildren[6], ref LinearUnpackedTree);
                current.c7 = FindIndex(LinearUnpackedTree[i].mChildren[7], ref LinearUnpackedTree);
            }
            else
            {
                current.c0 = -1;
                current.c1 = -1;
                current.c2 = -1;
                current.c3 = -1;
                current.c4 = -1;
                current.c5 = -1;
                current.c6 = -1;
                current.c7 = -1;
            }

            LinearList.Add(current);
        }

        //used to set a ComputeBuffer later on
        nodeArray = LinearList.ToArray();
    }