Beispiel #1
0
    private void Split()
    {
        //discard parent's resources
        if (Parent != null)
        {
            Parent.DestroyNode();
        }

        //force too coarse neighbors to split as well
        for (byte i = 0; i < 4; i++)
        {
            if (SplitLevel > Neighbors[i].Node.SplitLevel && !Neighbors[i].Node.HasChildren)
            {
                Neighbors[i].Node.Split();

                return;
            }
        }

        #region TOP LEFT

        var volume1 = new PatchAABB();

        volume1.Vertices.Add(Volume.Vertices[0]);
        volume1.Vertices.Add(Vector3.Lerp(Volume.Vertices[0], Volume.Vertices[1], 0.5f));
        volume1.Vertices.Add(Middle);
        volume1.Vertices.Add(Vector3.Lerp(Volume.Vertices[3], Volume.Vertices[0], 0.5f));

        var uv1a = Volume.UVs[0];
        var uv1b = Vector3.Lerp(Volume.UVs[0], Volume.UVs[1], 0.5f);
        var uv1d = Vector3.Lerp(Volume.UVs[3], Volume.UVs[0], 0.5f);
        var uv1c = new Vector3(uv1b.x, uv1d.y, 0);

        volume1.UVs.Add(uv1a);
        volume1.UVs.Add(uv1b);
        volume1.UVs.Add(uv1c);
        volume1.UVs.Add(uv1d);

        #endregion

        #region TOP RIGHT

        //second child - top right
        var volume2 = new PatchAABB();
        volume2.Vertices.Add(Vector3.Lerp(Volume.Vertices[0], Volume.Vertices[1], 0.5f));
        volume2.Vertices.Add(Volume.Vertices[1]);
        volume2.Vertices.Add(Vector3.Lerp(Volume.Vertices[1], Volume.Vertices[2], 0.5f));
        volume2.Vertices.Add(Middle);

        var uv2a = Vector3.Lerp(Volume.UVs[0], Volume.UVs[1], 0.5f);
        var uv2b = Volume.UVs[1];
        var uv2c = Vector3.Lerp(Volume.UVs[1], Volume.UVs[2], 0.5f);
        var uv2d = new Vector3(uv2a.x, uv2c.y, 0);

        volume2.UVs.Add(uv2a);
        volume2.UVs.Add(uv2b);
        volume2.UVs.Add(uv2c);
        volume2.UVs.Add(uv2d);

        #endregion

        #region BOTTOM RIGHT

        //third child - bottom right
        var volume3 = new PatchAABB();

        volume3.Vertices.Add(Middle);
        volume3.Vertices.Add(Vector3.Lerp(Volume.Vertices[1], Volume.Vertices[2], 0.5f));
        volume3.Vertices.Add(Volume.Vertices[2]);
        volume3.Vertices.Add(Vector3.Lerp(Volume.Vertices[3], Volume.Vertices[2], 0.5f));

        var uv3b = Vector3.Lerp(Volume.UVs[1], Volume.UVs[2], 0.5f);
        var uv3c = Volume.UVs[2];
        var uv3d = Vector3.Lerp(Volume.UVs[3], Volume.UVs[2], 0.5f);
        var uv3a = new Vector3(uv3d.x, uv3b.y, 0);

        volume3.UVs.Add(uv3a);
        volume3.UVs.Add(uv3b);
        volume3.UVs.Add(uv3c);
        volume3.UVs.Add(uv3d);

        #endregion

        #region BOTTOM LEFT

        //fourth child - bottom left
        var volume4 = new PatchAABB();

        volume4.Vertices.Add(Vector3.Lerp(Volume.Vertices[3], Volume.Vertices[0], 0.5f));
        volume4.Vertices.Add(Middle);
        volume4.Vertices.Add(Vector3.Lerp(Volume.Vertices[3], Volume.Vertices[2], 0.5f));
        volume4.Vertices.Add(Volume.Vertices[3]);

        var uv4a = Vector3.Lerp(Volume.UVs[3], Volume.UVs[0], 0.5f);
        var uv4c = Vector3.Lerp(Volume.UVs[3], Volume.UVs[2], 0.5f);
        var uv4d = Volume.UVs[3];
        var uv4b = new Vector3(uv4c.x, uv4a.y, 0);

        volume4.UVs.Add(uv4a);
        volume4.UVs.Add(uv4b);
        volume4.UVs.Add(uv4c);
        volume4.UVs.Add(uv4d);

        #endregion

        var q1 = new PatchTree(this, volume1);
        var q2 = new PatchTree(this, volume2);
        var q3 = new PatchTree(this, volume3);
        var q4 = new PatchTree(this, volume4);

        //set internal neighbors
        q1.SetNeighbor(PatchNeighborDirection.Bottom, q4, PatchNeighborDirection.Top);
        q1.SetNeighbor(PatchNeighborDirection.Right, q2, PatchNeighborDirection.Left);

        //set internal neighbors
        q2.SetNeighbor(PatchNeighborDirection.Bottom, q3, PatchNeighborDirection.Top);
        q2.SetNeighbor(PatchNeighborDirection.Left, q1, PatchNeighborDirection.Right);

        //set internal neighbors
        q3.SetNeighbor(PatchNeighborDirection.Top, q2, PatchNeighborDirection.Bottom);
        q3.SetNeighbor(PatchNeighborDirection.Left, q4, PatchNeighborDirection.Right);

        //set internal neighbors
        q4.SetNeighbor(PatchNeighborDirection.Top, q1, PatchNeighborDirection.Bottom);
        q4.SetNeighbor(PatchNeighborDirection.Right, q3, PatchNeighborDirection.Left);

        //store as children of the current node
        Children[0] = q1;
        Children[1] = q2;
        Children[2] = q3;
        Children[3] = q4;

        Sphere.Splitted = true;

        HasChildren = true;

        ReLink();
    }