Ejemplo n.º 1
0
        // Gets a list of globe sphere vertices contained within a latlon bounding box
        public VertexAndUvContainer LatLongBoundingBoxToGlobeVertexListAndUvs(LatLonBoundingBox bbox, int numberOfStackPartitions, int numberOfSlicePartitions)
        {
            // Get the fraction of the range (from 0.0 to 1.0) that this latlon bbox covers for latitude and longitude
            float latitudeStartFraction  = (bbox.minLat + 90.0f) / 180.0f;
            float latitudeEndFraction    = (bbox.maxLat + 90.0f) / 180.0f;
            float longitudeStartFraction = (bbox.minLon + 180.0f) / 360.0f;
            float longitudeEndFraction   = (bbox.maxLon + 180.0f) / 360.0f;

            List <int>     vertexIndicesOfInterest = new List <int>();
            List <Vector2> textureUvsForVertexIndicesOfInterest = new List <Vector2>();

            // Add top/bottom vertices if necessary
            if (latitudeStartFraction == 0.0f)
            {
                // Add top vertex index
                vertexIndicesOfInterest.Add(0);
                // Longitude is arbitrary
                textureUvsForVertexIndicesOfInterest.Add(new Vector2(0.0f, 0.0f));
            }

            if (latitudeEndFraction == 1.0f)
            {
                // Add bottom vertex index
                vertexIndicesOfInterest.Add((numberOfStackPartitions - 1) * numberOfSlicePartitions + 2 - 1);
                // Longitude is arbitrary
                textureUvsForVertexIndicesOfInterest.Add(new Vector2(1.0f, 1.0f));
            }

            // Go from the first latitude stack to the last one covered by this fraction
            for (int latitudeStackIndex = Mathf.CeilToInt(latitudeStartFraction * (numberOfStackPartitions - 2.0f)); latitudeStackIndex <= Mathf.FloorToInt(latitudeEndFraction * (numberOfStackPartitions - 1.0f)); latitudeStackIndex++)
            {
                // Go from the first longitude slice to the last one covered by this fraction
                for (int longitudeSliceIndex = Mathf.CeilToInt(longitudeStartFraction * numberOfSlicePartitions); longitudeSliceIndex <= Mathf.FloorToInt(longitudeEndFraction * numberOfStackPartitions); longitudeSliceIndex++)
                {
                    // Offset of 1 because GeographicGridTessellator adds a single top vertex first...
                    int vertexIndex = 1 + (latitudeStackIndex - 1) * numberOfSlicePartitions + longitudeSliceIndex;

                    float latitudeOfThisVertex  = latitudeStackIndex * (180.0f / (numberOfStackPartitions - 1.0f)) - 90.0f;
                    float longitudeOfThisVertex = longitudeSliceIndex * (360.0f / numberOfSlicePartitions) - 180.0f;

                    // Calculate the lat/long percentages within this box at which the vertex is located
                    float latPercent = (latitudeOfThisVertex - bbox.minLat) / bbox.DeltaLat;
                    float lonPercent = (longitudeOfThisVertex - bbox.minLon) / bbox.DeltaLon;

                    // Double-check that the vertex is included in the tile!
                    if (latPercent >= 0.0f && latPercent <= 1.0f && lonPercent >= 0.0f && lonPercent <= 1.0f && vertexIndex >= 0)
                    {
                        vertexIndicesOfInterest.Add(vertexIndex);
                        textureUvsForVertexIndicesOfInterest.Add(new Vector2(lonPercent, latPercent));
                    }
                }
            }

            VertexAndUvContainer vertexAndUvContainer =
                new VertexAndUvContainer
            {
                vertexIndices = vertexIndicesOfInterest,
                uvs           = textureUvsForVertexIndicesOfInterest
            };

            return(vertexAndUvContainer);
        }
Ejemplo n.º 2
0
        // When a new tile has been downloaded, use its texture and properties to calculate
        // a deformation which is then applied to the mesh attached to this object
        public override IEnumerator DeformBasedOnNewTile(Tile tile, float min, float max)
        {
            // Ensure that Globe has been set up properly before any deformations occur
            if (tessellator == null)
            {
                yield return(null);
            }

            float minValue = min;
            float maxValue = max;

            // Values for colormap translation
            float heightRange        = maxValue - minValue;
            float colorToHeightRStep = heightRange / 255.0f;
            float colorToHeightGStep = colorToHeightRStep / 255.0f;
            float colorToHeightBStep = colorToHeightGStep / 255.0f;

            Mesh mesh = GetComponent <MeshFilter>().mesh;

            Vector3[] vertices  = mesh.vertices;
            int[]     triangles = mesh.triangles;
            Color[]   colors    = mesh.colors;

            // Get a list of vertices to edit
            VertexAndUvContainer vertexAndUvContainer =
                tessellator.LatLongBoundingBoxToGlobeVertexListAndUvs(tile.bBox, StackPartitions, SlicePartitions);
            List <int>     vertexIndicesToEdit = vertexAndUvContainer.vertexIndices;
            List <Vector2> textureUvs          = vertexAndUvContainer.uvs;

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Cycle through points and deform according to the tile

            int vertsToProcessPerFrame  = vertexIndicesToEdit.Count / 10; //numFramesToSpan;
            int vertsProcessedThisFrame = 0;

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            for (int i = 0; i < vertexIndicesToEdit.Count; i++)
            {
                int vertexIndex = vertexIndicesToEdit[i];

                Color pixelColor = tile.scienceDataTexture.GetPixelBilinear(textureUvs[i].x, textureUvs[i].y);

                float value = ColormappedPixelColorToScienceValue(pixelColor, minValue, colorToHeightRStep,
                                                                  colorToHeightGStep, colorToHeightBStep);

                if (value > 0.0f)
                {
                    int contributionsAlreadyMadeToThisVertex = 0;

                    try
                    {
                        contributionsAlreadyMadeToThisVertex = globeVertexContributionCount[vertexIndex];
                    }
                    catch (Exception e)
                    {
                        Debug.LogError("Exception " + e.Message + " Was trying to get element " + vertexIndex + " of " + globeVertexContributionCount.Length + " elements!!");
                    }

                    float percentageThroughRange = (value - minValue) / (maxValue - minValue);
                    float vertexHeight           = minEarthRadius + percentageThroughRange * (maxEarthRadius - minEarthRadius);

                    if (contributionsAlreadyMadeToThisVertex > 0)
                    {
                        // Average with other values
                        float currentVertexHeight = vertices[vertexIndex].magnitude;
                        float averageVertexHeight =
                            (currentVertexHeight * contributionsAlreadyMadeToThisVertex + vertexHeight) /
                            ((float)contributionsAlreadyMadeToThisVertex + 1);
                        vertices[vertexIndex] = vertices[vertexIndex].normalized * averageVertexHeight;
                    }
                    else
                    {
                        vertices[vertexIndex] = vertices[vertexIndex].normalized * vertexHeight;
                    }
                    colors[vertexIndex] = pixelColor;

                    // Adjust alpha
                    colors[vertexIndex].a = colorAlpha;

                    globeVertexContributionCount[vertexIndex] = globeVertexContributionCount[vertexIndex] + 1;

                    if (vertsProcessedThisFrame > vertsToProcessPerFrame)
                    {
                        vertsProcessedThisFrame = 0;
                        yield return(null);
                    }
                }
            }

            // Finally, made a record of this contribution
            mesh.Clear();
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.colors    = colors;

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