public SgtPatch CreatePatch(string name, SgtPatch parent, Vector3 pointBL, Vector3 pointBR, Vector3 pointTL, Vector3 pointTR, Vector3 coordBL, Vector3 coordBR, Vector3 coordTL, Vector3 coordTR, int depth)
    {
        var parentTransform = parent != null ? parent.transform : transform;
        var patch           = SgtPatch.Create(name, gameObject.layer, parentTransform);

        patch.Terrain = this;
        patch.Parent  = parent;
        patch.Depth   = depth;
        patch.PointBL = pointBL;
        patch.PointBR = pointBR;
        patch.PointTL = pointTL;
        patch.PointTR = pointTR;
        patch.CoordBL = coordBL;
        patch.CoordBR = coordBR;
        patch.CoordTL = coordTL;
        patch.CoordTR = coordTR;

        patch.UpdateState();

#if UNITY_EDITOR
        if (Application.isPlaying == false)
        {
            patch.UpdateSplitMerge();
        }
#endif

        return(patch);
    }
 private void UpdatePatches()
 {
     if (negativeX == null)
     {
         negativeX = CreatePatch("Negative X", Quaternion.Euler(0.0f, 90.0f, 0.0f));
     }
     if (negativeY == null)
     {
         negativeY = CreatePatch("Negative Y", Quaternion.Euler(90.0f, 0.0f, 0.0f));
     }
     if (negativeZ == null)
     {
         negativeZ = CreatePatch("Negative Z", Quaternion.Euler(0.0f, 180.0f, 0.0f));
     }
     if (positiveX == null)
     {
         positiveX = CreatePatch("Positive X", Quaternion.Euler(0.0f, 270.0f, 0.0f));
     }
     if (positiveY == null)
     {
         positiveY = CreatePatch("Positive Y", Quaternion.Euler(270.0f, 0.0f, 0.0f));
     }
     if (positiveZ == null)
     {
         positiveZ = CreatePatch("Positive Z", Quaternion.Euler(0.0f, 0.0f, 0.0f));
     }
 }
    public static SgtPatch CreatePatch(string name, SgtTerrain terrain, SgtPatch parent, Vector3 pointBL, Vector3 pointBR, Vector3 pointTL, Vector3 pointTR, Vector3 coordBL, Vector3 coordBR, Vector3 coordTL, Vector3 coordTR, int depth)
    {
        if (terrain != null)
        {
            var parentTransform = parent != null ? parent.transform : terrain.transform;
            var patch           = SgtPatch.Create(name, terrain, parentTransform);

            patch.Parent  = parent;
            patch.Depth   = depth;
            patch.PointBL = pointBL;
            patch.PointBR = pointBR;
            patch.PointTL = pointTL;
            patch.PointTR = pointTR;
            patch.CoordBL = coordBL;
            patch.CoordBR = coordBR;
            patch.CoordTL = coordTL;
            patch.CoordTR = coordTR;

            patch.UpdateState();

        #if UNITY_EDITOR
            if (Application.isPlaying == false)
            {
                patch.UpdateSplitMerge();
            }
        #endif

            return patch;
        }

        return null;
    }
 protected virtual void OnDestroy()
 {
     negativeX = SgtPatch.MarkForDestruction(negativeX);
     negativeY = SgtPatch.MarkForDestruction(negativeY);
     negativeZ = SgtPatch.MarkForDestruction(negativeZ);
     positiveX = SgtPatch.MarkForDestruction(positiveX);
     positiveY = SgtPatch.MarkForDestruction(positiveY);
     positiveZ = SgtPatch.MarkForDestruction(positiveZ);
 }
Esempio n. 5
0
    public static SgtPatch MarkForDestruction(SgtPatch patch)
    {
        if (patch != null)
        {
            patch.Terrain = null;

            patch.gameObject.SetActive(true);
        }

        return(null);
    }
Esempio n. 6
0
    public static SgtPatch MarkForDestruction(SgtPatch patch)
    {
        if (patch != null)
        {
            patch.Terrain = null;

            patch.gameObject.SetActive(true);
        }

        return null;
    }
Esempio n. 7
0
    private void Merge()
    {
        if (ChildrenExist == true)
        {
            ChildBL = Pool(ChildBL);
            ChildBR = Pool(ChildBR);
            ChildTL = Pool(ChildTL);
            ChildTR = Pool(ChildTR);

            UpdateState();
        }
    }
Esempio n. 8
0
    public static SgtPatch Pool(SgtPatch patch)
    {
        if (patch != null)
        {
            patch.ChildBL = Pool(patch.ChildBL);
            patch.ChildBR = Pool(patch.ChildBR);
            patch.ChildTL = Pool(patch.ChildTL);
            patch.ChildTR = Pool(patch.ChildTR);

            patch.Terrain       = null;
            patch.Parent        = null;
            patch.Material      = null;
            patch.FinalMaterial = null;

            patch.PoolMeshNow();

            SgtComponentPool <SgtPatch> .Add(patch);
        }

        return(null);
    }
Esempio n. 9
0
    public static SgtPatch Pool(SgtPatch patch)
    {
        if (patch != null)
        {
            patch.ChildBL = Pool(patch.ChildBL);
            patch.ChildBR = Pool(patch.ChildBR);
            patch.ChildTL = Pool(patch.ChildTL);
            patch.ChildTR = Pool(patch.ChildTR);

            patch.Terrain       = null;
            patch.Parent        = null;
            patch.Material      = null;
            patch.FinalMaterial = null;

            patch.PoolMeshNow();

            SgtComponentPool<SgtPatch>.Add(patch);
        }

        return null;
    }
Esempio n. 10
0
    private void Split()
    {
        if (ChildrenExist == false)
        {
            var PointCC = (PointBL + PointTR) * 0.5f;
            var PointBC = (PointBL + PointBR) * 0.5f;
            var PointTC = (PointTL + PointTR) * 0.5f;
            var PointCL = (PointTL + PointBL) * 0.5f;
            var PointCR = (PointTR + PointBR) * 0.5f;

            var CoordCC = (CoordBL + CoordTR) * 0.5f;
            var CoordBC = (CoordBL + CoordBR) * 0.5f;
            var CoordTC = (CoordTL + CoordTR) * 0.5f;
            var CoordCL = (CoordTL + CoordBL) * 0.5f;
            var CoordCR = (CoordTR + CoordBR) * 0.5f;

            if (ChildBL == null)
            {
                ChildBL = SgtPatchBuilder.CreatePatch("Bottom Left", Terrain, this, PointBL, PointBC, PointCL, PointCC, CoordBL, CoordBC, CoordCL, CoordCC, Depth + 1);
            }
            if (ChildBR == null)
            {
                ChildBR = SgtPatchBuilder.CreatePatch("Bottom Right", Terrain, this, PointBC, PointBR, PointCC, PointCR, CoordBC, CoordBR, CoordCC, CoordCR, Depth + 1);
            }
            if (ChildTL == null)
            {
                ChildTL = SgtPatchBuilder.CreatePatch("Top Left", Terrain, this, PointCL, PointCC, PointTL, PointTC, CoordCL, CoordCC, CoordTL, CoordTC, Depth + 1);
            }
            if (ChildTR == null)
            {
                ChildTR = SgtPatchBuilder.CreatePatch("Top Right", Terrain, this, PointCC, PointCR, PointTC, PointTR, CoordCC, CoordCR, CoordTC, CoordTR, Depth + 1);
            }

            UpdateState();
        }
    }
    public static void GenerateMesh(SgtPatch patch)
    {
        var terrain = patch.Terrain;

        if (terrain.Resolution > 0)
        {
            var positions    = terrain.Positions;
            var coords1      = terrain.Coords1;
            var coords2      = terrain.Coords2;
            var normals      = terrain.Normals;
            var tangents     = terrain.Tangents;
            var quadPoints   = terrain.QuadPoints;
            var quadNormals  = terrain.QuadNormals;
            var quadTangents = terrain.QuadTangents;
            var indices      = terrain.Indices;
            var res          = terrain.Resolution;
            var resAdd1      = res + 1;
            var resAdd2      = res + 2;
            var resAdd3      = res + 3;
            var resRecip     = SgtHelper.Reciprocal(res);
            var mainVerts    = resAdd1 * resAdd1;
            var skirtVerts   = resAdd1 * 4;
            var mainIndices  = res * res * 6;
            var skirtIndices = res * 24;
            var vertex       = default(int);
            var vertex2      = default(int);
            var index        = default(int);

            if (positions.Length != mainVerts + skirtVerts)
            {
                terrain.Positions = positions = new Vector3[mainVerts + skirtVerts];
            }
            if (coords1.Length != mainVerts + skirtVerts)
            {
                terrain.Coords1 = coords1 = new Vector2[mainVerts + skirtVerts];
            }
            if (coords2.Length != mainVerts + skirtVerts)
            {
                terrain.Coords2 = coords2 = new Vector2[mainVerts + skirtVerts];
            }
            if (normals.Length != mainVerts + skirtVerts)
            {
                terrain.Normals = normals = new Vector3[mainVerts + skirtVerts];
            }
            if (tangents.Length != mainVerts + skirtVerts)
            {
                terrain.Tangents = tangents = new Vector4[mainVerts + skirtVerts];
            }
            if (quadPoints.Length != resAdd3 * resAdd3)
            {
                terrain.QuadPoints = quadPoints = new Vector3[resAdd3 * resAdd3];
            }
            if (quadNormals.Length != resAdd2 * resAdd2)
            {
                terrain.QuadNormals = quadNormals = new Vector3[resAdd2 * resAdd2];
            }
            if (quadTangents.Length != resAdd2 * resAdd2)
            {
                terrain.QuadTangents = quadTangents = new Vector3[resAdd2 * resAdd2];
            }

            // Go through all vertices, but extend the borders by one
            for (var y = -1; y < resAdd2; y++)
            {
                for (var x = -1; x < resAdd2; x++)
                {
                    var u      = x * resRecip;
                    var v      = y * resRecip;
                    var pointB = Lerp3(patch.PointBL, patch.PointBR, u);
                    var pointT = Lerp3(patch.PointTL, patch.PointTR, u);
                    var point  = Lerp3(pointB, pointT, v).normalized; point *= terrain.GetHeight(point);

                    index = x + 1 + (y + 1) * resAdd3;

                    quadPoints[index] = point;

                    // Is this a main vertex?
                    if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1)
                    {
                        var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u);
                        var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u);
                        var coord1 = Lerp2(coordB, coordT, v);

                        vertex = x + y * resAdd1;

                        positions[vertex] = point;

                        coords1[vertex] = coord1;

                        coords2[vertex] = new Vector2(u, v);
                    }
                }
            }

            // Quad normals & tangents
            for (var y = 0; y < resAdd2; y++)
            {
                for (var x = 0; x < resAdd2; x++)
                {
                    var bl = x + y * resAdd3;
                    var br = x + 1 + y * resAdd3;
                    var tl = x + (y + 1) * resAdd3;
                    var tr = x + 1 + (y + 1) * resAdd3;

                    var b = quadPoints[bl] - quadPoints[br];
                    var t = quadPoints[tl] - quadPoints[tr];
                    var l = quadPoints[bl] - quadPoints[tl];
                    var r = quadPoints[br] - quadPoints[tr];

                    var h = (b + t).normalized;
                    var v = (l + r).normalized;
                    var i = x + y * resAdd2;

                    quadNormals[i] = Vector3.Cross(h, v);

                    quadTangents[i] = v;
                }
            }

            // Normals & Tangents
            for (var y = 0; y < resAdd1; y++)
            {
                for (var x = 0; x < resAdd1; x++)
                {
                    var bl = x + y * resAdd2;
                    var br = x + 1 + y * resAdd2;
                    var tl = x + (y + 1) * resAdd2;
                    var tr = x + 1 + (y + 1) * resAdd2;

                    var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr];
                    var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr];
                    var i = x + y * resAdd1;

                    normals[i] = n.normalized;
                    //normals[i] = positions[i].normalized;

                    tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f);
                }
            }

            // Skirt vertices
            var scale = 1.0f - SgtHelper.Divide(terrain.SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f);

            for (var i = 0; i < resAdd1; i++)
            {
                // Bottom
                vertex  = mainVerts + i;
                vertex2 = i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Top
                vertex  = mainVerts + i + resAdd1;
                vertex2 = resAdd1 * res + i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Left
                vertex  = mainVerts + i + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Right
                vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i + res;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];
            }

            // Indices
            if (indices.Length != mainIndices + skirtIndices)
            {
                terrain.Indices = indices = new int[mainIndices + skirtIndices];

                // Main
                for (var y = 0; y < res; y++)
                {
                    for (var x = 0; x < res; x++)
                    {
                        index  = (x + y * res) * 6;
                        vertex = x + y * resAdd1;

                        indices[index + 0] = vertex;
                        indices[index + 1] = vertex + 1;
                        indices[index + 2] = vertex + resAdd1;
                        indices[index + 3] = vertex + resAdd1 + 1;
                        indices[index + 4] = vertex + resAdd1;
                        indices[index + 5] = vertex + 1;
                    }
                }

                // Skirt
                for (var i = 0; i < res; i++)
                {
                    // Bottom
                    index   = mainIndices + (res * 0 + i) * 6;
                    vertex  = mainVerts + i;
                    vertex2 = i;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex + 1;
                    indices[index + 2] = vertex2;
                    indices[index + 3] = vertex2 + 1;
                    indices[index + 4] = vertex2;
                    indices[index + 5] = vertex + 1;

                    // Top
                    index   = mainIndices + (res * 1 + i) * 6;
                    vertex  = mainVerts + i + resAdd1;
                    vertex2 = res * resAdd1 + i;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex2 + 1;
                    indices[index + 2] = vertex;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex;
                    indices[index + 5] = vertex2 + 1;

                    // Left
                    index   = mainIndices + (res * 2 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex2;
                    indices[index + 2] = vertex + 1;
                    indices[index + 3] = vertex2 + resAdd1;
                    indices[index + 4] = vertex + 1;
                    indices[index + 5] = vertex2;

                    // Right
                    index   = mainIndices + (res * 3 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1 + res;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex;
                    indices[index + 2] = vertex2 + resAdd1;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex2 + resAdd1;
                    indices[index + 5] = vertex;
                }
            }

            if (patch.Mesh != null)
            {
                patch.Mesh.Clear();
            }
            else
            {
                patch.Mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

                patch.Mesh.hideFlags = HideFlags.DontSave;
            }

            patch.Mesh.vertices  = positions;
            patch.Mesh.uv        = coords1;
            patch.Mesh.uv2       = coords2;
            patch.Mesh.normals   = normals;
            patch.Mesh.tangents  = tangents;
            patch.Mesh.triangles = indices;
            patch.Mesh.RecalculateBounds();

            patch.MeshCenter = patch.Mesh.bounds.center;
        }
    }
    public void RebuildPatch(SgtPatch patch)
    {
        if (Resolution > 0)
        {
            var resAdd1      = Resolution + 1;
            var resAdd2      = Resolution + 2;
            var resAdd3      = Resolution + 3;
            var resRecip     = SgtHelper.Reciprocal(Resolution);
            var mainVerts    = resAdd1 * resAdd1;
            var skirtVerts   = resAdd1 * 4;
            var mainIndices  = Resolution * Resolution * 6;
            var skirtIndices = Resolution * 24;
            var mesh         = patch.Mesh;
            var vertex       = default(int);
            var vertex2      = default(int);
            var index        = default(int);

            if (positions == null || positions.Length != mainVerts + skirtVerts)
            {
                positions = new Vector3[mainVerts + skirtVerts];
            }
            if (coords1 == null || coords1.Length != mainVerts + skirtVerts)
            {
                coords1 = new Vector2[mainVerts + skirtVerts];
            }
            if (coords2 == null || coords2.Length != mainVerts + skirtVerts)
            {
                coords2 = new Vector2[mainVerts + skirtVerts];
            }
            if (normals == null || normals.Length != mainVerts + skirtVerts)
            {
                normals = new Vector3[mainVerts + skirtVerts];
            }
            if (tangents == null || tangents.Length != mainVerts + skirtVerts)
            {
                tangents = new Vector4[mainVerts + skirtVerts];
            }
            if (quadPoints == null || quadPoints.Length != resAdd3 * resAdd3)
            {
                quadPoints = new Vector3[resAdd3 * resAdd3];
            }
            if (quadNormals == null || quadNormals.Length != resAdd2 * resAdd2)
            {
                quadNormals = new Vector3[resAdd2 * resAdd2];
            }
            if (quadTangents == null || quadTangents.Length != resAdd2 * resAdd2)
            {
                quadTangents = new Vector3[resAdd2 * resAdd2];
            }

            // Go through all vertices, but extend the borders by one
            for (var y = -1; y < resAdd2; y++)
            {
                for (var x = -1; x < resAdd2; x++)
                {
                    var u      = x * resRecip;
                    var v      = y * resRecip;
                    var pointB = Lerp3(patch.PointBL, patch.PointBR, u);
                    var pointT = Lerp3(patch.PointTL, patch.PointTR, u);
                    var point  = GetSurfacePositionLocal(Lerp3(pointB, pointT, v));

                    index = x + 1 + (y + 1) * resAdd3;

                    quadPoints[index] = point;

                    // Is this a main vertex?
                    if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1)
                    {
                        var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u);
                        var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u);
                        var coord1 = Lerp2(coordB, coordT, v);
                        var coord2 = new Vector2(u, v);
                        var center = (patch.PointBL + patch.PointBR + patch.PointTL + patch.PointTR) * 0.25f;

                        if (OnCalculateCoord1 != null)
                        {
                            OnCalculateCoord1(point, center, ref coord1);
                        }
                        if (OnCalculateCoord2 != null)
                        {
                            OnCalculateCoord2(point, center, ref coord2);
                        }

                        vertex = x + y * resAdd1;

                        positions[vertex] = point;

                        coords1[vertex] = coord1;

                        coords2[vertex] = coord2;
                    }
                }
            }

            // Quad normals & tangents
            for (var y = 0; y < resAdd2; y++)
            {
                for (var x = 0; x < resAdd2; x++)
                {
                    var bl = x + y * resAdd3;
                    var br = x + 1 + y * resAdd3;
                    var tl = x + (y + 1) * resAdd3;
                    var tr = x + 1 + (y + 1) * resAdd3;

                    var b = quadPoints[bl] - quadPoints[br];
                    var t = quadPoints[tl] - quadPoints[tr];
                    var l = quadPoints[bl] - quadPoints[tl];
                    var r = quadPoints[br] - quadPoints[tr];

                    var h = (b + t).normalized;
                    var v = (l + r).normalized;
                    var i = x + y * resAdd2;

                    quadNormals[i] = Vector3.Cross(h, v);

                    quadTangents[i] = v;
                }
            }

            // Normals & Tangents
            for (var y = 0; y < resAdd1; y++)
            {
                for (var x = 0; x < resAdd1; x++)
                {
                    var bl = x + y * resAdd2;
                    var br = x + 1 + y * resAdd2;
                    var tl = x + (y + 1) * resAdd2;
                    var tr = x + 1 + (y + 1) * resAdd2;

                    var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr];
                    var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr];
                    var i = x + y * resAdd1;

                    normals[i] = n.normalized;
                    //normals[i] = positions[i].normalized;

                    tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f);
                }
            }

            // Skirt vertices
            var scale = 1.0f - SgtHelper.Divide(SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f);

            for (var i = 0; i < resAdd1; i++)
            {
                // Bottom
                vertex  = mainVerts + i;
                vertex2 = i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Top
                vertex  = mainVerts + i + resAdd1;
                vertex2 = resAdd1 * Resolution + i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Left
                vertex  = mainVerts + i + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Right
                vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i + Resolution;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];
            }

            // Indices
            if (indices == null || indices.Length != mainIndices + skirtIndices)
            {
                indices = new int[mainIndices + skirtIndices];

                // Main
                for (var y = 0; y < Resolution; y++)
                {
                    for (var x = 0; x < Resolution; x++)
                    {
                        index  = (x + y * Resolution) * 6;
                        vertex = x + y * resAdd1;

                        indices[index + 0] = vertex;
                        indices[index + 1] = vertex + 1;
                        indices[index + 2] = vertex + resAdd1;
                        indices[index + 3] = vertex + resAdd1 + 1;
                        indices[index + 4] = vertex + resAdd1;
                        indices[index + 5] = vertex + 1;
                    }
                }

                // Skirt
                for (var i = 0; i < Resolution; i++)
                {
                    // Bottom
                    index   = mainIndices + (Resolution * 0 + i) * 6;
                    vertex  = mainVerts + i;
                    vertex2 = i;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex + 1;
                    indices[index + 2] = vertex2;
                    indices[index + 3] = vertex2 + 1;
                    indices[index + 4] = vertex2;
                    indices[index + 5] = vertex + 1;

                    // Top
                    index   = mainIndices + (Resolution * 1 + i) * 6;
                    vertex  = mainVerts + i + resAdd1;
                    vertex2 = Resolution * resAdd1 + i;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex2 + 1;
                    indices[index + 2] = vertex;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex;
                    indices[index + 5] = vertex2 + 1;

                    // Left
                    index   = mainIndices + (Resolution * 2 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex2;
                    indices[index + 2] = vertex + 1;
                    indices[index + 3] = vertex2 + resAdd1;
                    indices[index + 4] = vertex + 1;
                    indices[index + 5] = vertex2;

                    // Right
                    index   = mainIndices + (Resolution * 3 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1 + Resolution;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex;
                    indices[index + 2] = vertex2 + resAdd1;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex2 + resAdd1;
                    indices[index + 5] = vertex;
                }
            }

            if (mesh != null)
            {
                mesh.Clear();
            }
            else
            {
                mesh = patch.Mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

                mesh.name      = "Patch";
                mesh.hideFlags = HideFlags.DontSave;
            }

            mesh.vertices  = positions;
            mesh.uv        = coords1;
            mesh.uv2       = coords2;
            mesh.normals   = normals;
            mesh.tangents  = tangents;
            mesh.triangles = indices;
            mesh.RecalculateBounds();

            patch.MeshCenter = mesh.bounds.center;
        }
    }
Esempio n. 13
0
	private void UpdatePatches()
	{
		if (negativeX == null) negativeX = CreatePatch("Negative X", Quaternion.Euler(  0.0f,  90.0f, 0.0f));
		if (negativeY == null) negativeY = CreatePatch("Negative Y", Quaternion.Euler( 90.0f,   0.0f, 0.0f));
		if (negativeZ == null) negativeZ = CreatePatch("Negative Z", Quaternion.Euler(  0.0f, 180.0f, 0.0f));
		if (positiveX == null) positiveX = CreatePatch("Positive X", Quaternion.Euler(  0.0f, 270.0f, 0.0f));
		if (positiveY == null) positiveY = CreatePatch("Positive Y", Quaternion.Euler(270.0f,   0.0f, 0.0f));
		if (positiveZ == null) positiveZ = CreatePatch("Positive Z", Quaternion.Euler(  0.0f,   0.0f, 0.0f));
	}
Esempio n. 14
0
	protected virtual void OnDestroy()
	{
		negativeX = SgtPatch.MarkForDestruction(negativeX);
		negativeY = SgtPatch.MarkForDestruction(negativeY);
		negativeZ = SgtPatch.MarkForDestruction(negativeZ);
		positiveX = SgtPatch.MarkForDestruction(positiveX);
		positiveY = SgtPatch.MarkForDestruction(positiveY);
		positiveZ = SgtPatch.MarkForDestruction(positiveZ);
	}
Esempio n. 15
0
	public void RebuildPatch(SgtPatch patch)
	{
		if (Resolution > 0)
		{
			var resAdd1      = Resolution + 1;
			var resAdd2      = Resolution + 2;
			var resAdd3      = Resolution + 3;
			var resRecip     = SgtHelper.Reciprocal(Resolution);
			var mainVerts    = resAdd1 * resAdd1;
			var skirtVerts   = resAdd1 * 4;
			var mainIndices  = Resolution * Resolution * 6;
			var skirtIndices = Resolution * 24;
			var mesh         = patch.Mesh;
			var vertex       = default(int);
			var vertex2      = default(int);
			var index        = default(int);

			if (   positions == null ||    positions.Length != mainVerts + skirtVerts ) positions    = new Vector3[mainVerts + skirtVerts];
			if (     coords1 == null ||      coords1.Length != mainVerts + skirtVerts ) coords1      = new Vector2[mainVerts + skirtVerts];
			if (     coords2 == null ||      coords2.Length != mainVerts + skirtVerts ) coords2      = new Vector2[mainVerts + skirtVerts];
			if (     normals == null ||      normals.Length != mainVerts + skirtVerts ) normals      = new Vector3[mainVerts + skirtVerts];
			if (    tangents == null ||     tangents.Length != mainVerts + skirtVerts ) tangents     = new Vector4[mainVerts + skirtVerts];
			if (  quadPoints == null ||   quadPoints.Length != resAdd3   * resAdd3    ) quadPoints   = new Vector3[resAdd3 * resAdd3];
			if ( quadNormals == null ||  quadNormals.Length != resAdd2   * resAdd2    ) quadNormals  = new Vector3[resAdd2 * resAdd2];
			if (quadTangents == null || quadTangents.Length != resAdd2   * resAdd2    ) quadTangents = new Vector3[resAdd2 * resAdd2];

			// Go through all vertices, but extend the borders by one
			for (var y = -1; y < resAdd2; y++)
			{
				for (var x = -1; x < resAdd2; x++)
				{
					var u      = x * resRecip;
					var v      = y * resRecip;
					var pointB = Lerp3(patch.PointBL, patch.PointBR, u);
					var pointT = Lerp3(patch.PointTL, patch.PointTR, u);
					var point  = GetSurfacePositionLocal(Lerp3(pointB, pointT, v));

					index = x + 1 + (y + 1) * resAdd3;

					quadPoints[index] = point;

					// Is this a main vertex?
					if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1)
					{
						var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u);
						var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u);
						var coord1 = Lerp2(coordB, coordT, v);
						var coord2 = new Vector2(u, v);
						var center = (patch.PointBL + patch.PointBR + patch.PointTL + patch.PointTR) * 0.25f;

						if (OnCalculateCoord1 != null) OnCalculateCoord1(point, center, ref coord1);
						if (OnCalculateCoord2 != null) OnCalculateCoord2(point, center, ref coord2);

						vertex = x + y * resAdd1;

						positions[vertex] = point;

						coords1[vertex] = coord1;

						coords2[vertex] = coord2;
					}
				}
			}

			// Quad normals & tangents
			for (var y = 0; y < resAdd2; y++)
			{
				for (var x = 0; x < resAdd2; x++)
				{
					var bl = x + y * resAdd3;
					var br = x + 1 + y * resAdd3;
					var tl = x + (y + 1) * resAdd3;
					var tr = x + 1 + (y + 1) * resAdd3;

					var b = quadPoints[bl] - quadPoints[br];
					var t = quadPoints[tl] - quadPoints[tr];
					var l = quadPoints[bl] - quadPoints[tl];
					var r = quadPoints[br] - quadPoints[tr];

					var h = (b + t).normalized;
					var v = (l + r).normalized;
					var i = x + y * resAdd2;

					quadNormals[i] = Vector3.Cross(h, v);

					quadTangents[i] = v;
				}
			}

			// Normals & Tangents
			for (var y = 0; y < resAdd1; y++)
			{
				for (var x = 0; x < resAdd1; x++)
				{
					var bl = x + y * resAdd2;
					var br = x + 1 + y * resAdd2;
					var tl = x + (y + 1) * resAdd2;
					var tr = x + 1 + (y + 1) * resAdd2;

					var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr];
					var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr];
					var i = x + y * resAdd1;

					normals[i] = n.normalized;
					//normals[i] = positions[i].normalized;

					tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f);
				}
			}

			// Skirt vertices
			var scale = 1.0f - SgtHelper.Divide(SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f);

			for (var i = 0; i < resAdd1; i++)
			{
				// Bottom
				vertex  = mainVerts + i;
				vertex2 = i;

				positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

				// Top
				vertex  = mainVerts + i + resAdd1;
				vertex2 = resAdd1 * Resolution + i;

				positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

				// Left
				vertex  = mainVerts + i + resAdd1 + resAdd1;
				vertex2 = resAdd1 * i;

				positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

				// Right
				vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
				vertex2 = resAdd1 * i + Resolution;

				positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];
			}

			// Indices
			if (indices== null || indices.Length != mainIndices + skirtIndices)
			{
				indices = new int[mainIndices + skirtIndices];

				// Main
				for (var y = 0; y < Resolution; y++)
				{
					for (var x = 0; x < Resolution; x++)
					{
						index  = (x + y * Resolution) * 6;
						vertex = x + y * resAdd1;

						indices[index + 0] = vertex;
						indices[index + 1] = vertex + 1;
						indices[index + 2] = vertex + resAdd1;
						indices[index + 3] = vertex + resAdd1 + 1;
						indices[index + 4] = vertex + resAdd1;
						indices[index + 5] = vertex + 1;
					}
				}

				// Skirt
				for (var i = 0; i < Resolution; i++)
				{
					// Bottom
					index   = mainIndices + (Resolution * 0 + i) * 6;
					vertex  = mainVerts + i;
					vertex2 = i;

					indices[index + 0] = vertex;
					indices[index + 1] = vertex + 1;
					indices[index + 2] = vertex2;
					indices[index + 3] = vertex2 + 1;
					indices[index + 4] = vertex2;
					indices[index + 5] = vertex + 1;

					// Top
					index   = mainIndices + (Resolution * 1 + i) * 6;
					vertex  = mainVerts + i + resAdd1;
					vertex2 = Resolution * resAdd1 + i;

					indices[index + 0] = vertex2;
					indices[index + 1] = vertex2 + 1;
					indices[index + 2] = vertex;
					indices[index + 3] = vertex + 1;
					indices[index + 4] = vertex;
					indices[index + 5] = vertex2 + 1;

					// Left
					index   = mainIndices + (Resolution * 2 + i) * 6;
					vertex  = mainVerts + i + resAdd1 + resAdd1;
					vertex2 = i * resAdd1;

					indices[index + 0] = vertex;
					indices[index + 1] = vertex2;
					indices[index + 2] = vertex + 1;
					indices[index + 3] = vertex2 + resAdd1;
					indices[index + 4] = vertex + 1;
					indices[index + 5] = vertex2;

					// Right
					index   = mainIndices + (Resolution * 3 + i) * 6;
					vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
					vertex2 = i * resAdd1 + Resolution;

					indices[index + 0] = vertex2;
					indices[index + 1] = vertex;
					indices[index + 2] = vertex2 + resAdd1;
					indices[index + 3] = vertex + 1;
					indices[index + 4] = vertex2 + resAdd1;
					indices[index + 5] = vertex;
				}
			}

			if (mesh != null)
			{
				mesh.Clear();
			}
			else
			{
				mesh = patch.Mesh = SgtObjectPool<Mesh>.Pop() ?? new Mesh();

				mesh.name      = "Patch";
				mesh.hideFlags = HideFlags.DontSave;
			}

			mesh.vertices  = positions;
			mesh.uv        = coords1;
			mesh.uv2       = coords2;
			mesh.normals   = normals;
			mesh.tangents  = tangents;
			mesh.triangles = indices;
			mesh.RecalculateBounds();

			patch.MeshCenter = mesh.bounds.center;
		}
	}
    public static void GenerateMesh(SgtPatch patch)
    {
        var terrain = patch.Terrain;

        if (terrain.Resolution > 0)
        {
            var positions    = terrain.Positions;
            var coords1      = terrain.Coords1;
            var coords2      = terrain.Coords2;
            var normals      = terrain.Normals;
            var tangents     = terrain.Tangents;
            var quadPoints   = terrain.QuadPoints;
            var quadNormals  = terrain.QuadNormals;
            var quadTangents = terrain.QuadTangents;
            var indices      = terrain.Indices;
            var res          = terrain.Resolution;
            var resAdd1      = res + 1;
            var resAdd2      = res + 2;
            var resAdd3      = res + 3;
            var resRecip     = SgtHelper.Reciprocal(res);
            var mainVerts    = resAdd1 * resAdd1;
            var skirtVerts   = resAdd1 * 4;
            var mainIndices  = res * res * 6;
            var skirtIndices = res * 24;
            var vertex       = default(int);
            var vertex2      = default(int);
            var index        = default(int);

            if (    positions.Length != mainVerts + skirtVerts ) terrain.Positions    = positions    = new Vector3[mainVerts + skirtVerts];
            if (      coords1.Length != mainVerts + skirtVerts ) terrain.Coords1      = coords1      = new Vector2[mainVerts + skirtVerts];
            if (      coords2.Length != mainVerts + skirtVerts ) terrain.Coords2      = coords2      = new Vector2[mainVerts + skirtVerts];
            if (      normals.Length != mainVerts + skirtVerts ) terrain.Normals      = normals      = new Vector3[mainVerts + skirtVerts];
            if (     tangents.Length != mainVerts + skirtVerts ) terrain.Tangents     = tangents     = new Vector4[mainVerts + skirtVerts];
            if (   quadPoints.Length != resAdd3 * resAdd3) terrain.QuadPoints   = quadPoints   = new Vector3[resAdd3 * resAdd3];
            if (  quadNormals.Length != resAdd2 * resAdd2              ) terrain.QuadNormals  = quadNormals  = new Vector3[resAdd2 * resAdd2];
            if ( quadTangents.Length != resAdd2 * resAdd2              ) terrain.QuadTangents = quadTangents = new Vector3[resAdd2 * resAdd2];

            // Go through all vertices, but extend the borders by one
            for (var y = -1; y < resAdd2; y++)
            {
                for (var x = -1; x < resAdd2; x++)
                {
                    var u      = x * resRecip;
                    var v      = y * resRecip;
                    var pointB = Lerp3(patch.PointBL, patch.PointBR, u);
                    var pointT = Lerp3(patch.PointTL, patch.PointTR, u);
                    var point  = Lerp3(pointB, pointT, v).normalized; point *= terrain.GetHeight(point);

                    index = x + 1 + (y + 1) * resAdd3;

                    quadPoints[index] = point;

                    // Is this a main vertex?
                    if (x >= 0 && x < resAdd1 && y >= 0 && y < resAdd1)
                    {
                        var coordB = Lerp2(patch.CoordBL, patch.CoordBR, u);
                        var coordT = Lerp2(patch.CoordTL, patch.CoordTR, u);
                        var coord1 = Lerp2(coordB, coordT, v);

                        vertex = x + y * resAdd1;

                        positions[vertex] = point;

                        coords1[vertex] = coord1;

                        coords2[vertex] = new Vector2(u, v);
                    }
                }
            }

            // Quad normals & tangents
            for (var y = 0; y < resAdd2; y++)
            {
                for (var x = 0; x < resAdd2; x++)
                {
                    var bl = x + y * resAdd3;
                    var br = x + 1 + y * resAdd3;
                    var tl = x + (y + 1) * resAdd3;
                    var tr = x + 1 + (y + 1) * resAdd3;

                    var b = quadPoints[bl] - quadPoints[br];
                    var t = quadPoints[tl] - quadPoints[tr];
                    var l = quadPoints[bl] - quadPoints[tl];
                    var r = quadPoints[br] - quadPoints[tr];

                    var h = (b + t).normalized;
                    var v = (l + r).normalized;
                    var i = x + y * resAdd2;

                    quadNormals[i] = Vector3.Cross(h, v);

                    quadTangents[i] = v;
                }
            }

            // Normals & Tangents
            for (var y = 0; y < resAdd1; y++)
            {
                for (var x = 0; x < resAdd1; x++)
                {
                    var bl = x + y * resAdd2;
                    var br = x + 1 + y * resAdd2;
                    var tl = x + (y + 1) * resAdd2;
                    var tr = x + 1 + (y + 1) * resAdd2;

                    var n = quadNormals[bl] + quadNormals[br] + quadNormals[tl] + quadNormals[tr];
                    var t = quadTangents[bl] + quadTangents[br] + quadTangents[tl] + quadTangents[tr];
                    var i = x + y * resAdd1;

                    normals[i] = n.normalized;
                    //normals[i] = positions[i].normalized;

                    tangents[i] = SgtHelper.NewVector4(t.normalized, 1.0f);
                }
            }

            // Skirt vertices
            var scale = 1.0f - SgtHelper.Divide(terrain.SkirtThickness * Mathf.Pow(0.5f, patch.Depth), 1.0f);

            for (var i = 0; i < resAdd1; i++)
            {
                // Bottom
                vertex  = mainVerts + i;
                vertex2 = i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Top
                vertex  = mainVerts + i + resAdd1;
                vertex2 = resAdd1 * res + i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Left
                vertex  = mainVerts + i + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];

                // Right
                vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                vertex2 = resAdd1 * i + res;

                positions[vertex] = positions[vertex2] * scale; coords1[vertex] = coords1[vertex2]; coords2[vertex] = coords2[vertex2]; normals[vertex] = normals[vertex2]; tangents[vertex] = tangents[vertex2];
            }

            // Indices
            if (indices.Length != mainIndices + skirtIndices)
            {
                terrain.Indices = indices = new int[mainIndices + skirtIndices];

                // Main
                for (var y = 0; y < res; y++)
                {
                    for (var x = 0; x < res; x++)
                    {
                        index  = (x + y * res) * 6;
                        vertex = x + y * resAdd1;

                        indices[index + 0] = vertex;
                        indices[index + 1] = vertex + 1;
                        indices[index + 2] = vertex + resAdd1;
                        indices[index + 3] = vertex + resAdd1 + 1;
                        indices[index + 4] = vertex + resAdd1;
                        indices[index + 5] = vertex + 1;
                    }
                }

                // Skirt
                for (var i = 0; i < res; i++)
                {
                    // Bottom
                    index   = mainIndices + (res * 0 + i) * 6;
                    vertex  = mainVerts + i;
                    vertex2 = i;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex + 1;
                    indices[index + 2] = vertex2;
                    indices[index + 3] = vertex2 + 1;
                    indices[index + 4] = vertex2;
                    indices[index + 5] = vertex + 1;

                    // Top
                    index   = mainIndices + (res * 1 + i) * 6;
                    vertex  = mainVerts + i + resAdd1;
                    vertex2 = res * resAdd1 + i;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex2 + 1;
                    indices[index + 2] = vertex;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex;
                    indices[index + 5] = vertex2 + 1;

                    // Left
                    index   = mainIndices + (res * 2 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1;

                    indices[index + 0] = vertex;
                    indices[index + 1] = vertex2;
                    indices[index + 2] = vertex + 1;
                    indices[index + 3] = vertex2 + resAdd1;
                    indices[index + 4] = vertex + 1;
                    indices[index + 5] = vertex2;

                    // Right
                    index   = mainIndices + (res * 3 + i) * 6;
                    vertex  = mainVerts + i + resAdd1 + resAdd1 + resAdd1;
                    vertex2 = i * resAdd1 + res;

                    indices[index + 0] = vertex2;
                    indices[index + 1] = vertex;
                    indices[index + 2] = vertex2 + resAdd1;
                    indices[index + 3] = vertex + 1;
                    indices[index + 4] = vertex2 + resAdd1;
                    indices[index + 5] = vertex;
                }
            }

            if (patch.Mesh != null)
            {
                patch.Mesh.Clear();
            }
            else
            {
                patch.Mesh = SgtObjectPool<Mesh>.Pop() ?? new Mesh();
                patch.Mesh.hideFlags = HideFlags.DontSave;
            }

            patch.Mesh.vertices  = positions;
            patch.Mesh.uv        = coords1;
            patch.Mesh.uv2       = coords2;
            patch.Mesh.normals   = normals;
            patch.Mesh.tangents  = tangents;
            patch.Mesh.triangles = indices;
            patch.Mesh.RecalculateBounds();

            patch.MeshCenter = patch.Mesh.bounds.center;
        }
    }
Esempio n. 17
0
    private void Split()
    {
        if (ChildrenExist == false)
        {
            var PointCC = (PointBL + PointTR) * 0.5f;
            var PointBC = (PointBL + PointBR) * 0.5f;
            var PointTC = (PointTL + PointTR) * 0.5f;
            var PointCL = (PointTL + PointBL) * 0.5f;
            var PointCR = (PointTR + PointBR) * 0.5f;

            var CoordCC = (CoordBL + CoordTR) * 0.5f;
            var CoordBC = (CoordBL + CoordBR) * 0.5f;
            var CoordTC = (CoordTL + CoordTR) * 0.5f;
            var CoordCL = (CoordTL + CoordBL) * 0.5f;
            var CoordCR = (CoordTR + CoordBR) * 0.5f;

            if (ChildBL == null) ChildBL = Terrain.CreatePatch("Bottom Left" , this, PointBL, PointBC, PointCL, PointCC, CoordBL, CoordBC, CoordCL, CoordCC, Depth + 1);
            if (ChildBR == null) ChildBR = Terrain.CreatePatch("Bottom Right", this, PointBC, PointBR, PointCC, PointCR, CoordBC, CoordBR, CoordCC, CoordCR, Depth + 1);
            if (ChildTL == null) ChildTL = Terrain.CreatePatch("Top Left"    , this, PointCL, PointCC, PointTL, PointTC, CoordCL, CoordCC, CoordTL, CoordTC, Depth + 1);
            if (ChildTR == null) ChildTR = Terrain.CreatePatch("Top Right"   , this, PointCC, PointCR, PointTC, PointTR, CoordCC, CoordCR, CoordTC, CoordTR, Depth + 1);

            UpdateState();
        }
    }
Esempio n. 18
0
    private void Merge()
    {
        if (ChildrenExist == true)
        {
            ChildBL = Pool(ChildBL);
            ChildBR = Pool(ChildBR);
            ChildTL = Pool(ChildTL);
            ChildTR = Pool(ChildTR);

            UpdateState();
        }
    }