def makeChunkVertices(self, chunk, limitBox): tilePositions = [] defaultColor = (0xff, 0xff, 0x33, 0x44) for i, ref in enumerate(chunk.TileEntities): if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue if ref.id == "Control": continue tilePositions.append(ref.Position) if not len(tilePositions): return tiles = self._computeVertices(tilePositions, defaultColor, chunkPosition=chunk.chunkPosition) vertexNode = VertexNode([tiles]) polygonMode = PolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) vertexNode.addState(polygonMode) lineWidth = LineWidth(2.0) vertexNode.addState(lineWidth) depthFunc = DepthFunc(GL.GL_ALWAYS) vertexNode.addState(depthFunc) self.sceneNode = Node("tileEntityLocations") self.sceneNode.addChild(vertexNode) vertexNode = VertexNode([tiles]) self.sceneNode.addChild(vertexNode)
def makeChunkVertices(self, chunk, limitBox): monsterPositions = [] for i, entityRef in enumerate(chunk.Entities): if i % 10 == 0: yield ID = entityRef.id if ID in self.notMonsters: continue pos = entityRef.Position if limitBox and pos not in limitBox: continue monsterPositions.append(pos) monsters = self._computeVertices(monsterPositions, (0xff, 0x22, 0x22, 0x44), offset=True, chunkPosition=chunk.chunkPosition) yield vertexNode = VertexNode(monsters) polyNode = PolygonModeNode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) polyNode.addChild(vertexNode) lineNode = LineWidthNode(2.0) lineNode.addChild(polyNode) depthNode = DepthFuncNode(GL.GL_ALWAYS) depthNode.addChild(lineNode) self.sceneNode = Node() self.sceneNode.addChild(depthNode) vertexNode = VertexNode(monsters) self.sceneNode.addChild(vertexNode)
def makeChunkVertices(self, chunk, limitBox): monsterPositions = [] for i, entityRef in enumerate(chunk.Entities): if i % 10 == 0: yield ID = entityRef.id if ID in self.notMonsters: continue pos = entityRef.Position if limitBox and pos not in limitBox: continue monsterPositions.append(pos) if not len(monsterPositions): return monsters = self._computeVertices(monsterPositions, (0xff, 0x22, 0x22, 0x44), offset=True, chunkPosition=chunk.chunkPosition) yield vertexNode = VertexNode(monsters) vertexNode.addState(PolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)) vertexNode.addState(LineWidth(2.0)) vertexNode.addState(DepthFunc(GL.GL_ALWAYS)) self.sceneNode = Node("monsterLocations") self.sceneNode.addChild(vertexNode) vertexNode = VertexNode(monsters) self.sceneNode.addChild(vertexNode)
def makeChunkVertices(self, chunk, limitBox): mapTiles = [] for i, ref in enumerate(chunk.Entities): if ref.id != "ItemFrame": continue if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue try: item = ref.Item if item.itemType.internalName != "minecraft:filled_map": continue except KeyError: log.exception( "Error while getting ItemFrame item ID in frame at %s", ref.TilePos) continue mapID = item.Damage mapTex = self.chunkUpdate.updateTask.getMapTexture(mapID) # xxx if mapTex is None: mapTex = missingNoTex # xxxx assumes 1.8 TilePos - fix this in ref?? mapTiles.append((mapTex, ref.TilePos, ref.Facing)) if not len(mapTiles): return nodes = [] for mapTex, (x, y, z), facing in mapTiles: vertexBuffer = QuadVertexArrayBuffer(1, lights=False, textures=True) # chunk is already translated - why? x -= chunk.cx << 4 z -= chunk.cz << 4 vertexBuffer.vertex[:] = x, y, z corners = self.faceCorners[facing] vertexBuffer.vertex[:] += corners texCorners = [(1, 1), (1, 0), (0, 0), (0, 1)] vertexBuffer.texcoord[:] += texCorners vertexNode = VertexNode([vertexBuffer]) if mapTex is not None: bindTexture = BindTexture(mapTex) vertexNode.addState(bindTexture) nodes.append(vertexNode) self.sceneNode = scenenode.Node("itemFrames") for node in nodes: self.sceneNode.addChild(node)
def makeChunkVertices(self, chunk, limitBox): mapTiles = [] for i, ref in enumerate(chunk.Entities): if ref.id != "ItemFrame": continue if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue try: item = ref.Item if item.itemType.internalName != "minecraft:filled_map": continue except KeyError: log.exception("Error while getting ItemFrame item ID in frame at %s", ref.TilePos) continue mapID = item.Damage mapTex = self.chunkUpdate.updateTask.getMapTexture(mapID) # xxx if mapTex is None: mapTex = missingNoTex # xxxx assumes 1.8 TilePos - fix this in ref?? mapTiles.append((mapTex, ref.TilePos, ref.Facing)) if not len(mapTiles): return nodes = [] for mapTex, (x, y, z), facing in mapTiles: vertexBuffer = QuadVertexArrayBuffer(1, lights=False, textures=True) # chunk is already translated - why? x -= chunk.cx << 4 z -= chunk.cz << 4 vertexBuffer.vertex[:] = x, y, z corners = self.faceCorners[facing] vertexBuffer.vertex[:] += corners texCorners = [(1, 1), (1, 0), (0, 0), (0, 1)] vertexBuffer.texcoord[:] += texCorners vertexNode = VertexNode([vertexBuffer]) if mapTex is not None: bindTexture = BindTexture(mapTex) vertexNode.addState(bindTexture) nodes.append(vertexNode) self.sceneNode = scenenode.Node("itemFrames") for node in nodes: self.sceneNode.addChild(node)
def entityModelNode(ref, model, modelTex, chunk): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0] // 4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1 / 16. modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1 / 64. modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=True) vertexBuffer.vertex[:] = modelVerts[..., :3] vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) rotate = Rotate(ref.Rotation[0], (0., 1., 0.)) node.addState(rotate) translate = Translate((ref.Position - (chunk.cx << 4, 0, chunk.cz << 4))) node.addState(translate) bindTexture = BindTexture(modelTex, (1. / model.texWidth, 1. / model.texHeight, 1)) node.addState(bindTexture) return node
def entityModelNode(ref, model, modelTex=None, chunk=None, flip=False): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0] // 4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1 / 16. modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1 / 64. modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=modelTex is not None) vertexBuffer.vertex[:] = modelVerts[..., :3] if modelTex is not None: vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) pos = ref.Position if chunk is not None: pos = pos - (chunk.cx << 4, 0, chunk.cz << 4) translate = Translate(pos) node.addState(translate) rotate = Rotate(ref.Rotation[0], (0., 1., 0.)) node.addState(rotate) if modelTex is not None: bindTexture = BindTexture(modelTex, (1. / model.texWidth, 1. / model.texHeight * (-1 if flip else 1), 1)) node.addState(bindTexture) return node
def makeChunkVertices(self, chunk, limitBox): entityPositions = [] entityColors = [] colorMap = { "Item": (0x22, 0xff, 0x22, 0x5f), "XPOrb": (0x88, 0xff, 0x88, 0x5f), "Painting": (134, 96, 67, 0x5f), } for i, entityRef in enumerate(chunk.Entities): if i % 10 == 0: yield color = colorMap.get(entityRef.id) if color is None: continue pos = entityRef.Position if limitBox and pos not in limitBox: continue entityPositions.append(pos) entityColors.append(color) items = self._computeVertices(entityPositions, entityColors, offset=True, chunkPosition=chunk.chunkPosition) yield self.sceneNode = VertexNode(items)
def loadSections(self): selection = self.renderSelection if selection is None: self.loadTimer.setInterval(333) return else: self.loadTimer.setInterval(0) for cx, cz in selection.chunkPositions(): if self.groupNode.containsChunkNode((cx, cz)): continue vertexArrays = [] for cy in selection.sectionPositions(cx, cz): box = SectionBox(cx, cy, cz).expand(1) mask = selection.box_mask(box) if mask is not None: vertexArrays.extend(self.buildSection(mask, cy)) if len(vertexArrays): chunkNode = ChunkNode((cx, cz)) vertexNode = VertexNode(vertexArrays) chunkNode.addChild(vertexNode) self.groupNode.addChunkNode(chunkNode) yield self.loadTimer.setInterval(333)
def makeChunkVertices(self, chunk, limitBox): tilePositions = [] tileColors = [] defaultColor = (0xff, 0xff, 0x33, 0x44) for i, ref in enumerate(chunk.TileEntities): if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue if ref.id == "Control": cmdText = ref.Command if len(cmdText): if cmdText[0] == "/": cmdText = cmdText[1:] command, _ = cmdText.split(None, 1) color = commandColor(command) tileColors.append(color + (0x44, )) else: tileColors.append(defaultColor) else: continue tilePositions.append(ref.Position) tiles = self._computeVertices(tilePositions, tileColors, chunkPosition=chunk.chunkPosition) vertexNode = VertexNode([tiles]) self.sceneNode = vertexNode
def makeChunkVertices(self, chunk, _limitBox): neighbors = self.chunkUpdate.neighboringChunks def getpop(face): ch = neighbors.get(face) if ch: return getattr(ch, "TerrainPopulated", True) else: return True pop = getattr(chunk, "TerrainPopulated", True) yield if pop: return visibleFaces = [ getpop(faces.FaceXIncreasing), getpop(faces.FaceXDecreasing), True, True, getpop(faces.FaceZIncreasing), getpop(faces.FaceZDecreasing), ] visibleFaces = numpy.array(visibleFaces, dtype='bool') verts = self.vertexTemplate[visibleFaces] buffer = QuadVertexArrayBuffer(0, textures=False, lights=False) buffer.buffer = verts self.sceneNode = VertexNode(buffer) yield
def LineStripNode(points, rgba): vertexArray = VertexArrayBuffer(len(points), GL.GL_LINE_STRIP, False, False) vertexArray.vertex[:] = points vertexArray.rgba[:] = rgba node = VertexNode([vertexArray]) return node
def __init__(self, small=False): super(CompassNode, self).__init__() self.small = small v = QuadVertexArrayBuffer(1, textures=True) v.vertex[..., :2] = makeQuad(-.1, -.1, 0.2, 0.2) v.texcoord[:] = makeQuad(0, 0, 1, 1) v.rgba[:] = 0xff self.vertexNode = VertexNode([v]) self.pitchState = Rotate(0, (1., 0., 0.)) self.yawState = Rotate(0, (0., 0., 1.)) self.addState(Identity()) self.addState(Translate((0.9, 0.1, 0.0))) self.addState(self.pitchState) self.addState(self.yawState) self.addState(Disable(GL.GL_DEPTH_TEST)) self.addState(Enable(GL.GL_BLEND, GL.GL_TEXTURE_2D)) if small: filename = "compass_small.png" else: filename = "compass.png" self._tex = loadPNGTexture(filename, minFilter=GL.GL_LINEAR, magFilter=GL.GL_LINEAR) self.textureState = BindTexture(self._tex) self.addState(self.textureState) self.addChild(self.vertexNode)
def entityModelNode(ref, model, modelTex=None, chunk=None, flip=False): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1/16. modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1/64. modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=modelTex is not None) vertexBuffer.vertex[:] = modelVerts[..., :3] if modelTex is not None: vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) pos = ref.Position if chunk is not None: pos = pos - (chunk.cx << 4, 0, chunk.cz << 4) translate = Translate(pos) node.addState(translate) rotate = Rotate(ref.Rotation[0], (0., 1., 0.)) node.addState(rotate) if modelTex is not None: bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight * (-1 if flip else 1), 1)) node.addState(bindTexture) return node
def makeChunkVertices(self, chunk, limitBox): tilePositions = [] tileColors = [] defaultColor = (0xff, 0x33, 0x33, 0x44) for i, ref in enumerate(chunk.TileEntities): if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue if ref.id == "Control": tilePositions.append(ref.Position) cmdText = ref.Command if len(cmdText): if cmdText[0] == "/": cmdText = cmdText[1:] command, _ = cmdText.split(None, 1) color = commandColor(command) tileColors.append(color + (0x44,)) else: tileColors.append(defaultColor) else: continue tiles = self._computeVertices(tilePositions, tileColors, chunkPosition=chunk.chunkPosition) vertexNode = VertexNode([tiles]) vertexNode.addState(PolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)) vertexNode.addState(LineWidth(2.0)) vertexNode.addState(DepthFunc(GL.GL_ALWAYS)) self.sceneNode = Node() self.sceneNode.addChild(vertexNode)
def renderSceneNodes(self): vertexArray = VertexArrayBuffer(2, GL.GL_LINES, False, False) vertexArray.vertex[:] = [self.p1, self.p2] vertexArray.vertex[:] += 0.5 # draw using box centers vertexArray.rgba[:] = self.glColor node = VertexNode([vertexArray]) # xxx LineNode return [node]
def makeChunkVertices(self, chunk, limitBox): if hasattr(chunk, "TileTicks"): ticks = chunk.TileTicks if len(ticks): self.sceneNode = VertexNode( self._computeVertices([[t[i].value for i in "xyz"] for t in ticks], (0xff, 0xff, 0xff, 0x44), chunkPosition=chunk.chunkPosition)) yield
def makeChunkVertices(self, chunk, _limitBox): positions = chunk.sectionPositions() buffer = VertexArrayBuffer((len(positions), 6, 4), GL.GL_LINE_STRIP, textures=False, lights=False) for i, cy in enumerate(positions): buffer.buffer[i, :] = self.vertexTemplate buffer.vertex[i, ..., 1] += cy * 16 self.sceneNode = VertexNode(buffer) yield
def renderSceneNodes(self, symbol_list): points = [] for cell in symbol_list: if not isinstance(cell, Cell): continue points.append(cell.origin) vertexArray = VertexArrayBuffer(len(points), GL.GL_LINE_STRIP, False, False) vertexArray.vertex[:] = points vertexArray.vertex[:] += 0.5 # draw using box centers vertexArray.rgba[:] = [(255, 0, 255, 255)] node = VertexNode([vertexArray]) # xxx LineNode return [node]
def makeChunkVertices(self, chunk, limitBox): """ :param chunk: :type chunk: WorldEditorChunk :param limitBox: :return: :raise: """ if not hasattr(chunk, 'HeightMap') or chunk.HeightMap is None: return heightMap = chunk.HeightMap chunkWidth = chunkLength = 16 chunkHeight = chunk.dimension.bounds.height z, x = list(numpy.indices((chunkLength, chunkWidth))) y = (heightMap - 1)[:chunkLength, :chunkWidth] numpy.clip(y, 0, chunkHeight - 1, y) nonZeroHeights = y > 0 x = x[nonZeroHeights] if not len(x): return z = z[nonZeroHeights] y = y[nonZeroHeights] yield vertexBuffer = QuadVertexArrayBuffer(len(x), textures=False, lights=False) vertexBuffer.vertex[..., 0] = x[:, numpy.newaxis] vertexBuffer.vertex[..., 1] = y[:, numpy.newaxis] vertexBuffer.vertex[..., 2] = z[:, numpy.newaxis] vertexBuffer.vertex[:] += standardCubeTemplates[faces.FaceYIncreasing, ..., :3] vertexBuffer.rgba[:] = (0xff, 0x00, 0xff, 0x9f) self.sceneNode = VertexNode(vertexBuffer) yield
def axis(self, axis): self._axis = axis self.dirty = True gridSize = 64 left = -gridSize // 2 right = gridSize // 2 gridArrayBuffer = VertexArrayBuffer((gridSize * 4, ), GL.GL_LINES, textures=False, lights=False) gridArrayBuffer.rgba[:] = 255, 255, 255, 100 # y=0, move by translating gridArrayBuffer.vertex[:, axis] = 0 axis1 = (axis - 1) % 3 axis2 = (axis + 1) % 3 # left edge gridArrayBuffer.vertex[0:gridSize * 2:2, axis2] = left gridArrayBuffer.vertex[0:gridSize * 2:2, axis1] = range(left, right) # right edge gridArrayBuffer.vertex[1:gridSize * 2:2, axis2] = right - 1 gridArrayBuffer.vertex[1:gridSize * 2:2, axis1] = range(left, right) # bottom edge gridArrayBuffer.vertex[gridSize * 2::2, axis1] = left gridArrayBuffer.vertex[gridSize * 2::2, axis2] = range(left, right) # top edge gridArrayBuffer.vertex[gridSize * 2 + 1::2, axis1] = right - 1 gridArrayBuffer.vertex[gridSize * 2 + 1::2, axis2] = range(left, right) if self.vertexNode: self.translateNode.removeChild(self.vertexNode) self.vertexNode = VertexNode([gridArrayBuffer]) self.translateNode.addChild(self.vertexNode)
def makeChunkVertices(self, chunk, limitBox): tilePositions = [] tileColors = [] defaultColor = (0xff, 0x33, 0x33, 0x44) for i, ref in enumerate(chunk.TileEntities): if i % 10 == 0: yield if limitBox and ref.Position not in limitBox: continue if ref.id == "Control": tilePositions.append(ref.Position) cmdText = ref.Command if len(cmdText): if cmdText[0] == "/": cmdText = cmdText[1:] command, _ = cmdText.split(None, 1) color = commandColor(command) tileColors.append(color + (0x44, )) else: tileColors.append(defaultColor) else: continue if not len(tileColors): return tiles = self._computeVertices(tilePositions, tileColors, chunkPosition=chunk.chunkPosition) vertexNode = VertexNode([tiles]) vertexNode.addState(PolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)) vertexNode.addState(LineWidth(2.0)) vertexNode.addState(DepthFunc(GL.GL_ALWAYS)) self.sceneNode = Node("commandBlockLocations") self.sceneNode.addChild(vertexNode)
def chestEntityModelNode(ref, model, modelTex, chunk, facing, largeX, largeZ): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0] // 4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1 / 16. # modelVerts[..., 1] = -modelVerts[..., 1] # modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=True) vertexBuffer.vertex[:] = modelVerts[..., :3] vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) rotations = {"north": 180, "east": 270, "south": 0, "west": 90} decenterTranslateNode = TranslateNode((-0.5, -0.5, -0.5)) decenterTranslateNode.addChild(node) rotateNode = RotateNode(rotations[facing], (0., 1., 0.)) # rotateNode = RotateNode(0, (0., 1., 0.)) rotateNode.addChild(decenterTranslateNode) dx = dz = 0 if largeX and facing == "north": dx = 1. if largeZ and facing == "east": dz = -1. recenterTranslateNode = TranslateNode((0.5 + dx, 0.5, 0.5 + dz)) recenterTranslateNode.addChild(rotateNode) x, y, z = (ref.Position - (chunk.cx << 4, 0, chunk.cz << 4)) scaleNode = ScaleNode((1., -1., -1.)) scaleNode.addChild(recenterTranslateNode) posTranslateNode = TranslateNode((x, y + 1., z + 1.)) posTranslateNode.addChild(scaleNode) textureNode = BindTextureNode( modelTex, (1. / model.texWidth, 1. / model.texHeight, 1)) textureNode.addChild(posTranslateNode) return textureNode
def entityModelNode(ref, model, modelTex, chunk): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1/16. modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1/64. modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=True) vertexBuffer.vertex[:] = modelVerts[..., :3] vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) rotate = Rotate(ref.Rotation[0], (0., 1., 0.)) node.addState(rotate) translate = Translate((ref.Position - (chunk.cx << 4, 0, chunk.cz << 4))) node.addState(translate) bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight, 1)) node.addState(bindTexture) return node
def makeChunkVertices(self, chunk, limitBox): """ :param chunk: :type chunk: WorldEditorChunk :param limitBox: :return: :raise: """ dim = chunk.dimension cx, cz = chunk.chunkPosition if not hasattr(chunk, 'HeightMap') or chunk.HeightMap is None: return heightMap = chunk.HeightMap chunkWidth = chunkLength = 16 chunkHeight = chunk.dimension.bounds.height z, x = list(numpy.indices((chunkLength, chunkWidth))) y = (heightMap - 1)[:chunkLength, :chunkWidth] numpy.clip(y, 0, chunkHeight - 1, y) nonZeroHeights = y > 0 heights = y.reshape((16, 16)) x = x[nonZeroHeights] if not len(x): return z = z[nonZeroHeights] y = y[nonZeroHeights] # Get the top block in each column blockResult = dim.getBlocks(x + (cx * 16), y, z + (cz * 16), return_Data=True) topBlocks = blockResult.Blocks topBlockData = blockResult.Data # Get the block above each column top. We'll recolor the top face of the column if a flower or another # transparent block is on top. aboveY = y + 1 numpy.clip(aboveY, 0, chunkHeight - 1, aboveY) blocksAbove = dim.getBlocks(x + (cx * 16), aboveY, z + (cz * 16)).Blocks flatcolors = dim.blocktypes.mapColor[topBlocks, topBlockData][:, numpy.newaxis, :] yield vertexBuffer = QuadVertexArrayBuffer(len(x), textures=False, lights=False) vertexBuffer.vertex[..., 0] = x[:, numpy.newaxis] vertexBuffer.vertex[..., 1] = y[:, numpy.newaxis] vertexBuffer.vertex[..., 2] = z[:, numpy.newaxis] va0 = vertexBuffer.copy() va0.vertex[:] += standardCubeTemplates[faces.FaceYIncreasing, ..., :3] overmask = blocksAbove > 0 colors = dim.blocktypes.mapColor[:, 0][blocksAbove[overmask]][:, numpy.newaxis] flatcolors[overmask] = colors if self.detailLevel == 2: heightfactor = (y / float(chunk.dimension.bounds.height)) * 0.33 + 0.66 flatcolors[..., :3] *= heightfactor[:, numpy.newaxis, numpy.newaxis] # xxx implicit cast from byte to float and back va0.rgb[:] = flatcolors yield if self.detailLevel == 2: self.sceneNode = VertexNode(va0) return # Calculate how deep each column needs to go to be flush with the adjacent column; # If columns extend all the way down, performance suffers due to fill rate. depths = numpy.zeros((chunkWidth, chunkLength), dtype='uint16') depths[1:-1, 1:-1] = reduce(numpy.minimum, (heights[1:-1, :-2], heights[1:-1, 2:], heights[:-2, 1:-1], heights[2:, 1:-1])) depths = depths[nonZeroHeights] yield va1 = vertexBuffer.copy() va1.vertex[..., :3] += standardCubeTemplates[faces.FaceXIncreasing, ..., :3] va1.vertex[:, 0, 1] = depths va1.vertex[:, 0, 1] = depths # stretch to floor va1.vertex[:, (2, 3), 1] -= 0.5 # drop down to prevent intersection pixels numpy.multiply(flatcolors, 0.8, out=flatcolors, casting='unsafe') #flatcolors *= 0.8 va1.rgb[:] = flatcolors grassmask = topBlocks == 2 # color grass sides with dirt's color va1.rgb[grassmask] = dim.blocktypes.mapColor[:, 0][[3]][:, numpy.newaxis] va2 = va1.copy() va1.vertex[:, (1, 2), 0] -= 1.0 # turn diagonally va2.vertex[:, (0, 3), 0] -= 1.0 # turn diagonally nodes = [VertexNode(v) for v in (va1, va2, va0)] self.sceneNode = scenenode.Node() for node in nodes: self.sceneNode.addChild(node)
def chestEntityModelNode(ref, model, modelTex, chunk, facing, largeX, largeZ): modelVerts = numpy.array(model.vertices) modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1] # scale down modelVerts[..., :3] *= 1/16. # modelVerts[..., 1] = -modelVerts[..., 1] # modelVerts[..., 0] = -modelVerts[..., 0] vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=True) vertexBuffer.vertex[:] = modelVerts[..., :3] vertexBuffer.texcoord[:] = modelVerts[..., 3:5] node = VertexNode([vertexBuffer]) rotations = { "north": 180, "east": 270, "south": 0, "west": 90 } decenterState = Translate((-0.5, -0.5, -0.5)) node.addState(decenterState) rotate = Rotate(rotations[facing], (0., 1., 0.)) node.addState(rotate) dx = dz = 0 if largeX and facing == "north": dx = 1. if largeZ and facing == "east": dz = -1. recenterState = Translate((0.5 + dx, 0.5, 0.5 + dz)) node.addState(recenterState) x, y, z = (ref.Position - (chunk.cx << 4, 0, chunk.cz << 4)) scale = Scale((1., -1., -1.)) node.addState(scale) posTranslate = Translate((x, y + 1., z + 1.)) node.addState(posTranslate) bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight, 1)) node.addState(bindTexture) return node
def makeChunkVertices(self, chunk, limitBox): """ :param chunk: :type chunk: WorldEditorChunk :param limitBox: :return: :raise: """ dim = chunk.dimension cx, cz = chunk.chunkPosition if not hasattr(chunk, 'HeightMap') or chunk.HeightMap is None: return heightMap = chunk.HeightMap chunkWidth = chunkLength = 16 chunkHeight = chunk.dimension.bounds.height z, x = list(numpy.indices((chunkLength, chunkWidth))) y = (heightMap - 1)[:chunkLength, :chunkWidth] numpy.clip(y, 0, chunkHeight - 1, y) nonZeroHeights = y > 0 heights = y.reshape((16, 16)) x = x[nonZeroHeights] if not len(x): return z = z[nonZeroHeights] y = y[nonZeroHeights] # Get the top block in each column blockResult = dim.getBlocks(x + (cx * 16), y, z + (cz * 16), return_Data=True) topBlocks = blockResult.Blocks topBlockData = blockResult.Data # Get the block above each column top. We'll recolor the top face of the column if a flower or another # transparent block is on top. aboveY = y + 1 numpy.clip(aboveY, 0, chunkHeight - 1, aboveY) blocksAbove = dim.getBlocks(x + (cx * 16), aboveY, z + (cz * 16)).Blocks flatcolors = dim.blocktypes.mapColor[topBlocks, topBlockData][:, numpy.newaxis, :] yield vertexBuffer = QuadVertexArrayBuffer(len(x), textures=False, lights=False) vertexBuffer.vertex[..., 0] = x[:, numpy.newaxis] vertexBuffer.vertex[..., 1] = y[:, numpy.newaxis] vertexBuffer.vertex[..., 2] = z[:, numpy.newaxis] va0 = vertexBuffer.copy() va0.vertex[:] += standardCubeTemplates[faces.FaceYIncreasing, ..., :3] overmask = blocksAbove > 0 colors = dim.blocktypes.mapColor[:, 0][ blocksAbove[overmask]][:, numpy.newaxis] flatcolors[overmask] = colors if self.detailLevel == 2: heightfactor = (y / float(chunk.dimension.bounds.height)) * 0.33 + 0.66 flatcolors[ ..., : 3] *= heightfactor[:, numpy.newaxis, numpy. newaxis] # xxx implicit cast from byte to float and back va0.rgb[:] = flatcolors yield if self.detailLevel == 2: self.sceneNode = VertexNode(va0) return # Calculate how deep each column needs to go to be flush with the adjacent column; # If columns extend all the way down, performance suffers due to fill rate. depths = numpy.zeros((chunkWidth, chunkLength), dtype='uint16') depths[1:-1, 1:-1] = reduce(numpy.minimum, (heights[1:-1, :-2], heights[1:-1, 2:], heights[:-2, 1:-1], heights[2:, 1:-1])) depths = depths[nonZeroHeights] yield va1 = vertexBuffer.copy() va1.vertex[..., :3] += standardCubeTemplates[faces.FaceXIncreasing, ..., :3] va1.vertex[:, 0, 1] = depths va1.vertex[:, 0, 1] = depths # stretch to floor va1.vertex[:, (2, 3), 1] -= 0.5 # drop down to prevent intersection pixels numpy.multiply(flatcolors, 0.8, out=flatcolors, casting='unsafe') #flatcolors *= 0.8 va1.rgb[:] = flatcolors grassmask = topBlocks == 2 # color grass sides with dirt's color va1.rgb[grassmask] = dim.blocktypes.mapColor[:, 0][[3]][:, numpy.newaxis] va2 = va1.copy() va1.vertex[:, (1, 2), 0] -= 1.0 # turn diagonally va2.vertex[:, (0, 3), 0] -= 1.0 # turn diagonally nodes = [VertexNode(v) for v in (va1, va2, va0)] self.sceneNode = scenenode.Node() for node in nodes: self.sceneNode.addChild(node)
def makeChunkVertices(self, chunk, limitBox): """ :param chunk: :type chunk: WorldEditorChunk :param limitBox: :return: :raise: """ vertexes = [] blocktypes = chunk.blocktypes for cy in chunk.sectionPositions(): section = chunk.getSection(cy) if section is None: continue blockLight = section.BlockLight skyLight = section.SkyLight blocks = section.Blocks # This `!= 0` is weird. blocktypes.normalCube has dtype 'uint8'; numpy 1.10 # refuses to perform an `&` between a 'uint8' and a 'bool'; so we use `!= 0` # to coerce the 'uint8' to a 'bool' # # If blocktypes.normalCube and other arrays on blocktypes were changed to # 'bool', Cython will refuse to coerce the arrays to typed memoryviews, # claiming the array format string '?' is not understood. normalCube = blocktypes.normalCube[blocks] != 0 materialLiquid = blocktypes.materialLiquid[blocks] != 0 # A block can spawn monsters if: # the block is not a normal cube # the block is not a liquid # the block above is not a normal cube # the block below has a solid top surface # the block below is not bedrock or barrier # And the block's light level: # blockLight < 8 AND skyLight < 8 will always spawn monsters # blockLight < 8 AND skyLight >= 8 will only spawn monsters at night # A block "has a solid top surface" if: # it is opaque and is a full cube OR # it is a stairs of type "half=top" OR # it is a slab of type "half=top" OR # it is a hopper OR # it is a snow layer of type "level==7" # f**k it validBelowBlocks = normalCube & (blocks != blocktypes['minecraft:bedrock'].ID) if 'minecraft:barrier' in blocktypes: validBelowBlocks &= (blocks != blocktypes['minecraft:barrier'].ID) lowBlockLight = blockLight < 8 lowNightLight = lowBlockLight & (skyLight < 8) lowDayLight = lowBlockLight & (skyLight >= 8) validBlocks = normalCube == 0 # block is not normal validBlocks &= materialLiquid == 0 # block is not liquid validBlocks[:-1] &= normalCube[1:] == 0 # block above is not normal validBlocks[1:] &= validBelowBlocks[:-1] # block below has solid top surface belowSection = chunk.getSection(cy-1) if belowSection: belowSectionBlocks = belowSection.Blocks[-1:] validBlocks[:1] &= blocktypes.normalCube[belowSectionBlocks] != 0 else: validBlocks[:1] = 0 aboveSection = chunk.getSection(cy+1) if aboveSection: validBlocks[-1:] &= blocktypes.normalCube[aboveSection.Blocks[:1]] == 0 def getVertexes(mask, color): y, z, x = mask.nonzero() vertexBuffer = QuadVertexArrayBuffer(len(x), textures=False, lights=False) vertexBuffer.vertex[..., 0] = x[:, None] vertexBuffer.vertex[..., 1] = y[:, None] vertexBuffer.vertex[..., 2] = z[:, None] vertexBuffer.vertex[:] += (0, (cy << 4), 0) vertexBuffer.vertex[:] += standardCubeTemplates[faces.FaceYDecreasing, ..., :3] vertexBuffer.rgba[:] = color return vertexBuffer nightVertexes = getVertexes(lowNightLight & validBlocks, (0xff, 0x00, 0x00, 0x6f)) dayVertexes = getVertexes(lowDayLight & validBlocks, (0xff, 0xFF, 0x00, 0x6f)) vertexes.append(dayVertexes) vertexes.append(nightVertexes) self.sceneNode = VertexNode(vertexes) yield