Exemplo n.º 1
0
        public PositionData FindPositionData(int triangleIndex)
        {
            int tIndex = LandingQuad.StartTri(triangleIndex);

            if (positionGrid.ContainsKey(tIndex))
            {
                Debug.Assert(positionGrid[tIndex].landingQuad.startTriangleIndex == tIndex);

                return(positionGrid[tIndex]);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 2
0
        // Create the mesh and position data. Does not
        // rely on Platform prefab. This is what is now
        // being used in the reworked code. Energy will
        // be stored in active actors rather than the
        // platforms. Actors will be tracked by a table
        // storing all viable positions (level quads)
        public void CreateLandscapeMesh()
        {
            positionGrid.Clear();

            timer = Time.realtimeSinceStartup;
            Debug.Log("Starting timer in CreateLandscapeMesh");

            GetComponent <MeshFilter>().mesh = mesh = new Mesh();
            mesh.name = "Landscape";

            vertices = new Vector3[(xSize + 1) * (zSize + 1)];
            Vector2[] uv       = new Vector2[vertices.Length];
            Vector4[] tangents = new Vector4[vertices.Length];
            Vector4   tangent  = new Vector4(1f, 0f, 0f, -1f);

            colorArray  = new Color32[vertices.Length];
            colorBuffer = new Color32[vertices.Length];

            // Landing positions are on each alternate quad in x & z
            xPanels = (int)(xSize / 2.0f);
            zPanels = (int)(zSize / 2.0f);
            quads   = new LandingQuad[xPanels * zPanels];

            int vertexIndex = 0;
            int panelIndex  = 0;

            xStride = xSize + 1;

            float midZ        = (zSize + 1f) / 2f;
            float midX        = (xSize + 1f) / 2f;
            float maxDistance = Vector2.Distance(Vector2.zero, new Vector2(xSize + 1, zSize + 1));

            for (int z = 0; z <= zSize; z++)
            {
                float curZ = z - midZ;

                for (int x = 0; x <= xSize; x++)
                {
                    float curX = x - midX;
                    float distanceFromCentreCoeff = Vector2.Distance(Vector2.zero, new Vector2(curX, curZ)) / maxDistance;
                    float coeff = distanceCurve.Evaluate(distanceFromCentreCoeff);

                    float scaledX = curX * coeff;
                    float scaledZ = curZ * coeff;

                    vertices[vertexIndex] = new Vector3(scaledX, 0, scaledZ);
                    uv[vertexIndex]       = new Vector2((float)x / xSize, (float)z / zSize);
                    tangents[vertexIndex] = tangent;

                    if (x > 0 && z > 0 && x % 2 == 0 && z % 2 == 0)
                    {
                        Debug.Assert(vertexIndex == xStride * z + x);

                        int firstVertexIndex = xStride * (z - 1) + x - 1;

                        var lq = new LandingQuad
                        {
                            ixBottomLeft  = firstVertexIndex,
                            ixTopLeft     = firstVertexIndex + xStride,
                            ixTopRight    = vertexIndex,
                            ixBottomRight = firstVertexIndex + 1,
                            // Need to work out the triangle index that corresponds
                            // with the index returned from a raycast. Raycast index
                            // returned is virtual triangle. This needs to be
                            // converted to an index that can query the tri array
                            // by multiplying the index by 3
                            startTriangleIndex = (z - 1) * (xStride - 1) * 2 + x * 2 - 2
                        };

                        quads[panelIndex] = lq;

                        panelIndex++;
                    }
                    vertexIndex++;
                }
            }

            Debug.Log("Elapsed after adding vertices: " + (Time.realtimeSinceStartup - timer));
            timer = Time.realtimeSinceStartup;

            // Make quads out of tri pairs starting bottom left
            int[] triangles = new int[xSize * zSize * 6];
            for (int ti = 0, vi = 0, z = 0; z < zSize; z++, vi++)
            {
                for (int x = 0; x < xSize; x++, ti += 6, vi++)
                {
                    triangles[ti]     = vi;
                    triangles[ti + 3] = triangles[ti + 2] = vi + 1;
                    triangles[ti + 4] = triangles[ti + 1] = vi + xSize + 1;
                    triangles[ti + 5] = vi + xSize + 2;
                }
            }

            Debug.Log("Elapsed after adding triangles: " + (Time.realtimeSinceStartup - timer));
            timer = Time.realtimeSinceStartup;

            float highestPoint = 0.0f, lowestPoint = landscapeHeight;
            float yRange = landscapeHeight * .25f;

            // The virtual quads cover all vertices except zero, as there's
            // no adjacent vertex to take colour from, Same with last vertex
            // if it's an odd size, so add edge colour manually.
            Color edgeCol = useGradient ? gradient.Evaluate(0f) : defaultColor;

            colorArray[0] = edgeCol;
            if (xPanels % 2 != 0)
            {
                colorArray[colorArray.Length - 1] = edgeCol;
            }

            for (int z = 0; z < zPanels; z++)
            {
                for (int x = 0; x < xPanels; x++)
                {
                    float zEdgeProximity = 1f - NormalizedDistanceFromMid(z, zPanels - 1f);
                    float xEdgeProximity = 1f - NormalizedDistanceFromMid(x, xPanels - 1f);

                    float closest  = Mathf.Min(zEdgeProximity, xEdgeProximity);
                    float topRange = landscapeHeight * closest; //approaches 1 toward middle
                    float botRange = topRange - yRange;         // the range of randomness
                    if (z == 0 || x == 0)
                    {
                        botRange = 0f;
                        topRange = botRange + landscapeHeight * 0.01f;
                    }
                    var y = Mathf.Max(0f, UnityEngine.Random.Range(botRange, topRange));

                    var pIndex = z * xPanels + x;

                    var quad = quads[pIndex];
                    vertices[quad.ixBottomLeft].y  = y;
                    vertices[quad.ixTopLeft].y     = y;
                    vertices[quad.ixTopRight].y    = y;
                    vertices[quad.ixBottomRight].y = y;

                    Color col = useGradient ? gradient.Evaluate(closest) : defaultColor;

                    colorArray[quad.ixBottomLeft]  = col;
                    colorArray[quad.ixTopLeft]     = col;
                    colorArray[quad.ixTopRight]    = col;
                    colorArray[quad.ixBottomRight] = col;

                    positionGrid[quad.startTriangleIndex] = new PositionData
                    {
                        centrePos   = Vector3.Lerp(vertices[quad.ixTopLeft], vertices[quad.ixBottomRight], .5f),
                        landingQuad = quad
                    };

                    if (y > highestPoint)
                    {
                        highestPoint           = y;
                        highestPointPanelIndex = quad.startTriangleIndex;
                    }
                    if (y < lowestPoint)
                    {
                        lowestPoint           = y;
                        lowestPointPanelIndex = quad.startTriangleIndex;
                    }
                }
            }

            Debug.Log("Elapsed after calculating landing quads: " + (Time.realtimeSinceStartup - timer));
            timer = Time.realtimeSinceStartup;

            Debug.LogFormat("Highest index: {0} at {1}, Lowest index: {2} at {3}",
                            highestPointPanelIndex, highestPoint, lowestPointPanelIndex, lowestPoint);

            Array.Copy(colorArray, colorBuffer, vertices.Length);

            //mesh.uv = uv; // Leave out if we're doing vertex colours

            mesh.vertices  = vertices;
            mesh.tangents  = tangents;
            mesh.triangles = triangles;
            mesh.colors32  = colorBuffer;

            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            Debug.Log("Elapsed after adding landscape mesh: " + (Time.realtimeSinceStartup - timer));
            timer = Time.realtimeSinceStartup;

            var renderer = GetComponent <MeshRenderer>();

            if (renderer)
            {
                renderer.enabled = true;
            }
            var collider = GetComponent <MeshCollider>();

            if (collider)
            {
                collider.sharedMesh = mesh;
            }

            positionIndices = new int[positionGrid.Count];
            int pix = 0;

            foreach (var kv in positionGrid)
            {
                positionIndices[pix++] = kv.Key;
            }

            ready = true;
        }