diff --git a/src/mcedit2/rendering/blockmodels.py b/src/mcedit2/rendering/blockmodels.py index 18ee5a2..e32d202 100644 --- a/src/mcedit2/rendering/blockmodels.py +++ b/src/mcedit2/rendering/blockmodels.py @@ -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) diff --git a/src/mcedit2/rendering/chunkupdate.py b/src/mcedit2/rendering/chunkupdate.py index cf18051..c230359 100644 --- a/src/mcedit2/rendering/chunkupdate.py +++ b/src/mcedit2/rendering/chunkupdate.py @@ -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]