protected override Vector2 GetCoordFromHit(RaycastHit hit)
        {
            GlobeTerrainModel terrainModel = GetActiveTerrainModel();

            if (!terrainModel)
            {
                throw new Exception("Globe model is not currently active.");
            }
            return(BoundingBoxUtils.UVToCoordinates(UnrestrictedBoundingBox.Global, hit.textureCoord));
        }
        protected override Vector2 GetCoordFromHit(RaycastHit hit)
        {
            LocalTerrainModel terrainModel = GetActiveTerrainModel();

            if (!terrainModel)
            {
                throw new Exception("Active localized terrain model not found.");
            }
            return(BoundingBoxUtils.UVToCoordinates(terrainModel.SquareBoundingBox, hit.textureCoord));
        }
Beispiel #3
0
        public void UpdateArea(IBoundingBox bbox)
        {
            IBoundingBox currentBoundingBox = Controller.CurrentBoundingBox;

            if (currentBoundingBox == BoundingBox.Zero)
            {
                return;
            }
            UVBounds uvBounds = BoundingBoxUtils.CalculateUVBounds(currentBoundingBox, bbox);

            UpdateArea(uvBounds);
        }
        public void CreateLocalTerrainFromBookmark(string bookmarkJson)
        {
            Bookmark               bookmark            = JsonConvert.DeserializeObject <Bookmark>(bookmarkJson, JsonConfig.SerializerSettings);
            BoundingBox            bbox                = BoundingBoxUtils.ParseBoundingBox(bookmark.BoundingBox);
            TerrainProductMetadata baseProductMetadata = new TerrainProductMetadata(bookmark.TexturesUUID[0], bbox, 0);
            // TODO Add additional product layers if present.

            TerrainModelManager terrainModelManager = TerrainModelManager.Instance;
            LocalTerrainModel   terrainModel        = terrainModelManager.CreateLocalModelFromBookmark(bbox, bookmark.DemUUID, bookmark.TexturesUUID);

            terrainModelManager.ShowTerrainModel(terrainModel);
        }
        public void NavigateToCoordinate(string bbox)
        {
            TerrainModelManager        terrainModelManager = TerrainModelManager.Instance;
            XRInteractableGlobeTerrain globe = (XRInteractableGlobeTerrain)terrainModelManager.GlobeModel.InteractionController;

            if (globe)
            {
                BoundingBox boundingBox = BoundingBoxUtils.ParseBoundingBox(bbox);
                Vector2     latLon      = BoundingBoxUtils.MedianLatLon(boundingBox);
                Camera      eye         = UserInterfaceManager.Instance.XRCamera;
                globe.NavigateTo(latLon, eye.transform.position);
            }
        }
        public void HighlightBoundingBoxOnGlobe(string bbox)
        {
            TerrainModelManager terrainModelManager = TerrainModelManager.Instance;

            if (string.IsNullOrEmpty(bbox))
            {
                terrainModelManager.ClearHighlightedAreaOnGlobe();
            }
            else
            {
                BoundingBox boundingBox = BoundingBoxUtils.ParseBoundingBox(bbox);
                terrainModelManager.HighlightAreaOnGlobe(boundingBox);
            }
        }
Beispiel #7
0
        private void ControllerModalAddPoint(Vector2 uv)
        {
            ControllerModal controllerModal = GetControllerModal();

            if (!controllerModal)
            {
                return;
            }

            Vector2 latLon = BoundingBoxUtils.UVToCoordinates(GetBoundingBoxFromTerrainModel(), uv);

            string js =
                $"let component = {AngularComponentContainerPath}.{GetControllerModalName()};" +
                $"component && component.addPoint({latLon.x}, {latLon.y});";

            controllerModal.Browser.EvalJS(js);
            _framesSinceLastControllerModalUpdate = 0;
        }
Beispiel #8
0
        protected override TerrainMeshData GenerateForLod(IntensityImage image, int downsample)
        {
            // Downsampling rate must be a power of 2.
            if (!MathUtils.IsPowerOfTwo(downsample))
            {
                throw new Exception($"Downsample rate of {downsample} is not a power of 2.");
            }

            // Calculate image bounds based on UV bounds.
            int imageStartX = Mathf.RoundToInt(_uvBounds.U1 * image.Width / downsample);
            int imageEndX   = Mathf.RoundToInt(_uvBounds.U2 * (image.Width / downsample - 1));
            int imageStartY = Mathf.RoundToInt(_uvBounds.V1 * image.Height / downsample);
            int imageEndY   = Mathf.RoundToInt(_uvBounds.V2 * (image.Height / downsample - 1));

            // Each pixel in the selected area of the downsampled image represents a vertex.
            int lonVertCount = imageEndX - imageStartX + 1;
            int latVertCount = imageEndY - imageStartY + 1;

            float latIncrement = _boundingBox.LatSwing / (latVertCount - 1);
            float lonIncrement = _boundingBox.LonSwing / (lonVertCount - 1);

            Vector3[] verts     = new Vector3[latVertCount * lonVertCount];
            Vector2[] uvs       = new Vector2[latVertCount * lonVertCount];
            Vector3[] edgeVerts = new Vector3[4 * (latVertCount + lonVertCount - 2) + 2];

            Vector2 latLongOffset = BoundingBoxUtils.MedianLatLon(_boundingBox);

            Vector3 min = new Vector3(float.PositiveInfinity, 0, 0);

            int yIndex = 0, vertexIndex = 0;

            for (float vy = _boundingBox.LatStart; yIndex < latVertCount; vy += latIncrement)
            {
                // The y-coordinate on the image that corresponds to the current row of vertices.
                // Note this is actually inverted since we are traversing from bottom up.
                int y = (latVertCount - yIndex - 1 + imageStartY) * downsample;

                // Create a new vertex using the latitude angle. The coordinates of this vertex
                // will serve as a base for all the other vertices of the same latitude.
                Vector3 baseLatVertex = GenerateBaseLatitudeVertex(vy);

                int xIndex = 0;
                for (float vx = _boundingBox.LonStart; xIndex < lonVertCount; vx += lonIncrement)
                {
                    // The x-coordinate on the image that corresponds to the current vertex.
                    int x = (xIndex + imageStartX) * downsample;

                    // Get the raw intensity value from the image.
                    float value = downsample == 1 ?
                                  image.GetPixel(x, y) :
                                  image.GetCenteredAverage(x, y, downsample + 1);

                    // Scale the intensity value by the height scale, and
                    // then add it to the radius to get the final "height".
                    float height = value * _metadata.HeightScale + _metadata.Radius;

                    Vector3 vertex = GenerateVertex(height * baseLatVertex, vx, latLongOffset, _metadata.Radius);

                    // Keep track of minimum; this will be used later to position the terrain on the table-top.
                    if (vertex.x < min.x)
                    {
                        min = vertex;
                    }

                    // Add to edge vertices
                    if (yIndex == 0)
                    {
                        edgeVerts[xIndex] = vertex;
                    }
                    else if (xIndex == lonVertCount - 1)
                    {
                        edgeVerts[lonVertCount + yIndex - 1] = vertex;
                    }
                    else if (yIndex == latVertCount - 1)
                    {
                        edgeVerts[2 * (lonVertCount - 1) + latVertCount - xIndex - 1] = vertex;
                    }
                    else if (xIndex == 0)
                    {
                        edgeVerts[2 * (lonVertCount + latVertCount - 2) - yIndex] = vertex;
                    }

                    verts[vertexIndex] = vertex;
                    uvs[vertexIndex]   = GenerateUVCoord(xIndex, yIndex, lonVertCount, latVertCount, _uvBounds);

                    xIndex++;
                    vertexIndex++;
                }

                yIndex++;
            }

            // Finish generating the data for the terrain edge.
            ProcessEdgeVertices(edgeVerts, min.x);

            return(new TerrainMeshData()
            {
                Vertices = verts,
                TexCoords = uvs,
                Triangles = GenerateTriangles(lonVertCount, latVertCount),
                ExtraVertices = edgeVerts,
                ExtraTriangles = GenerateTriangles(edgeVerts.Length / 2, 2, true),
                MinimumVertex = min
            });
        }
        private Vector2 GetCoordinatesFromHit(RaycastHit hit)
        {
            BoundingBox bbox = _terrainModel.SquareBoundingBox;

            return(BoundingBoxUtils.UVToCoordinates(bbox, hit.textureCoord));
        }
        protected override void Generate()
        {
            float latIncrement = _boundingBox.LatSwing / (LatLongVertCount - 1);
            float lonIncrement = _boundingBox.LonSwing / (LatLongVertCount - 1);

            Vector3[] verts     = new Vector3[LatLongVertCount * LatLongVertCount];
            Vector2[] uvs       = new Vector2[LatLongVertCount * LatLongVertCount];
            Vector3[] edgeVerts = new Vector3[8 * (LatLongVertCount - 1) + 2];

            Vector2 latLongOffset = BoundingBoxUtils.MedianLatLon(_boundingBox);

            Vector3 min = new Vector3(float.PositiveInfinity, 0, 0);

            int yIndex = 0, vertIndex = 0;

            for (float vy = _boundingBox.LatStart; yIndex < LatLongVertCount; vy += latIncrement)
            {
                // Create a new vertex using the latitude angle. The coordinates of this vertex
                // will serve as a base for all the other vertices of the same latitude.
                Vector3 baseLatVertex = _metadata.Radius * GenerateBaseLatitudeVertex(vy);

                int xIndex = 0;
                for (float vx = _boundingBox.LonStart; xIndex < LatLongVertCount; vx += lonIncrement)
                {
                    Vector3 vertex = GenerateVertex(baseLatVertex, vx, latLongOffset, _metadata.Radius);

                    // Keep track of minimum; this will be used later to position the terrain on the table-top.
                    if (vertex.x < min.x)
                    {
                        min = vertex;
                    }

                    // Add to edge vertices
                    if (yIndex == 0)
                    {
                        edgeVerts[xIndex] = vertex;
                    }
                    else if (xIndex == LatLongVertCount - 1)
                    {
                        edgeVerts[LatLongVertCount + yIndex - 1] = vertex;
                    }
                    else if (yIndex == LatLongVertCount - 1)
                    {
                        edgeVerts[3 * (LatLongVertCount - 1) - xIndex] = vertex;
                    }
                    else if (xIndex == 0)
                    {
                        edgeVerts[4 * (LatLongVertCount - 1) - yIndex] = vertex;
                    }

                    verts[vertIndex] = vertex;
                    uvs[vertIndex]   = GenerateUVCoord(xIndex, yIndex, LatLongVertCount, LatLongVertCount, _uvBounds);

                    xIndex++;
                    vertIndex++;
                }

                yIndex++;
            }

            // Finish generating the data for the terrain edge.
            ProcessEdgeVertices(edgeVerts, min.x);

            _progress = 1f;

            // Only one LOD is generated.
            _meshData = new TerrainMeshData[] {
                new TerrainMeshData()
                {
                    Vertices       = verts,
                    TexCoords      = uvs,
                    Triangles      = GenerateTriangles(LatLongVertCount, LatLongVertCount),
                    ExtraVertices  = edgeVerts,
                    ExtraTriangles = GenerateTriangles(edgeVerts.Length / 2, 2, true),
                    MinimumVertex  = min
                }
            };
        }