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); } } } } } } } } }
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(); }
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); } } } } } } }
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)); }
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; }
public VoxelChunk GetChunk(GlobalChunkCoordinate Coordinate) { if (!CheckBounds(Coordinate)) { throw new IndexOutOfRangeException(); } return(ChunkMap[(Coordinate.Z - ChunkMapMinZ) * ChunkMapWidth + (Coordinate.X - ChunkMapMinX)]); }
public void CopyFrom(ChunkFile chunkFile) { ID = chunkFile.ID; Liquid = chunkFile.Liquid; LiquidTypes = chunkFile.LiquidTypes; Origin = chunkFile.Origin; Types = chunkFile.Types; Explored = chunkFile.Explored; }
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)); }
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); }
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; }
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); }
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(); }
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; }
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); }
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; }
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); } }
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); }
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); }
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); }
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)); } } } } }
// 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; }
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); } } } } }
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); } } } } }
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; }
public int GetChunkIndex(GlobalChunkCoordinate ID) { return((ID.Y - MapOrigin.Y) * MapDimensions.X * MapDimensions.Z + (ID.Z - MapOrigin.Z) * MapDimensions.X + (ID.X - MapOrigin.X)); }