2019-01-10 17:21:34 +03:00
|
|
|
package mapblockrenderer
|
|
|
|
|
|
|
|
import (
|
2019-01-13 18:37:03 +03:00
|
|
|
"errors"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"image"
|
|
|
|
"image/draw"
|
2019-01-10 19:50:31 +03:00
|
|
|
"mapserver/colormapping"
|
|
|
|
"mapserver/coords"
|
2019-01-11 12:24:10 +03:00
|
|
|
"mapserver/mapblockaccessor"
|
2019-01-11 16:17:16 +03:00
|
|
|
"time"
|
2019-01-10 17:21:34 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type MapBlockRenderer struct {
|
2019-01-11 12:24:10 +03:00
|
|
|
accessor *mapblockaccessor.MapBlockAccessor
|
2019-01-10 19:50:31 +03:00
|
|
|
colors *colormapping.ColorMapping
|
2019-01-10 17:21:34 +03:00
|
|
|
}
|
|
|
|
|
2019-01-11 12:24:10 +03:00
|
|
|
func NewMapBlockRenderer(accessor *mapblockaccessor.MapBlockAccessor, colors *colormapping.ColorMapping) MapBlockRenderer {
|
|
|
|
return MapBlockRenderer{accessor: accessor, colors: colors}
|
2019-01-10 17:21:34 +03:00
|
|
|
}
|
|
|
|
|
2019-01-11 13:44:17 +03:00
|
|
|
const (
|
2019-01-13 18:37:03 +03:00
|
|
|
IMG_SCALE = 16
|
|
|
|
IMG_SIZE = IMG_SCALE * 16
|
|
|
|
EXPECTED_BLOCKS_PER_FLAT_MAPBLOCK = 16 * 16
|
2019-01-11 13:44:17 +03:00
|
|
|
)
|
|
|
|
|
2019-01-11 15:30:51 +03:00
|
|
|
func (r *MapBlockRenderer) Render(pos1, pos2 coords.MapBlockCoords) (*image.NRGBA, error) {
|
|
|
|
if pos1.X != pos2.X {
|
|
|
|
return nil, errors.New("X does not line up")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pos1.Z != pos2.Z {
|
|
|
|
return nil, errors.New("Z does not line up")
|
|
|
|
}
|
2019-01-13 18:37:03 +03:00
|
|
|
|
2019-01-11 16:17:16 +03:00
|
|
|
start := time.Now()
|
2019-01-13 18:37:03 +03:00
|
|
|
defer func() {
|
2019-01-11 16:17:16 +03:00
|
|
|
t := time.Now()
|
|
|
|
elapsed := t.Sub(start)
|
2019-01-13 18:37:03 +03:00
|
|
|
log.WithFields(logrus.Fields{"elapsed": elapsed}).Debug("Rendering completed")
|
2019-01-11 16:17:16 +03:00
|
|
|
}()
|
2019-01-11 15:30:51 +03:00
|
|
|
|
2019-01-11 13:44:17 +03:00
|
|
|
upLeft := image.Point{0, 0}
|
|
|
|
lowRight := image.Point{IMG_SIZE, IMG_SIZE}
|
2019-01-11 15:30:51 +03:00
|
|
|
img := image.NewNRGBA(image.Rectangle{upLeft, lowRight})
|
|
|
|
|
|
|
|
maxY := pos1.Y
|
|
|
|
minY := pos2.Y
|
|
|
|
|
|
|
|
if minY > maxY {
|
|
|
|
maxY, minY = minY, maxY
|
|
|
|
}
|
|
|
|
|
|
|
|
foundBlocks := 0
|
|
|
|
xzOccupationMap := make([][]bool, 16)
|
|
|
|
for x := range xzOccupationMap {
|
|
|
|
xzOccupationMap[x] = make([]bool, 16)
|
|
|
|
}
|
|
|
|
|
|
|
|
for mapBlockY := maxY; mapBlockY >= minY; mapBlockY-- {
|
|
|
|
currentPos := coords.NewMapBlockCoords(pos1.X, mapBlockY, pos1.Z)
|
|
|
|
mb, err := r.accessor.GetMapBlock(currentPos)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if mb == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for x := 0; x < 16; x++ {
|
|
|
|
for z := 0; z < 16; z++ {
|
|
|
|
for y := 15; y >= 0; y-- {
|
|
|
|
if xzOccupationMap[x][z] {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2019-01-13 18:37:03 +03:00
|
|
|
nodeName := mb.GetNodeName(x, y, z)
|
2019-01-11 15:30:51 +03:00
|
|
|
|
|
|
|
if nodeName == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
c := r.colors.GetColor(nodeName)
|
|
|
|
|
|
|
|
if c == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
rect := image.Rect(
|
|
|
|
x*IMG_SCALE, z*IMG_SCALE,
|
|
|
|
(x*IMG_SCALE)+IMG_SCALE, (z*IMG_SCALE)+IMG_SCALE,
|
|
|
|
)
|
|
|
|
|
|
|
|
foundBlocks++
|
|
|
|
xzOccupationMap[x][z] = true
|
|
|
|
draw.Draw(img, rect, &image.Uniform{c}, image.ZP, draw.Src)
|
|
|
|
|
|
|
|
if foundBlocks == EXPECTED_BLOCKS_PER_FLAT_MAPBLOCK {
|
2019-01-11 15:53:41 +03:00
|
|
|
return img, nil
|
2019-01-11 15:30:51 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-11 13:44:17 +03:00
|
|
|
|
2019-01-11 16:17:16 +03:00
|
|
|
if foundBlocks == 0 {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2019-01-11 15:30:51 +03:00
|
|
|
return img, nil
|
2019-01-10 17:21:34 +03:00
|
|
|
}
|