Ejemplo n.º 1
0
            /// <summary>
            /// Get the terrain elevation map corresponding to the specified position.
            /// </summary>
            /// <param name="viewPosition">
            /// The <see cref="Vertex2d"/> that specify the current view position, using an absolute cartesian reference system.
            /// </param>
            /// <returns>
            /// It returns the <see cref="Image"/> that contains the terrain elevation data corresponding to <paramref name="viewPosition"/>.
            /// </returns>
            public Image GetTerrainElevationMap(Vertex2d viewPosition)
            {
                // Apply clipmap offset
                double   lodUnitScale          = Math.Pow(2.0, Lod) * UnitScale;
                Vertex2d texturePositionOffset = viewPosition - _CurrentViewPosition;

                texturePositionOffset /= lodUnitScale;

                // Determine whether an texture update is not required
                bool xNormOffset = texturePositionOffset.x > -1.0 && texturePositionOffset.x < 1.0;
                bool yNormOffset = texturePositionOffset.y > -1.0 && texturePositionOffset.y < 1.0;

                if (xNormOffset && yNormOffset && _TerrainElevationInitialized)
                {
                    return(null);
                }

                // Discard fractional part, move towards zero
                texturePositionOffset = new Vertex2d(Math.Truncate(texturePositionOffset.x), Math.Truncate(texturePositionOffset.y));

                // Determine the dataset section to load
                Vertex2d rasterPosition = _CurrentTexPosition + (texturePositionOffset * Math.Pow(2.0, Lod));

                double w2 = _TerrainElevation.Width / 2, h2 = _TerrainElevation.Height / 2;

                // Specify the LOD 0 size
                // Note: the dataset should have overviews, in order to make CPU friendly update
                w2 *= Math.Pow(2.0, Lod);
                h2 *= Math.Pow(2.0, Lod);

                double x1 = rasterPosition.x - w2, x2 = rasterPosition.x + w2;
                double y1 = rasterPosition.y - h2, y2 = rasterPosition.y + h2;

                Rectangle datasetSection = new Rectangle();

                datasetSection.X     = (int)Math.Floor(x1);
                datasetSection.Y     = (int)Math.Floor(y1);
                datasetSection.Width = (int)Math.Floor(x2 - x1);
                Debug.Assert(datasetSection.Width % _TerrainElevation.Width == 0);
                datasetSection.Height = (int)Math.Floor(y2 - y1);
                Debug.Assert(datasetSection.Height % _TerrainElevation.Height == 0);

                // Update current terrain elevation, following the updated position
                ImageCodecCriteria datasetCriteria = new ImageCodecCriteria();

                datasetCriteria.ImageSection = datasetSection;

                GdalImageCodecPlugin.Load_GrayIndex(_DatabaseDataset, 1, datasetCriteria, _TerrainElevation);

                // Update current positions
                _CurrentTexPosition  = rasterPosition;
                _CurrentViewPosition = _CurrentViewPosition + (texturePositionOffset * lodUnitScale);;

                // Trace.TraceInformation("Texture LOD {0} reposition: {1}", Lod, _CurrentTexPosition);

                // Allow first time initialization
                _TerrainElevationInitialized = true;

                return(_TerrainElevation);
            }
Ejemplo n.º 2
0
 /// <summary>
 /// Static constructor.
 /// </summary>
 static Terrain()
 {
     GdalImageCodecPlugin.AllRegister();
 }