mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-17 23:58:17 +01:00
Moved generation of base level tiles to separate file and made the base level generation optional.
This commit is contained in:
parent
dddb9c0a6b
commit
bbd96172a3
203
cmd/mtseeder/baselevel.go
Normal file
203
cmd/mtseeder/baselevel.go
Normal file
@ -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
|
||||||
|
}
|
@ -7,157 +7,19 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
|
||||||
"log"
|
"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() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
port int
|
port int
|
||||||
host string
|
host string
|
||||||
xMin, zMin int
|
xMin, zMin int
|
||||||
xMax, zMax int
|
xMax, zMax int
|
||||||
colorsfile string
|
colorsFile string
|
||||||
outDir string
|
outDir string
|
||||||
numWorkers int
|
numWorkers int
|
||||||
|
skipBaseLevel bool
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.IntVar(&port, "port", 6379, "port to of mtredisalize server")
|
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(&xMax, "xmax", 1920, "x max of the area to tile")
|
||||||
flag.IntVar(&zMin, "zmin", -1936, "z min 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.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, "output-dir", "map", "directory with the resulting image tree")
|
||||||
flag.StringVar(&outDir, "o", "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, "worker", 1, "number of workers")
|
||||||
flag.IntVar(&numWorkers, "w", 1, "number of workers (shorthand)")
|
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()
|
flag.Parse()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var colors *common.Colors
|
if !skipBaseLevel {
|
||||||
|
address := fmt.Sprintf("%s:%d", host, port)
|
||||||
if colors, err = common.ParseColors(colorsfile); err != nil {
|
if err = createBaseLevel(
|
||||||
log.Fatalf("Cannot open color file: %s", err)
|
address, xMin, zMin, xMax, zMax, colorsFile, outDir, numWorkers); err != nil {
|
||||||
}
|
log.Fatalf("Creating base level failed: %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)
|
|
||||||
}
|
}
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user