dump resourceVariants from minecraft
This commit is contained in:
parent
3f9c56c226
commit
8ce6571f88
@ -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
Reference in New Issue
Block a user