public void EnumerateIntersectingObjects(BoundingBox Box, HashSet <GameComponent> Into, Func <GameComponent, bool> Filter = null)
        {
            var minChunkID = GlobalVoxelCoordinate.FromVector3(Box.Min).GetGlobalChunkCoordinate();
            var maxChunkID = GlobalVoxelCoordinate.FromVector3(Box.Max).GetGlobalChunkCoordinate();

            for (var x = minChunkID.X; x <= maxChunkID.X; ++x)
            {
                for (var y = minChunkID.Y; y <= maxChunkID.Y; ++y)
                {
                    for (var z = minChunkID.Z; z <= maxChunkID.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkManager.CheckBounds(coord))
                        {
                            var chunk = ChunkManager.GetChunk(coord);
                            lock (chunk)
                            {
                                foreach (var entity in chunk.Entities)
                                {
                                    if (Box.Contains(entity.BoundingBox) != ContainmentType.Disjoint)
                                    {
                                        if (Filter == null || Filter(entity))
                                        {
                                            Into.Add(entity);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
        public void EnumerateIntersectingObjectsLoose(BoundingBox Box, HashSet <GameComponent> Into, Func <GameComponent, bool> Filter = null)
        {
            PerformanceMonitor.PushFrame("CollisionManager.EnumerateIntersectingObjects w/ Filter");
            var minChunkID = GlobalVoxelCoordinate.FromVector3(Box.Min).GetGlobalChunkCoordinate();
            var maxChunkID = GlobalVoxelCoordinate.FromVector3(Box.Max).GetGlobalChunkCoordinate();

            for (var x = minChunkID.X; x <= maxChunkID.X; ++x)
            {
                for (var y = minChunkID.Y; y <= maxChunkID.Y; ++y)
                {
                    for (var z = minChunkID.Z; z <= maxChunkID.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkManager.CheckBounds(coord))
                        {
                            var chunk = ChunkManager.GetChunk(coord);
                            lock (chunk)
                            {
                                foreach (var entity in chunk.Components)
                                {
                                    if (Filter == null || Filter(entity))
                                    {
                                        Into.Add(entity);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            PerformanceMonitor.PopFrame();
        }
Beispiel #3
0
        public void EnumerateIntersectingRootEntitiesLoose(BoundingBox Box, HashSet <GameComponent> Into)
        {
            var minChunkID = GlobalVoxelCoordinate.FromVector3(Box.Min).GetGlobalChunkCoordinate();
            var maxChunkID = GlobalVoxelCoordinate.FromVector3(Box.Max).GetGlobalChunkCoordinate();

            for (var x = minChunkID.X; x <= maxChunkID.X; ++x)
            {
                for (var y = minChunkID.Y; y <= maxChunkID.Y; ++y)
                {
                    for (var z = minChunkID.Z; z <= maxChunkID.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkManager.CheckBounds(coord))
                        {
                            var chunk = ChunkManager.GetChunk(coord);
                            lock (chunk)
                            {
                                foreach (var entity in chunk.RootEntities)
                                {
                                    Into.Add(entity);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #4
0
        private void GetChunksIntersecting(BoundingFrustum Frustum, HashSet <VoxelChunk> chunks)
        {
            chunks.Clear();
            var frustumBox = MathFunctions.GetBoundingBox(Frustum.GetCorners());
            var minChunk   = ChunkData.ConfineToBounds(GlobalVoxelCoordinate.FromVector3(frustumBox.Min).GetGlobalChunkCoordinate());
            var maxChunk   = ChunkData.ConfineToBounds(GlobalVoxelCoordinate.FromVector3(frustumBox.Max).GetGlobalChunkCoordinate());


            for (var x = minChunk.X; x <= maxChunk.X; ++x)
            {
                for (var y = minChunk.Y; y <= maxChunk.Y; ++y)
                {
                    for (var z = minChunk.Z; z <= maxChunk.Z; ++z)
                    {
                        var chunkCoord = new GlobalChunkCoordinate(x, y, z);
                        var min        = new GlobalVoxelCoordinate(chunkCoord, new LocalVoxelCoordinate(0, 0, 0));
                        var box        = new BoundingBox(min.ToVector3(), min.ToVector3() + new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeZ));
                        if (Frustum.Contains(box) != ContainmentType.Disjoint)
                        {
                            chunks.Add(ChunkData.GetChunk(chunkCoord));
                        }
                    }
                }
            }
        }
 public VoxelChunk GetChunk(GlobalChunkCoordinate Coordinate)
 {
     if (!CheckBounds(Coordinate))
     {
         throw new IndexOutOfRangeException();
     }
     return(ChunkMap[GetChunkIndex(Coordinate)]);
 }
        public GlobalChunkCoordinate ConfineToBounds(GlobalChunkCoordinate Coordinate)
        {
            var x = (Coordinate.X < MapOrigin.X) ? MapOrigin.X : (Coordinate.X >= (MapOrigin.X + MapDimensions.X) ? (MapOrigin.X + MapDimensions.X - 1) : Coordinate.X);
            var y = (Coordinate.Y < MapOrigin.Y) ? MapOrigin.Y : (Coordinate.Y >= (MapOrigin.Y + MapDimensions.Y) ? (MapOrigin.Y + MapDimensions.Y - 1) : Coordinate.Y);
            var z = (Coordinate.Z < MapOrigin.Z) ? MapOrigin.Z : (Coordinate.Z >= (MapOrigin.Z + MapDimensions.Z) ? (MapOrigin.Z + MapDimensions.Z - 1) : Coordinate.Z);

            return(new GlobalChunkCoordinate(x, y, z));
        }
Beispiel #7
0
 public ExploredListener(ComponentManager manager, ChunkManager chunkManager, VoxelHandle vref) :
     base("ExploredListener", manager)
 {
     Chunk   = vref.Chunk;
     VoxelID = vref.Coordinate.GetLocalVoxelCoordinate();
     Chunk.OnVoxelExplored += ExploredListener_OnVoxelExplored;
     ChunkID = Chunk.ID;
 }
Beispiel #8
0
 public VoxelChunk GetChunk(GlobalChunkCoordinate Coordinate)
 {
     if (!CheckBounds(Coordinate))
     {
         throw new IndexOutOfRangeException();
     }
     return(ChunkMap[(Coordinate.Z - ChunkMapMinZ) * ChunkMapWidth + (Coordinate.X - ChunkMapMinX)]);
 }
Beispiel #9
0
 public void CopyFrom(ChunkFile chunkFile)
 {
     ID          = chunkFile.ID;
     Liquid      = chunkFile.Liquid;
     LiquidTypes = chunkFile.LiquidTypes;
     Origin      = chunkFile.Origin;
     Types       = chunkFile.Types;
     Explored    = chunkFile.Explored;
 }
Beispiel #10
0
        public GlobalChunkCoordinate ConfineToBounds(GlobalChunkCoordinate Coordinate)
        {
            var x = (Coordinate.X < ChunkMapMinX) ? ChunkMapMinX :
                    (Coordinate.X >= (ChunkMapMinX + ChunkMapWidth) ? (ChunkMapMinX + ChunkMapWidth - 1) : Coordinate.X);
            var z = (Coordinate.Z < ChunkMapMinZ) ? ChunkMapMinZ :
                    (Coordinate.Z >= (ChunkMapMinZ + ChunkMapHeight) ? (ChunkMapMinZ + ChunkMapHeight - 1) : Coordinate.Z);

            return(new GlobalChunkCoordinate(x, 0, z));
        }
Beispiel #11
0
 public ChunkFile(VoxelChunk chunk)
 {
     ID          = chunk.ID;
     Types       = new byte[VoxelConstants.ChunkVoxelCount];
     LiquidTypes = new byte[VoxelConstants.ChunkVoxelCount];
     Liquid      = new byte[VoxelConstants.ChunkVoxelCount];
     Explored    = new bool[VoxelConstants.ChunkVoxelCount];
     Origin      = chunk.Origin;
     FillDataFromChunk(chunk);
 }
Beispiel #12
0
 public void CopyFrom(ChunkFile chunkFile)
 {
     ID                    = chunkFile.ID;
     Liquid                = chunkFile.Liquid;
     Origin                = chunkFile.Origin;
     Types                 = chunkFile.Types;
     GrassType             = chunkFile.GrassType;
     Decals                = chunkFile.Decals;
     RampsSunlightExplored = chunkFile.RampsSunlightExplored;
 }
Beispiel #13
0
 public ChunkFile(VoxelChunk chunk)
 {
     ID                    = chunk.ID;
     Types                 = new byte[VoxelConstants.ChunkVoxelCount];
     Liquid                = new byte[VoxelConstants.ChunkVoxelCount];
     GrassType             = new byte[VoxelConstants.ChunkVoxelCount];
     Decals                = new byte[VoxelConstants.ChunkVoxelCount];
     RampsSunlightExplored = new byte[VoxelConstants.ChunkVoxelCount];
     Origin                = chunk.Origin;
     FillDataFromChunk(chunk);
 }
Beispiel #14
0
        public void EnqueueInvalidColumn(int X, int Z)
        {
            var columnCoordinate = new GlobalChunkCoordinate(X, 0, Z);

            InvalidColumnLock.WaitOne();
            if (!InvalidColumns.Contains(columnCoordinate))
            {
                InvalidColumns.Enqueue(columnCoordinate);
            }
            InvalidColumnLock.ReleaseMutex();
        }
Beispiel #15
0
 public void CopyFrom(ChunkFile chunkFile)
 {
     ID          = chunkFile.ID;
     Liquid      = chunkFile.Liquid;
     LiquidTypes = chunkFile.LiquidTypes;
     Origin      = chunkFile.Origin;
     Types       = chunkFile.Types;
     Explored    = chunkFile.Explored;
     GrassType   = chunkFile.GrassType;
     GrassDecay  = chunkFile.GrassDecay;
     Decals      = chunkFile.Decals;
 }
Beispiel #16
0
        public VoxelChunk(ChunkManager manager, GlobalChunkCoordinate id)
        {
            ID      = id;
            Origin  = new GlobalVoxelCoordinate(id, new LocalVoxelCoordinate(0, 0, 0));
            Data    = VoxelData.Allocate();
            Manager = manager;

            PrimitiveMutex = new Mutex();
            DynamicLights  = new List <DynamicLight>();

            Liquids = new Dictionary <LiquidType, LiquidPrimitive>();
            Liquids[LiquidType.Water] = new LiquidPrimitive(LiquidType.Water);
            Liquids[LiquidType.Lava]  = new LiquidPrimitive(LiquidType.Lava);
        }
Beispiel #17
0
        public void GenerateInitialChunks(GlobalChunkCoordinate origin, Action <String> SetLoadingMessage)
        {
            // todo: Since the world isn't infinite we can get rid of this.
            float origBuildRadius = GenerateDistance;

            GenerateDistance = origBuildRadius * 2.0f;

            var initialChunkCoordinates = new List <GlobalChunkCoordinate>();

            for (int dx = origin.X - WorldSize.X / 2 + 1; dx < origin.X + WorldSize.X / 2; dx++)
            {
                for (int dz = origin.Z - WorldSize.Z / 2 + 1; dz < origin.Z + WorldSize.Z / 2; dz++)
                {
                    initialChunkCoordinates.Add(new GlobalChunkCoordinate(dx, 0, dz));
                }
            }

            SetLoadingMessage("Generating Chunks...");

            foreach (var box in initialChunkCoordinates)
            {
                Vector3 worldPos = new Vector3(
                    box.X * VoxelConstants.ChunkSizeX,
                    box.Y * VoxelConstants.ChunkSizeY,
                    box.Z * VoxelConstants.ChunkSizeZ);
                VoxelChunk chunk = ChunkGen.GenerateChunk(worldPos, World);
                chunk.IsVisible = true;
                ChunkData.AddChunk(chunk);
            }

            // This is critical at the beginning to allow trees to spawn on ramps correctly,
            // and also to ensure no inconsistencies in chunk geometry due to ramps.
            foreach (var chunk in ChunkData.ChunkMap)
            {
                ChunkGen.GenerateCaves(chunk, World);
                for (var i = 0; i < VoxelConstants.ChunkSizeY; ++i)
                {
                    // Update corner ramps on all chunks so that they don't have seams when they
                    // are initially built.
                    //VoxelListPrimitive.UpdateCornerRamps(chunk, i);
                    chunk.InvalidateSlice(i);
                }
            }
            RecalculateBounds();
            SetLoadingMessage("Generating Ores...");

            GenerateOres();

            GenerateDistance = origBuildRadius;
        }
Beispiel #18
0
        private static void InvalidateNeighborSlice(ChunkManager Chunks, GlobalChunkCoordinate ChunkCoordinate,
                                                    Point3 NeighborOffset, int LocalY)
        {
            var neighborCoordinate = new GlobalChunkCoordinate(
                ChunkCoordinate.X + NeighborOffset.X,
                ChunkCoordinate.Y + NeighborOffset.Y,
                ChunkCoordinate.Z + NeighborOffset.Z);

            if (Chunks.CheckBounds(neighborCoordinate))
            {
                var chunk = Chunks.GetChunk(neighborCoordinate);
                chunk.InvalidateSlice(LocalY);
            }
        }
Beispiel #19
0
        public VoxelChunk(ChunkManager manager, Vector3 origin, GlobalChunkCoordinate id)
        {
            ID        = id;
            Origin    = origin;
            Data      = VoxelData.Allocate();
            Primitive = new VoxelListPrimitive();
            Manager   = manager;

            InitializeStatics();
            PrimitiveMutex = new Mutex();
            DynamicLights  = new List <DynamicLight>();

            Liquids = new Dictionary <LiquidType, LiquidPrimitive>();
            Liquids[LiquidType.Water] = new LiquidPrimitive(LiquidType.Water);
            Liquids[LiquidType.Lava]  = new LiquidPrimitive(LiquidType.Lava);
        }
Beispiel #20
0
 public bool CheckBounds(GlobalChunkCoordinate Coordinate)
 {
     if (Coordinate.X < ChunkMapMinX || Coordinate.X >= ChunkMapMinX + ChunkMapWidth)
     {
         return(false);
     }
     if (Coordinate.Z < ChunkMapMinZ || Coordinate.Z >= ChunkMapMinZ + ChunkMapHeight)
     {
         return(false);
     }
     if (Coordinate.Y != 0)
     {
         return(false);
     }
     return(true);
 }
Beispiel #21
0
 public bool CheckBounds(GlobalChunkCoordinate Coordinate)
 {
     if (Coordinate.X < MapOrigin.X || Coordinate.X >= MapOrigin.X + MapDimensions.X)
     {
         return(false);
     }
     if (Coordinate.Y < MapOrigin.Y || Coordinate.Y >= MapOrigin.Y + MapDimensions.Y)
     {
         return(false);
     }
     if (Coordinate.Z < MapOrigin.Z || Coordinate.Z >= MapOrigin.Z + MapDimensions.Z)
     {
         return(false);
     }
     return(true);
 }
Beispiel #22
0
 private IEnumerable <VoxelChunk> EnumerateAdjacentChunks(VoxelChunk Chunk)
 {
     for (int dx = -1; dx < 2; dx++)
     {
         for (int dz = -1; dz < 2; dz++)
         {
             if (dx != 0 || dz != 0)
             {
                 var adjacentCoord = new GlobalChunkCoordinate(
                     Chunk.ID.X + dx, 0, Chunk.ID.Z + dz);
                 if (ChunkData.CheckBounds(adjacentCoord))
                 {
                     yield return(ChunkData.GetChunk(adjacentCoord));
                 }
             }
         }
     }
 }
Beispiel #23
0
        // Todo: Move to ChunkGenerator
        public void GenerateInitialChunks(Rectangle spawnRect, GlobalChunkCoordinate origin, Action <String> SetLoadingMessage)
        {
            var initialChunkCoordinates = new List <GlobalChunkCoordinate>();

            for (int dx = 0; dx < WorldSize.X; dx++)
            {
                for (int dz = 0; dz < WorldSize.Z; dz++)
                {
                    initialChunkCoordinates.Add(new GlobalChunkCoordinate(dx, 0, dz));
                }
            }

            SetLoadingMessage("Generating Chunks...");
            float maxHeight = Math.Max(Overworld.GetMaxHeight(spawnRect), 0.17f);

            foreach (var box in initialChunkCoordinates)
            {
                Vector3 worldPos = new Vector3(
                    box.X * VoxelConstants.ChunkSizeX,
                    box.Y * VoxelConstants.ChunkSizeY,
                    box.Z * VoxelConstants.ChunkSizeZ);
                VoxelChunk chunk = ChunkGen.GenerateChunk(worldPos, World, maxHeight);
                ChunkData.AddChunk(chunk);
            }


            // This is critical at the beginning to allow trees to spawn on ramps correctly,
            // and also to ensure no inconsistencies in chunk geometry due to ramps.
            foreach (var chunk in ChunkData.ChunkMap)
            {
                ChunkGen.GenerateChunkData(chunk, World, maxHeight);
                for (var i = 0; i < VoxelConstants.ChunkSizeY; ++i)
                {
                    chunk.InvalidateSlice(i);
                }
            }
            RecalculateBounds();
            SetLoadingMessage("Generating Ores...");

            GenerateOres();
            NeedsMinimapUpdate = true;
        }
Beispiel #24
0
        public void GetChunksIntersecting(BoundingBox box, HashSet <VoxelChunk> chunks)
        {
            chunks.Clear();
            var minChunk = GlobalVoxelCoordinate.FromVector3(box.Min).GetGlobalChunkCoordinate();
            var maxChunk = GlobalVoxelCoordinate.FromVector3(box.Max).GetGlobalChunkCoordinate();

            for (var x = minChunk.X; x <= maxChunk.X; ++x)
            {
                for (var y = minChunk.Y; y <= maxChunk.Y; ++y)
                {
                    for (var z = minChunk.Z; z <= maxChunk.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkData.CheckBounds(coord))
                        {
                            chunks.Add(ChunkData.GetChunk(coord));
                        }
                    }
                }
            }
        }
        public void AddGameObject(GameComponent GameObject, BoundingBox LastBounds)
        {
            var minChunkID = GlobalVoxelCoordinate.FromVector3(LastBounds.Min).GetGlobalChunkCoordinate();
            var maxChunkID = GlobalVoxelCoordinate.FromVector3(LastBounds.Max).GetGlobalChunkCoordinate();

            for (var x = minChunkID.X; x <= maxChunkID.X; ++x)
            {
                for (var y = minChunkID.Y; y <= maxChunkID.Y; ++y)
                {
                    for (var z = minChunkID.Z; z <= maxChunkID.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkManager.CheckBounds(coord))
                        {
                            var chunk = ChunkManager.GetChunk(coord);
                            lock (chunk)
                                chunk.Entities.Add(GameObject);
                        }
                    }
                }
            }
        }
Beispiel #26
0
        public void RemoveGameObject(GameComponent GameObject, BoundingBox LastBounds)
        {
            var minChunkID = GlobalVoxelCoordinate.FromVector3(LastBounds.Min).GetGlobalChunkCoordinate(); // Todo: Clamp to actual world size.
            var maxChunkID = GlobalVoxelCoordinate.FromVector3(LastBounds.Max).GetGlobalChunkCoordinate();

            for (var x = minChunkID.X; x <= maxChunkID.X; ++x)
            {
                for (var y = minChunkID.Y; y <= maxChunkID.Y; ++y)
                {
                    for (var z = minChunkID.Z; z <= maxChunkID.Z; ++z)
                    {
                        var coord = new GlobalChunkCoordinate(x, y, z);
                        if (ChunkManager.CheckBounds(coord))
                        {
                            var chunk = ChunkManager.GetChunk(coord);
                            lock (chunk)
                                chunk.Components.Remove(GameObject);
                        }
                    }
                }
            }
        }
Beispiel #27
0
 public GlobalVoxelCoordinate(GlobalChunkCoordinate C, LocalVoxelCoordinate L)
 {
     X = (C.X * VoxelConstants.ChunkSizeX) + L.X;
     Y = (C.Y * VoxelConstants.ChunkSizeY) + L.Y;
     Z = (C.Z * VoxelConstants.ChunkSizeZ) + L.Z;
 }
Beispiel #28
0
 public int GetChunkIndex(GlobalChunkCoordinate ID)
 {
     return((ID.Y - MapOrigin.Y) * MapDimensions.X * MapDimensions.Z
            + (ID.Z - MapOrigin.Z) * MapDimensions.X
            + (ID.X - MapOrigin.X));
 }