// 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 bool RegionIsSolid(Vector3 origin, Vector3 size) { Vector3 lowerPoint; Vector3 upperPoint; lowerPoint.x = Mathf.Ceil(origin.x - size.x / 2.0f); lowerPoint.y = Mathf.Ceil(origin.y - size.y / 2.0f); lowerPoint.z = Mathf.Ceil(origin.z - size.z / 2.0f); upperPoint.x = Mathf.Ceil(origin.x + size.x / 2.0f); upperPoint.y = Mathf.Ceil(origin.y + size.y / 2.0f); upperPoint.z = Mathf.Ceil(origin.z + size.z / 2.0f); #if DEBUG DebugUtils.DrawCube(origin, size / 2.0f, Color.yellow, 0, true); #endif Vector3 drawSize; drawSize.x = (upperPoint.x - lowerPoint.x + 1.0f) / 2.0f; drawSize.y = (upperPoint.y - lowerPoint.y + 1.0f) / 2.0f; drawSize.z = (upperPoint.z - lowerPoint.z + 1.0f) / 2.0f; Vector3 drawPoint; drawPoint.x = lowerPoint.x + drawSize.x - 1.0f; drawPoint.y = lowerPoint.y + drawSize.y - 1.0f; drawPoint.z = lowerPoint.z + drawSize.z - 1.0f; #if DEBUG DebugUtils.DrawCube(drawPoint, drawSize, Color.green, 0, true); DebugUtils.DrawMark(lowerPoint, Color.red, 0); DebugUtils.DrawMark(upperPoint, Color.red, 0); #endif bool solid = false; int checkX, checkY, checkZ; for (checkX = (int)lowerPoint.x; checkX <= upperPoint.x; checkX += 1) { for (checkY = (int)lowerPoint.y; checkY <= upperPoint.y; checkY += 1) { for (checkZ = (int)lowerPoint.z; checkZ <= upperPoint.z; checkZ += 1) { BlockSpacePosition checkPosition; checkPosition.x = checkX; checkPosition.y = checkY; checkPosition.z = checkZ; Block checkBlock = ChunkRepository.GetBlockAtPosition(checkPosition); solid = checkBlock.IsSolidToTouch(); if (solid) { Vector3 markPoint; markPoint.x = checkX; markPoint.y = checkY; markPoint.z = checkZ; #if DEBUG DebugUtils.DrawMark(markPoint, Color.blue, 0); #endif } if (solid) { break; } } if (solid) { break; } } if (solid) { break; } } return(solid); }
private static bool BlockIsActive(BlockSpacePosition position) { return(ChunkRepository.GetBlockAtPosition(position).IsActive()); }
public bool RaytraceCollision(Vector3 origin, Vector3 direction, float maxDistance, bool ignoreStartAndEnd, bool drawDebug, out Block hitBlock, out Vector3 hitBlockLocation, out Vector3 hitNormal) { hitBlock = Block.EmptyBlock(); hitBlockLocation = Vector3.zero; hitNormal = Vector3.zero; bool hit = false; Vector3 movementAddition = Vector3.Normalize(direction); float movementSpeed = 0.05f; movementAddition.x *= movementSpeed; movementAddition.y *= movementSpeed; movementAddition.z *= movementSpeed; ray.direction = direction.normalized; Vector3 checkPosition = origin; Vector3 prevCheckPosition = checkPosition; float checkDistance = 0.0f; bool refreshXPlane = true; bool refreshYPlane = true; bool refreshZPlane = true; float xDistance = maxDistance; float yDistance = maxDistance; float zDistance = maxDistance; Chunk chunkCache = null; while (checkDistance <= maxDistance) { bool validBlock = ignoreStartAndEnd == false || ( ( (int)checkPosition.x != (int)origin.x || (int)checkPosition.y != (int)origin.y || (int)checkPosition.z != (int)origin.z ) ); ChunkBlockPair chunkBlockPair = ChunkRepository.GetBlockAtPosition(checkPosition, chunkCache); chunkCache = chunkBlockPair.chunk; if (drawDebug && chunkBlockPair.chunk != null) { Vector3 drawPosition; drawPosition.x = chunkBlockPair.chunk.WorldPosition().x *Chunk.SIZE + Chunk.SIZE / 2; drawPosition.y = chunkBlockPair.chunk.WorldPosition().y *Chunk.SIZE + Chunk.SIZE / 2; drawPosition.z = chunkBlockPair.chunk.WorldPosition().z *Chunk.SIZE + Chunk.SIZE / 2; DebugUtils.DrawCube(drawPosition, Vector3.one * Chunk.SIZE / 2, Color.magenta, 0, true); } Block checkBlock = chunkBlockPair.block; if (checkBlock.IsSolidToTouch() && validBlock) { hitBlock = checkBlock; hitBlockLocation = checkPosition; hit = true; if ((int)prevCheckPosition.y != (int)checkPosition.y) { hitNormal.y = ((int)prevCheckPosition.y).CompareTo((int)checkPosition.y); } else if ((int)prevCheckPosition.x != (int)checkPosition.x) { hitNormal.x = ((int)prevCheckPosition.x).CompareTo((int)checkPosition.x); } else if ((int)prevCheckPosition.z != (int)checkPosition.z) { hitNormal.z = ((int)prevCheckPosition.z).CompareTo((int)checkPosition.z); } break; } else { prevCheckPosition = checkPosition; ray.origin = checkPosition; // ---- X ---- if (refreshXPlane) { if (direction.x < 0.0f) { Vector3 westPlanePosition; if (checkPosition.x == Mathf.Floor(checkPosition.x)) { westPlanePosition.x = Mathf.Floor(checkPosition.x) - 1.0f - INSIDE_WALL_OFFSET; } else { westPlanePosition.x = Mathf.Floor(checkPosition.x) - INSIDE_WALL_OFFSET; } westPlanePosition.y = 0.0f; westPlanePosition.z = 0.0f; plane.SetNormalAndPosition(Vector3.right, westPlanePosition); plane.Raycast(ray, out xDistance); } else if (direction.x > 0.0f) { Vector3 eastPlanePosition; eastPlanePosition.x = Mathf.Floor(checkPosition.x) + 1.0f; eastPlanePosition.y = 0.0f; eastPlanePosition.z = 0.0f; plane.SetNormalAndPosition(Vector3.left, eastPlanePosition); plane.Raycast(ray, out xDistance); } } // ---- Y ---- if (refreshYPlane) { if (direction.y < 0.0f) { Vector3 downwardPlanePosition; downwardPlanePosition.x = 0.0f; if (checkPosition.y == Mathf.Floor(checkPosition.y)) { downwardPlanePosition.y = Mathf.Floor(checkPosition.y) - 1.0f - INSIDE_WALL_OFFSET; } else { downwardPlanePosition.y = Mathf.Floor(checkPosition.y) - INSIDE_WALL_OFFSET; } downwardPlanePosition.z = 0.0f; plane.SetNormalAndPosition(Vector3.down, downwardPlanePosition); plane.Raycast(ray, out yDistance); } else if (direction.y > 0.0f) { Vector3 upwardPlanePosition; upwardPlanePosition.x = 0.0f; upwardPlanePosition.y = Mathf.Floor(checkPosition.y) + 1.0f; upwardPlanePosition.z = 0.0f; plane.SetNormalAndPosition(Vector3.up, upwardPlanePosition); plane.Raycast(ray, out yDistance); } } // ---- Z ---- if (refreshZPlane) { if (direction.z < 0.0f) { Vector3 southPlanePosition; southPlanePosition.x = 0.0f; southPlanePosition.y = 0.0f; if (checkPosition.z == Mathf.Floor(checkPosition.z)) { southPlanePosition.z = Mathf.Floor(checkPosition.z) - 1.0f - INSIDE_WALL_OFFSET; } else { southPlanePosition.z = Mathf.Floor(checkPosition.z) - INSIDE_WALL_OFFSET; } plane.SetNormalAndPosition(Vector3.forward, southPlanePosition); plane.Raycast(ray, out zDistance); } else if (direction.z > 0.0f) { Vector3 northPlanePosition; northPlanePosition.x = 0.0f; northPlanePosition.y = 0.0f; northPlanePosition.z = Mathf.Floor(checkPosition.z) + 1.0f; plane.SetNormalAndPosition(Vector3.back, northPlanePosition); plane.Raycast(ray, out zDistance); } } float distance; if (xDistance > 0.0f && (xDistance < zDistance || zDistance == 0.0f) && (xDistance < yDistance || yDistance == 0.0f)) { distance = xDistance; refreshXPlane = true; } else if (zDistance > 0.0f && (zDistance < yDistance || yDistance == 0.0f)) { distance = zDistance; refreshZPlane = true; if (xDistance == zDistance) { refreshXPlane = true; } } else { distance = yDistance; refreshYPlane = true; if (xDistance == yDistance) { refreshXPlane = true; } if (zDistance == yDistance) { refreshZPlane = true; } } if (distance < 0.0f) { Debug.LogWarning("Distance: " + distance); throw new Exception("Distance: " + distance + ". direction: " + direction + ". x dist: " + xDistance + ". y dist: " + yDistance + ". z dist: " + zDistance); } Vector3 drawPoint1 = checkPosition; if (drawDebug) { DebugUtils.DrawMark(checkPosition, Color.red, 0); Vector3 drawPosition; drawPosition.x = Mathf.Floor(checkPosition.x) + 0.5f; drawPosition.y = Mathf.Floor(checkPosition.y) + 0.5f; drawPosition.z = Mathf.Floor(checkPosition.z) + 0.5f; DebugUtils.DrawCube(drawPosition, Vector3.one / 2.0f, Color.blue, 0, true); } checkPosition = ray.GetPoint(distance); checkDistance += distance; if (drawDebug) { DebugUtils.DrawMark(checkPosition, Color.green, 0); UnityEngine.Debug.DrawLine(drawPoint1, checkPosition, Color.white, 0.0f, true); } xDistance -= distance; yDistance -= distance; zDistance -= distance; } } return(hit); }
private bool RaytraceLightBeam(BlockSpacePosition lightPosition, BlockSpacePosition samplePosition, CubeSide sampleSide, byte inLightHue, byte inLightSaturation, byte inLightValue, out byte outLightHue, out byte outLightSaturation, out byte outLightValue) { // Setup outLightHue = inLightHue; outLightSaturation = inLightSaturation; outLightValue = inLightValue; Vector3 originVector; Vector3 endpointVector; originVector = lightPosition.GetVector3(); originVector.x += 0.5f; originVector.y += 0.5f; originVector.z += 0.5f; endpointVector = samplePosition.GetVector3(); endpointVector.x += 0.5f; endpointVector.y += 0.5f; endpointVector.z += 0.5f; if (sampleSide == CubeSide.West) { endpointVector.x -= 0.5f; } if (sampleSide == CubeSide.East) { endpointVector.x += 0.5f; } if (sampleSide == CubeSide.North) { endpointVector.z -= 0.5f; } if (sampleSide == CubeSide.South) { endpointVector.z += 0.5f; } if (sampleSide == CubeSide.Bottom) { endpointVector.y -= 0.5f; } if (sampleSide == CubeSide.Top) { endpointVector.y += 0.5f; } // Do the raytrace Vector3 direction = Vector3.Normalize(endpointVector - originVector); float maxDistance = Vector3.Distance(originVector, endpointVector) - 1.0f; Vector3 movementAddition = Vector3.Normalize(direction); float movementSpeed = 0.05f; movementAddition.x *= movementSpeed; movementAddition.y *= movementSpeed; movementAddition.z *= movementSpeed; Vector3 checkPosition = originVector; Vector3 prevCheckPosition = checkPosition; float checkDistance = 0.0f; Chunk chunkCache = null; while (checkDistance <= maxDistance) { bool validBlock = (int)checkPosition.x != (int)originVector.x || (int)checkPosition.y != (int)originVector.y || (int)checkPosition.z != (int)originVector.z; ChunkBlockPair chunkBlockPair = ChunkRepository.GetBlockAtPosition(checkPosition, chunkCache); chunkCache = chunkBlockPair.chunk; Block checkBlock = chunkBlockPair.block; if (checkBlock.IsActive() && checkBlock.IsTransparent()) { HSBColor outLightColor = FilterLightSample(outLightHue, outLightSaturation, outLightValue, checkBlock.FilterColorHue(), checkBlock.FilterColorSaturation(), checkBlock.FilterColorValue()); outLightHue = (byte)(outLightColor.h * byte.MaxValue); outLightSaturation = (byte)(outLightColor.s * byte.MaxValue); outLightValue = (byte)(outLightColor.b * byte.MaxValue); } if (checkBlock.IsSolidToTouch() && validBlock && checkBlock.IsNotTransparent()) { return(true); } else { prevCheckPosition = checkPosition; do { checkPosition += movementAddition; checkDistance += movementSpeed; }while((int)checkPosition.x == (int)prevCheckPosition.x && (int)checkPosition.y == (int)prevCheckPosition.y && (int)checkPosition.z == (int)prevCheckPosition.z); } } return(false); }