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.setSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding) self.setFocusPolicy(Qt.ClickFocus) self.layerToggleGroup = LayerToggleGroup() self.layerToggleGroup.layerToggled.connect(self.setLayerVisible) self.dimension = None self.worldScene = None self.loadableChunksNode = None self.textureAtlas = None 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.compassOrthoNode = scenegraph.OrthoNode((1, float(self.height()) / self.width())) self.compassOrthoNode.addChild(self.compassNode) 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.matrixNode = None self.overlayNode = scenegraph.Node() self.sceneGraph = None self.renderGraph = None self.frameSamples = deque(maxlen=500) self.frameSamples.append(time.time()) self.cursorNode = None self.setDimension(dimension)
def __init__(self, pos, commandObj): """ Parameters ---------- commandObj : ExecuteCommand Returns ------- """ super(ExecuteVisuals, self).__init__() selector = commandObj.targetSelector if selector.playerName is not None: return selectorPos = [selector.getArg(a) for a in 'xyz'] if None in (selectorPos): log.warn("No selector coordinates for command %s", commandObj) targetPos = commandObj.resolvePosition((0, 0, 0)) else: targetPos = commandObj.resolvePosition(selectorPos) # Draw box at selector pos and draw line from command block to selector pos # xxxx selector pos is a sphere of radius `selector.getArg('r')` boxNode = SelectionBoxNode() boxNode.filled = False boxNode.wireColor = (0.9, 0.2, 0.2, 0.6) boxNode.selectionBox = BoundingBox(selectorPos, (1, 1, 1)) lineNode = LineArcNode( Vector(*pos) + (0.5, 0.5, 0.5), Vector(*selectorPos) + (.5, .5, .5), (0.9, 0.2, 0.2, 0.6)) self.addChild(boxNode) self.addChild(lineNode) if selectorPos != targetPos: # Command block's own coordinates are different from the selected pos, # either relative or absolute. # Draw a box at the target coordinates and a line from # the selected pos to the target boxNode = SelectionBoxNode() boxNode.filled = False boxNode.wireColor = (0.9, 0.2, 0.2, 0.6) boxNode.selectionBox = BoundingBox(targetPos, (1, 1, 1)) lineNode = LineArcNode( Vector(*selectorPos) + (0.5, 0.5, 0.5), Vector(*targetPos) + (.5, .5, .5), (0.9, 0.2, 0.2, 0.6)) self.addChild(boxNode) self.addChild(lineNode) if not isinstance(commandObj.subcommand, UnknownCommand): subvisuals = CommandVisuals(targetPos, commandObj.subcommand) self.addChild(subvisuals)
def transformBounds(bounds, matrix): # matrix goes from dest to source; we need source to dest here, so get inverse matrix = np.linalg.inv(matrix) corners = np.array(boundsCorners(bounds)) corners = np.hstack([corners, ([1], ) * 8]) corners = corners * matrix minx = math.floor(min(corners[:, 0])) miny = math.floor(min(corners[:, 1])) minz = math.floor(min(corners[:, 2])) maxx = math.ceil(max(corners[:, 0])) maxy = math.ceil(max(corners[:, 1])) maxz = math.ceil(max(corners[:, 2])) # Why? Weird hacks for rotation? # if maxx % 1: # maxx += 1 # if maxy % 1: # maxy += 1 # if maxz % 1: # maxz += 1 newbox = BoundingBox(origin=Vector(minx, miny, minz).intfloor(), maximum=Vector(maxx, maxy, maxz).intfloor()) return newbox
def intersect(self, box): """ Return a box containing the area self and box have in common. Box will have zero volume if there is no common area. """ #if (self.minx > box.maxx or self.maxx < box.minx or # self.miny > box.maxy or self.maxy < box.miny or # self.minz > box.maxz or self.maxz < box.minz): # #Zero size intersection. # return BoundingBox() origin = Vector( max(self.minx, box.minx), max(self.miny, box.miny), max(self.minz, box.minz), ) maximum = Vector( min(self.maxx, box.maxx), min(self.maxy, box.maxy), min(self.maxz, box.maxz), ) size = maximum - origin if any(s <= 0 for s in size): return ZeroBox # print "Intersect of {0} and {1}: {2}".format(self, box, newbox) # return self.__class__(origin, size) return BoundingBox(origin, size)
def cameraVector(self): if self.axis == 'x': return Vector(-1, 0, 0) if self.axis == 'y': return Vector(0, -1, 0) if self.axis == 'z': return Vector(0, 0, -1)
def main(): vector = Vector(.333, .555, .2831).normalize() origin = Vector(138.2, 22.459, 12) maxDistance = 1000 def cast_py(): return numpy.array(list(_cast(origin, vector, maxDistance, 1))) def cast_np(): return _cast_np(origin, vector, maxDistance, 1) res_py = cast_py() res_np = cast_np() print("res_py", res_py.shape) print("res_np", res_np.shape) s = min(len(res_py), len(res_np)) passed = (res_py[:s] == res_np[:s]).all() print("Passed" if passed else "Failed") from timeit import timeit t_py = timeit(cast_py, number=1) t_np = timeit(cast_np, number=1) print("Time cast_py", t_py) print("Time cast_np", t_np)
def brushBoundingBox(self, center, options={}): # Return a box of size options['brushSize'] centered around point. # also used to position the preview cursor size = options['brushSize'] x, y, z = size origin = Vector(*center) - (Vector(x, y, z) / 2) + Vector((x % 2) * 0.5, (y % 2) * 0.5, (z % 2) * 0.5) return BoundingBox(origin, size)
def __init__(self, origin=(0, 0, 0), size=(0, 0, 0), maximum=None): if isinstance(origin, BoundingBox): self._origin = origin._origin self._size = origin._size else: self._origin = Vector(*[self.type(a) for a in origin]) if maximum is not None: maximum = Vector(*maximum) self._size = maximum - self._origin else: self._size = Vector(*[self.type(a) for a in size])
def union(self, box): """ Return a box large enough to contain both self and box. """ origin = Vector( min(self.minx, box.minx), min(self.miny, box.miny), min(self.minz, box.minz), ) maximum = Vector( max(self.maxx, box.maxx), max(self.maxy, box.maxy), max(self.maxz, box.maxz), ) return self.__class__(origin, maximum - origin)
def __init__(self, pos, commandObj): super(CloneVisuals, self).__init__() sourceBox = commandObj.resolveBoundingBox(pos) dest = commandObj.resolveDestination(pos) destBox = BoundingBox(dest, sourceBox.size) sourceColor = (0.3, 0.5, 0.9, 0.6) destColor = (0.0, 0.0, 0.9, 0.6) sourceBoxNode = SelectionBoxNode() sourceBoxNode.filled = False sourceBoxNode.wireColor = sourceColor sourceBoxNode.selectionBox = sourceBox destBoxNode = SelectionBoxNode() destBoxNode.filled = False destBoxNode.wireColor = destColor destBoxNode.selectionBox = destBox lineToSourceNode = LineArcNode( Vector(*pos) + (0.5, 0.5, 0.5), sourceBox.center, sourceColor) lineToDestNode = LineArcNode(sourceBox.center, destBox.center, destColor) self.addChild(sourceBoxNode) self.addChild(destBoxNode) self.addChild(lineToSourceNode) self.addChild(lineToDestNode)
def basePosition(self, value): if value == self._pos: return self._pos = Vector(*value) self.updateImportPos() self.positionChanged.emit(self._pos)
def updateWorkplane(self): distance = 40 pos = self.centerPoint + self.cameraVector * distance pos = pos.intfloor() self.workplaneNode.position = Vector(pos[0], self.workplaneLevel, pos[2])
def loadDone(self): # Called by MCEditApp after the view is on screen to make sure view.center() works correctly # xxx was needed because view.centerOnPoint used a depthbuffer read for that, now what? try: try: player = self.worldEditor.getPlayer() center = Vector(*player.Position) + (0, 1.8, 0) dimNo = player.Dimension dimName = self.worldEditor.dimNameFromNumber(dimNo) log.info("Setting view angle to single-player player's view in dimension %s.", dimName) rotation = player.Rotation if dimName: self.gotoDimension(dimName) try: self.editorTab.currentView().yawPitch = rotation except AttributeError: pass except PlayerNotFound: try: center = self.worldEditor.getWorldMetadata().Spawn log.info("Centering on spawn position.") except AttributeError: log.info("Centering on world center") center = self.currentDimension.bounds.origin + (self.currentDimension.bounds.size * 0.5) self.editorTab.miniMap.centerOnPoint(center) self.editorTab.currentView().centerOnPoint(center, distance=0) except Exception as e: log.exception("Error while centering on player for world editor: %s", e)
def rotationMatrix(anchor, rotX, rotY, rotZ): translate = np.matrix(np.identity(4)) translate[3, 0] = anchor[0] translate[3, 1] = anchor[1] translate[3, 2] = anchor[2] # Rotate around center of cells. anchor = Vector(*anchor) - (0.5, 0.5, 0.5) reverse_translate = np.matrix(np.identity(4)) reverse_translate[3, 0] = -anchor[0] reverse_translate[3, 1] = -anchor[1] reverse_translate[3, 2] = -anchor[2] matrix = translate if rotX: matrix = npRotate('x', rotX) * matrix if rotY: matrix = npRotate('y', rotY) * matrix if rotZ: matrix = npRotate('z', rotZ) * matrix matrix = reverse_translate * matrix return matrix
def tickCamera(self): vector = self.worldView.cameraVector point = self.worldView.centerPoint up = Vector(0, 1, 0) left = vector.cross(up).normalize() if self.anyKey(): self.speed += self.accelUp self.speed = max(self.speed, self.minSpeed) else: self.speed = 0 self.speed = max(0, min(self.maxSpeed, self.speed)) vector = vector * self.speed up = up * self.speed left = left * self.speed if self.forward: point += vector if self.backward: point -= vector if self.left: point -= left if self.right: point += left if self.up: point += up if self.down: point -= up self.worldView.centerPoint = point
class OverheadWorldView(WorldView): cameraVector = Vector(0, -1, 0) def __init__(self, *a, **kw): WorldView.__init__(self, *a, **kw) self.scale = 1. self.compassNode.yawPitch = 180, 0 self.viewActions.extend((MoveViewMouseAction(), )) self.viewActions.extend(ZoomWheelActions()) self.worldScene.minlod = 2 def updateMatrices(self): w, h = self.width(), self.height() w *= self.scale h *= self.scale projection = QtGui.QMatrix4x4() projection.ortho(-w / 2, w / 2, -h / 2, h / 2, -1000, 2000) self.matrixState.projection = projection modelview = QtGui.QMatrix4x4() modelview.rotate(90., 1., 0., 0.) modelview.translate(-self.centerPoint[0], 0, -self.centerPoint[2]) self.matrixState.modelview = modelview
def basePosition(self, value): if value == self.positionTranslateNode.translateOffset: return self.positionTranslateNode.translateOffset = Vector(*value) self.updateTransformedSceneOffset() self.updateBoxHandle()
def __get__(self, instance, owner): tag = instance.rootTag for key in self.keys: if key not in tag: tag[key] = self.tagType(value=self.default) return Vector(*[tag[k].value for k in self.keys])
def getViewCorners(self): """ Returns corners: bottom left, near bottom left, far top left, near top left, far bottom right, near bottom right, far top right, near top right, far :return: :rtype: list[QVector4D] """ corners = [ QtGui.QVector4D(x, y, z, 1.) for x, y, z in itertools.product((-1., 1.), (-1., 1.), (0., 1.)) ] matrix = self.matrixState.projection * self.matrixState.modelview matrix, inverted = matrix.inverted() worldCorners = [matrix.map(corner) for corner in corners] worldCorners = [ Vector(*((corner / corner.w()).toTuple()[:3])) for corner in worldCorners ] return worldCorners
def __init__(self, point=Vector(0, 0, 0), face=faces.FaceXDecreasing, color=(.3, .3, 1)): super(SelectionCursor, self).__init__() self._point = point self._face = face self._color = color
def basePosition(self, value): value = Vector(*value) if value == self.positionTranslate.translateOffset: return self.positionTranslate.translateOffset = value self.updateTransformedPosition() self.updateBoxHandle()
def SectionBox(cx, cy, cz, section=None): if section is None: shape = 16, 16, 16 else: shape = section.Blocks.shape # XXX needed because FakeChunkedLevel returns odd sized sections - fix with storage adapter shape = shape[2], shape[0], shape[1] return BoundingBox(Vector(cx, cy, cz) * 16, shape)
def point(self, point): self.setEnabled(point is not None) point = Vector(*point) if self._point != point: self._point = point if point is not None: self.updateInputs() self.pointChanged.emit(point)
def centerPoint(self, value): value = Vector(*value) if value != self._centerPoint: self._centerPoint = value self._updateMatrices() log.debug("update(): centerPoint %s %s", self, value) self.update() self.resetLoadOrder() self.viewportMoved.emit(self)
def basePosition(self, value): value = Vector(*value) if value == self.positionTranslateNode.translateOffset: return self.positionTranslateNode.translateOffset = value self.transformedPosition = self.basePosition + self.pendingImport.transformOffset self.updateTransformedSceneOffset() self.updateBoxHandle()
def __get__(self, instance, owner): if instance is None: return self val = super(NBTVectorAttr, self).__get__(instance, owner) try: return Vector(*val) except TypeError: raise TypeError("NBT list too short for Vector: %s" % list(val))
def _changed(self, value, idx): if self.blockPos is None: return if self.blockPos[idx] == value: return pos = list(self.blockPos) pos[idx] = value self.inspectBlock(Vector(*pos))
def updateTransform(self): if self.rotation == (0, 0, 0) and self.scale == (0, 0, 0): self.transformedDim = None self.transformOffset = Vector(0, 0, 0) else: selectionDim = SelectionTransform(self.sourceDim, self.selection) self.transformedDim = DimensionTransform(selectionDim, self.rotateAnchor, *self.rotation) self.transformOffset = self.transformedDim.bounds.origin - self.selection.origin self.updateImportPos()
def setCoord(self, value, index): old = self.point if self._relative: old = old - self._origin new = list(old) new[index] = value new = Vector(*new) if self._relative: new = new + self._origin self.point = new
def _anglesToVector(self, yaw, pitch): def nanzero(x): if math.isnan(x): return 0 else: return x dx = -math.sin(math.radians(yaw)) * math.cos(math.radians(pitch)) dy = -math.sin(math.radians(pitch)) dz = math.cos(math.radians(yaw)) * math.cos(math.radians(pitch)) return Vector(*map(nanzero, [dx, dy, dz]))