internal bool addBud(short x, short y, int level, Direction dir, int sleep) { // ignore if the road is already exist. PointS at = PointS.pointFrom(x, y, dir, 1); if (!world.isInWorld(at.x, at.y)) { return(false); } Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(dir) <= level) { return(false); } vector key = new vector(x, y, dir); if (buds.ContainsKey(key)) { return(false); } RoadBud bud = new RoadBud(level, sleep); buds.Add(key, bud); Debug.WriteLine("new bud at:(" + x + "," + y + ") to " + dir); return(true); }
protected PointS adjustPoint2(PointS src, int level, Direction dir, ref int[] right, ref int[] left) { PointS p = src; // overlap to nearest lower level road (if exist) if (level < Configure.RoadLevelMax) { int start; if (dir == Direction.SOUTH || dir == Direction.NORTH) { start = p.y; } else { start = p.x; } int l = min_length[Configure.RoadLevelMax]; int dR = right[Configure.RoadLevelMax]; int dL = left[Configure.RoadLevelMax]; int sR = Math.Abs(dR - start); int sL = Math.Abs(dL - start); if (dR >= 0) { if (dL >= 0) { if (sL < sR) { if (sL < l) { p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL)); } } else { if (sR < l) { p = PointS.pointFrom(p, DirConvertor.rotR(dir), (short)(l - sR)); } } } else if (sR < l) { p = PointS.pointFrom(p, DirConvertor.rotR(dir), (short)(l - sR)); } } else if (dL >= 0) { if (sL < l) { p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL)); } } } return(p); }
// retruns true if no road is extended. protected bool extend(vector key) { RoadBud bud = (RoadBud)buds[key]; if (bud == null) { return(false); } // remove if the road is already exist. PointS at = PointS.pointFrom(key.x, key.y, key.dir, 1); Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(key.dir) <= bud.level) { removeBud(key); return(true); } // sleep check bool f = bud.sleeping; if (f) { Debug.Write("."); bud.stepSleep(); } else { removeBud(key); int length = min_length[bud.level]; PointS p = adjustPoint(bud.level, key.x, key.y, length, key.dir); if (p == null || p.IsEmpty) { return(true); } extendRoad(bud, p, length, key.dir); if (bud.level < Configure.noTrunkLevel) { makeBranch(bud, p, length, key.dir); } Debug.WriteLine("extends from (" + p.x + "," + p.y + ") to " + key.dir + " by " + length + " voxels."); } return(f); }
internal bool addBud(RoadBud bud, short x, short y, Direction dir) { PointS at = PointS.pointFrom(x, y, dir, 1); if (!world.isInWorld(at.x, at.y)) { return(false); } Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(dir) <= bud.level) { return(false); } vector key = new vector(x, y, dir); if (buds.ContainsKey(key)) { buds.Remove(key); } buds.Add(key, bud); Debug.WriteLine("new bud at:(" + x + "," + y + ") to " + dir); return(true); }
protected int[] getLastBranches(RoadBud bud, PointS p, Direction dir) { if (!bud.sprouted || bud.lastBranch == null) { short w = min_length[0]; int n = w * 2; Direction r = DirConvertor.reverse(dir); int[] b0 = getNearestBranches(p, r, n); int[] bR = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotR(dir), w), r, n); int[] bL = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotL(dir), w), r, n); if (dir == Direction.WEST || dir == Direction.NORTH) { for (int i = 0; i < b0.Length; i++) { if (bR[i] > b0[i]) { b0[i] = bR[i]; } if (bL[i] > b0[i]) { b0[i] = bL[i]; } } } else { for (int i = 0; i < b0.Length; i++) { if (bR[i] > 0 && bR[i] < b0[i]) { b0[i] = bR[i]; } if (bL[i] > 0 && bL[i] < b0[i]) { b0[i] = bL[i]; } } } bud.lastBranch = b0; bud.sprouted = true; } // high level branch is substitutable for lower one int v; if (dir == Direction.WEST || dir == Direction.NORTH) { v = -1; } else { v = 1; } for (int i = 1; i <= Configure.RoadLevelMax; i++) { if (bud.lastBranch[i - 1] != -1) { if (bud.lastBranch[i] == -1) { bud.lastBranch[i] = bud.lastBranch[i - 1]; } else if ((bud.lastBranch[i - 1] - bud.lastBranch[i]) * v > 0) { bud.lastBranch[i] = bud.lastBranch[i - 1]; } } } return(bud.lastBranch); }
protected void makeBranch(RoadBud bud, PointS p, int length, Direction dir) { int[] b = getLastBranches(bud, p, dir); int d_min = min_length[Configure.RoadLevelMax]; // prepare arguments int start; if (dir == Direction.SOUTH || dir == Direction.NORTH) { start = p.y; } else { start = p.x; } int last = Math.Abs(b[Configure.RoadLevelMax] - start); int n = length / d_min + 1; // points proposed for branch short[] grid = new short[n]; // set first point grid[0] = (short)world.randEx(0, 2); if (last < d_min) { grid[0] += (short)d_min; } // set followed points for (int i = 1; i < n; i++) { grid[i] = (short)(grid[i - 1] + d_min + world.randEx(0, 2)); } // sleep count of the bud int[] counter = new int[n]; for (int lv = bud.level; lv <= Configure.RoadLevelMax; lv++) { for (int i = 0; i < n; i++) { counter[i] = -1; } last = Math.Abs(b[lv] - start); makeBranch2(lv, length, last, ref grid, ref counter); for (int i = 0; i < n; i++) { if (counter[i] > -1) { PointS p2 = PointS.pointFrom(p, dir, grid[i]); addBud(p2.x, p2.y, lv, DirConvertor.rotL(dir), counter[i]); addBud(p2.x, p2.y, lv, DirConvertor.rotR(dir), counter[i]); if (dir == Direction.EAST || dir == Direction.WEST) { bud.lastBranch[lv] = p2.x; } else { bud.lastBranch[lv] = p2.y; } } } } }
protected PointS adjustPoint(int level, short x, short y, int length, Direction dir) { PointS p = new PointS(x, y); short start; if (dir == Direction.SOUTH || dir == Direction.NORTH) { start = y; } else { start = x; } int l = min_length[level]; Direction dirR = DirConvertor.rotR(dir); Direction dirL = DirConvertor.rotL(dir); int[] bR = getNearestBranches(PointS.pointFrom(p, dirR, 1), dirR, l * 4 / 3); int[] bL = getNearestBranches(PointS.pointFrom(p, dirL, 1), dirL, l * 4 / 3); int dR = bR[level]; int dL = bL[level]; int sR = Math.Abs(dR - start); int sL = Math.Abs(dL - start); int s = Math.Abs(dR - dL); if (dR >= 0) { // too close branch on ether side if (dL >= 0 && s < l) { Debug.WriteLine("bud canceled 0"); return(null); } // close branch on right side if (sR < l) { // can shift left side? if (sL - l > l - sR) { p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sR)); bR[Configure.RoadLevelMax] = -1; return(adjustPoint2(p, level, dir, ref bR, ref bL)); } else { Debug.WriteLine("bud canceled R"); return(null); } } } if (dL >= 0) { // close branch on left side if (sL < l) { // can shift right side? if (sR - l > l - sL) { p = PointS.pointFrom(p, DirConvertor.rotL(dir), (short)(l - sL)); bL[Configure.RoadLevelMax] = -1; return(adjustPoint2(p, level, dir, ref bR, ref bL)); } else { Debug.WriteLine("bud canceled L"); return(null); } } } return(adjustPoint2(p, level, dir, ref bR, ref bL)); }