Refactor
This commit is contained in:
154
tools/asset/process/map.py
Normal file
154
tools/asset/process/map.py
Normal file
@@ -0,0 +1,154 @@
|
||||
import struct
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
from tools.asset.args import args
|
||||
from tools.asset.cache import assetCache, assetGetCache
|
||||
from tools.asset.path import getAssetRelativePath
|
||||
from tools.dusk.defs import TILE_WIDTH, TILE_HEIGHT, TILE_DEPTH, CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, CHUNK_TILE_COUNT
|
||||
from tools.dusk.map import Map
|
||||
from tools.dusk.chunk import Chunk
|
||||
|
||||
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': outVertices,
|
||||
'uvs': outUVs,
|
||||
'colors': outColors
|
||||
}
|
||||
|
||||
def processChunk(chunk):
|
||||
cache = assetGetCache(chunk.getFilename())
|
||||
if cache:
|
||||
return cache
|
||||
|
||||
baseModel = {
|
||||
'vertices': [],
|
||||
'colors': [],
|
||||
'uvs': []
|
||||
}
|
||||
models = [ baseModel ]
|
||||
|
||||
for tileIndex, tile in chunk.tiles.items():
|
||||
tileBase = tile.getBaseTileModel()
|
||||
|
||||
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(models).to_bytes(1, 'little')) # Number of models
|
||||
buffer.extend(len(chunk.entities).to_bytes(1, 'little')) # Number of entities
|
||||
|
||||
# Buffer tile data as array of uint8_t
|
||||
for tileIndex, tile in chunk.tiles.items():
|
||||
buffer.extend(tile.shape.to_bytes(1, 'little'))
|
||||
|
||||
# # For each model
|
||||
for model in models:
|
||||
vertexCount = len(model['vertices'])
|
||||
buffer.extend(vertexCount.to_bytes(4, 'little'))
|
||||
for i in range(vertexCount):
|
||||
vertex = model['vertices'][i]
|
||||
uv = model['uvs'][i]
|
||||
color = model['colors'][i]
|
||||
|
||||
buffer.extend(color[0].to_bytes(1, 'little'))
|
||||
buffer.extend(color[1].to_bytes(1, 'little'))
|
||||
buffer.extend(color[2].to_bytes(1, 'little'))
|
||||
buffer.extend(color[3].to_bytes(1, 'little'))
|
||||
|
||||
buffer.extend(bytearray(struct.pack('<f', uv[0])))
|
||||
buffer.extend(bytearray(struct.pack('<f', uv[1])))
|
||||
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[0])))
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[1])))
|
||||
buffer.extend(bytearray(struct.pack('<f', vertex[2])))
|
||||
|
||||
# For each entity
|
||||
for entity in chunk.entities.values():
|
||||
buffer.extend(entity.type.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localX.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localY.to_bytes(1, 'little'))
|
||||
buffer.extend(entity.localZ.to_bytes(1, 'little'))
|
||||
pass
|
||||
|
||||
# Write out map file
|
||||
relative = getAssetRelativePath(chunk.getFilename())
|
||||
fileNameWithoutExt = os.path.splitext(os.path.basename(relative))[0]
|
||||
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dcf")
|
||||
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
|
||||
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
|
||||
with open(outputFilePath, "wb") as f:
|
||||
f.write(buffer)
|
||||
|
||||
outChunk = {
|
||||
'files': [ outputFilePath ],
|
||||
'chunk': chunk
|
||||
}
|
||||
return assetCache(chunk.getFilename(), outChunk)
|
||||
|
||||
def processMap(asset):
|
||||
cache = assetGetCache(asset['path'])
|
||||
if cache is not None:
|
||||
return cache
|
||||
|
||||
map = Map(None)
|
||||
map.load(asset['path'])
|
||||
chunksDir = map.getChunkDirectory()
|
||||
|
||||
files = os.listdir(chunksDir)
|
||||
if len(files) == 0:
|
||||
print(f"Error: No chunk files found in {chunksDir}.")
|
||||
sys.exit(1)
|
||||
|
||||
chunkFiles = []
|
||||
for fileName in files:
|
||||
if not fileName.endswith('.json'):
|
||||
continue
|
||||
|
||||
fNameNoExt = os.path.splitext(fileName)[0]
|
||||
fnPieces = fNameNoExt.split('_')
|
||||
if len(fnPieces) != 3:
|
||||
print(f"Error: Chunk filename {fileName} does not contain valid chunk coordinates.")
|
||||
sys.exit(1)
|
||||
chunk = Chunk(map, int(fnPieces[0]), int(fnPieces[1]), int(fnPieces[2]))
|
||||
chunk.load()
|
||||
result = processChunk(chunk)
|
||||
chunkFiles.extend(result['files'])
|
||||
|
||||
# Map file
|
||||
outBuffer = bytearray()
|
||||
outBuffer.extend(b'DMF')
|
||||
outBuffer.extend(len(chunkFiles).to_bytes(4, 'little'))
|
||||
|
||||
# DMF (Dusk Map file)
|
||||
fileRelative = getAssetRelativePath(asset['path'])
|
||||
fileNameWithoutExt = os.path.splitext(os.path.basename(fileRelative))[0]
|
||||
outputMapRelative = os.path.join(os.path.dirname(fileRelative), f"{fileNameWithoutExt}.dmf")
|
||||
outputMapPath = os.path.join(args.output_assets, outputMapRelative)
|
||||
os.makedirs(os.path.dirname(outputMapPath), exist_ok=True)
|
||||
with open(outputMapPath, "wb") as f:
|
||||
f.write(outBuffer)
|
||||
|
||||
outMap = {
|
||||
'files': chunkFiles
|
||||
}
|
||||
outMap['files'].append(outputMapPath)
|
||||
return assetCache(asset['path'], outMap)
|
||||
Reference in New Issue
Block a user