/// <summary>
    /// Updates smart cap
    /// </summary>
    /// <param name="updateShared">Shared mesh of cap should be updated too?</param>
    void UpdateCapSmart(bool updateShared)
    {
        #region Check mesh
        Mesh capMesh;
        if (CapObj.GetComponent <MeshFilter>().sharedMesh == null)
        {
            capMesh      = new Mesh();
            capMesh.name = "Terrain2D_cap_mesh_" + InstanceId;
            CapObj.GetComponent <MeshFilter>().mesh = capMesh;
        }
        else
        {
            if (updateShared)
            {
                capMesh = CapObj.GetComponent <MeshFilter>().sharedMesh;
                capMesh.Clear();
            }
            else
            {
                capMesh = CapObj.GetComponent <MeshFilter>().mesh;
            }
        }
        #endregion

        Vector3[] vertices = GetVertsPos();
        SmartCapAreas = new List <SmartCapArea>();

        #region Create smart cap areas
        SmartCapArea curSmartCapArea  = new SmartCapArea();
        bool         nextSmartCapArea = false;
        int          counterSign      = 1;
        for (int i = 0; i < vertices.Length; i += 2)
        {
            if (i == vertices.Length - 2)
            {
                counterSign = -1;
            }

            if (Mathf.Abs(vertices[i].y - vertices[i + (2 * counterSign)].y) < SmartCapCutHeight)
            {
                if (!nextSmartCapArea)
                {
                    SmartCapAreas.Add(new SmartCapArea());
                    curSmartCapArea  = SmartCapAreas[SmartCapAreas.Count - 1];
                    nextSmartCapArea = true;
                }

                curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f));
                curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f));
            }
            else
            {
                if (nextSmartCapArea)
                {
                    curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f));
                    curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f));
                }
                nextSmartCapArea = false;
            }
        }

        #endregion

        #region Remove too small areas
        for (int i = SmartCapAreas.Count - 1; i >= 0; i--)
        {
            SmartCapAreas[i].MainSegmentsCount = (SmartCapAreas[i].VertsPoints.Count - 2) / 2;
            if (SmartCapAreas[i].MainSegmentsCount < Resolution)
            {
                SmartCapAreas.RemoveAt(i);
            }
        }
        #endregion

        #region Combine all vertices
        List <Vector3> totalCapVertices = new List <Vector3>();
        Vector3[]      sideVertices     = new Vector3[4];
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            curSmartCapArea = SmartCapAreas[i];

            //Add side segments vertices
            sideVertices[0] = curSmartCapArea.VertsPoints[0] - new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[1] = curSmartCapArea.VertsPoints[1] - new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[2] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 1] + new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[3] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 2] + new Vector3(SmartCapSideSegmentsWidth, 0, 0);

            sideVertices[0].y += (sideVertices[0].y - curSmartCapArea.VertsPoints[2].y);
            sideVertices[1].y += (sideVertices[1].y - curSmartCapArea.VertsPoints[3].y);
            sideVertices[2].y += (sideVertices[2].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 3].y);
            sideVertices[3].y += (sideVertices[3].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 4].y);

            curSmartCapArea.VertsPoints.Insert(0, sideVertices[1]);
            curSmartCapArea.VertsPoints.Insert(0, sideVertices[0]);
            curSmartCapArea.VertsPoints.Add(sideVertices[3]);
            curSmartCapArea.VertsPoints.Add(sideVertices[2]);

            for (int j = 0; j < curSmartCapArea.VertsPoints.Count; j += 2)
            {
                totalCapVertices.Add(curSmartCapArea.VertsPoints[j]);
                totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]);

                if (j >= 2 && j <= curSmartCapArea.VertsPoints.Count - 3)
                {
                    totalCapVertices.Add(curSmartCapArea.VertsPoints[j]);
                    totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]);
                }
            }
        }
        #endregion

        #region Generate UV
        Vector2[] uv        = new Vector2[totalCapVertices.Count];
        float     uvPerUnit = (SmartCapSegmentsUv.y - SmartCapSegmentsUv.x) / Resolution;
        int       uvIndex   = 0;
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            curSmartCapArea = SmartCapAreas[i];

            uv[uvIndex]     = new Vector2(0, 1);
            uv[uvIndex + 1] = new Vector2(0, 0);
            uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x, 1);
            uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x, 0);

            uvIndex += 4;

            int unitCounter  = 0;
            int uvTotalVerts = curSmartCapArea.VertsPoints.Count + (curSmartCapArea.VertsPoints.Count - 14);
            for (int j = 0; j < uvTotalVerts; j += 4)
            {
                uv[uvIndex]     = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 1);
                uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 0);
                uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 1);
                uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 0);

                uvIndex += 4;

                unitCounter++;
                if (unitCounter >= Resolution)
                {
                    unitCounter = 0;
                }
            }

            if (uv[uvIndex - 1].x < SmartCapSegmentsUv.y)
            {
                SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 1]);
                SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 2]);
            }

            uv[uvIndex]     = new Vector2(SmartCapSegmentsUv.y, 1);
            uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.y, 0);
            uv[uvIndex + 2] = new Vector2(1, 1);
            uv[uvIndex + 3] = new Vector2(1, 0);

            uvIndex += 4;
        }

        #endregion

        #region Generate triangles

        int unusedVertsCount = 0;
        foreach (var smartCapArea in SmartCapAreas)
        {
            unusedVertsCount += smartCapArea.VertsPoints.Count - 4;
        }

        int[] totalCapTris = new int[((totalCapVertices.Count - unusedVertsCount) - 2) * 3];
        int   curTrisIndex = 0;
        int   vertCounter  = 0;
        bool  toSide       = false;
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            SmartCapArea curArea = SmartCapAreas[i];

            int skipVertCounter = 0;
            for (int j = 2; j < curArea.VertsPoints.Count + (curArea.VertsPoints.Count - 4); j++)
            {
                if (skipVertCounter > 1)
                {
                    vertCounter    += 2;
                    j              += 2;
                    skipVertCounter = 0;
                }

                if (toSide)
                {
                    totalCapTris[curTrisIndex]     = vertCounter;
                    totalCapTris[curTrisIndex + 1] = vertCounter + 1;
                    totalCapTris[curTrisIndex + 2] = vertCounter + 2;
                }
                else
                {
                    totalCapTris[curTrisIndex]     = vertCounter + 2;
                    totalCapTris[curTrisIndex + 1] = vertCounter + 1;
                    totalCapTris[curTrisIndex + 2] = vertCounter;
                }
                toSide = !toSide;

                vertCounter++;
                curTrisIndex += 3;
                skipVertCounter++;
            }

            vertCounter += 2;

            toSide = false;
        }
        #endregion

        capMesh.SetVertices(totalCapVertices);
        capMesh.triangles = totalCapTris;
        capMesh.normals   = GetMeshNormals(totalCapVertices.Count);
        capMesh.uv        = uv;
        capMesh.SetColors(GetMeshColors(CapColor, totalCapVertices.Count).ToList());
        capMesh.RecalculateBounds();
    }
예제 #2
0
    /// <summary>
    /// Updates smart cap
    /// </summary>
    /// <param name="updateShared">Shared mesh of cap should be updated too?</param>
    void UpdateCapSmart(bool updateShared)
    {
        #region Check mesh
        Mesh capMesh;
        if (CapObj.GetComponent<MeshFilter>().sharedMesh == null)
        {
            capMesh = new Mesh();
            capMesh.name = "Terrain2D_cap_mesh_" + InstanceId;
            CapObj.GetComponent<MeshFilter>().mesh = capMesh;
        }
        else
        {
            if (updateShared)
            {
                capMesh = CapObj.GetComponent<MeshFilter>().sharedMesh;
                capMesh.Clear();
            }
            else capMesh = CapObj.GetComponent<MeshFilter>().mesh;

        }
        #endregion

        Vector3[] vertices = GetVertsPos();
        SmartCapAreas = new List<SmartCapArea>();

        #region Create smart cap areas
        SmartCapArea curSmartCapArea = new SmartCapArea();
        bool nextSmartCapArea = false;
        int counterSign = 1;
        for (int i = 0; i < vertices.Length; i += 2)
        {
            if (i == vertices.Length - 2)
                counterSign = -1;

            if (Mathf.Abs(vertices[i].y - vertices[i + (2 * counterSign)].y) < SmartCapCutHeight)
            {
                if (!nextSmartCapArea)
                {
                    SmartCapAreas.Add(new SmartCapArea());
                    curSmartCapArea = SmartCapAreas[SmartCapAreas.Count - 1];
                    nextSmartCapArea = true;
                }

                curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f));
                curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f));
            }
            else
            {
                if (nextSmartCapArea)
                {
                    curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i].x, vertices[i].y + CapOffset, -0.01f));
                    curSmartCapArea.VertsPoints.Add(new Vector3(vertices[i + 1].x, vertices[i].y - CapHeight + CapOffset, -0.01f));
                }
                nextSmartCapArea = false;
            }
        }

        #endregion

        #region Remove too small areas
        for (int i = SmartCapAreas.Count - 1; i >= 0; i--)
        {
            SmartCapAreas[i].MainSegmentsCount = (SmartCapAreas[i].VertsPoints.Count - 2) / 2;
            if (SmartCapAreas[i].MainSegmentsCount < Resolution)
                SmartCapAreas.RemoveAt(i);
        }
        #endregion

        #region Combine all vertices
        List<Vector3> totalCapVertices = new List<Vector3>();
        Vector3[] sideVertices = new Vector3[4];
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            curSmartCapArea = SmartCapAreas[i];

            //Add side segments vertices
            sideVertices[0] = curSmartCapArea.VertsPoints[0] - new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[1] = curSmartCapArea.VertsPoints[1] - new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[2] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 1] + new Vector3(SmartCapSideSegmentsWidth, 0, 0);
            sideVertices[3] = curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 2] + new Vector3(SmartCapSideSegmentsWidth, 0, 0);

            sideVertices[0].y += (sideVertices[0].y - curSmartCapArea.VertsPoints[2].y);
            sideVertices[1].y += (sideVertices[1].y - curSmartCapArea.VertsPoints[3].y);
            sideVertices[2].y += (sideVertices[2].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 3].y);
            sideVertices[3].y += (sideVertices[3].y - curSmartCapArea.VertsPoints[curSmartCapArea.VertsPoints.Count - 4].y);

            curSmartCapArea.VertsPoints.Insert(0, sideVertices[1]);
            curSmartCapArea.VertsPoints.Insert(0, sideVertices[0]);
            curSmartCapArea.VertsPoints.Add(sideVertices[3]);
            curSmartCapArea.VertsPoints.Add(sideVertices[2]);

            for (int j = 0; j < curSmartCapArea.VertsPoints.Count; j += 2)
            {
                totalCapVertices.Add(curSmartCapArea.VertsPoints[j]);
                totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]);

                if (j >= 2 && j <= curSmartCapArea.VertsPoints.Count - 3)
                {
                    totalCapVertices.Add(curSmartCapArea.VertsPoints[j]);
                    totalCapVertices.Add(curSmartCapArea.VertsPoints[j + 1]);
                }

            }
        }
        #endregion

        #region Generate UV
        Vector2[] uv = new Vector2[totalCapVertices.Count];
        float uvPerUnit = (SmartCapSegmentsUv.y - SmartCapSegmentsUv.x) / Resolution;
        int uvIndex = 0;
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            curSmartCapArea = SmartCapAreas[i];

            uv[uvIndex] = new Vector2(0, 1);
            uv[uvIndex + 1] = new Vector2(0, 0);
            uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x, 1);
            uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x, 0);

            uvIndex += 4;

            int unitCounter = 0;
            int uvTotalVerts = curSmartCapArea.VertsPoints.Count + (curSmartCapArea.VertsPoints.Count - 14);
            for (int j = 0; j < uvTotalVerts; j += 4)
            {
                uv[uvIndex] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 1);
                uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * unitCounter), 0);
                uv[uvIndex + 2] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 1);
                uv[uvIndex + 3] = new Vector2(SmartCapSegmentsUv.x + (uvPerUnit * (unitCounter + 1)), 0);

                uvIndex += 4;

                unitCounter++;
                if (unitCounter >= Resolution)
                    unitCounter = 0;
            }

            if (uv[uvIndex - 1].x < SmartCapSegmentsUv.y)
            {
                SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 1]);
                SmartCapAreas[i].CorruptedTilesVertsPoints.Add(totalCapVertices[uvIndex - 2]);
            }

            uv[uvIndex] = new Vector2(SmartCapSegmentsUv.y, 1);
            uv[uvIndex + 1] = new Vector2(SmartCapSegmentsUv.y, 0);
            uv[uvIndex + 2] = new Vector2(1, 1);
            uv[uvIndex + 3] = new Vector2(1, 0);

            uvIndex += 4;
        }

        #endregion

        #region Generate triangles

        int unusedVertsCount = 0;
        foreach (var smartCapArea in SmartCapAreas)
        {
            unusedVertsCount += smartCapArea.VertsPoints.Count - 4;
        }

        int[] totalCapTris = new int[((totalCapVertices.Count - unusedVertsCount) - 2) * 3];
        int curTrisIndex = 0;
        int vertCounter = 0;
        bool toSide = false;
        for (int i = 0; i < SmartCapAreas.Count; i++)
        {
            SmartCapArea curArea = SmartCapAreas[i];

            int skipVertCounter = 0;
            for (int j = 2; j < curArea.VertsPoints.Count + (curArea.VertsPoints.Count - 4); j++)
            {
                if (skipVertCounter > 1)
                {
                    vertCounter += 2;
                    j += 2;
                    skipVertCounter = 0;
                }

                if (toSide)
                {
                    totalCapTris[curTrisIndex] = vertCounter;
                    totalCapTris[curTrisIndex + 1] = vertCounter + 1;
                    totalCapTris[curTrisIndex + 2] = vertCounter + 2;
                }
                else
                {
                    totalCapTris[curTrisIndex] = vertCounter + 2;
                    totalCapTris[curTrisIndex + 1] = vertCounter + 1;
                    totalCapTris[curTrisIndex + 2] = vertCounter;
                }
                toSide = !toSide;

                vertCounter++;
                curTrisIndex += 3;
                skipVertCounter++;
            }

            vertCounter += 2;

            toSide = false;
        }
        #endregion

        capMesh.SetVertices(totalCapVertices);
        capMesh.triangles = totalCapTris;
        capMesh.normals = GetMeshNormals(totalCapVertices.Count);
        capMesh.uv = uv;
        capMesh.SetColors(GetMeshColors(CapColor, totalCapVertices.Count).ToList());
        capMesh.RecalculateBounds();
    }