def __init__(self, editorSession, *args, **kwargs): super(MoveTool, self).__init__(editorSession, *args, **kwargs) self.overlayNode = scenenode.Node("moveOverlay") self._currentImport = None self._currentImportNode = None self.toolWidget = QtGui.QWidget() self.pointInput = CoordinateWidget() self.pointInput.pointChanged.connect(self.pointInputChanged) self.rotationInput = RotationWidget() self.rotationInput.rotationChanged.connect(self.rotationChanged) self.copyOptionsWidget = QtGui.QGroupBox(self.tr("Options")) self.copyAirCheckbox = QtGui.QCheckBox(self.tr("Copy Air")) self.copyOptionsWidget.setLayout(Column(self.copyAirCheckbox)) confirmButton = QtGui.QPushButton( "Confirm") # xxxx should be in worldview confirmButton.clicked.connect(self.confirmImport) self.toolWidget.setLayout( Column(self.pointInput, self.rotationInput, self.copyOptionsWidget, confirmButton, None))
def __init__(self, editorSession): """ :param editorSession: :type editorSession: mcedit2.editorsession.EditorSession :return: :rtype: """ super(InspectorWidget, self).__init__() load_ui("inspector.ui", baseinstance=self) self.editorSession = editorSession self.blockNBTEditor.editorSession = self.editorSession self.entityNBTEditor.editorSession = self.editorSession self.chunkNBTEditor.editorSession = self.editorSession self.blockEditorWidget = None self.tileEntity = None self.entity = None self.currentChunk = None # xxxx unused! how! self.selectionNode = None self.overlayNode = scenenode.Node() self.chunkTabWidget.currentChanged.connect(self.chunkTabDidChange) self.terrainPopulatedInput.toggled.connect( self.terrainPopulatedDidChange) self.lightPopulatedInput.toggled.connect(self.lightPopulatedDidChange) self.inhabitedTimeInput.valueChanged.connect( self.inhabitedTimeDidChange) self.updateTimeInput.valueChanged.connect(self.updateTimeDidChange)
def createSceneGraph(self): sceneGraph = scenenode.Node("WorldView SceneGraph") self.worldScene = self.createWorldScene() self.worldScene.setVisibleLayers( self.layerToggleGroup.getVisibleLayers()) clearNode = ClearNode() self.skyNode = sky.SkyNode() self.loadableChunksNode = loadablechunks.LoadableChunksNode( self.dimension) self.worldNode = Node("World Container") self.matrixState = MatrixState() self.worldNode.addState(self.matrixState) self._updateMatrices() self.worldNode.addChild(self.loadableChunksNode) self.worldNode.addChild(self.worldScene) self.worldNode.addChild(self.overlayNode) sceneGraph.addChild(clearNode) sceneGraph.addChild(self.skyNode) sceneGraph.addChild(self.worldNode) sceneGraph.addChild(self.compassNode) if self.cursorNode: self.worldNode.addChild(self.cursorNode) return sceneGraph
def makeChunkVertices(self, chunk, limitBox): sceneNode = scenenode.Node("monsters") for i, ref in enumerate(chunk.Entities): ID = ref.id if ID not in models.cookedModels: continue model = models.cookedModels[ID] texturePath = models.getModelTexture(ref) if texturePath is None: modelTex = None else: modelTex = self.chunkUpdate.updateTask.getModelTexture( texturePath) node = entityModelNode(ref, model, modelTex, chunk) sceneNode.addChild(node) if ID == "Sheep": woolID = "MCEDIT_SheepWool" model = models.cookedModels[woolID] texturePath = models.getTexture(woolID) modelTex = self.chunkUpdate.updateTask.getModelTexture( texturePath) node = entityModelNode(ref, model, modelTex, chunk) sceneNode.addChild(node) yield if not sceneNode.childCount(): return self.sceneNode = sceneNode
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 __init__(self, editorSession, *args, **kwargs): """ :type editorSession: EditorSession """ super(SelectionTool, self).__init__(editorSession, *args, **kwargs) toolWidget = QtGui.QWidget() editorSession.selectionChanged.connect(self.selectionDidChange) self.toolWidget = toolWidget self.optionsButton = QtGui.QPushButton(self.tr("Options")) self.optionsMenu = QtGui.QMenu() self.optionsButton.setMenu(self.optionsMenu) classicSelectionAction = self.optionsMenu.addAction( self.tr("Classic Selection")) stickySelectionAction = self.optionsMenu.addAction( self.tr("Sticky Selection")) self.coordInput = SelectionCoordinateWidget() self.coordInput.boxChanged.connect(self.coordInputChanged) self.shapeInput = ShapeWidget(addShapes=[ChunkShape()]) self.shapeInput.shapeChanged.connect(self.shapeDidChange) self.shapeInput.shapeOptionsChanged.connect(self.shapeDidChange) self.toolWidget.setLayout( Column(self.optionsButton, self.coordInput, self.shapeInput, None)) self.cursorNode = SelectionCursor() self.overlayNode = scenenode.Node("selectOverlay") self.faceHoverNode = SelectionFaceNode() self.selectionNode = SelectionScene() self.overlayNode.addChild(self.selectionNode) self.overlayNode.addChild(self.faceHoverNode) self.boxHandleNode = BoxHandle() self.boxHandleNode.boundsChanged.connect(self.boxHandleResized) self.boxHandleNode.boundsChangedDone.connect(self.boxHandleResizedDone) self.overlayNode.addChild(self.boxHandleNode) self.newSelectionNode = None classicSelectionAction.setCheckable(True) classicSelectionAction.toggled.connect(ClassicSelectionOption.setValue) classicSelectionAction.setChecked(ClassicSelectionOption.value()) ClassicSelectionOption.connectAndCall(self.setClassicSelection) stickySelectionAction.setCheckable(True) stickySelectionAction.toggled.connect(StickySelectionOption.setValue) stickySelectionAction.setChecked(StickySelectionOption.value()) StickySelectionOption.connectAndCall(self.setStickySelection) editorSession.dimensionChanged.connect(self.dimensionDidChange) editorSession.revisionChanged.connect(self.revisionDidChange)
def __init__(self, editorSession): """ :param editorSession: :type editorSession: mcedit2.editorsession.EditorSession :return: :rtype: """ super(InspectorWidget, self).__init__() self.setupUi(self) self.editorSession = editorSession self.blockNBTEditor.editorSession = self.editorSession self.entityNBTEditor.editorSession = self.editorSession self.chunkNBTEditor.editorSession = self.editorSession self.blockEditorWidget = None self.tileEntity = None self.entity = None self.blockPos = None self.currentChunk = None self.overlayNode = scenenode.Node("inspectorOverlay") self.selectionNode = SelectionBoxNode() self.selectionNode.depth = depths.DepthOffsets.SelectionCursor self.selectionNode.filled = False self.selectionNode.wireColor = (0.2, 0.9, .2, .8) self.overlayNode.addChild(self.selectionNode) self.commandBlockVisualsNode = None self.chunkTabWidget.currentChanged.connect(self.chunkTabDidChange) self.terrainPopulatedInput.toggled.connect( self.terrainPopulatedDidChange) self.lightPopulatedInput.toggled.connect(self.lightPopulatedDidChange) self.inhabitedTimeInput.valueChanged.connect( self.inhabitedTimeDidChange) self.updateTimeInput.valueChanged.connect(self.updateTimeDidChange) self.blockXSpinBox.valueChanged.connect(self.blockXChanged) self.blockYSpinBox.valueChanged.connect(self.blockYChanged) self.blockZSpinBox.valueChanged.connect(self.blockZChanged) self.removeEntityButton.clicked.connect(self.removeEntity) self.addTileEntityButton.clicked.connect(self.addTileEntity) self.removeTileEntityButton.clicked.connect(self.removeTileEntity)
def __init__(self, editorSession, *args, **kwargs): super(CloneTool, self).__init__(editorSession, *args, **kwargs) self.originPoint = None self.pendingClones = [] self.pendingCloneNodes = [] self.mainCloneNode = None self.overlayNode = scenenode.Node("cloneOverlay") self.toolWidget = QtGui.QWidget() self.pointInput = CoordinateWidget() self.pointInput.pointChanged.connect(self.pointInputChanged) self.rotationInput = RotationWidget() self.rotationInput.rotationChanged.connect(self.rotationChanged) self.scaleInput = ScaleWidget() self.scaleInput.scaleChanged.connect(self.scaleChanged) confirmButton = QtGui.QPushButton(self.tr("Confirm")) # xxxx should be in worldview confirmButton.clicked.connect(self.confirmClone) self.repeatCount = 1 self.repeatCountInput = QtGui.QSpinBox(minimum=1, maximum=10000, value=1) self.repeatCountInput.valueChanged.connect(self.setRepeatCount) self.rotateRepeatsCheckbox = QtGui.QCheckBox(self.tr("Rotate Repeats")) self.rotateRepeatsCheckbox.toggled.connect(self.updateTiling) self.rotateOffsetCheckbox = QtGui.QCheckBox(self.tr("Rotate Offset")) self.rotateOffsetCheckbox.toggled.connect(self.updateTiling) self.toolWidget.setLayout(Column(self.pointInput, self.rotationInput, Row(self.rotateRepeatsCheckbox, self.rotateOffsetCheckbox), self.scaleInput, Row(QtGui.QLabel(self.tr("Repeat count: ")), self.repeatCountInput), confirmButton, None)) self.mainPendingClone = None # Do this after creating pointInput to disable inputs
def makeChunkVertices(self, chunk, limitBox): sceneNode = scenenode.Node("tileEntityModels") chests = {} for i, ref in enumerate(chunk.TileEntities): ID = ref.id if ID not in models.cookedTileEntityModels: continue if ID == "Chest": chests[ref.Position] = ref, {} continue for (x, y, z), (ref, adj) in chests.iteritems(): for dx, dz in ((-1, 0), (1, 0), (0, -1), (0, 1)): if (x + dx, y, z + dz) in chests: adj[dx, dz] = ref for ref, adj in chests.itervalues(): if (-1, 0) not in adj and (0, -1) not in adj: if (1, 0) not in adj and (0, 1) not in adj: model = models.cookedTileEntityModels[ref.id] else: model = models.cookedTileEntityModels["MCEDIT_LargeChest"] texturePath = model.modelTexture if texturePath is None: modelTex = None else: modelTex = self.chunkUpdate.updateTask.getModelTexture( texturePath) block = chunk.dimension.getBlock(*ref.Position) if block.internalName != "minecraft:chest": continue blockState = block.blockState[1:-1] facing = blockState.split("=")[1] node = chestEntityModelNode(ref, model, modelTex, chunk, facing, (1, 0) in adj, (0, 1) in adj) sceneNode.addChild(node) yield self.sceneNode = sceneNode
def __init__(self, editorSession, *args, **kwargs): super(CloneTool, self).__init__(editorSession, *args, **kwargs) self.originPoint = None self.offsetPoint = None self.pendingCloneNodes = [] self.mainCloneNode = None self.overlayNode = scenenode.Node() self.overlayNode.name = "Clone Overlay" self.toolWidget = QtGui.QWidget() self.pointInput = CoordinateWidget() self.pointInput.pointChanged.connect(self.pointInputChanged) confirmButton = QtGui.QPushButton( self.tr("Confirm")) # xxxx should be in worldview confirmButton.clicked.connect(self.confirmClone) self.repeatCount = 1 self.repeatCountInput = QtGui.QSpinBox(minimum=1, maximum=100, value=1) self.repeatCountInput.valueChanged.connect(self.setRepeatCount) self.tileX = self.tileY = self.tileZ = False self.tileXCheckbox = QtGui.QCheckBox(self.tr("Tile X")) self.tileXCheckbox.toggled.connect(self.setTileX) self.tileYCheckbox = QtGui.QCheckBox(self.tr("Tile Y")) self.tileYCheckbox.toggled.connect(self.setTileY) self.tileZCheckbox = QtGui.QCheckBox(self.tr("Tile Z")) self.tileZCheckbox.toggled.connect(self.setTileZ) self.toolWidget.setLayout( Column( self.pointInput, Row(QtGui.QLabel(self.tr("Repeat count: ")), self.repeatCountInput), Row(self.tileXCheckbox, self.tileYCheckbox, self.tileZCheckbox), confirmButton, None)) self.pendingClone = None # Do this after creating pointInput to disable inputs
def updateNodePreview(self): bounds = self.previewBounds if self.currentGenerator is None: return if bounds is not None and bounds.volume > 0: try: node = self.currentGenerator.getPreviewNode(bounds) except Exception: log.exception("Error while getting scene nodes from generator:") else: if node is not None: self.clearNode() if isinstance(node, list): nodes = node node = scenenode.Node() for c in nodes: node.addChild(c) self.overlayNode.addChild(node) self.previewNode = node
def __init__(self, editorSession, *args, **kwargs): """ :type editorSession: EditorSession """ super(SelectionTool, self).__init__(editorSession, *args, **kwargs) toolWidget = QtGui.QWidget() editorSession.selectionChanged.connect(self.selectionDidChange) self.toolWidget = toolWidget self.coordInput = SelectionCoordinateWidget() self.coordInput.boxChanged.connect(self.coordInputChanged) self.shapeInput = ShapeWidget(addShapes=[ChunkShape()]) self.shapeInput.shapeChanged.connect(self.shapeDidChange) self.shapeInput.shapeOptionsChanged.connect(self.shapeDidChange) self.toolWidget.setLayout( Column(self.coordInput, self.shapeInput, None)) self.cursorNode = SelectionCursor() self.overlayNode = scenenode.Node() self.faceHoverNode = SelectionFaceNode() self.selectionNode = SelectionScene() self.overlayNode.addChild(self.selectionNode) self.overlayNode.addChild(self.faceHoverNode) self.boxHandleNode = BoxHandle() self.boxHandleNode.boundsChanged.connect(self.boxHandleResized) self.boxHandleNode.boundsChangedDone.connect(self.boxHandleResizedDone) self.overlayNode.addChild(self.boxHandleNode) self.newSelectionNode = None editorSession.dimensionChanged.connect(self.dimensionDidChange) editorSession.revisionChanged.connect(self.revisionDidChange)
def __init__(self, *args, **kwargs): EditorTool.__init__(self, *args, **kwargs) self.livePreview = False self.blockPreview = False self.glPreview = True toolWidget = QtGui.QWidget() self.toolWidget = toolWidget column = [] self.generatorTypes = [ pluginClass(self) for pluginClass in GeneratePlugins.registeredPlugins ] self.currentGenerator = None if len(self.generatorTypes): self.currentGenerator = self.generatorTypes[0] self.generatorTypeInput = QtGui.QComboBox() self.generatorTypesChanged() self.generatorTypeInput.currentIndexChanged.connect( self.currentTypeChanged) self.livePreviewCheckbox = QtGui.QCheckBox("Live Preview") self.livePreviewCheckbox.setChecked(self.livePreview) self.livePreviewCheckbox.toggled.connect(self.livePreviewToggled) self.blockPreviewCheckbox = QtGui.QCheckBox("Block Preview") self.blockPreviewCheckbox.setChecked(self.blockPreview) self.blockPreviewCheckbox.toggled.connect(self.blockPreviewToggled) self.glPreviewCheckbox = QtGui.QCheckBox("GL Preview") self.glPreviewCheckbox.setChecked(self.glPreview) self.glPreviewCheckbox.toggled.connect(self.glPreviewToggled) self.optionsHolder = QtGui.QStackedWidget() self.optionsHolder.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.generateButton = QtGui.QPushButton(self.tr("Generate")) self.generateButton.clicked.connect(self.generateClicked) column.append(self.generatorTypeInput) column.append(self.livePreviewCheckbox) column.append(self.blockPreviewCheckbox) column.append(self.glPreviewCheckbox) column.append(self.optionsHolder) column.append(self.generateButton) self.toolWidget.setLayout(Column(*column)) self.overlayNode = scenenode.Node("generateOverlay") self.sceneHolderNode = Node("sceneHolder") self.sceneTranslate = Translate() self.sceneHolderNode.addState(self.sceneTranslate) self.overlayNode.addChild(self.sceneHolderNode) self.previewNode = None self.boxHandleNode = BoxHandle() self.boxHandleNode.boundsChanged.connect(self.boundsDidChange) self.boxHandleNode.boundsChangedDone.connect(self.boundsDidChangeDone) self.overlayNode.addChild(self.boxHandleNode) self.worldScene = None self.loader = None self.previewBounds = None self.schematicBounds = None self.currentSchematic = None self.currentTypeChanged(0) # Name of last selected generator plugin is saved after unloading # so it can be reselected if it is immediately reloaded self._lastTypeName = None GeneratePlugins.pluginAdded.connect(self.addPlugin) GeneratePlugins.pluginRemoved.connect(self.removePlugin)
def __init__(self, dimension, textureAtlas=None, geometryCache=None, sharedGLWidget=None): """ :param dimension: :type dimension: WorldEditorDimension :param textureAtlas: :type textureAtlas: TextureAtlas :param geometryCache: :type geometryCache: GeometryCache :param sharedGLWidget: :type sharedGLWidget: QGLWidget :return: :rtype: """ QGLWidget.__init__(self, shareWidget=sharedGLWidget) self.dimension = None self.worldScene = None self.loadableChunksNode = None self.textureAtlas = None validateWidgetQGLContext(self) self.bufferSwapDone = True if THREADED_BUFFER_SWAP: self.setAutoBufferSwap(False) self.bufferSwapThread = QtCore.QThread() self.bufferSwapper = BufferSwapper(self) self.bufferSwapper.moveToThread(self.bufferSwapThread) self.doSwapBuffers.connect(self.bufferSwapper.swap) self.bufferSwapThread.start() self.setAcceptDrops(True) self.setSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding) self.setFocusPolicy(Qt.ClickFocus) self.layerToggleGroup = LayerToggleGroup() self.layerToggleGroup.layerToggled.connect(self.setLayerVisible) self.mouseRay = Ray(Vector(0, 1, 0), Vector(0, -1, 0)) self.setMouseTracking(True) self.lastAutoUpdate = time.time() self.autoUpdateInterval = 0.5 # frequency of screen redraws in response to loaded chunks self.compassNode = self.createCompass() self.compassOrtho = Ortho((1, float(self.height()) / self.width())) self.compassNode.addState(self.compassOrtho) self.viewActions = [] self.pressedKeys = set() self.setTextureAtlas(textureAtlas) if geometryCache is None and sharedGLWidget is not None: geometryCache = sharedGLWidget.geometryCache if geometryCache is None: geometryCache = GeometryCache() self.geometryCache = geometryCache self.worldNode = None self.skyNode = None self.overlayNode = scenenode.Node("WorldView Overlay") self.sceneGraph = None self.renderGraph = None self.frameSamples = deque(maxlen=500) self.frameSamples.append(time.time()) self.cursorNode = None self.setDimension(dimension)
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)