Models have directional shading, texture rotation is observed

This commit is contained in:
David Vierra 2014-12-31 15:59:14 -10:00
parent ee22c24ddd
commit 3f9c56c226
2 changed files with 80 additions and 55 deletions

View File

@ -39,9 +39,9 @@ class BlockModels(object):
self.cookedModels = {} # nameAndState -> [face -> xyzuv, cullface]
for block in blocktypes:
name = block.internalName.replace(blocktypes.namePrefix, "")
if name == "air":
if block.renderType != 3: # only rendertype 3 uses block models
continue
name = block.internalName.replace(blocktypes.namePrefix, "")
try:
statesJson = json.load(resourceLoader.openStream("blockstates/%s.json" % block.resourcePath))
except KeyError:
@ -62,17 +62,13 @@ class BlockModels(object):
# if not all keys in variantState are found in blockState, return false
if variantState == "all":
return True
try:
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
except:
log.info("MATCHING %s %s", variantState, blockState)
raise
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:
if variantBlockState != "normal" and not matchVariantState(variantBlockState, block.blockState):
@ -112,6 +108,8 @@ class BlockModels(object):
textureVars = {}
allElements = []
# grab textures and elements from this model, then get parent and merge its textures and elements
# continue until no parent is found
for i in range(30):
textures = modelDict.get("textures")
if textures is not None:
@ -127,10 +125,12 @@ class BlockModels(object):
raise ValueError("Parent loop detected in block model %s" % modelName)
try:
# each element describes a box with up to six faces, each with a texture. convert the box into
# quads.
allQuads = []
for element in allElements:
shade = element.get("shade", True)
fromPoint = Vector(*element["from"])
toPoint = Vector(*element["to"])
fromPoint /= 16.
@ -139,7 +139,17 @@ class BlockModels(object):
box = FloatBox(fromPoint, maximum=toPoint)
for face, info in element["faces"].iteritems():
texture = info["texture"]
uv = info.get("uv", [0, 0, 16, 16])
textureRotation = info.get("rotation")
if textureRotation is not None:
textureRotation %= 360
while textureRotation > 0:
uv = uv[3:] + uv[:3]
textureRotation -= 90
lastvar = texture
# resolve texture variables
for i in range(30):
if texture is None:
raise ValueError("Texture variable %s is not assigned." % lastvar)
@ -153,10 +163,18 @@ class BlockModels(object):
self.firstTextures.setdefault(name, texture)
self._textureNames.add(texture)
allQuads.append((box, facesByCardinal[face], texture, info.get("uv", [ 0, 0, 16, 16 ]),
info.get("cullface")))
allQuads.append((box, facesByCardinal[face], texture, uv, info.get("cullface"), shade))
rotation = element.get("rotation")
if rotation is not None:
origin = rotation["origin"]
axis = rotation["axis"]
angle = rotation["angle"]
rescale = rotation.get("rescale", False)
# construct rotation matrix, run quad vertices through it
# element["rotation"] xxxxxxxxxx
self.modelQuads[block.internalName + block.blockState] = allQuads
except Exception as e:
@ -175,7 +193,7 @@ class BlockModels(object):
cookedModels = {}
for nameAndState, allQuads in self.modelQuads.iteritems():
cookedQuads = []
for (box, face, texture, uv, cullface) in allQuads:
for (box, face, texture, uv, cullface, shade) in allQuads:
l, t, w, h = textureAtlas.texCoordsByName[texture]
u1, v1, u2, v2 = uv # xxxx (u2-u1) / w etc scale to texture width
u1 += l
@ -184,10 +202,13 @@ class BlockModels(object):
v2 += t
uv = (u1, v1, u2, v2)
xyzuv = getBlockFaceVertices(box, face, uv)
xyzuvc = getBlockFaceVertices(box, face, uv)
if cullface:
cullface = facesByCardinal[cullface]
cookedQuads.append((face, xyzuv, cullface))
if shade:
xyzuvc.shape = 4, 6
xyzuvc.view('uint8')[:, 20:] = faceShades[face]
cookedQuads.append((face, xyzuvc, cullface))
cookedModels[nameAndState] = cookedQuads
@ -203,58 +224,67 @@ facesByCardinal = dict(
)
faceShades = {
faces.FaceNorth: 0xBB,
faces.FaceSouth: 0xBB,
faces.FaceEast: 0xDD,
faces.FaceWest: 0xDD,
faces.FaceUp: 0xFF,
faces.FaceDown: 0x77,
}
# teutures = (u1, v1, u2, v1, u2, v2, u1, v2)
def getBlockFaceVertices(box, face, uv):
x, y, z, = box.origin
x1, y1, z1, = box.origin
x2, y2, z2 = box.maximum
u1, v1, u2, v2 = uv
if face == faces.FaceXDecreasing:
faceVertices = numpy.array(
(x, y, z, u1, v1,
x, y2, z, u1, v2,
x, y2, z2, u2, v2,
x, y, z2, u2, v1,
(x1, y1, z1, u1, v1, 0.0,
x1, y2, z1, u1, v2, 0.0,
x1, y2, z2, u2, v2, 0.0,
x1, y1, z2, u2, v1, 0.0,
), dtype='f4')
elif face == faces.FaceXIncreasing:
faceVertices = numpy.array(
(x2, y, z, u1, v1,
x2, y2, z, u1, v2,
x2, y2, z2, u2, v2,
x2, y, z2, u2, v1,
(x2, y1, z1, u1, v1, 0.0,
x2, y2, z1, u1, v2, 0.0,
x2, y2, z2, u2, v2, 0.0,
x2, y1, z2, u2, v1, 0.0,
), dtype='f4')
elif face == faces.FaceYDecreasing:
faceVertices = numpy.array(
(x2, y, z2, u1, v1,
x, y, z2, u1, v2,
x, y, z, u2, v2,
x2, y, z, u2, v1,
(x2, y1, z2, u1, v1, 0.0,
x1, y1, z2, u1, v2, 0.0,
x1, y1, z1, u2, v2, 0.0,
x2, y1, z1, u2, v1, 0.0,
), dtype='f4')
elif face == faces.FaceYIncreasing:
faceVertices = numpy.array(
(x2, y2, z, u1, v1,
x, y2, z, u1, v2,
x, y2, z2, u2, v2,
x2, y2, z2, u2, v1,
(x2, y2, z1, u1, v1, 0.0,
x1, y2, z1, u1, v2, 0.0,
x1, y2, z2, u2, v2, 0.0,
x2, y2, z2, u2, v1, 0.0,
), dtype='f4')
elif face == faces.FaceZDecreasing:
faceVertices = numpy.array(
(x, y, z, u1, v1,
x, y2, z, u1, v2,
x2, y2, z, u2, v2,
x2, y, z, u2, v1,
(x1, y1, z1, u1, v1, 0.0,
x1, y2, z1, u1, v2, 0.0,
x2, y2, z1, u2, v2, 0.0,
x2, y1, z1, u2, v1, 0.0,
), dtype='f4')
elif face == faces.FaceZIncreasing:
faceVertices = numpy.array(
(x2, y, z2, u1, v1,
x2, y2, z2, u1, v2,
x, y2, z2, u2, v2,
x, y, z2, u2, v1
(x2, y1, z2, u1, v1, 0.0,
x2, y2, z2, u1, v2, 0.0,
x1, y2, z2, u2, v2, 0.0,
x1, y1, z2, u2, v1, 0.0,
), dtype='f4')
else:
raise ValueError("Unknown face %s" % face)

View File

@ -442,13 +442,9 @@ class BlockModelMesh(object):
if block.renderType != 3: # only model blocks for now
continue
nameAndState = block.internalName + block.blockState
try:
quads = blockModels.cookedModels[nameAndState]
except KeyError as e:
log.exception("%s!\nModel keys: %s", e, pprint.pformat(blockModels.cookedModels.keys()))
raise SystemExit
quads = blockModels.cookedModels[nameAndState]
for face, xyzuv, cullface in quads:
for face, xyzuvc, cullface in quads:
if cullface is not None:
dx, dy, dz = cullface.vector
nx = x + dx
@ -460,9 +456,8 @@ class BlockModelMesh(object):
if nBlock.opaqueCube:
continue
verts = numpy.array(xyzuv)
verts.shape = 1, 4, 5
verts = numpy.array(xyzuvc)
verts.shape = 1, 4, 6
verts[..., :3] += (x - 1, y - 1 + (cy << 4), z - 1)
faceQuadVerts.append(verts)
# log.info("Block %s:\nVertices: %s", (x-1, y-1, z-1), verts)
@ -470,6 +465,6 @@ class BlockModelMesh(object):
# raise SystemExit
if len(faceQuadVerts):
vertexArray = VertexArrayBuffer(len(faceQuadVerts), lights=False)
vertexArray.buffer[..., :5] = numpy.vstack(faceQuadVerts)
vertexArray.buffer[..., :6] = numpy.vstack(faceQuadVerts)
self.vertexArrays = [vertexArray]