diff --git a/chunk.py b/chunk.py index 0921e54..6f8ccba 100644 --- a/chunk.py +++ b/chunk.py @@ -70,21 +70,22 @@ def get_lvldata(world, filename, x, y, retries=2): if not d: raise NoSuchChunk(x,y) return d -def get_blockarray(level, north_direction): +def get_blockarray(level): """Takes the level struct as returned from get_lvldata, and returns the Block array, which just contains all the block ids""" - return numpy.rot90(numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128)), get_north_rotations(north_direction)) + return level['Blocks'] def get_blockarray_fromfile(filename, north_direction): """Same as get_blockarray except takes a filename. This is a shortcut""" + #TODO Update this for configurable-north d = nbt.load_from_region(filename, x, y, north_direction) level = d[1]['Level'] - return get_blockarray(level, north_direction) + return get_blockarray(level) -def get_skylight_array(level, north_direction): +def get_skylight_array(level): """Returns the skylight array. This is 4 bits per block, but it is expanded for you so you may index it normally.""" - skylight = numpy.rot90(numpy.frombuffer(level['SkyLight'], dtype=numpy.uint8).reshape((16,16,64)), get_north_rotations(north_direction)) + skylight = level['SkyLight'] # this array is 2 blocks per byte, so expand it skylight_expanded = numpy.empty((16,16,128), dtype=numpy.uint8) # Even elements get the lower 4 bits @@ -93,36 +94,26 @@ def get_skylight_array(level, north_direction): skylight_expanded[:,:,1::2] = (skylight & 0xF0) >> 4 return skylight_expanded -def get_blocklight_array(level, north_direction): +def get_blocklight_array(level): """Returns the blocklight array. This is 4 bits per block, but it is expanded for you so you may index it normally.""" # expand just like get_skylight_array() - blocklight = numpy.rot90(numpy.frombuffer(level['BlockLight'], dtype=numpy.uint8).reshape((16,16,64)), get_north_rotations(north_direction)) + blocklight = level['BlockLight'] blocklight_expanded = numpy.empty((16,16,128), dtype=numpy.uint8) blocklight_expanded[:,:,::2] = blocklight & 0x0F blocklight_expanded[:,:,1::2] = (blocklight & 0xF0) >> 4 return blocklight_expanded -def get_blockdata_array(level, north_direction): +def get_blockdata_array(level): """Returns the ancillary data from the 'Data' byte array. Data is packed in a similar manner to skylight data""" - return numpy.rot90(numpy.frombuffer(level['Data'], dtype=numpy.uint8).reshape((16,16,64)), get_north_rotations(north_direction)) + return level['Data'] def get_tileentity_data(level): """Returns the TileEntities TAG_List from chunk dat file""" data = level['TileEntities'] return data -def get_north_rotations(north_direction): - if north_direction == "upper-left": - return 1 - elif north_direction == "upper-right": - return 2 - elif north_direction == "lower-right": - return 3 - elif north_direction == "lower-left": - return 0 - # This set holds blocks ids that can be seen through, for occlusion calculations transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, @@ -148,14 +139,13 @@ class NoSuchChunk(Exception): pass class ChunkRenderer(object): - def __init__(self, chunkcoords, worldobj, rendermode, queue, north_direction): + def __init__(self, chunkcoords, worldobj, rendermode, queue): """Make a new chunk renderer for the given chunk coordinates. chunkcoors should be a tuple: (chunkX, chunkY) cachedir is a directory to save the resulting chunk images to """ self.queue = queue - self.north_direction = north_direction self.regionfile = worldobj.get_region_path(*chunkcoords) #if not os.path.exists(self.regionfile): @@ -192,21 +182,21 @@ class ChunkRenderer(object): def _load_blocks(self): """Loads and returns the block array""" if not hasattr(self, "_blocks"): - self._blocks = get_blockarray(self._load_level(), self.north_direction) + self._blocks = get_blockarray(self._load_level()) return self._blocks blocks = property(_load_blocks) def _load_skylight(self): """Loads and returns skylight array""" if not hasattr(self, "_skylight"): - self._skylight = get_skylight_array(self.level, self.north_direction) + self._skylight = get_skylight_array(self.level) return self._skylight skylight = property(_load_skylight) def _load_blocklight(self): """Loads and returns blocklight array""" if not hasattr(self, "_blocklight"): - self._blocklight = get_blocklight_array(self.level, self.north_direction) + self._blocklight = get_blocklight_array(self.level) return self._blocklight blocklight = property(_load_blocklight) @@ -215,9 +205,9 @@ class ChunkRenderer(object): chunk_path = self.world.get_region_path(self.chunkX - 1, self.chunkY) try: chunk_data = get_lvldata(self.world,chunk_path, self.chunkX - 1, self.chunkY) - self._left_skylight = get_skylight_array(chunk_data, self.north_direction) - self._left_blocklight = get_blocklight_array(chunk_data, self.north_direction) - self._left_blocks = get_blockarray(chunk_data, self.north_direction) + self._left_skylight = get_skylight_array(chunk_data) + self._left_blocklight = get_blocklight_array(chunk_data) + self._left_blocks = get_blockarray(chunk_data) except NoSuchChunk: self._left_skylight = None self._left_blocklight = None @@ -249,9 +239,9 @@ class ChunkRenderer(object): chunk_path = self.world.get_region_path(self.chunkX, self.chunkY + 1) try: chunk_data = get_lvldata(self.world,chunk_path, self.chunkX, self.chunkY + 1) - self._right_skylight = get_skylight_array(chunk_data, self.north_direction) - self._right_blocklight = get_blocklight_array(chunk_data, self.north_direction) - self._right_blocks = get_blockarray(chunk_data, self.north_direction) + self._right_skylight = get_skylight_array(chunk_data) + self._right_blocklight = get_blocklight_array(chunk_data) + self._right_blocks = get_blockarray(chunk_data) except NoSuchChunk: self._right_skylight = None self._right_blocklight = None @@ -283,9 +273,9 @@ class ChunkRenderer(object): chunk_path = self.world.get_region_path(self.chunkX + 1, self.chunkY) try: chunk_data = get_lvldata(self.world,chunk_path, self.chunkX + 1, self.chunkY) - self._up_right_skylight = get_skylight_array(chunk_data, self.north_direction) - self._up_right_blocklight = get_blocklight_array(chunk_data, self.north_direction) - self._up_right_blocks = get_blockarray(chunk_data, self.north_direction) + self._up_right_skylight = get_skylight_array(chunk_data) + self._up_right_blocklight = get_blocklight_array(chunk_data) + self._up_right_blocks = get_blockarray(chunk_data) except NoSuchChunk: self._up_right_skylight = None self._up_right_blocklight = None @@ -310,9 +300,9 @@ class ChunkRenderer(object): chunk_path = self.world.get_region_path(self.chunkX, self.chunkY - 1) try: chunk_data = get_lvldata(self.world,chunk_path, self.chunkX, self.chunkY - 1) - self._up_left_skylight = get_skylight_array(chunk_data, self.north_direction) - self._up_left_blocklight = get_blocklight_array(chunk_data, self.north_direction) - self._up_left_blocks = get_blockarray(chunk_data, self.north_direction) + self._up_left_skylight = get_skylight_array(chunk_data) + self._up_left_blocklight = get_blocklight_array(chunk_data) + self._up_left_blocks = get_blockarray(chunk_data) except NoSuchChunk: self._up_left_skylight = None self._up_left_blocklight = None @@ -402,7 +392,7 @@ class ChunkRenderer(object): rendered, and blocks are drawn with a color tint depending on their depth.""" - blockData = get_blockdata_array(self.level, self.north_direction) + blockData = get_blockdata_array(self.level) blockData_expanded = numpy.empty((16,16,128), dtype=numpy.uint8) # Even elements get the lower 4 bits blockData_expanded[:,:,::2] = blockData & 0x0F diff --git a/nbt.py b/nbt.py index 994b0e8..b027026 100644 --- a/nbt.py +++ b/nbt.py @@ -210,13 +210,12 @@ class MCRFileReader(object): 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 + return 1 elif self.north_direction == "upper-right": return 2 elif self.north_direction == "lower-right": - return 1 + return 3 elif self.north_direction == "lower-left": return 0 diff --git a/quadtree.py b/quadtree.py index fe5002f..ceb543e 100644 --- a/quadtree.py +++ b/quadtree.py @@ -469,7 +469,7 @@ class QuadtreeGen(object): # draw the chunk! try: - a = chunk.ChunkRenderer((chunkx, chunky), world, rendermode, poi_queue, self.north_direction) + a = chunk.ChunkRenderer((chunkx, chunky), world, rendermode, poi_queue) a.chunk_render(tileimg, xpos, ypos, None) except chunk.ChunkCorrupt: # an error was already printed diff --git a/world.py b/world.py index b5ce5a0..aa1509d 100644 --- a/world.py +++ b/world.py @@ -153,6 +153,18 @@ class World(object): data = nbt.read_all() level = data[1]['Level'] chunk_data = level + chunk_data['Blocks'] = numpy.rot90(numpy.frombuffer( + level['Blocks'], dtype=numpy.uint8).reshape((16,16,128)), + self._get_north_rotations()) + chunk_data['Data'] = numpy.rot90(numpy.frombuffer( + level['Data'], dtype=numpy.uint8).reshape((16,16,64)), + self._get_north_rotations()) + chunk_data['SkyLight'] = numpy.rot90(numpy.frombuffer( + level['SkyLight'], dtype=numpy.uint8).reshape((16,16,64)), + self._get_north_rotations()) + chunk_data['BlockLight'] = numpy.rot90(numpy.frombuffer( + level['BlockLight'], dtype=numpy.uint8).reshape((16,16,64)), + self._get_north_rotations()) #chunk_data = {} #chunk_data['skylight'] = chunk.get_skylight_array(level) #chunk_data['blocklight'] = chunk.get_blocklight_array(level) @@ -276,6 +288,16 @@ class World(object): self.findTrueSpawn() + def _get_north_rotations(self): + if self.north_direction == "upper-left": + return 1 + elif self.north_direction == "upper-right": + return 2 + elif self.north_direction == "lower-right": + return 3 + elif self.north_direction == "lower-left": + return 0 + def _iterate_regionfiles(self,regionlist=None): """Returns an iterator of all of the region files, along with their coordinates