From bbd96172a3a3b62366d3cd31fbca8d77ba95c90e Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Sun, 14 Sep 2014 17:12:28 +0200 Subject: [PATCH] Moved generation of base level tiles to separate file and made the base level generation optional. --- cmd/mtseeder/baselevel.go | 203 +++++++++++++++++++++++++++++++++++++ cmd/mtseeder/main.go | 205 +++----------------------------------- 2 files changed, 219 insertions(+), 189 deletions(-) create mode 100644 cmd/mtseeder/baselevel.go diff --git a/cmd/mtseeder/baselevel.go b/cmd/mtseeder/baselevel.go new file mode 100644 index 0000000..5a24bf3 --- /dev/null +++ b/cmd/mtseeder/baselevel.go @@ -0,0 +1,203 @@ +// Copyright 2014 by Sascha L. Teichmann +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "image/color" + "log" + "os" + "path/filepath" + "sync" + + "bitbucket.org/s_l_teichmann/mtredisalize/common" +) + +const ( + width = 18 + height = 18 + baseLevelDir = "8" + yOrderCapacity = 512 +) + +// To scan the whole height in terms of the y coordinate +// the database is queried in height units defined in the yRanges table. +var yRanges = [][]int16{ + {1024, 1934}, + {256, 1023}, + {128, 255}, + {64, 127}, + {32, 63}, + {16, 31}, + {8, 15}, + {4, 7}, + {2, 3}, + {0, 1}, + {-1, 0}, + {-4, -2}, + {-8, -5}, + {-16, -9}, + {-32, -17}, + {-64, -33}, + {-128, -65}, + {-256, -129}, + {-1024, -257}, + {-1936, -1025}} + +type blockPos struct { + x, z int16 + j, i int +} + +type baseLevelWorker struct { + client *common.RedisClient + colors *common.Colors + renderer *common.Renderer + yOrder *common.YOrder + baseDir string +} + +func newBaseLevelWorker(client *common.RedisClient, + colors *common.Colors, baseDir string) *baseLevelWorker { + renderer := common.NewRenderer(width, height) + return &baseLevelWorker{ + client: client, + colors: colors, + baseDir: baseDir, + renderer: renderer, + yOrder: common.NewYOrder(renderer, yOrderCapacity)} +} + +func (blw *baseLevelWorker) close() error { + return blw.client.Close() +} + +func (blw *baseLevelWorker) createTile(x, z int16, i, j int) { + blw.renderer.Reset() + blw.renderer.SetPos(x, z) + blw.yOrder.Reset() + + drawBlock := func(block *common.Block) { + if err := blw.yOrder.RenderBlock(block, blw.colors.NameIndex); err != nil { + log.Printf("WARN: rendering block failed: %s", err) + } + } + + var c1, c2 common.Coord + + nareas := make([]common.Area, 0, width*height/2) + oareas := make([]common.Area, 1, width*height/2) + + oareas[0] = common.Area{ + X1: 0, Z1: 0, + X2: int16(width) - 1, Z2: int16(height) - 1} + + var err error + + for _, yRange := range yRanges { + c1.Y = yRange[0] + c2.Y = yRange[1] + + nareas = blw.renderer.UncoveredAreas(nareas, oareas) + + if len(nareas) == 0 { + break + } + + for _, area := range nareas { + c1.X = area.X1 + x + c1.Z = area.Z1 + z + c2.X = area.X2 + x + c2.Z = area.Z2 + z + query := common.Cuboid{P1: c1, P2: c2} + if err = blw.client.QueryCuboid(query, drawBlock); err != nil { + log.Printf("WARN: query failed: %s", err) + return + } + if err = blw.yOrder.Drain(blw.colors.NameIndex); err != nil { + log.Printf("WARN: rendering block failed: %s", err) + } + } + oareas, nareas = nareas, oareas[0:0] + } + + image := blw.renderer.CreateShadedImage( + 16, 16, (width-2)*16, (height-2)*16, + blw.colors.Colors, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}) + + path := filepath.Join(blw.baseDir, fmt.Sprintf("%d", i), fmt.Sprintf("%d.png", j)) + + log.Printf("Writing (%d, %d) (%d, %d)", i, j, x, z) + + if err = common.SaveAsPNG(path, image); err != nil { + log.Fatalf("writing image failed: %s", err) + } +} + +func (blw *baseLevelWorker) run(jobs chan blockPos, done *sync.WaitGroup) { + defer done.Done() + for job := range jobs { + blw.createTile(job.x-1, job.z-1, job.i, job.j) + } +} + +func order(a, b int) (int, int) { + if a < b { + return a, b + } + return b, a +} + +func createBaseLevel( + address string, + xMin, zMin, xMax, zMax int, + colorsFile, outDir string, + numWorkers int) (err error) { + + var colors *common.Colors + + if colors, err = common.ParseColors(colorsFile); err != nil { + return + } + + baseDir := filepath.Join(outDir, baseLevelDir) + if err = os.MkdirAll(baseDir, os.ModePerm); err != nil { + return + } + + jobs := make(chan blockPos) + var done sync.WaitGroup + + for i := 0; i < numWorkers; i++ { + var client *common.RedisClient + if client, err = common.NewRedisClient("tcp", address); err != nil { + return + } + done.Add(1) + blw := newBaseLevelWorker(client, colors, baseDir) + defer blw.close() + go blw.run(jobs, &done) + } + + zMin, zMax = order(zMin, zMax) + + for x, i := int16(xMin), 0; x <= int16(xMax); x += 16 { + xDir := filepath.Join(baseDir, fmt.Sprintf("%d", i)) + log.Printf("creating dir: %s", xDir) + if err = os.MkdirAll(xDir, os.ModePerm); err != nil { + log.Fatalf("Cannot create directory '%s': %s", xDir, err) + } + for z, j := int16(zMin), 0; z <= int16(zMax); z += 16 { + jobs <- blockPos{x: x, z: z, i: i, j: j} + j++ + } + i++ + } + close(jobs) + + done.Wait() + + return +} diff --git a/cmd/mtseeder/main.go b/cmd/mtseeder/main.go index d436e5e..9e99c84 100644 --- a/cmd/mtseeder/main.go +++ b/cmd/mtseeder/main.go @@ -7,157 +7,19 @@ package main import ( "flag" "fmt" - "image/color" "log" - "os" - "path/filepath" - "sync" - - "bitbucket.org/s_l_teichmann/mtredisalize/common" ) -const ( - width = 18 - height = 18 - baseLevelDir = "8" - yOrderCapacity = 512 -) - -var yRanges = [][]int16{ - {1024, 1934}, - {256, 1023}, - {128, 255}, - {64, 127}, - {32, 63}, - {16, 31}, - {8, 15}, - {4, 7}, - {2, 3}, - {0, 1}, - {-1, 0}, - {-4, -2}, - {-8, -5}, - {-16, -9}, - {-32, -17}, - {-64, -33}, - {-128, -65}, - {-256, -129}, - {-1024, -257}, - {-1936, -1025}} - -type blockPos struct { - x, z int16 - j, i int -} - -type baseLevelWorker struct { - client *common.RedisClient - colors *common.Colors - renderer *common.Renderer - yOrder *common.YOrder - baseDir string -} - -func newBaseLevelWorker(client *common.RedisClient, - colors *common.Colors, baseDir string) *baseLevelWorker { - renderer := common.NewRenderer(width, height) - return &baseLevelWorker{ - client: client, - colors: colors, - baseDir: baseDir, - renderer: renderer, - yOrder: common.NewYOrder(renderer, yOrderCapacity)} -} - -func (blw *baseLevelWorker) close() error { - return blw.client.Close() -} - -func (blw *baseLevelWorker) createTile(x, z int16, i, j int) { - blw.renderer.Reset() - blw.renderer.SetPos(x, z) - blw.yOrder.Reset() - - drawBlock := func(block *common.Block) { - if err := blw.yOrder.RenderBlock(block, blw.colors.NameIndex); err != nil { - log.Printf("WARN: rendering block failed: %s", err) - } - } - - var c1, c2 common.Coord - - nareas := make([]common.Area, 0, width*height/2) - oareas := make([]common.Area, 1, width*height/2) - - oareas[0] = common.Area{ - X1: 0, Z1: 0, - X2: int16(width) - 1, Z2: int16(height) - 1} - - var err error - - for _, yRange := range yRanges { - c1.Y = yRange[0] - c2.Y = yRange[1] - - nareas = blw.renderer.UncoveredAreas(nareas, oareas) - - if len(nareas) == 0 { - break - } - - for _, area := range nareas { - c1.X = area.X1 + x - c1.Z = area.Z1 + z - c2.X = area.X2 + x - c2.Z = area.Z2 + z - query := common.Cuboid{P1: c1, P2: c2} - if err = blw.client.QueryCuboid(query, drawBlock); err != nil { - log.Printf("WARN: query failed: %s", err) - return - } - if err = blw.yOrder.Drain(blw.colors.NameIndex); err != nil { - log.Printf("WARN: rendering block failed: %s", err) - } - } - oareas, nareas = nareas, oareas[0:0] - } - - image := blw.renderer.CreateShadedImage( - 16, 16, (width-2)*16, (height-2)*16, - blw.colors.Colors, color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}) - - path := filepath.Join(blw.baseDir, fmt.Sprintf("%d", i), fmt.Sprintf("%d.png", j)) - - log.Printf("Writing (%d, %d) (%d, %d)", i, j, x, z) - - if err = common.SaveAsPNG(path, image); err != nil { - log.Fatalf("writing image failed: %s", err) - } -} - -func (blw *baseLevelWorker) run(jobs chan blockPos, done *sync.WaitGroup) { - defer done.Done() - for job := range jobs { - blw.createTile(job.x-1, job.z-1, job.i, job.j) - } -} - -func order(a, b int) (int, int) { - if a < b { - return a, b - } - return b, a -} - func main() { var ( - port int - host string - xMin, zMin int - xMax, zMax int - colorsfile string - outDir string - numWorkers int + port int + host string + xMin, zMin int + xMax, zMax int + colorsFile string + outDir string + numWorkers int + skipBaseLevel bool ) flag.IntVar(&port, "port", 6379, "port to of mtredisalize server") @@ -167,57 +29,22 @@ func main() { flag.IntVar(&xMax, "xmax", 1920, "x max of the area to tile") flag.IntVar(&zMin, "zmin", -1936, "z min of the area to tile") flag.IntVar(&zMax, "zmax", 1920, "z max of the area to tile") - flag.StringVar(&colorsfile, "colors", "colors.txt", "definition of colors") + flag.StringVar(&colorsFile, "colors", "colors.txt", "definition of colors") flag.StringVar(&outDir, "output-dir", "map", "directory with the resulting image tree") flag.StringVar(&outDir, "o", "map", "directory with the resulting image tree") flag.IntVar(&numWorkers, "worker", 1, "number of workers") flag.IntVar(&numWorkers, "w", 1, "number of workers (shorthand)") + flag.BoolVar(&skipBaseLevel, "skip-base-level", false, "Do not generate baselevel") + flag.BoolVar(&skipBaseLevel, "sb", false, "Do not generate baselevel (shorthand)") flag.Parse() var err error - var colors *common.Colors - - if colors, err = common.ParseColors(colorsfile); err != nil { - log.Fatalf("Cannot open color file: %s", err) - } - - baseDir := filepath.Join(outDir, baseLevelDir) - if err = os.MkdirAll(baseDir, os.ModePerm); err != nil { - log.Fatalf("Cannot create base dir '%s': %s", baseDir, err) - } - - jobs := make(chan blockPos) - var done sync.WaitGroup - - address := fmt.Sprintf("%s:%d", host, port) - - for i := 0; i < numWorkers; i++ { - var client *common.RedisClient - if client, err = common.NewRedisClient("tcp", address); err != nil { - log.Fatalf("Cannot connect to '%s': %s", address, err) + if !skipBaseLevel { + address := fmt.Sprintf("%s:%d", host, port) + if err = createBaseLevel( + address, xMin, zMin, xMax, zMax, colorsFile, outDir, numWorkers); err != nil { + log.Fatalf("Creating base level failed: %s", err) } - done.Add(1) - blw := newBaseLevelWorker(client, colors, baseDir) - defer blw.close() - go blw.run(jobs, &done) } - - zMin, zMax = order(zMin, zMax) - - for x, i := int16(xMin), 0; x <= int16(xMax); x += 16 { - xDir := filepath.Join(baseDir, fmt.Sprintf("%d", i)) - log.Printf("creating dir: %s", xDir) - if err = os.MkdirAll(xDir, os.ModePerm); err != nil { - log.Fatalf("Cannot create directory '%s': %s", xDir, err) - } - for z, j := int16(zMin), 0; z <= int16(zMax); z += 16 { - jobs <- blockPos{x: x, z: z, i: i, j: j} - j++ - } - i++ - } - close(jobs) - - done.Wait() }