dump resourceVariants from minecraft

This commit is contained in:
David Vierra 2015-01-01 04:45:54 -10:00
parent 3f9c56c226
commit 8ce6571f88
3 changed files with 1471 additions and 1485 deletions

View File

@ -48,8 +48,7 @@ class BlockModels(object):
log.warn("Could not get blockstates resource for %s, skipping...", block) log.warn("Could not get blockstates resource for %s, skipping...", block)
continue continue
variants = statesJson['variants'] variants = statesJson['variants']
# variants is a dict with each key a blockstate, without the "[]" around them # variants is a dict with each key a resourceVariant value (from the block's ModelResourceLocation)
# for blocks without blockstates, the key is "normal"
# the value for this key is either a dict describing which model to use # the value for this key is either a dict describing which model to use
# ... or a list of such models to be selected from randomly # ... or a list of such models to be selected from randomly
# #
@ -58,129 +57,116 @@ class BlockModels(object):
# around that axis # around that axis
# another optional key is 'uvlock', which needs investigating # another optional key is 'uvlock', which needs investigating
def matchVariantState(variantState, blockState): variantBlockState = block.resourceVariant
# if not all keys in variantState are found in blockState, return false
if variantState == "all":
return True
blockState = blockState[1:-1]
vd = [s.split("=") for s in variantState.split(",")]
bd = {k: v for (k, v) in (s.split("=") for s in blockState.split(","))}
for k, v in vd:
if bd.get(k) != v:
return False
return True
for variantBlockState in variants: variantDict = variants[variantBlockState]
if variantBlockState != "normal" and not matchVariantState(variantBlockState, block.blockState): if isinstance(variantDict, list):
continue variantDict = variantDict[0] # do the random pick thing later, if at all
variantDict = variants[variantBlockState] modelName = variantDict['model']
if isinstance(variantDict, list): modelDict = self._getBlockModel("block/" + modelName)
variantDict = variantDict[0] # do the random pick thing later, if at all
modelName = variantDict['model']
modelDict = self._getBlockModel("block/" + modelName)
# model will either have an 'elements' key or a 'parent' key (maybe both). # model will either have an 'elements' key or a 'parent' key (maybe both).
# 'parent' will be the name of a model # 'parent' will be the name of a model
# following 'parent' keys will eventually lead to a model with 'elements' # following 'parent' keys will eventually lead to a model with 'elements'
# #
# 'elements' is a list of dicts each describing a cube that makes up the model. # 'elements' is a list of dicts each describing a cube that makes up the model.
# each cube dict has 'from' and 'to' keys, which are lists of 3 float coordinates. # each cube dict has 'from' and 'to' keys, which are lists of 3 float coordinates.
# #
# the 'crossed squares' model demonstrates most of the keys found in a cube element # the 'crossed squares' model demonstrates most of the keys found in a cube element
# #
# { "from": [ 0.8, 0, 8 ], # { "from": [ 0.8, 0, 8 ],
# "to": [ 15.2, 16, 8 ], # "to": [ 15.2, 16, 8 ],
# "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true }, # "rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": 45, "rescale": true },
# "shade": false, # "shade": false,
# "faces": { # "faces": {
# "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" }, # "north": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" },
# "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" } # "south": { "uv": [ 0, 0, 16, 16 ], "texture": "#cross" }
# } # }
# } # }
# #
# model may also have a 'textures' dict which assigns a texture file to a texture variable, # model may also have a 'textures' dict which assigns a texture file to a texture variable,
# or a texture variable to another texture variable. # or a texture variable to another texture variable.
# #
# the result of loading a model should be a list of quads, with four vertexes and four pairs of texture # the result of loading a model should be a list of quads, with four vertexes and four pairs of texture
# coordinates each, plus a Face telling which adjacent block when present causes that quad to be # coordinates each, plus a Face telling which adjacent block when present causes that quad to be
# culled. # culled.
textureVars = {} textureVars = {}
allElements = [] allElements = []
# grab textures and elements from this model, then get parent and merge its textures and elements # grab textures and elements from this model, then get parent and merge its textures and elements
# continue until no parent is found # continue until no parent is found
for i in range(30): for i in range(30):
textures = modelDict.get("textures") textures = modelDict.get("textures")
if textures is not None: if textures is not None:
textureVars.update(textures) textureVars.update(textures)
elements = modelDict.get("elements") elements = modelDict.get("elements")
if elements is not None: if elements is not None:
allElements.extend(elements) allElements.extend(elements)
parentName = modelDict.get("parent") parentName = modelDict.get("parent")
if parentName is None: if parentName is None:
break break
modelDict = self._getBlockModel(parentName) modelDict = self._getBlockModel(parentName)
else: else:
raise ValueError("Parent loop detected in block model %s" % modelName) raise ValueError("Parent loop detected in block model %s" % modelName)
try: try:
# each element describes a box with up to six faces, each with a texture. convert the box into # each element describes a box with up to six faces, each with a texture. convert the box into
# quads. # quads.
allQuads = [] allQuads = []
for element in allElements: for element in allElements:
shade = element.get("shade", True) shade = element.get("shade", True)
fromPoint = Vector(*element["from"]) fromPoint = Vector(*element["from"])
toPoint = Vector(*element["to"]) toPoint = Vector(*element["to"])
fromPoint /= 16. fromPoint /= 16.
toPoint /= 16. toPoint /= 16.
box = FloatBox(fromPoint, maximum=toPoint) box = FloatBox(fromPoint, maximum=toPoint)
for face, info in element["faces"].iteritems(): for face, info in element["faces"].iteritems():
texture = info["texture"] texture = info["texture"]
uv = info.get("uv", [0, 0, 16, 16]) uv = info.get("uv", [0, 0, 16, 16])
textureRotation = info.get("rotation") textureRotation = info.get("rotation")
if textureRotation is not None: if textureRotation is not None:
textureRotation %= 360 textureRotation %= 360
while textureRotation > 0: while textureRotation > 0:
uv = uv[3:] + uv[:3] uv = uv[3:] + uv[:3]
textureRotation -= 90 textureRotation -= 90
lastvar = texture lastvar = texture
# resolve texture variables # resolve texture variables
for i in range(30): for i in range(30):
if texture is None: if texture is None:
raise ValueError("Texture variable %s is not assigned." % lastvar) raise ValueError("Texture variable %s is not assigned." % lastvar)
elif texture[0] == "#": elif texture[0] == "#":
lastvar = texture lastvar = texture
texture = textureVars[texture[1:]] texture = textureVars[texture[1:]]
else:
break
else: else:
raise ValueError("Texture variable loop detected!") break
else:
raise ValueError("Texture variable loop detected!")
self.firstTextures.setdefault(name, texture) self.firstTextures.setdefault(name, texture)
self._textureNames.add(texture) self._textureNames.add(texture)
allQuads.append((box, facesByCardinal[face], texture, uv, info.get("cullface"), shade)) allQuads.append((box, facesByCardinal[face], texture, uv, info.get("cullface"), shade))
rotation = element.get("rotation") rotation = element.get("rotation")
if rotation is not None: if rotation is not None:
origin = rotation["origin"] origin = rotation["origin"]
axis = rotation["axis"] axis = rotation["axis"]
angle = rotation["angle"] angle = rotation["angle"]
rescale = rotation.get("rescale", False) rescale = rotation.get("rescale", False)
# construct rotation matrix, run quad vertices through it # construct rotation matrix, run quad vertices through it
self.modelQuads[block.internalName + block.blockState] = allQuads self.modelQuads[block.internalName + block.blockState] = allQuads
except Exception as e: except Exception as e:
log.error("Failed to parse variant of block %s\nelements:\n%s\ntextures:\n%s", name, log.error("Failed to parse variant of block %s\nelements:\n%s\ntextures:\n%s", name,
allElements, textureVars) allElements, textureVars)
raise raise
# for name in self.modelQuads: # for name in self.modelQuads:
# log.info("Quads for %s:\n%s\n", name, self.modelQuads[name]) # log.info("Quads for %s:\n%s\n", name, self.modelQuads[name])

File diff suppressed because it is too large Load Diff