/// <summary> /// Iterate all the the chunks within a radius of a given point. /// </summary> public static IEnumerable IterateChunksWithinRadius(BlockSpacePosition position, int distance) { foreach (Chunk chunk in Instance().IterateChunksWithinRadius(position, distance)) { yield return(chunk); } }
public List <BlockLight> GetAllLightsWithinMaxRange(ChunkSpacePosition chunkPosition) { int distance = Configuration.MAX_LIGHT_RADIUS + Chunk.SIZE / 2; BlockSpacePosition checkPosition; checkPosition.x = chunkPosition.x * Chunk.SIZE + Chunk.SIZE / 2; checkPosition.y = chunkPosition.y * Chunk.SIZE + Chunk.SIZE / 2; checkPosition.z = chunkPosition.z * Chunk.SIZE + Chunk.SIZE / 2; List <BlockLight> lights = new List <BlockLight>(); foreach (Chunk chunk in ChunkRepository.IterateChunksWithinRadius(checkPosition, distance)) { // TODO -- This isn't super efficient on memory, but required for thread safety. Try to figure out a // better way of doing this. BlockLight[] chunkLights; lock (chunk) { chunkLights = chunk.LightsArray(); } int chunkLightsLength = chunkLights.Length; for (int chunkLightsIndex = 0; chunkLightsIndex < chunkLightsLength; chunkLightsIndex++) { BlockLight light = chunkLights[chunkLightsIndex]; BlockSpacePosition lightPosition = light.chunkPosition.GetBlockSpacePosition(chunk); if (BlockIsNotHidden(lightPosition)) { lights.Add(light); } } } return(lights); }
public void RemoveBlockAtPosition(BlockSpacePosition position, RemoveBlockCallback callback) { ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this); if (subspacePosition.x < 0 || subspacePosition.y < 0 || subspacePosition.z < 0 || subspacePosition.x >= SIZE || subspacePosition.y >= SIZE || subspacePosition.z >= SIZE) { return; } Block block = GetBlock(subspacePosition); if (block.IsBedrock()) { // Bedrock is a special case - it can't be removed return; } if (callback != null) { callback(position, block); } SetBlock(subspacePosition, BlockType.Air, true); }
private bool LightCanAffectFace(BlockSpacePosition samplePosition, BlockSpacePosition lightPosition, CubeSide sampleSide) { if (sampleSide == CubeSide.Bottom) { return(lightPosition.y < samplePosition.y); } else if (sampleSide == CubeSide.Top) { return(lightPosition.y > samplePosition.y); } else if (sampleSide == CubeSide.West) { return(lightPosition.x < samplePosition.x); } else if (sampleSide == CubeSide.East) { return(lightPosition.x > samplePosition.x); } else if (sampleSide == CubeSide.North) { return(lightPosition.z < samplePosition.z); } else if (sampleSide == CubeSide.South) { return(lightPosition.z > samplePosition.z); } return(false); }
public IEnumerable IterateChunksWithinRadius(BlockSpacePosition position, int distance) { ChunkSpacePosition checkPosition; int xIttr, yIttr, zIttr; for (xIttr = (int)((position.x - distance) / Chunk.SIZE); xIttr < (int)Math.Ceiling((position.x + distance) / (double)Chunk.SIZE); xIttr += 1) { checkPosition.x = xIttr; for (yIttr = (int)((position.y - distance) / Chunk.SIZE); yIttr < (int)Math.Ceiling((position.y + distance) / (double)Chunk.SIZE); yIttr += 1) { checkPosition.y = yIttr; for (zIttr = (int)((position.z - distance) / Chunk.SIZE); zIttr < (int)Math.Ceiling((position.z + distance) / (double)Chunk.SIZE); zIttr += 1) { checkPosition.z = zIttr; Chunk additionalChunk = GetChunkAtPosition(checkPosition); if (additionalChunk != null) { yield return(additionalChunk); } } } } }
public List <BlockLight> GetAllLightsFromChunks(List <Chunk> chunkList) { if (chunkList == null) { Debug.LogWarning("GetAllLightsFromChunks provided with null chunkList."); return(null); } List <BlockLight> lights = new List <BlockLight>(); int chunkListCount = chunkList.Count; for (int chunkListIndex = 0; chunkListIndex < chunkListCount; chunkListIndex++) { Chunk chunk = chunkList[chunkListIndex]; // TODO -- This isn't super effecient on memory, but required for thread safety. Try to figure out a // better way of doing this. BlockLight[] chunkLights = chunk.LightsArray(); int chunkLightsLength = chunkLights.Length; for (int chunkLightsIndex = 0; chunkLightsIndex < chunkLightsLength; chunkLightsIndex++) { BlockLight light = chunkLights[chunkLightsIndex]; BlockSpacePosition lightPosition = light.chunkPosition.GetBlockSpacePosition(chunk); if (BlockIsNotHidden(lightPosition)) { lights.Add(light); } } } return(lights); }
private void MarkForMeshUpdateWithinRadius(BlockSpacePosition position, int distance) { foreach (Chunk updateChunk in IterateChunksWithinRadius(position, distance)) { updateChunk.MarkForMeshUpdate(); } }
private void PullTransparencyCacheFromAdjacentBlock(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset) { ChunkSubspacePosition checkPosition; checkPosition = position; checkPosition.x += xOffset; checkPosition.y += yOffset; checkPosition.z += zOffset; if (checkPosition.x >= 0 && checkPosition.x < SIZE && checkPosition.y >= 0 && checkPosition.y < SIZE && checkPosition.z >= 0 && checkPosition.z < SIZE) { SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset, GetBlock(checkPosition).IsTransparent()); } else { BlockSpacePosition blockPosition = checkPosition.GetBlockSpacePosition(this); Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition); if (otherChunk != null) { ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk); SetAdjacentBlockTransparentFlag(position, xOffset, yOffset, zOffset, otherChunk.GetBlock(otherChunkPosition).IsTransparent()); } } }
// TODO -- This needs to be updated to not directly reference the player public bool PotentialEntityCollision(BlockSpacePosition position) { Block block = ChunkRepository.GetBlockAtPosition(position); if (block.IsSolidToTouch()) { // No use checking for entities if we already know that this spot is taken return(true); } VoxelCharacterController[] characters = UnityEngine.Component.FindObjectsOfType(typeof(VoxelCharacterController)) as VoxelCharacterController[]; int charactersLength = characters.Length; for (int i = 0; i < charactersLength; i++) { VoxelCharacterController character = characters[i]; if (character.transform.position.x - character.radius + 0.5f < position.x + 0.5f && character.transform.position.x + character.radius + 0.5f > position.x - 0.5f && character.transform.position.z - character.radius + 0.5f < position.z + 0.5f && character.transform.position.z + character.radius + 0.5f > position.z - 0.5f && character.transform.position.y - character.height / 2.0f + 0.5f < position.y + 0.5f && character.transform.position.y + character.height / 2.0f + 0.5f > position.y - 0.5f) { return(true); } } return(false); }
public ChunkBlockPair GetBlockAtPosition(BlockSpacePosition position, Chunk hintChunk) { if (hintChunk == null) { return(GetBlockAtPosition(position)); } ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(hintChunk); if (subspacePosition.x < 0 || subspacePosition.y < 0 || subspacePosition.z < 0 || subspacePosition.x >= Chunk.SIZE || subspacePosition.y >= Chunk.SIZE || subspacePosition.z >= Chunk.SIZE) { return(GetBlockAtPosition(position)); } ChunkBlockPair returnPair; returnPair.block = hintChunk.GetBlock(subspacePosition); returnPair.chunk = hintChunk; return(returnPair); }
/// <summary> /// Runs a raytrace for a collision. /// </summary> /// <returns><c>true</c> if there was a collision</returns> /// <param name="origin">Point for the raytrace to start at.</param> /// <param name="endpoint">Point for the raytrace to end at.</param> /// <param name="endpointSide">Which side of the endpoint to target.</param> /// <param name="ignoreStartAndEnd"> /// Whether to ignore blocks that are actually within the start and end point. You can enable this if you /// actually only care about what is between two blocks, but not the blocks themselves. /// </param> /// <param name="reverseScan">If set to <c>true</c>, it will scan from the endpoint towards the origin.</param> public static bool RaytraceCollision(BlockSpacePosition origin, BlockSpacePosition endpoint, CubeSide endpointSide, bool ignoreStartAndEnd, bool reverseScan) { return(Instance().RaytraceCollision(origin, endpoint, endpointSide, ignoreStartAndEnd, reverseScan)); }
private void PushTransparencyCacheToAdjacentBlock(ChunkSubspacePosition position, int xOffset, int yOffset, int zOffset, bool transparent) { position.x += xOffset; position.y += yOffset; position.z += zOffset; if (position.x >= 0 && position.x < SIZE && position.y >= 0 && position.y < SIZE && position.z >= 0 && position.z < SIZE) { SetAdjacentBlockTransparentFlag(position, -xOffset, -yOffset, -zOffset, transparent); } else { BlockSpacePosition blockPosition = position.GetBlockSpacePosition(this); Chunk otherChunk = ChunkRepository.GetChunkAtPosition(blockPosition); if (otherChunk != null) { ChunkSubspacePosition otherChunkPosition = blockPosition.GetChunkSubspacePosition(otherChunk); otherChunk.SetAdjacentBlockTransparentFlag(otherChunkPosition, -xOffset, -yOffset, -zOffset, transparent); } } }
public void ApplyToChunk(BlockSpacePosition origin, ironVoxel.Domain.Chunk chunk) { if (chunk == null) { return; } BlockSpacePosition setPosition; BlockType setType; int xIttr, yIttr, zIttr; for (xIttr = 0; xIttr < SizeX(); xIttr++) { for (yIttr = 0; yIttr < SizeY(); yIttr++) { for (zIttr = 0; zIttr < SizeZ(); zIttr++) { setType = Blocks()[xIttr, yIttr, zIttr]; if (setType != BlockType.Air || SetAir()) { setPosition.x = (int)(origin.x + xIttr - OriginX()); setPosition.y = (int)(origin.y + yIttr - OriginY() + 1); setPosition.z = (int)(origin.z + zIttr - OriginZ()); chunk.SetBlockAtPosition(setPosition, setType, true); } } } } }
private static bool BlockIsHidden(BlockSpacePosition blockPosition) { return(BlockIsActive(blockPosition.x - 1, blockPosition.y, blockPosition.z) && BlockIsActive(blockPosition.x + 1, blockPosition.y, blockPosition.z) && BlockIsActive(blockPosition.x, blockPosition.y - 1, blockPosition.z) && BlockIsActive(blockPosition.x, blockPosition.y + 1, blockPosition.z) && BlockIsActive(blockPosition.x, blockPosition.y, blockPosition.z - 1) && BlockIsActive(blockPosition.x, blockPosition.y, blockPosition.z + 1)); }
public void MarkChunksWithinMaxLightRadiusForMeshUpdate(BlockSpacePosition position) { int distance = Configuration.MAX_LIGHT_RADIUS + Chunk.SIZE / 2; foreach (Chunk chunk in ChunkRepository.IterateChunksWithinRadius(position, distance)) { chunk.MarkForMeshUpdate(); ChunkRepository.AddToProcessingChunkList(chunk); } }
public Chunk GetChunkAtPosition(BlockSpacePosition position) { ChunkSpacePosition chunkspacePosition; chunkspacePosition.y = position.y / Chunk.SIZE; chunkspacePosition.x = (int)Math.Floor((double)position.x / (double)Chunk.SIZE); chunkspacePosition.z = (int)Math.Floor((double)position.z / (double)Chunk.SIZE); return(GetChunkAtPosition(chunkspacePosition)); }
private bool GenerateIronSample(BlockSpacePosition blockPosition) { double calcX = blockPosition.x * 0.1 + 20.0; double calcY = blockPosition.y * 0.05 - 20.0; double calcZ = blockPosition.z * 0.1; double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ); return(noiseSample < -7.5); }
private bool GenerateCoalSample(BlockSpacePosition blockPosition) { double calcX = blockPosition.x * 0.20; double calcY = blockPosition.y * 0.20 + 5.0; double calcZ = blockPosition.z * 0.20; double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ); return(noiseSample < -0.465); }
private double GenerateCaveSample(BlockSpacePosition blockPosition) { double calcX = blockPosition.x * 0.03; double calcY = blockPosition.y * 0.03; double calcZ = blockPosition.z * 0.03; double noiseSample1 = MultifractalNoise.GenerateRidged((float)calcX, (float)calcY, (float)calcZ, 2.0f, 0.0f, 1.0f, 1.0f, 2.0f); double noiseSample2 = MultifractalNoise.GenerateRidged((float)calcX + 100.0f, (float)calcZ, (float)calcY, 2.0f, 0.0f, 1.0f, 1.0f, 2.0f); return(noiseSample1 * noiseSample2 - blockPosition.y * 0.002); }
private bool GenerateRockSample(BlockSpacePosition blockPosition) { double calcX = blockPosition.x * 0.018; double calcY = blockPosition.y * 0.020; double calcZ = blockPosition.z * 0.018; double noiseSample = PerlinNoise.Generate(calcX, calcY + 0.01, calcZ); return((1.0 + noiseSample - ((double)blockPosition.y / 32.0)) > -1.45 || noiseSample < -0.3); }
public void SetBlockAtPosition(BlockSpacePosition position, BlockType type, bool triggerLightingUpdate) { Chunk chunk = GetChunkAtPosition(position); if (chunk == null) { return; } chunk.SetBlockAtPosition(position, type, triggerLightingUpdate); MarkForMeshUpdateWithinRadius(position, Configuration.MAX_LIGHT_RADIUS); }
private double GenerateOverworldSample(BlockSpacePosition blockPosition) { Vector3Double calc; calc.x = blockPosition.x * 0.005; calc.y = blockPosition.y * 0.008; calc.z = blockPosition.z * 0.005; double sample = PerlinNoise.RidgedTurbulence(calc, 10); return(1.0 + sample - ((double)blockPosition.y / 64.0)); }
public void RemoveBlockAtPosition(BlockSpacePosition position, Chunk.RemoveBlockCallback callback) { Chunk chunk = GetChunkAtPosition(position); if (chunk == null) { return; } chunk.RemoveBlockAtPosition(position, callback); MarkForMeshUpdateWithinRadius(position, Configuration.MAX_LIGHT_RADIUS); }
public void SetBlockAtPosition(BlockSpacePosition position, BlockType type, bool triggerLightingUpdate) { if (type == BlockType.Air) { throw new Exception("Can not use SetBlockAtPosition to set a block to air. Rather, use " + "RemoveBlockAtPosition for this purpose."); } ChunkSubspacePosition subspacePosition = position.GetChunkSubspacePosition(this); SetBlock(subspacePosition, type, triggerLightingUpdate); }
private void HandlePlacingBlock(bool hit, Vector3 hitPosition, Vector3 hitNormal) { if (Input.GetKeyDown(KeyCode.Mouse0)) { BlockSpacePosition newBlockPosition = BlockSpacePosition.CreateFromVector3(hitPosition + hitNormal); if (hit && ironVoxel.Service.CollisionService.PotentialEntityCollision(newBlockPosition) == false) { Vector3 setPosition = hitPosition + hitNormal; ironVoxel.Service.ChunkRepository.SetBlockAtPosition(setPosition, buildType); } } }
private Sample GenerateDensitySample(BlockSpacePosition blockPosition) { Sample sample; sample.overworld = 0.0; sample.cave = 0.0; sample.overworld = GenerateOverworldSample(blockPosition); if (OverworldSampleIsSolid(sample.overworld)) { sample.cave = GenerateCaveSample(blockPosition); } return(sample); }
public bool RaytraceCollision(BlockSpacePosition origin, BlockSpacePosition endpoint, CubeSide endpointSide, bool ignoreStartAndEnd, bool reverseScan) { Vector3 originVector; Vector3 endpointVector; originVector = origin.GetVector3(); originVector.x += 0.5f; originVector.y += 0.5f; originVector.z += 0.5f; endpointVector = endpoint.GetVector3(); endpointVector.x += 0.5f; endpointVector.y += 0.5f; endpointVector.z += 0.5f; if (endpointSide == CubeSide.West) { endpointVector.x -= 0.5f; } if (endpointSide == CubeSide.East) { endpointVector.x += 0.5f; } if (endpointSide == CubeSide.North) { endpointVector.z -= 0.5f; } if (endpointSide == CubeSide.South) { endpointVector.z += 0.5f; } if (endpointSide == CubeSide.Bottom) { endpointVector.y -= 0.5f; } if (endpointSide == CubeSide.Top) { endpointVector.y += 0.5f; } if (reverseScan) { Vector3 originalOriginVector = originVector; originVector = endpointVector; endpointVector = originalOriginVector; } return(RaytraceCollision(originVector, Vector3.Normalize(endpointVector - originVector), Vector3.Distance(originVector, endpointVector) - 1.0f, ignoreStartAndEnd)); }
public ChunkBlockPair GetBlockAtPosition(BlockSpacePosition position) { ChunkBlockPair returnPair; Chunk chunk = GetChunkAtPosition(position); if (chunk == null) { returnPair.block = Block.EmptyBlock(); returnPair.chunk = null; return(returnPair); } returnPair.block = chunk.GetBlockAtPosition(position); returnPair.chunk = chunk; return(returnPair); }
public static void CreateBlockParticle(BlockSpacePosition blockPosition, Block block) { if (block.IsNotActive()) { return; } Vector3 position; position.x = blockPosition.x - 0.5f; position.y = blockPosition.y; position.z = blockPosition.z - 0.5f; BlockParticle createdBlockParticle = CreateBlockParticle(position); createdBlockParticle.UpdateTexture(blockPosition, block); }
public void UpdateTexture(BlockSpacePosition blockPosition, Block block) { Vector2 textureCoordinates = block.GetTextureCoordinates(CubeSide.Top, true, true, (byte)254); Vector2 overallTextureSize = block.GetOverallTextureSize(); Vector2 individualTextureSize = block.GetIndividualTextureSize(); Vector2 lowerUVs, upperUVs; lowerUVs.x = textureCoordinates.x / overallTextureSize.x; lowerUVs.y = 1.0f - textureCoordinates.y / overallTextureSize.y; upperUVs.x = (textureCoordinates.x + individualTextureSize.x) / overallTextureSize.x; upperUVs.y = 1.0f - (textureCoordinates.y + individualTextureSize.y) / overallTextureSize.y; Vector2[] uvs = CubeMesh.uv; for (int j = 0; j < 6; j++) { Vector2 uv; uv.x = lowerUVs.x; uv.y = upperUVs.y; uvs[j * 4 + 0] = uv; uv.x = lowerUVs.x; uv.y = lowerUVs.y; uvs[j * 4 + 1] = uv; uv.x = upperUVs.x; uv.y = upperUVs.y; uvs[j * 4 + 2] = uv; uv.x = upperUVs.x; uv.y = lowerUVs.y; uvs[j * 4 + 3] = uv; } CubeMesh.uv = uvs; Color lightColor = RenderService.SampleLight(blockPosition, CubeSide.Top); Color[] colors = CubeMesh.colors; for (int j = 0; j < 4 * 6; j++) { colors[j] = lightColor; } CubeMesh.colors = colors; }