0

A smarter (?) attempt at rotating everything.

This commit is contained in:
Ryan Rector
2011-07-10 21:05:45 -06:00
parent e81db44ea9
commit e732eb6450
4 changed files with 31 additions and 32 deletions

View File

@@ -55,8 +55,7 @@ def get_lvldata(world, filename, x, y, retries=2):
raise NoSuchChunk raise NoSuchChunk
try: try:
d = world.load_from_region(filename, x, y) d = world.load_from_region(filename, x, y)
#TODO should probably do rotation from here
except Exception, e: except Exception, e:
if retries > 0: if retries > 0:
# wait a little bit, and try again (up to `retries` times) # wait a little bit, and try again (up to `retries` times)
@@ -78,7 +77,7 @@ def get_blockarray(level, north_direction):
def get_blockarray_fromfile(filename, north_direction): def get_blockarray_fromfile(filename, north_direction):
"""Same as get_blockarray except takes a filename. This is a shortcut""" """Same as get_blockarray except takes a filename. This is a shortcut"""
d = nbt.load_from_region(filename, x, y) d = nbt.load_from_region(filename, x, y, north_direction)
level = d[1]['Level'] level = d[1]['Level']
return get_blockarray(level, north_direction) return get_blockarray(level, north_direction)

25
nbt.py
View File

@@ -17,6 +17,7 @@ import gzip, zlib
import struct import struct
import StringIO import StringIO
import os import os
import numpy
# decorator to handle filename or object as first parameter # decorator to handle filename or object as first parameter
def _file_loader(func): def _file_loader(func):
@@ -34,15 +35,15 @@ def _file_loader(func):
def load(fileobj): def load(fileobj):
return NBTFileReader(fileobj).read_all() return NBTFileReader(fileobj).read_all()
def load_from_region(filename, x, y): def load_from_region(filename, x, y, north_direction):
nbt = load_region(filename).load_chunk(x, y) nbt = load_region(filename, north_direction).load_chunk(x, y)
if nbt is None: if nbt is None:
return None ## return none. I think this is who we should indicate missing chunks return None ## return none. I think this is who we should indicate missing chunks
#raise IOError("No such chunk in region: (%i, %i)" % (x, y)) #raise IOError("No such chunk in region: (%i, %i)" % (x, y))
return nbt.read_all() return nbt.read_all()
def load_region(filename): def load_region(filename, north_direction):
return MCRFileReader(filename) return MCRFileReader(filename, north_direction)
# compile the unpacker's into a classes # compile the unpacker's into a classes
@@ -199,14 +200,26 @@ class MCRFileReader(object):
chunks (as instances of NBTFileReader), getting chunk timestamps, chunks (as instances of NBTFileReader), getting chunk timestamps,
and for listing chunks contained in the file.""" and for listing chunks contained in the file."""
def __init__(self, filename): def __init__(self, filename, north_direction):
self._file = None self._file = None
self._filename = filename self._filename = filename
self.north_direction = north_direction
# cache used when the entire header tables are read in get_chunks() # cache used when the entire header tables are read in get_chunks()
self._locations = None self._locations = None
self._timestamps = None self._timestamps = None
self._chunks = None self._chunks = None
def get_north_rotations(self):
#Upper-left and lower-right are swapped from chunk.py rots
if self.north_direction == "upper-left":
return 3
elif self.north_direction == "upper-right":
return 2
elif self.north_direction == "lower-right":
return 1
elif self.north_direction == "lower-left":
return 0
def _read_24bit_int(self): def _read_24bit_int(self):
"""Read in a 24-bit, big-endian int, used in the chunk """Read in a 24-bit, big-endian int, used in the chunk
location table.""" location table."""
@@ -328,11 +341,13 @@ class MCRFileReader(object):
locations_append = self._locations.append locations_append = self._locations.append
for _ in xrange(32*32): for _ in xrange(32*32):
locations_append(self._read_chunk_location()) locations_append(self._read_chunk_location())
self._locations = numpy.reshape(numpy.rot90(numpy.reshape(self._locations, (32,32)),self.get_north_rotations()), -1)
# read chunk timestamp table # read chunk timestamp table
timestamp_append = self._timestamps.append timestamp_append = self._timestamps.append
for _ in xrange(32*32): for _ in xrange(32*32):
timestamp_append(self._read_chunk_timestamp()) timestamp_append(self._read_chunk_timestamp())
self._timestamps = numpy.reshape(numpy.rot90(numpy.reshape(self._timestamps, (32,32)),self.get_north_rotations()), -1)
if closeFile: if closeFile:
self.closefile() self.closefile()

View File

@@ -240,10 +240,6 @@ class QuadtreeGen(object):
continue continue
chunkx, chunky = unconvert_coords(col, row) chunkx, chunky = unconvert_coords(col, row)
if self.north_direction == 'upper-right':
chunky = -chunky
elif self.north_direction == 'lower-right':
chunkx = -chunkx
regionx_ = chunkx//32 regionx_ = chunkx//32
regiony_ = chunky//32 regiony_ = chunky//32

View File

@@ -169,7 +169,7 @@ class World(object):
if self.regions.get(filename) is not None: if self.regions.get(filename) is not None:
self.regions[filename][0].closefile() self.regions[filename][0].closefile()
chunkcache = {} chunkcache = {}
mcr = nbt.MCRFileReader(filename) mcr = nbt.MCRFileReader(filename, self.north_direction)
self.regions[filename] = (mcr,os.path.getmtime(filename),chunkcache) self.regions[filename] = (mcr,os.path.getmtime(filename),chunkcache)
return mcr return mcr
@@ -185,26 +185,12 @@ class World(object):
in the image each one should be. Returns (col, row).""" in the image each one should be. Returns (col, row)."""
# change this function, and you MUST change unconvert_coords # change this function, and you MUST change unconvert_coords
if self.north_direction == 'lower-left': return (chunkx + chunky, chunky - chunkx)
return (chunkx + chunky, chunky - chunkx)
elif self.north_direction == 'lower-right':
return (chunkx + chunky, chunkx - chunky)
elif self.north_direction == 'upper-left':
return (chunkx - chunky, chunkx + chunky)
elif self.north_direction == 'upper-right':
return (chunky - chunkx, chunkx + chunky)
def unconvert_coords(self, col, row): def unconvert_coords(self, col, row):
"""Undoes what convert_coords does. Returns (chunkx, chunky).""" """Undoes what convert_coords does. Returns (chunkx, chunky)."""
if self.north_direction == 'lower-left': return ((col - row) / 2, (row + col) / 2)
return ((col - row) / 2, (row + col) / 2)
if self.north_direction == 'lower-right':
return ((col + row) / 2, (col - row) / 2)
if self.north_direction == 'upper-left':
return ((col + row) / 2, (row - col) / 2)
if self.north_direction == 'upper-right':
return ((row - col) / 2, (col + row) / 2)
def findTrueSpawn(self): def findTrueSpawn(self):
"""Adds the true spawn location to self.POI. The spawn Y coordinate """Adds the true spawn location to self.POI. The spawn Y coordinate
@@ -225,7 +211,10 @@ class World(object):
chunkFile = self.get_region_path(chunkX, chunkY) chunkFile = self.get_region_path(chunkX, chunkY)
if chunkFile is not None: if chunkFile is not None:
data = nbt.load_from_region(chunkFile, chunkX, chunkY)[1] #TODO I broke it
#data = nbt.load_from_region(chunkFile, chunkX, chunkY, self.north_direction)[1]
data = None
if data is not None: if data is not None:
level = data['Level'] level = data['Level']
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128)) blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))