diff options
author | Kevin Chabowski <kevin@kch42.de> | 2013-08-17 00:54:41 +0200 |
---|---|---|
committer | Kevin Chabowski <kevin@kch42.de> | 2013-08-17 11:44:40 +0200 |
commit | 8cd7d24da3d2ad3f18b2e86f444d1457874820c0 (patch) | |
tree | 772000905e49f59585ee66abffa221dd460044da | |
parent | 45b4350fc3d98d3c7fc93c3303489d8d6376c3d0 (diff) | |
download | biomed-8cd7d24da3d2ad3f18b2e86f444d1457874820c0.tar.gz biomed-8cd7d24da3d2ad3f18b2e86f444d1457874820c0.tar.bz2 biomed-8cd7d24da3d2ad3f18b2e86f444d1457874820c0.zip |
A faster Fill implementation.
(Still not super fast, but it's OK, I guess)
-rw-r--r-- | tools.go | 78 |
1 files changed, 68 insertions, 10 deletions
@@ -45,20 +45,78 @@ type fillTool struct{} func (f *fillTool) SingleClick() bool { return true } +func chkBounds(x, z, xStart, zStart, xEnd, zEnd int) bool { + return (x >= xStart) && (z >= zStart) && (x < xEnd) && (z < zEnd) +} + func (f *fillTool) Do(bio mcmap.Biome, biogs BiomeGetSetter, x, z int) { - if oldbio, ok := biogs.GetBiomeAt(x, z); ok { - floodfill(oldbio, bio, biogs, x, z) + oldbio, ok := biogs.GetBiomeAt(x, z) + if !ok { + return } -} -func floodfill(oldbio, newbio mcmap.Biome, biogs BiomeGetSetter, x, z int) { - if bio, ok := biogs.GetBiomeAt(x, z); ok && (bio == oldbio) { - biogs.SetBiomeAt(x, z, newbio) + inChunkQueue := []XZPos{} + outOfChunkQueue := []XZPos{{x, z}} + + for { + oocqL := len(outOfChunkQueue) - 1 + if oocqL < 0 { + break + } + + pos := outOfChunkQueue[oocqL] + inChunkQueue = []XZPos{pos} + outOfChunkQueue = outOfChunkQueue[:oocqL] + + cx, cz, _, _ := mcmap.BlockToChunk(pos.X, pos.Z) + xStart := cx * mcmap.ChunkSizeXZ + zStart := cz * mcmap.ChunkSizeXZ + xEnd := xStart + mcmap.ChunkSizeXZ + zEnd := zStart + mcmap.ChunkSizeXZ - floodfill(oldbio, newbio, biogs, x-1, z) - floodfill(oldbio, newbio, biogs, x+1, z) - floodfill(oldbio, newbio, biogs, x, z-1) - floodfill(oldbio, newbio, biogs, x, z+1) + for { + icqL := len(inChunkQueue) - 1 + if icqL < 0 { + break + } + + pos := inChunkQueue[icqL] + inChunkQueue = inChunkQueue[:icqL] + + px, pz := pos.X, pos.Z + + if haveBio, ok := biogs.GetBiomeAt(px, pz); ok && (haveBio == oldbio) { + biogs.SetBiomeAt(px, pz, bio) + + nx, nz := px+1, pz + if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { + inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) + } else { + outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) + } + + nx, nz = px-1, pz + if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { + inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) + } else { + outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) + } + + nx, nz = px, pz+1 + if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { + inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) + } else { + outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) + } + + nx, nz = px, pz-1 + if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { + inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) + } else { + outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) + } + } + } } } |