private void BuildCells() { idCounter = 0; rawCells = new List <Cell>(); cellArray = new Cell[cfg.cellCount.x, cfg.cellCount.y, cfg.cellCount.z]; float cellSize = cfg.cellSize / 1000f; float cellRadius = cellSize / 2f; for (int i = 0; i < subSpaces.Count; ++i) { SubSpace space = subSpaces[i]; Vector3 startPos = (Vector3)space.minPos + new Vector3(cellRadius, cellRadius, cellRadius); for (int x = 0; x < space.cellCount.x; ++x) { for (int y = 0; y < space.cellCount.y; ++y) { for (int z = 0; z < space.cellCount.z; ++z) { Vector3 worldPoint = startPos + Vector3.up * (y * cellSize) + Vector3.right * (x * cellSize) + Vector3.forward * (z * cellSize); PerformCellTest(worldPoint, space.startIndex.x + x, space.startIndex.y + y, space.startIndex.z + z); } } } EditorUtility.DisplayProgressBar(string.Format("Voxelizing {0}/{1}", i + 1, subSpaces.Count), "", (float)i + 1 / subSpaces.Count); } }
private void BuildSubSpace() { int subGridCount = 10 * 1000 / cfg.cellSize; int intSubSize = subGridCount * cfg.cellSize; float subSize = intSubSize / 1000f; float halfSubSize = subSize / 2f; Vector3 worldMinPos = (Vector3)cfg.worldMinPos; int xSpaceCount = cfg.cellCount.x / subGridCount + ((cfg.cellCount.x % subGridCount) == 0 ? 0 : 1); int ySpaceCount = cfg.cellCount.y / subGridCount + ((cfg.cellCount.y % subGridCount) == 0 ? 0 : 1); int zSpaceCount = cfg.cellCount.z / subGridCount + ((cfg.cellCount.z % subGridCount) == 0 ? 0 : 1); int totalCount = xSpaceCount * ySpaceCount * zSpaceCount; subSpaces.Clear(); int count = 0; for (int x = 0; x < xSpaceCount; ++x) { for (int y = 0; y < ySpaceCount; ++y) { for (int z = 0; z < zSpaceCount; ++z) { float startx = worldMinPos.x + x * subSize; float starty = worldMinPos.y + y * subSize; float startz = worldMinPos.z + z * subSize; Vector3 center = new Vector3(startx + halfSubSize, starty + halfSubSize, startz + halfSubSize); Vector3 halfExt = new Vector3(halfSubSize, halfSubSize, halfSubSize); var colliders = Physics.OverlapBox(center, halfExt, Quaternion.identity, cfg.allTestMask); if (colliders.Length > 0) { var space = new SubSpace(); subSpaces.Add(space); int xGrid = subGridCount; int yGrid = subGridCount; int zGrid = subGridCount; if (x == xSpaceCount - 1) { xGrid = cfg.cellCount.x - x * subGridCount; } if (y == ySpaceCount - 1) { yGrid = cfg.cellCount.y - y * subGridCount; } if (z == zSpaceCount - 1) { zGrid = cfg.cellCount.z - z * subGridCount; } space.cellCount = new Int3(xGrid, yGrid, zGrid); space.startIndex = new Int3(x * subGridCount, y * subGridCount, z * subGridCount); space.minPos = new Int3(cfg.worldMinPos.x + x * intSubSize, cfg.worldMinPos.y + y * intSubSize, cfg.worldMinPos.z + z * intSubSize); } count++; EditorUtility.DisplayProgressBar(string.Format("Subdividing scene{0}/{1}", count, totalCount), "", (float)count / totalCount); } } } }
public SpacePartition(RectInt area, int minSize, int maxSize, int seed) { Random.InitState(seed); rootSubSpace = new SubSpace(area); this.minSize = minSize; this.maxSize = maxSize; Partition(rootSubSpace); }
public void Partition(SubSpace subArea) { if (subArea.IsLeaf()) { // if the sub-dungeon is too large if (subArea.rect.width > maxSize || subArea.rect.height > maxSize || Random.value < 0.25f) { if (subArea.Split(minSize, maxSize)) { Partition(subArea.left); Partition(subArea.right); } } } }
private SubSpace GetSpace(Vector3 position) { int x = ((int)(position.X / SubSpaceSize)) * SubSpaceSize; int y = ((int)(position.Y / SubSpaceSize)) * SubSpaceSize; int z = ((int)(position.Z / SubSpaceSize)) * SubSpaceSize; Tuple<int, int, int> key = new Tuple<int, int, int>(x, y, z); SubSpace s; if (!spaces.TryGetValue(key, out s)) { s = new SubSpace(x, y, z, SubSpaceSize); spaces.Add(key, s); } return s; }
private SubSpace GetSpace(Vector3 position) { int x = ((int)(position.X / SubSpaceSize)) * SubSpaceSize; int y = ((int)(position.Y / SubSpaceSize)) * SubSpaceSize; int z = ((int)(position.Z / SubSpaceSize)) * SubSpaceSize; Tuple <int, int, int> key = new Tuple <int, int, int>(x, y, z); SubSpace s; if (!spaces.TryGetValue(key, out s)) { s = new SubSpace(x, y, z, SubSpaceSize); spaces.Add(key, s); } return(s); }
public bool Split(int minSize, int maxSize) { if (minSize > maxSize || minSize <= 0) { return(false); } if (!IsLeaf()) { return(false); } bool canSplitH = true, canSplitV = true; if (rect.height / 2 < minSize) { canSplitH = false; } if (rect.width / 2 < minSize) { canSplitV = false; } if (!(canSplitH || canSplitV)) { return(false); } // can't split at all bool splitH; if (canSplitH && canSplitV) { // choose a vertical or horizontal split depending on the proportions // i.e. if too wide split vertically, or too long horizontally, // or if nearly square choose vertical or horizontal at random if (rect.width / rect.height >= 1.25) { splitH = false; } else if (rect.height / rect.width >= 1.25) { splitH = true; } else { splitH = Random.Range(0.0f, 1.0f) > 0.5f; } } else if (canSplitH) { splitH = true; } else { splitH = false; } if (splitH) { // split so that the resulting sub-spaces heights are not too small // (since we are splitting horizontally) int split = Random.Range(minSize, rect.height - minSize); left = new SubSpace(new RectInt(rect.x, rect.y, rect.width, split)); right = new SubSpace(new RectInt(rect.x, rect.y + split, rect.width, rect.height - split)); } else { // split so that the resulting sub-spaces widths are not too small // (since we are splitting vertically) int split = Random.Range(minSize, (int)(rect.width - minSize)); left = new SubSpace(new RectInt(rect.x, rect.y, split, rect.height)); right = new SubSpace(new RectInt(rect.x + split, rect.y, rect.width - split, rect.height)); } return(true); }
public Flat(SubSpace subspace, IVector anchor) { if (anchor.Count != subspace.EuclideanSpaceDimension) throw new ArgumentException(); this.subspace = subspace; this.anchor = anchor; }