private bool IsEmpty(ref InsideDataProvider blockData, ref Vector3I size, int x, int y, int z) { if (x < 0 || y < 0 || z < 0 || x == size.X || y == size.Y || z == size.Z) { return(true); } return(blockData.GetBlock(x, y, z) == 0); }
/// <summary> /// Calculates frame bounding boxes for the shape collision test /// </summary> /// <param name="blockData"></param> /// <returns></returns> public static List <BoundingBox> GenerateShapeBBoxes(InsideDataProvider blockData) { // first of all create bb for each non-empty block var list = blockData.AllBlocks().Select(pair => new BoundingBox(pair.Key, pair.Key + Vector3.One)).ToList(); // enlarge each block as possible for (int i = 0; i < list.Count; i++) { var box = list[i]; while (TryEnlargeBBox(ref box, blockData)) { } list[i] = box; } // sort boxes by their volume desc list.Sort((b1, b2) => b2.GetVolume().CompareTo(b1.GetVolume())); // remove boxes that completely includes other and duplicates for (int i = list.Count - 1; i >= 0; i--) { var box = list[i]; bool remove = false; for (int j = 0; j < list.Count; j++) { if (i != j && (box == list[j] || list[j].Contains(ref box) == ContainmentType.Contains)) { remove = true; break; } } if (remove) { list.RemoveAt(i); } } return(list); }
public VoxelFrame() { _blockData = new InsideDataProvider(); Name = "Noname"; }
private static bool TryEnlargeBBox(ref BoundingBox box, InsideDataProvider blockData) { // try to enlarge each side var size = box.GetSize(); bool canEnlarge = true; bool enlarged = false; #region top if (box.Maximum.Y < blockData.ChunkSize.Y) { for (int x = 0; canEnlarge && x < size.X; x++) { for (int z = 0; z < size.Z; z++) { if (blockData.GetBlock(x + (int)box.Minimum.X, (int)box.Maximum.Y, z + (int)box.Minimum.Z) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Maximum.Y++; enlarged = true; size = box.GetSize(); } } #endregion #region bottom canEnlarge = true; if (box.Minimum.Y > 0) { for (int x = 0; canEnlarge && x < size.X; x++) { for (int z = 0; z < size.Z; z++) { if (blockData.GetBlock(x + (int)box.Minimum.X, (int)box.Minimum.Y - 1, z + (int)box.Minimum.Z) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Minimum.Y--; enlarged = true; size = box.GetSize(); } } #endregion #region left canEnlarge = true; if (box.Minimum.X > 0) { for (int y = 0; canEnlarge && y < size.Y; y++) { for (int z = 0; z < size.Z; z++) { if (blockData.GetBlock((int)box.Minimum.X - 1, y + (int)box.Minimum.Y, z + (int)box.Minimum.Z) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Minimum.X--; enlarged = true; size = box.GetSize(); } } #endregion #region right canEnlarge = true; if (box.Maximum.X < blockData.ChunkSize.X) { for (int y = 0; canEnlarge && y < size.Y; y++) { for (int z = 0; z < size.Z; z++) { if (blockData.GetBlock((int)box.Maximum.X, y + (int)box.Minimum.Y, z + (int)box.Minimum.Z) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Maximum.X++; enlarged = true; size = box.GetSize(); } } #endregion #region front canEnlarge = true; if (box.Maximum.Z < blockData.ChunkSize.Z) { for (int y = 0; canEnlarge && y < size.Y; y++) { for (int x = 0; x < size.X; x++) { if (blockData.GetBlock(x + (int)box.Minimum.X, y + (int)box.Minimum.Y, (int)box.Maximum.Z) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Maximum.Z++; enlarged = true; size = box.GetSize(); } } #endregion #region back canEnlarge = true; if (box.Minimum.Z > 0) { for (int y = 0; canEnlarge && y < size.Y; y++) { for (int x = 0; x < size.X; x++) { if (blockData.GetBlock(x + (int)box.Minimum.X, y + (int)box.Minimum.Y, (int)box.Minimum.Z - 1) == 0) { canEnlarge = false; break; } } } if (canEnlarge) { box.Minimum.Z--; enlarged = true; size = box.GetSize(); } } #endregion return(enlarged); }
private bool IsEmpty(ref InsideDataProvider blockData, ref Vector3I size, int x, int y, int z, FrameMirror mirror) { if (x < 0) { if ((mirror & FrameMirror.MirrorLeft) == FrameMirror.MirrorLeft) { x = 0; } else if ((mirror & FrameMirror.TileLeft) == FrameMirror.TileLeft) { x = size.X + x; } else { return(true); } } if (x == size.X) { if ((mirror & FrameMirror.MirrorRight) == FrameMirror.MirrorRight) { x = size.X - 1; } else if ((mirror & FrameMirror.TileRight) == FrameMirror.TileRight) { x = 0; } else { return(true); } } if (y < 0) { if ((mirror & FrameMirror.MirrorBottom) == FrameMirror.MirrorBottom) { y = 0; } else if ((mirror & FrameMirror.TileBottom) == FrameMirror.TileBottom) { y = size.Y - 1; } else { return(true); } } if (y == size.Y) { if ((mirror & FrameMirror.MirrorTop) == FrameMirror.MirrorTop) { y = size.Y - 1; } else if ((mirror & FrameMirror.TileTop) == FrameMirror.TileTop) { y = 0; } else { return(true); } } if (z < 0) { if ((mirror & FrameMirror.MirrorFront) == FrameMirror.MirrorFront) { z = 0; } else if ((mirror & FrameMirror.TileFront) == FrameMirror.TileFront) { z = size.Z - 1; } else { return(true); } } if (z == size.Z) { if ((mirror & FrameMirror.MirrorBack) == FrameMirror.MirrorBack) { z = size.Z - 1; } else if ((mirror & FrameMirror.TileBack) == FrameMirror.TileBack) { z = 0; } else { return(true); } } return(blockData.GetBlock(x, y, z) == 0); }