/// <summary> /// Scales up the head boct. /// </summary> /// <returns>An old head address</returns> /// <param name="iteration">Scale up iteration</param> public List <byte> ScaleUp(int iteration = 1) { var newHead = new Boct(); newHead.Divide(false); newHead.Children[0] = new Boct(newHead); Boct b = newHead.Children[0]; for (int i = 0; i < iteration; i++) { b.Divide(false); b.Children[6] = new Boct(b); b = b.Children[6]; } b.Parent.Children[6] = Head; Head.Parent = b.Parent; var address = Head.Address; Head = newHead; foreach (var region in Regions) { region.Value.SetDirty(); } return(address); }
public static int CountSolid(Boct b, int depth) { if (b.HasMaterial) { return(1); } else { depth--; if (depth < 0) { return(0); } if (b.HasChild) { int cnt = 0; for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { cnt += CountSolid(b.Children[i], depth); } } return(cnt); } else { return(0); } } }
static void LargerThanR(Boct b) { if (b.HasMaterial) { __param1++; } else { if (__param1 > __param0) { return; } if (b.HasChild) { for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { LargerThanR(b.Children[i]); } } } } }
public static bool LargerThan(Boct b, int num) { __param0 = num; __param1 = 0; LargerThanR(b); return(__param1 > __param0); }
public static int GetMaxDepth(Boct target) { var scanList = new List <Boct>(); scanList.Add(target); int maxDepth = 0; while (scanList.Any()) { var nextList = new List <Boct>(); foreach (var b in scanList) { if (b.HasChild) { for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { nextList.Add(b.Children[i]); } } } } if (nextList.Count == 0) { break; } scanList = nextList; maxDepth++; } return(maxDepth); }
public static int CountSolid(Boct b) { if (b.HasMaterial) { return(1); } else { if (b.HasChild) { int cnt = 0; for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { cnt += CountSolid(b.Children[i]); } } return(cnt); } else { return(0); } } }
/// <summary> /// Divide the boct. /// </summary> public List <Boct> Divide(bool[] spawnList) { if (Children == null) { var list = new List <Boct>(); Children = new Boct[8]; for (int i = 0; i < 8; i++) { if (spawnList[i]) { Children[i] = new Boct(this); Children[i].MaterialId = MaterialId; Children[i].RegionId = RegionId; list.Add(Children[i]); } } MaterialId = BoctMaterial.EmptyId; return(list); } else { Debug.LogWarning("Children is not null."); return(new List <Boct>()); } }
static void FindSameDepthBoctR(int targetDepth, Boct boct, List <Boct> output, int depth) { if (depth == targetDepth) { if (boct.HasMaterial) { output.Add(boct); } } else { depth++; if (boct.HasChild) { foreach (var child in boct.Children) { if (child == null) { continue; } FindSameDepthBoctR(targetDepth, child, output, depth); } } } }
/// <summary> /// Divide /// </summary> public static bool DivideDeeply(Boct target, int depth, bool spawn = true) { var scanList = new List <Boct>(); scanList.Add(target); for (int d = 0; d <= depth; d++) { var nextList = new List <Boct>(); foreach (var b in scanList) { bool res = b.Divide(spawn); if (res) { for (int i = 0; i < 8; i++) { nextList.Add(b.Children[i]); } } } scanList = nextList; } // TODO fix return(true); }
/// <summary> /// Finds bocts of same depth. /// </summary> public static void FindSameDepthBoct(int targetDepth, Boct head, List <Boct> output) { // Debug.Log("[FindSameDepthBoct]"); // Debug.Log(head.ToString()); // Debug.Log("Depth: " + targetDepth); FindSameDepthBoctR(targetDepth, head, output, 0); }
public List <int> GetExpandInflictRegionList(Boct boct) { var list = new List <int>(); var dic = new Dictionary <int, int>(); var children = boct.Parent.Children; foreach (var child in children) { if (child != null && child != boct) { BoctTools.GetRegionBoctCount(child, dic); } } foreach (var d in dic) { var rid = d.Key; // Ignore the empty ID and the self ID. if (rid != BoctRegion.EmptyId && rid != boct.RegionId) { list.Add(rid); } } return(list); }
void UpdateRegionR(Boct b) { if (b == null) { Debug.LogWarning("Boct is null."); return; } if (BoctTools.LargerThan(b, RegionSize)) { b.RegionId = BoctRegion.EmptyId; if (b.HasChild) { for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { UpdateRegionR(b.Children[i]); } } } } else { AddRegion(b); } }
// TODO public static void Validate(Boct b) { if (b.HasMaterial && b.HasChild) { Debug.LogWarning("C M"); } }
/// <summary> /// Get the flood boct list. /// </summary> public static List <Boct> GetFloodBoctList(Boct target, Boct head) { // Debug.Log("[GetFloodBoctList]"); var sameDepthBoctList = new List <Boct>(); BoctTools.FindSameDepthBoct(target.Depth, head, sameDepthBoctList); // Debug.Log("SameDepthBoct: " + sameDepthBoctList.Count); var sameMaterialBoctList = sameDepthBoctList.Where(b => b.MaterialId == target.MaterialId).ToList <Boct>(); // Debug.Log("SameMaterialBoct: " + sameMaterialBoctList.Count); // Debug.Log("Dictionary"); var dic = BoctTools.ToDictionary(sameMaterialBoctList); //foreach (var kv in dic) //{ // Debug.Log(kv.Key + " " + kv.Value.ToString()); //} // Remove target. dic.Remove(target.AddressString); var output = new List <Boct>(); output.Add(target); var searchList = new List <Boct>(); searchList.Add(target); while (searchList.Count > 0) { var b = searchList[0]; searchList.RemoveAt(0); for (int i = 0; i < 6; i++) { var address = BoctAddressTools.GetAdjoiningBoctAddress(b.Address, i); if (address == null) { continue; } var addressString = BoctAddressTools.ToString(address); // Debug.Log("Address" + i + ": " + addressString); if (dic.ContainsKey(addressString)) { output.Add(dic[addressString]); searchList.Add(dic[addressString]); dic.Remove(addressString); } } } return(output); }
public static void MirrorCopy(Direction direction, Boct target) { Assert.IsTrue(target.HasChild); byte[] mirrorTable = null; switch (direction) { case Direction.South: target.TrimChild(new int[] { 1, 2, 5, 6 }); mirrorTable = MirrorConvertTableSN; break; case Direction.East: target.TrimChild(new int[] { 2, 3, 6, 7 }); mirrorTable = MirrorConvertTableEW; break; case Direction.North: target.TrimChild(new int[] { 0, 3, 4, 7 }); mirrorTable = MirrorConvertTableSN; break; case Direction.West: target.TrimChild(new int[] { 0, 1, 4, 5 }); mirrorTable = MirrorConvertTableEW; break; case Direction.Top: target.TrimChild(new int[] { 0, 1, 2, 3 }); mirrorTable = MirrorConvertTableTB; break; case Direction.Bottom: target.TrimChild(new int[] { 4, 5, 6, 7 }); mirrorTable = MirrorConvertTableTB; break; } var sourceAddressList = GetSolidBoctArray(target); var mirrorAddressList = new List <List <byte> >(sourceAddressList.Length); for (int i = 0; i < sourceAddressList.Length; i++) { var sourceAddress = sourceAddressList[i].Address; var mirrorAddress = new List <byte>(sourceAddress.Count); for (int j = 0; j < sourceAddress.Count; j++) { mirrorAddress.Add(mirrorTable[sourceAddress[j]]); } mirrorAddressList.Add(mirrorAddress); } for (int i = 0; i < sourceAddressList.Length; i++) { BoctTools.InsertBoct(mirrorAddressList[i], target, sourceAddressList[i].MaterialId); } }
/// <summary> /// Optimize Boct /// </summary> public static void Optimize(Boct b) { var list = GetSolidBoctArray(b); foreach (var b1 in list) { OptimizeBoct(b1); } }
public static bool InsertBoct(List <Boct> boctList, Boct head) { foreach (var b in boctList) { if (!InsertBoct(b, head)) { return(false); } } return(true); }
public BoctModel() { _head = new Boct(); _regions = new Dictionary <int, BoctRegion>(); _materialList = new BoctMaterialList(); _extensionList = new BoctExtensionList(); CenterAddress = new List <byte>(); RegionStream = new Subject <BoctRegion>(); SolidBounds = new Bounds(Vector3.zero, Vector3.one); }
public static int[] CountSolid2(Boct b) { const int size = 100; _countList = new int[size]; ReportR(b, 0); _countList[_maxDepth + 1] = -1; var list = _countList; _countList = null; return(list); }
public ExpandResult Expand(Boct boct) { if (!boct.HasMaterial) { return(ExpandResult.Failed); } if (!boct.HasParent) { return(ExpandResult.Failed); } var rid = boct.RegionId; bool outsideRegion = false; if (boct.Parent.RegionId != boct.RegionId) { var dic = new Dictionary <int, int>(); var children = boct.Parent.Children; foreach (var child in children) { if (child != null && child != boct) { BoctTools.GetRegionBoctCount(child, dic); } } foreach (var d in dic) { var id = d.Key; if (id != BoctRegion.EmptyId) { _regions[id].Dispose(true); } } _regions[rid].Head = boct.Parent; outsideRegion = true; } boct.ClearChildren(); var parent = boct.Parent; boct.Parent.ClearChildren(); parent.MaterialId = boct.MaterialId; parent.RegionId = boct.RegionId; parent.ExtensionId = boct.ExtensionId; _regions[rid].SetDirty(); return(outsideRegion ? ExpandResult.OutsideRegion: ExpandResult.InsideRegion); }
public Boct Find(List <byte> address, bool create = false) { var target = _head; foreach (var b in address) { if (target.HasMaterial) { return(null); } else { if (target.HasChild) { if (target.Children[b] == null) { if (create) { var boct = new Boct(target); boct.RegionId = target.RegionId; target.Children[b] = boct; target = boct; } else { return(null); } } else { target = target.Children[b]; } } else { if (create) { target.Divide(false); var boct = new Boct(target); boct.RegionId = target.RegionId; target.Children[b] = boct; target = boct; } else { return(null); } } } } return(target); }
public static Boct GetAdjoiningBoct(Boct b, int face, BoctModel model) { var adjoiningAddress = BoctAddressTools.GetAdjoiningBoctAddress(b.Address, face); if (adjoiningAddress == null) { return(null); } else { return(model.Find(adjoiningAddress)); } }
public static Dictionary <int, int> CountMaterials(Boct head, Dictionary <int, BoctMaterial> materials) { var dic = CreateMaterialContainer(materials); var solidBoctList = BoctTools.GetSolidBoctArray(head); for (int i = 0; i < solidBoctList.Length; i++) { var boct = solidBoctList[i]; dic[boct.MaterialId]++; } return(dic); }
public static bool InsertBoct(List <byte> address, Boct head, int mid) { if (address == null) { // Debug.Log("Address is null."); return(false); } Boct target = head; // Insert bocts for (int i = 0; i < address.Count; i++) { if (target.HasMaterial) { // Debug.Log("Target has a material."); // Debug.Log("Address: " + BoctAddressTools.ToString(target.Address)); // Debug.Log("RID: " + target.RegionId); return(false); } else { byte b = address[i]; if (target.Children == null) { target.Children = new Boct[8]; target.Children[b] = new Boct(target); target = target.Children[b]; target.RegionId = head.RegionId; } else { if (target.Children[b] == null) { target.Children[b] = new Boct(target); target = target.Children[b]; } else { target = target.Children[b]; } } } } target.MaterialId = mid; return(true); }
public static void DivideArea(Boct target, int depth) { // Debug.Log("DivideArea: depth=" + depth); var dic = BoctTools.GetHierarchizedSolidBoctList(target, depth); foreach (var kv in dic) { int d = depth - kv.Key; //Kenny.D(string.Format("Key: {0}, Count: {1}, d: {2}", kv.Key, kv.Value.Count, d)); List <Boct> list = kv.Value; for (int i = 0; i < list.Count; i++) { DivideDeeply(list[i], d); } } }
static void FillRegionIdR(Boct b) { b.RegionId = __param0; if (b.HasChild) { if (b.Children != null) { for (int i = 0; i < 8; i++) { if (b.Children[i] != null) { FillRegionIdR(b.Children[i]); } } } } }
public static Dictionary <int, List <Boct> > GetHierarchizedSolidBoctList(Boct target, int depth) { // Debug.Log("GetSolidBoctList: depth=" + depth); var res = new Dictionary <int, List <Boct> >(); var scanList = new List <Boct>(); scanList.Add(target); for (int d = 0; d <= depth; d++) { res.Add(d, new List <Boct>()); var nextList = new List <Boct>(); for (int i = 0; i < scanList.Count; i++) { var boct = scanList[i]; if (boct.HasMaterial) { res[d].Add(boct); } else { if (boct.HasChild) { for (int j = 0; j < 8; j++) { if (boct.Children[j] != null) { nextList.Add(boct.Children[j]); } } } } } scanList = nextList; } // Debug.Log("Result: " + res.Count); // foreach (var kv in res) // { // Debug.Log(kv.Key + ": " + kv.Value.Count); // } return(res); }
public static void Trace(Boct b) { if (b.HasChild) { // Debug.Log("Address: " + BoctAddressTools.ToString(b.Address, true) + " " + "E"); Boct[] bc = b.Children; for (int i = 0; i < 8; i++) { if (bc[i] != null) { Trace(bc[i]); } } } else { // Debug.Log("Address: " + BoctAddressTools.ToString(b.Address, true) + " " + "S"); } }
void AddRegion(Boct head, Guid?guid = null, int?regionId = null) { var region = new BoctRegion(); region.GUID = guid ?? Guid.NewGuid(); region.LUID = regionId ?? RegionIndex; BoctTools.FillRegionId(head, region.LUID); region.Head = head; Regions.Add(region.LUID, region); if (NewRegionIdList != null) { NewRegionIdList.Add(RegionIndex); } if (regionId == null) { RegionIndex++; } region.CurrentState.Subscribe(state => { switch (state) { case BoctRegion.State.Ready: break; case BoctRegion.State.Disposed: Regions.Remove(region.LUID); break; case BoctRegion.State.Dirty: region.MaterialCounts = BoctMaterialTools.CountMaterials(region.Head, MaterialList.Materials); break; } }); // Call last time. RegionStream.OnNext(region); }
static void GetRegionBoctCountR(Boct boct, Dictionary <int, int> output) { if (!output.ContainsKey(boct.RegionId)) { output.Add(boct.RegionId, 0); } output[boct.RegionId] = output[boct.RegionId] + 1; if (boct.HasChild) { foreach (var child in boct.Children) { if (child != null) { GetRegionBoctCountR(child, output); } } } }