diff --git a/assets/map/CMakeLists.txt b/assets/map/CMakeLists.txt index 656d3ba..03f4a37 100644 --- a/assets/map/CMakeLists.txt +++ b/assets/map/CMakeLists.txt @@ -3,4 +3,4 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT -add_asset(MAP map) \ No newline at end of file +add_asset(MAP map.json) \ No newline at end of file diff --git a/tools/assetstool/processmap.py b/tools/assetstool/processmap.py index f890eab..f4a0ea0 100644 --- a/tools/assetstool/processmap.py +++ b/tools/assetstool/processmap.py @@ -6,148 +6,83 @@ from assetstool.args import args from assetstool.assetcache import assetCache, assetGetCache from assetstool.assethelpers import getAssetRelativePath from dusk.defs import TILE_WIDTH, TILE_HEIGHT, TILE_DEPTH, CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, CHUNK_TILE_COUNT +from dusk.map import Map +from dusk.chunk import Chunk -def processTile(tileIndex, x=0, y=0, z=0, chunkX=0, chunkY=0, chunkZ=0): - vertices = [] - indices = [] - tileType = tileIndex - - # Placement X, Y, Z - px = (x * TILE_WIDTH) + (chunkX * CHUNK_WIDTH * TILE_WIDTH) - py = (y * TILE_HEIGHT) + (chunkY * CHUNK_HEIGHT * TILE_HEIGHT) - pz = (z * TILE_DEPTH) + (chunkZ * CHUNK_DEPTH * TILE_DEPTH) - - if tileIndex == 0: - # Tile 0, nothing - return None - - elif tileIndex == 5: - # Tile 2, ramp up - color = (255,0,0) - vertices = [ - {'position': (px, py, pz + TILE_DEPTH), 'color': color, 'uv': (0,0)}, # 0,0 - {'position': (px + TILE_WIDTH, py, pz + TILE_DEPTH), 'color': color, 'uv': (1,0)}, # 1,0 - {'position': (px + TILE_WIDTH, py + TILE_HEIGHT, pz), 'color': color, 'uv': (1,1)}, # 1,1 - {'position': (px, py, pz + TILE_DEPTH), 'color': color, 'uv': (0,0)}, # 0,0 (repeat) - {'position': (px + TILE_WIDTH, py + TILE_HEIGHT, pz), 'color': color, 'uv': (1,1)}, # 1,1 (repeat) - {'position': (px, py + TILE_HEIGHT, pz), 'color': color, 'uv': (0,1)} # 0,1 - ] - indices = [0, 1, 2, 3, 4, 5] - - else: - # Determine color for checkerboard pattern - if tileIndex == 1: - color = (255, 255, 255) - else: - color = (0, 0, 255) - - vertices = [ - {'position': (px, py, pz), 'color': color, 'uv': (0,0)}, # 0,0 - {'position': (px + TILE_WIDTH, py, pz), 'color': color, 'uv': (1,0)}, # 1,0 - {'position': (px + TILE_WIDTH, py + TILE_HEIGHT, pz), 'color': color, 'uv': (1,1)}, # 1,1 - {'position': (px, py, pz), 'color': color, 'uv': (0,0)}, # 0,0 (repeat) - {'position': (px + TILE_WIDTH, py + TILE_HEIGHT, pz), 'color': color, 'uv': (1,1)}, # 1,1 (repeat) - {'position': (px, py + TILE_HEIGHT, pz), 'color': color, 'uv': (0,1)} # 0,1 - ] - indices = [0, 1, 2, 3, 4, 5] +def convertModelData(modelData): + # TLDR; Model data stores things efficiently with indices, but we buffer it + # out to 6 vertex quads for simplicity. + outVertices = [] + outUVs = [] + outColors = [] + for indice in modelData['indices']: + vertex = modelData['vertices'][indice] + uv = modelData['uvs'][indice] + color = modelData['colors'][indice] + outVertices.append(vertex) + outUVs.append(uv) + outColors.append(color) return { - 'vertices': vertices, - 'indices': indices, - 'tileType': tileType + 'vertices': outVertices, + 'uvs': outUVs, + 'colors': outColors } -def processChunk(path): - cache = assetGetCache(path) +def processChunk(chunk): + cache = assetGetCache(chunk.getFilename()) if cache: return cache - # Read input file as JSON - with open(path, 'r') as f: - inData = json.load(f) - - # Filename must contain chunk coordinates as X_Y_Z - fileName = os.path.basename(path) - nameParts = os.path.splitext(fileName)[0].split('_') - if len(nameParts) != 3: - print(f"Error: Chunk filename {fileName} does not contain valid chunk coordinates.") - sys.exit(1) - - chunk = { - 'chunkX': int(nameParts[0]), - 'chunkY': int(nameParts[1]), - 'chunkZ': int(nameParts[2]), - 'tiles': [0] * CHUNK_TILE_COUNT, - 'models': [] - } - baseModel = { 'vertices': [], - 'indices': [], - 'vertexCount': 0, - 'indexCount': 0 + 'colors': [], + 'uvs': [] } + models = [ baseModel ] - # Append the model to chunk.models - chunk['models'].append(baseModel) + for tileIndex, tile in chunk.tiles.items(): + tileBase = tile.getBaseTileModel() - for i, tile in enumerate(inData['shapes']): - # Set to chunk - - # Calculate x, y, z from i - x = i % CHUNK_WIDTH - y = (i // CHUNK_WIDTH) % CHUNK_HEIGHT - z = i // (CHUNK_WIDTH * CHUNK_HEIGHT) - - # Add tile 3D model - result = processTile(tile, x, y, z, chunk['chunkX'], chunk['chunkY'], chunk['chunkZ']) - if result is not None and len(result['vertices']) > 0: - base = len(baseModel['vertices']) - quad_indices = [base + idx for idx in result['indices']] - baseModel['vertices'].extend(result['vertices']) - baseModel['indices'].extend(quad_indices) - baseModel['vertexCount'] = len(baseModel['vertices']) - baseModel['indexCount'] = len(baseModel['indices']) - chunk['tiles'][i] = result['tileType'] + convertedBase = convertModelData(tileBase) + baseModel['vertices'].extend(convertedBase['vertices']) + baseModel['colors'].extend(convertedBase['colors']) + baseModel['uvs'].extend(convertedBase['uvs']) # Generate binary buffer for efficient output buffer = bytearray() buffer.extend(b'DCF')# Header - buffer.extend(len(chunk['tiles']).to_bytes(4, 'little')) # Number of tiles - buffer.extend(len(chunk['models']).to_bytes(1, 'little')) # Number of models + buffer.extend(len(chunk.tiles).to_bytes(4, 'little')) # Number of tiles + buffer.extend(len(models).to_bytes(1, 'little')) # Number of models # Buffer tile data as array of uint8_t - for tileIndex in chunk['tiles']: - buffer.append(tileIndex.to_bytes(1, 'little')[0]) + for tileIndex, tile in chunk.tiles.items(): + buffer.extend(tile.shape.to_bytes(1, 'little')) - # For each model - for model in chunk['models']: - # Write vertex count and index count - buffer.extend(model['vertexCount'].to_bytes(4, 'little')) - - # For each vertex - for vertex in model['vertices']: - # This is not tightly packed in memory. - # R G B A U V X Y Z - # Color is 4 bytes (RGBA) - # Rest is floats - r, g, b = vertex['color'] - a = 255 - buffer.extend(r.to_bytes(1, 'little')) - buffer.extend(g.to_bytes(1, 'little')) - buffer.extend(b.to_bytes(1, 'little')) - buffer.extend(a.to_bytes(1, 'little')) - u, v = vertex['uv'] - buffer.extend(bytearray(struct.pack('