public static void Split(int verticesStep, HideFlags hideFlags)
    {
        if (positions.Count > 0)
        {
            var stepCount       = positions.Count / verticesStep;
            var stepsPerMesh    = 65000 / verticesStep;
            var verticesPerMesh = stepsPerMesh * verticesStep;
            var meshCount       = (positions.Count + verticesPerMesh - 1) / verticesPerMesh;

            for (var i = 0; i < meshCount; i++)
            {
                var stepA = i * stepsPerMesh;
                var stepB = Mathf.Min(stepA + stepsPerMesh, stepCount);
                var stepC = stepB - stepA;
                var vertA = stepA * verticesStep;
                var vertC = stepC * verticesStep;
                var mesh  = SgtObjectPool <Mesh> .Pop() ?? new Mesh(); meshes.Add(mesh);

                mesh.Clear(false);

                mesh.hideFlags = hideFlags;
                mesh.vertices  = GetRange(positions, vertA, vertC);

                if (colors.Count > 0)
                {
                    mesh.colors = GetRange(colors, vertA, vertC);
                }

                if (color32s.Count > 0)
                {
                    mesh.colors32 = GetRange(color32s, vertA, vertC);
                }

                if (coords1.Count > 0)
                {
                    mesh.uv = GetRange(coords1, vertA, vertC);
                }

                if (coords2.Count > 0)
                {
                    mesh.uv2 = GetRange(coords2, vertA, vertC);
                }

                if (normals.Count > 0)
                {
                    mesh.normals = GetRange(normals, vertA, vertC);
                }

                if (tangents.Count > 0)
                {
                    mesh.tangents = GetRange(tangents, vertA, vertC);
                }
            }
        }
    }
Пример #2
0
    public static Mesh CreateTempMesh(string meshName)
    {
        var mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

        mesh.name = meshName;

#if UNITY_EDITOR
        mesh.hideFlags = HideFlags.DontSave;
#endif
        return(mesh);
    }
Пример #3
0
    public Mesh GetColliderMesh()
    {
        if (colliderMesh == null)
        {
            colliderMesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

#if UNITY_EDITOR
            colliderMesh.hideFlags = HideFlags.DontSave;
#endif
            colliderMesh.name = "Terrain (Capped)";
        }

        return(colliderMesh);
    }
Пример #4
0
    public Mesh GetMesh()
    {
        if (mesh == null)
        {
            mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

#if UNITY_EDITOR
            mesh.hideFlags = HideFlags.DontSave;
#endif
            mesh.name = "Terrain";
        }

        if (meshFilter == null)
        {
            meshFilter = GetComponent <MeshFilter>();
        }

        meshFilter.sharedMesh = mesh;

        return(mesh);
    }
Пример #5
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;
        }
    }
Пример #6
0
    private void Build(SgtTerrain terrain, Vector3 bestPoint)
    {
        if (meshCollider == null)
        {
            var gameObject = new GameObject("Plane");
#if UNITY_EDITOR
            gameObject.hideFlags = HideFlags.DontSave;
#endif
            meshCollider = gameObject.AddComponent <MeshCollider>();
        }

        if (mesh == null)
        {
            mesh = SgtObjectPool <Mesh> .Pop() ?? new Mesh();

#if UNITY_EDITOR
            mesh.hideFlags = HideFlags.DontSave;
#endif
            mesh.name = "Plane";
        }

        var sideE        = Detail;
        var sideP        = Detail + 1;
        var vertexCount  = sideP * sideP;
        var indexCount   = sideE * sideE * 6;
        var rotation     = Quaternion.Inverse(terrain.transform.rotation) * Quaternion.LookRotation(bestPoint);
        var distance     = bestPoint.magnitude;
        var uniformScale = SgtHelper.UniformScale(terrain.transform.lossyScale);
        var size         = Size * SgtHelper.Reciprocal(uniformScale);
        var step         = (size * 2.0f) / Detail;

        if (positions == null || positions.Length != vertexCount)
        {
            positions = new Vector3[vertexCount];
        }

        for (var y = 0; y <= Detail; y++)
        {
            for (var x = 0; x <= Detail; x++)
            {
                var index = x + y * sideP;
                var point = rotation * new Vector3(x * step - size, y * step - size, distance);

                positions[index] = terrain.GetLocalPoint(point);
            }
        }

        // Regen indices?
        if (indices == null || indices.Length != indexCount)
        {
            indices = new int[indexCount];

            for (var y = 0; y < sideE; y++)
            {
                for (var x = 0; x < sideE; x++)
                {
                    var index  = (x + y * sideE) * 6;
                    var vertex = x + y * sideP;

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

            mesh.Clear();
        }

        mesh.vertices  = positions;
        mesh.triangles = indices;

        meshCollider.sharedMesh = mesh;

        meshCollider.transform.SetParent(terrain.transform, false);
    }
    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;
        }
    }