Esempio n. 1
0
        private void UpdateImagery(ClipmapLevel level, ClipmapLevel coarserLevel, Context context, SceneState sceneState)
        {
            int deltaX = level.NextImageryExtent.West - level.CurrentImageryExtent.West;
            int deltaY = level.NextImageryExtent.South - level.CurrentImageryExtent.South;

            if (deltaX == 0 && deltaY == 0)
            {
                return;
            }

            int minLongitude = deltaX > 0 ? level.CurrentImageryExtent.East + 1 : level.NextImageryExtent.West;
            int maxLongitude = deltaX > 0 ? level.NextImageryExtent.East : level.CurrentImageryExtent.West - 1;
            int minLatitude  = deltaY > 0 ? level.CurrentImageryExtent.North + 1 : level.NextImageryExtent.South;
            int maxLatitude  = deltaY > 0 ? level.NextImageryExtent.North : level.CurrentImageryExtent.South - 1;

            int width  = maxLongitude - minLongitude + 1;
            int height = maxLatitude - minLatitude + 1;

            if (level.CurrentImageryExtent.West > level.CurrentImageryExtent.East || // initial update
                width >= level.ImageryWidth || height >= level.ImageryHeight)        // complete update
            {
                // Initial or complete update.
                width        = level.ImageryWidth;
                height       = level.ImageryHeight;
                deltaX       = level.ImageryWidth;
                deltaY       = level.ImageryHeight;
                minLongitude = level.NextImageryExtent.West;
                maxLongitude = level.NextImageryExtent.East;
                minLatitude  = level.NextImageryExtent.South;
                maxLatitude  = level.NextImageryExtent.North;
            }

            if (height > 0)
            {
                ClipmapUpdate horizontalUpdate = new ClipmapUpdate(
                    level,
                    level.NextImageryExtent.West,
                    minLatitude,
                    level.NextImageryExtent.East,
                    maxLatitude);
                _updater.UpdateImagery(context, horizontalUpdate);
            }

            if (width > 0)
            {
                ClipmapUpdate verticalUpdate = new ClipmapUpdate(
                    level,
                    minLongitude,
                    level.NextImageryExtent.South,
                    maxLongitude,
                    level.NextImageryExtent.North);
                _updater.UpdateImagery(context, verticalUpdate);
            }


            level.CurrentImageryExtent.West  = level.NextImageryExtent.West;
            level.CurrentImageryExtent.South = level.NextImageryExtent.South;
            level.CurrentImageryExtent.East  = level.NextImageryExtent.East;
            level.CurrentImageryExtent.North = level.NextImageryExtent.North;
        }
Esempio n. 2
0
        private void UpdateNormals(Context context, ClipmapUpdate update)
        {
            ClipmapLevel level = update.Level;

            context.TextureUnits[0].Texture        = update.Level.HeightTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.NearestRepeat;

            _framebuffer.ColorAttachments[_normalOutput] = level.NormalTexture;

            int clipmapSize = level.NextExtent.East - level.NextExtent.West + 1;
            int west        = (level.OriginInTextures.X + (update.West - level.NextExtent.West)) % clipmapSize;
            int south       = (level.OriginInTextures.Y + (update.South - level.NextExtent.South)) % clipmapSize;

            _computeNormalsUpdateSize.Value           = new Vector2F(update.Width, update.Height);
            _computeNormalsOrigin.Value               = new Vector2F(west, south);
            _computeNormalsOneOverHeightMapSize.Value = new Vector2F(1.0f / update.Level.HeightTexture.Description.Width, 1.0f / update.Level.HeightTexture.Description.Height);
            _postDelta.Value = (float)update.Level.Terrain.PostDeltaLongitude;

            // Save the current state of the context
            Rectangle   oldViewport    = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport    = new Rectangle(0, 0, level.NormalTexture.Description.Width, level.NormalTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _computeNormalsDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport    = oldViewport;
        }
Esempio n. 3
0
        private void Update(Context context, ClipmapUpdate update, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel)
        {
            ClipmapUpdate[] updates = SplitUpdateToAvoidWrapping(update, details);
            foreach (ClipmapUpdate nonWrappingUpdate in updates)
            {
                RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nonWrappingUpdate.West, nonWrappingUpdate.South, nonWrappingUpdate.East, nonWrappingUpdate.North);
                foreach (RasterTileRegion region in tileRegions)
                {
                    Texture2D tileTexture;
                    bool      loaded = details.LoadedTiles.TryGetValue(region.Tile.Identifier, out tileTexture);
                    if (loaded)
                    {
                        RenderTileToLevelTexture(context, level, details, region, tileTexture);
                    }
                    else
                    {
                        UpsampleTileData(context, level, details, region);
                    }
                }
            }

            if (details.Type == RasterType.Terrain)
            {
                // Normals at edges are incorrect, so include a one-post buffer around the update region
                // when updating normals in order to update normals that were previously at the edge.
                ClipmapUpdate   updateWithBuffer = update.AddBufferWithinLevelNextExtent();
                ClipmapUpdate[] normalUpdates    = SplitUpdateToAvoidWrapping(updateWithBuffer, details);
                foreach (ClipmapUpdate normalUpdate in normalUpdates)
                {
                    UpdateNormals(context, normalUpdate);
                }
            }
        }
Esempio n. 4
0
        private ClipmapUpdate IntersectUpdates(ClipmapUpdate first, ClipmapUpdate second)
        {
            int west  = Math.Max(first.West, second.West);
            int south = Math.Max(first.South, second.South);
            int east  = Math.Min(first.East, second.East);
            int north = Math.Min(first.North, second.North);

            return(new ClipmapUpdate(first.Level, west, south, east, north));
        }
Esempio n. 5
0
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent  = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel         rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }
Esempio n. 6
0
        private void UpdateImagery(ClipmapLevel level, ClipmapLevel coarserLevel, Context context, SceneState sceneState)
        {
            int deltaX = level.NextImageryExtent.West - level.CurrentImageryExtent.West;
            int deltaY = level.NextImageryExtent.South - level.CurrentImageryExtent.South;
            if (deltaX == 0 && deltaY == 0)
                return;

            int minLongitude = deltaX > 0 ? level.CurrentImageryExtent.East + 1 : level.NextImageryExtent.West;
            int maxLongitude = deltaX > 0 ? level.NextImageryExtent.East : level.CurrentImageryExtent.West - 1;
            int minLatitude = deltaY > 0 ? level.CurrentImageryExtent.North + 1 : level.NextImageryExtent.South;
            int maxLatitude = deltaY > 0 ? level.NextImageryExtent.North : level.CurrentImageryExtent.South - 1;

            int width = maxLongitude - minLongitude + 1;
            int height = maxLatitude - minLatitude + 1;

            if (level.CurrentImageryExtent.West > level.CurrentImageryExtent.East || // initial update
                width >= level.ImageryWidth || height >= level.ImageryHeight) // complete update
            {
                // Initial or complete update.
                width = level.ImageryWidth;
                height = level.ImageryHeight;
                deltaX = level.ImageryWidth;
                deltaY = level.ImageryHeight;
                minLongitude = level.NextImageryExtent.West;
                maxLongitude = level.NextImageryExtent.East;
                minLatitude = level.NextImageryExtent.South;
                maxLatitude = level.NextImageryExtent.North;
            }

            if (height > 0)
            {
                ClipmapUpdate horizontalUpdate = new ClipmapUpdate(
                    level,
                    level.NextImageryExtent.West,
                    minLatitude,
                    level.NextImageryExtent.East,
                    maxLatitude);
                _updater.UpdateImagery(context, horizontalUpdate);
            }

            if (width > 0)
            {
                ClipmapUpdate verticalUpdate = new ClipmapUpdate(
                    level,
                    minLongitude,
                    level.NextImageryExtent.South,
                    maxLongitude,
                    level.NextImageryExtent.North);
                _updater.UpdateImagery(context, verticalUpdate);
            }


            level.CurrentImageryExtent.West = level.NextImageryExtent.West;
            level.CurrentImageryExtent.South = level.NextImageryExtent.South;
            level.CurrentImageryExtent.East = level.NextImageryExtent.East;
            level.CurrentImageryExtent.North = level.NextImageryExtent.North;
        }
Esempio n. 7
0
        private ClipmapUpdate[] SplitUpdateToAvoidWrapping(ClipmapUpdate update, RasterDataDetails details)
        {
            ClipmapLevel level  = update.Level;
            Vector2I     origin = details.Type == RasterType.Terrain ? level.OriginInTextures : level.OriginInImagery;

            ClipmapLevel.Extent extent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;

            int clipmapSizeX = extent.East - extent.West + 1;
            int clipmapSizeY = extent.North - extent.South + 1;

            int west  = (origin.X + (update.West - extent.West)) % clipmapSizeX;
            int east  = (origin.X + (update.East - extent.West)) % clipmapSizeX;
            int south = (origin.Y + (update.South - extent.South)) % clipmapSizeY;
            int north = (origin.Y + (update.North - extent.South)) % clipmapSizeY;

            if (east < west && north < south)
            {
                // Horizontal AND vertical wrap
                ClipmapUpdate bottomLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate bottomRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate topRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[4];
                result[0] = bottomLeftUpdate;
                result[1] = bottomRightUpdate;
                result[2] = topLeftUpdate;
                result[3] = topRightUpdate;
                return(result);
            }
            else if (east < west)
            {
                // Horizontal wrap
                ClipmapUpdate leftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate rightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = leftUpdate;
                result[1] = rightUpdate;
                return(result);
            }
            else if (north < south)
            {
                // Vertical wrap
                ClipmapUpdate bottomUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = bottomUpdate;
                result[1] = topUpdate;
                return(result);
            }
            else
            {
                // No wrap
                ClipmapUpdate[] result = new ClipmapUpdate[1];
                result[0] = update;
                return(result);
            }
        }
Esempio n. 8
0
        public void UpdateImagery(Context context, ClipmapUpdate update)
        {
            ClipmapLevel level = update.Level;

            Update(context, update, level, _imagery, level.Imagery);
        }
Esempio n. 9
0
        public void UpdateTerrain(Context context, ClipmapUpdate update)
        {
            ClipmapLevel level = update.Level;

            Update(context, update, level, _terrain, level.Terrain);
        }
Esempio n. 10
0
        private void UpdateNormals(Context context, ClipmapUpdate update)
        {
            ClipmapLevel level = update.Level;

            context.TextureUnits[0].Texture = update.Level.HeightTexture;
            context.TextureUnits[0].TextureSampler = Device.TextureSamplers.NearestRepeat;

            _framebuffer.ColorAttachments[_normalOutput] = level.NormalTexture;

            int clipmapSize = level.NextExtent.East - level.NextExtent.West + 1;
            int west = (level.OriginInTextures.X + (update.West - level.NextExtent.West)) % clipmapSize;
            int south = (level.OriginInTextures.Y + (update.South - level.NextExtent.South)) % clipmapSize;

            _computeNormalsUpdateSize.Value = new Vector2F(update.Width, update.Height);
            _computeNormalsOrigin.Value = new Vector2F(west, south);
            _computeNormalsOneOverHeightMapSize.Value = new Vector2F(1.0f / update.Level.HeightTexture.Description.Width, 1.0f / update.Level.HeightTexture.Description.Height);
            _postDelta.Value = (float)update.Level.Terrain.PostDeltaLongitude;

            // Save the current state of the context
            Rectangle oldViewport = context.Viewport;
            Framebuffer oldFramebuffer = context.Framebuffer;

            // Update the context and draw
            context.Viewport = new Rectangle(0, 0, level.NormalTexture.Description.Width, level.NormalTexture.Description.Height);
            context.Framebuffer = _framebuffer;
            context.Draw(_unitQuadPrimitiveType, _computeNormalsDrawState, _sceneState);

            // Restore the context to its original state
            context.Framebuffer = oldFramebuffer;
            context.Viewport = oldViewport;
        }
Esempio n. 11
0
        private ClipmapUpdate[] SplitUpdateToAvoidWrapping(ClipmapUpdate update, RasterDataDetails details)
        {
            ClipmapLevel level = update.Level;
            Vector2I origin = details.Type == RasterType.Terrain ? level.OriginInTextures : level.OriginInImagery;
            ClipmapLevel.Extent extent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;

            int clipmapSizeX = extent.East - extent.West + 1;
            int clipmapSizeY = extent.North - extent.South + 1;

            int west = (origin.X + (update.West - extent.West)) % clipmapSizeX;
            int east = (origin.X + (update.East - extent.West)) % clipmapSizeX;
            int south = (origin.Y + (update.South - extent.South)) % clipmapSizeY;
            int north = (origin.Y + (update.North - extent.South)) % clipmapSizeY;

            if (east < west && north < south)
            {
                // Horizontal AND vertical wrap
                ClipmapUpdate bottomLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate bottomRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topLeftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate topRightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[4];
                result[0] = bottomLeftUpdate;
                result[1] = bottomRightUpdate;
                result[2] = topLeftUpdate;
                result[3] = topRightUpdate;
                return result;
            }
            else if (east < west)
            {
                // Horizontal wrap
                ClipmapUpdate leftUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    extent.West + (clipmapSizeX - origin.X - 1),
                    update.North);

                ClipmapUpdate rightUpdate = new ClipmapUpdate(
                    level,
                    extent.West + clipmapSizeX - origin.X,
                    update.South,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = leftUpdate;
                result[1] = rightUpdate;
                return result;
            }
            else if (north < south)
            {
                // Vertical wrap
                ClipmapUpdate bottomUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    update.South,
                    update.East,
                    extent.South + (clipmapSizeY - origin.Y - 1));

                ClipmapUpdate topUpdate = new ClipmapUpdate(
                    level,
                    update.West,
                    extent.South + clipmapSizeY - origin.Y,
                    update.East,
                    update.North);

                ClipmapUpdate[] result = new ClipmapUpdate[2];
                result[0] = bottomUpdate;
                result[1] = topUpdate;
                return result;
            }
            else
            {
                // No wrap
                ClipmapUpdate[] result = new ClipmapUpdate[1];
                result[0] = update;
                return result;
            }
        }
Esempio n. 12
0
        private void Update(Context context, ClipmapUpdate update, ClipmapLevel level, RasterDataDetails details, RasterLevel rasterLevel)
        {
            ClipmapUpdate[] updates = SplitUpdateToAvoidWrapping(update, details);
            foreach (ClipmapUpdate nonWrappingUpdate in updates)
            {
                RasterTileRegion[] tileRegions = rasterLevel.GetTilesInExtent(nonWrappingUpdate.West, nonWrappingUpdate.South, nonWrappingUpdate.East, nonWrappingUpdate.North);
                foreach (RasterTileRegion region in tileRegions)
                {
                    Texture2D tileTexture;
                    bool loaded = details.LoadedTiles.TryGetValue(region.Tile.Identifier, out tileTexture);
                    if (loaded)
                    {
                        RenderTileToLevelTexture(context, level, details, region, tileTexture);
                    }
                    else
                    {
                        UpsampleTileData(context, level, details, region);
                    }
                }
            }

            if (details.Type == RasterType.Terrain)
            {
                // Normals at edges are incorrect, so include a one-post buffer around the update region
                // when updating normals in order to update normals that were previously at the edge.
                ClipmapUpdate updateWithBuffer = update.AddBufferWithinLevelNextExtent();
                ClipmapUpdate[] normalUpdates = SplitUpdateToAvoidWrapping(updateWithBuffer, details);
                foreach (ClipmapUpdate normalUpdate in normalUpdates)
                {
                    UpdateNormals(context, normalUpdate);
                }
            }
        }
Esempio n. 13
0
 public void UpdateImagery(Context context, ClipmapUpdate update)
 {
     ClipmapLevel level = update.Level;
     Update(context, update, level, _imagery, level.Imagery);
 }
Esempio n. 14
0
 public void UpdateTerrain(Context context, ClipmapUpdate update)
 {
     ClipmapLevel level = update.Level;
     Update(context, update, level, _terrain, level.Terrain);
 }
Esempio n. 15
0
 private ClipmapUpdate IntersectUpdates(ClipmapUpdate first, ClipmapUpdate second)
 {
     int west = Math.Max(first.West, second.West);
     int south = Math.Max(first.South, second.South);
     int east = Math.Min(first.East, second.East);
     int north = Math.Min(first.North, second.North);
     return new ClipmapUpdate(first.Level, west, south, east, north);
 }
Esempio n. 16
0
        private void ApplyNewTile(Context context, RasterDataDetails details, ClipmapLevel level, RasterTile tile)
        {
            ClipmapLevel.Extent nextExtent = details.Type == RasterType.Terrain ? level.NextExtent : level.NextImageryExtent;
            RasterLevel rasterLevel = details.Type == RasterType.Terrain ? level.Terrain : level.Imagery;

            ClipmapUpdate entireLevel = new ClipmapUpdate(
                level,
                nextExtent.West,
                nextExtent.South,
                nextExtent.East,
                nextExtent.North);

            ClipmapUpdate thisTile = new ClipmapUpdate(
                level,
                tile.West - 1,
                tile.South - 1,
                tile.East + 1,
                tile.North + 1);

            ClipmapUpdate intersection = IntersectUpdates(entireLevel, thisTile);

            if (intersection.Width > 0 && intersection.Height > 0)
            {
                Update(context, intersection, level, details, rasterLevel);

                // Recurse on child tiles if they're NOT loaded.  Unloaded children will use data from this tile.
                ClipmapLevel finer = level.FinerLevel;
                if (finer != null)
                {
                    ApplyIfNotLoaded(context, details, finer, tile.SouthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.SoutheastChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NorthwestChild);
                    ApplyIfNotLoaded(context, details, finer, tile.NortheastChild);
                }
            }
        }