public static bool CheckGroundedAABB(Vector3 position, AABB aabb, IWorld world, out BlockData groundBlock) { aabb += position; int y = Mathf.FloorToInt(aabb.Min.y - 0.5f); if (y >= 0 && y < ChunkHeight) { int startX = Mathf.FloorToInt(aabb.Min.x); int endX = Mathf.FloorToInt(aabb.Max.x); int startZ = Mathf.FloorToInt(aabb.Min.z); int endZ = Mathf.FloorToInt(aabb.Max.z); for (int x = startX; x <= endX; x++) { for (int z = startZ; z <= endZ; z++) { groundBlock = world.RWAccessor.GetBlock(x, y, z); AABB?blockAABB = groundBlock.GetBoundingBox(x, y, z, world, true); if (blockAABB != null && aabb.Intersects(blockAABB.Value)) { return(true); } } } } groundBlock = null; return(false); }
private static bool CollideWithTerrainAABB(int axis, AABB aabb, IWorld world, PhysicMaterial material, float time, ref float velocity, out float movement) { movement = velocity * time; if (movement == 0) { return(false); } Vector3Int start = default; Vector3Int end = default; Vector3Int step = default; if (movement > 0) { for (int i = 0; i < 3; i++) { if (axis == i) { start[i] = Mathf.FloorToInt(aabb.Max[i]); end[i] = Mathf.FloorToInt(aabb.Max[i] + movement); } else { start[i] = Mathf.FloorToInt(aabb.Min[i]); end[i] = Mathf.FloorToInt(aabb.Max[i]); } step[i] = 1; } } else { for (int i = 0; i < 3; i++) { if (axis == i) { end[i] = Mathf.FloorToInt(aabb.Min[i] + movement); step[i] = -1; } else { end[i] = Mathf.FloorToInt(aabb.Max[i]); step[i] = 1; } start[i] = Mathf.FloorToInt(aabb.Min[i]); } } end += step; for (int x = start.x; x != end.x; x += step.x) { for (int z = start.z; z != end.z; z += step.z) { for (int y = start.y; y != end.y; y += step.y) { BlockData block = world.RWAccessor.GetBlock(x, y, z); AABB? blockAABB = block.GetBoundingBox(x, y, z, world, true); if (blockAABB == null) { continue; } AABB blockBB = blockAABB.Value; bool flag = true; for (int i = 0; i < 3; i++) { if (i != axis) { flag &= blockBB.Max[i] > aabb.Min[i] && blockBB.Min[i] < aabb.Max[i]; } } if (!flag) { continue; } if (movement > 0 && aabb.Max[axis] <= blockBB.Min[axis]) { float maxMovement = blockBB.Min[axis] - aabb.Max[axis]; if (movement > maxMovement) { CalculateVelocityAfterCollisionWithTerrain(material, block, ref velocity); movement = maxMovement; return(true); } } else if (movement < 0 && aabb.Min[axis] >= blockBB.Max[axis]) { float maxMovement = blockBB.Max[axis] - aabb.Min[axis]; if (movement < maxMovement) { CalculateVelocityAfterCollisionWithTerrain(material, block, ref velocity); movement = maxMovement; return(true); } } } } } return(false); }