def _onSelectedFaceChanged(self): self._handle.setEnabled(not Selection.getFaceSelectMode()) selected_face = Selection.getSelectedFace() if not Selection.getSelectedFace() or not (Selection.hasSelection() and Selection.getFaceSelectMode()): return original_node, face_id = selected_face meshdata = original_node.getMeshDataTransformed() if not meshdata or face_id < 0: return rotation_point, face_normal = meshdata.getFacePlane(face_id) rotation_point_vector = Vector(rotation_point[0], rotation_point[1], rotation_point[2]) face_normal_vector = Vector(face_normal[0], face_normal[1], face_normal[2]) rotation_quaternion = Quaternion.rotationTo(face_normal_vector.normalized(), Vector(0.0, -1.0, 0.0)) operation = GroupedOperation() current_node = None # type: Optional[SceneNode] for node in Selection.getAllSelectedObjects(): current_node = node parent_node = current_node.getParent() while parent_node and parent_node.callDecoration("isGroup"): current_node = parent_node parent_node = current_node.getParent() if current_node is None: return rotate_operation = RotateOperation(current_node, rotation_quaternion, rotation_point_vector) operation.addOperation(rotate_operation) operation.push()
def _zoomCamera(self, zoom_range: float, event: Optional[Event] = None) -> None: camera = self._scene.getActiveCamera() if not camera or not camera.isEnabled(): return self.clipToZoom() if camera.isPerspective(): r = (camera.getWorldPosition() - self._origin).length() delta = r * (zoom_range / 128 / 10.0) r -= delta if self._invert_zoom: delta *= -1 move_vector = Vector(0.0, 0.0, 1.0) if event is not None and self._zoom_to_mouse: viewport_center_x = QtApplication.getInstance().getRenderer( ).getViewportWidth() / 2 viewport_center_y = QtApplication.getInstance().getRenderer( ).getViewportHeight() / 2 main_window = cast(MainWindow, QtApplication.getInstance().getMainWindow()) mouse_diff_center_x = viewport_center_x - main_window.mouseX mouse_diff_center_y = viewport_center_y - main_window.mouseY x_component = mouse_diff_center_x / QtApplication.getInstance( ).getRenderer().getViewportWidth() y_component = mouse_diff_center_y / QtApplication.getInstance( ).getRenderer().getViewportHeight() move_vector = Vector(x_component, -y_component, 1) move_vector = move_vector.normalized() move_vector = -delta * move_vector if delta != 0: if self._min_zoom < r < self._max_zoom: camera.translate(move_vector) if self._zoom_to_mouse: # Set the origin of the camera to the new distance, right in front of the new camera position. self._origin = (r * Vector(0.0, 0.0, -1.0)).preMultiply( camera.getWorldTransformation()) else: amount_of_zoom = zoom_range / 1280 / 10.0 if self._invert_zoom: amount_of_zoom *= -1 new_zoom_factor = camera.getZoomFactor() - amount_of_zoom if new_zoom_factor > 1: camera.setZoomFactor(1) elif new_zoom_factor < -0.495: camera.setZoomFactor(-0.495) else: camera.setZoomFactor(new_zoom_factor)
def setByAngleAxis(self, angle: float, axis: Vector) -> None: """Set quaternion by providing rotation about an axis. :param angle: :type{float} Angle in radians :param axis: :type{Vector} Axis of rotation """ a = axis.normalized().getData() halfAngle = angle / 2.0 self._data[3] = math.cos(halfAngle) self._data[0:3] = a * math.sin(halfAngle) self.normalize()
def _zoomCamera(self, zoom_range, event=None): camera = self._scene.getActiveCamera() if not camera or not camera.isEnabled(): return self._scene.acquireLock() r = (camera.getWorldPosition() - self._origin).length() delta = r * (zoom_range / 128 / 10.0) r -= delta if self._invert_zoom: delta *= -1 move_vector = Vector(0.0, 0.0, 1.0) if event is not None and self._zoom_to_mouse: viewport_center_x = Application.getInstance().getRenderer( ).getViewportWidth() / 2 viewport_center_y = Application.getInstance().getRenderer( ).getViewportHeight() / 2 mouse_diff_center_x = viewport_center_x - Application.getInstance( ).getMainWindow().mouseX mouse_diff_center_y = viewport_center_y - Application.getInstance( ).getMainWindow().mouseY x_component = mouse_diff_center_x / Application.getInstance( ).getRenderer().getViewportWidth() y_component = mouse_diff_center_y / Application.getInstance( ).getRenderer().getViewportHeight() move_vector = Vector(x_component, -y_component, 1) move_vector = move_vector.normalized() move_vector = -delta * move_vector if delta != 0: if r > self._min_zoom: camera.translate(move_vector) if self._zoom_to_mouse: # Set the origin of the camera to the new distance, right in front of the new camera position. self._origin = (r * Vector(0.0, 0.0, -1.0)).preMultiply( camera.getWorldTransformation()) if r < self._max_zoom: camera.translate(move_vector) if self._zoom_to_mouse: # Set the origin of the camera to the new distance, right in front of the new camera position. self._origin = (r * Vector(0.0, 0.0, -1.0)).preMultiply( camera.getWorldTransformation()) self._scene.releaseLock()
def lookAt(self, target: Vector, up: Vector = Vector.Unit_Y): if not self._enabled: return eye = self.getWorldPosition() f = (target - eye).normalized() up = up.normalized() s = f.cross(up).normalized() u = s.cross(f).normalized() m = Matrix([[s.x, u.x, -f.x, 0.0], [s.y, u.y, -f.y, 0.0], [s.z, u.z, -f.z, 0.0], [0.0, 0.0, 0.0, 1.0]]) self.setOrientation(Quaternion.fromMatrix(m))
def lookAt(self, target: Vector, up: Vector = Vector.Unit_Y): if not self._enabled: return eye = self.getWorldPosition() f = (target - eye).normalized() up = up.normalized() s = f.cross(up).normalized() u = s.cross(f).normalized() m = Matrix([ [ s.x, u.x, -f.x, 0.0], [ s.y, u.y, -f.y, 0.0], [ s.z, u.z, -f.z, 0.0], [ 0.0, 0.0, 0.0, 1.0] ]) self.setOrientation(Quaternion.fromMatrix(m))
def _onSelectedFaceChanged(self): if not self._select_face_mode: return self._handle.setEnabled(not Selection.getFaceSelectMode()) selected_face = Selection.getSelectedFace() if not Selection.getSelectedFace() or not ( Selection.hasSelection() and Selection.getFaceSelectMode()): return original_node, face_id = selected_face meshdata = original_node.getMeshDataTransformed() if not meshdata or face_id < 0: return if face_id > (meshdata.getVertexCount() / 3 if not meshdata.hasIndices() else meshdata.getFaceCount()): return face_mid, face_normal = meshdata.getFacePlane(face_id) object_mid = original_node.getBoundingBox().center rotation_point_vector = Vector(object_mid.x, object_mid.y, face_mid[2]) face_normal_vector = Vector(face_normal[0], face_normal[1], face_normal[2]) rotation_quaternion = Quaternion.rotationTo( face_normal_vector.normalized(), Vector(0.0, -1.0, 0.0)) operation = GroupedOperation() current_node = None # type: Optional[SceneNode] for node in Selection.getAllSelectedObjects(): current_node = node parent_node = current_node.getParent() while parent_node and parent_node.callDecoration("isGroup"): current_node = parent_node parent_node = current_node.getParent() if current_node is None: return rotate_operation = RotateOperation(current_node, rotation_quaternion, rotation_point_vector) gravity_operation = GravityOperation(current_node) operation.addOperation(rotate_operation) operation.addOperation(gravity_operation) operation.push()
def lookAt(self, target: Vector, up: Vector = Vector.Unit_Y) -> None: """Rotate this scene node in such a way that it is looking at target. :param target: :type{Vector} The target to look at. :param up: :type{Vector} The vector to consider up. Defaults to Vector.Unit_Y, i.e. (0, 1, 0). """ if not self._enabled: return eye = self.getWorldPosition() f = (target - eye).normalized() up = up.normalized() s = f.cross(up).normalized() u = s.cross(f).normalized() m = Matrix([[s.x, u.x, -f.x, 0.0], [s.y, u.y, -f.y, 0.0], [s.z, u.z, -f.z, 0.0], [0.0, 0.0, 0.0, 1.0]]) self.setOrientation(Quaternion.fromMatrix(m))
def _zoomCamera(self, zoom_range: float, event: Optional[Event] = None) -> None: camera = self._scene.getActiveCamera() if not camera or not camera.isEnabled(): return self.clipToZoom() self._scene.getSceneLock().acquire() r = (camera.getWorldPosition() - self._origin).length() delta = r * (zoom_range / 128 / 10.0) r -= delta if self._invert_zoom: delta *= -1 move_vector = Vector(0.0, 0.0, 1.0) if event is not None and self._zoom_to_mouse: viewport_center_x = QtApplication.getInstance().getRenderer().getViewportWidth() / 2 viewport_center_y = QtApplication.getInstance().getRenderer().getViewportHeight() / 2 main_window = cast(MainWindow, QtApplication.getInstance().getMainWindow()) mouse_diff_center_x = viewport_center_x - main_window.mouseX mouse_diff_center_y = viewport_center_y - main_window.mouseY x_component = mouse_diff_center_x / QtApplication.getInstance().getRenderer().getViewportWidth() y_component = mouse_diff_center_y / QtApplication.getInstance().getRenderer().getViewportHeight() move_vector = Vector(x_component, -y_component, 1) move_vector = move_vector.normalized() move_vector = -delta * move_vector if delta != 0: if self._min_zoom < r < self._max_zoom: camera.translate(move_vector) if self._zoom_to_mouse: # Set the origin of the camera to the new distance, right in front of the new camera position. self._origin = (r * Vector(0.0, 0.0, -1.0)).preMultiply(camera.getWorldTransformation()) self._scene.getSceneLock().release()
def bottomFaceSelection(self) -> None: selected_face = Selection.getSelectedFace() if not selected_face: Logger.log( "e", "Bottom face operation shouldn't have been called without a selected face." ) return original_node, face_id = selected_face meshdata = original_node.getMeshDataTransformed() if not meshdata or face_id < 0 or face_id > Selection.getMaxFaceSelectionId( ): return rotation_point, face_normal = meshdata.getFacePlane(face_id) rotation_point_vector = Vector(rotation_point[0], rotation_point[1], rotation_point[2]) face_normal_vector = Vector(face_normal[0], face_normal[1], face_normal[2]) rotation_quaternion = Quaternion.rotationTo( face_normal_vector.normalized(), Vector(0.0, -1.0, 0.0)) operation = GroupedOperation() current_node = None # type: Optional[SceneNode] for node in Selection.getAllSelectedObjects(): current_node = node parent_node = current_node.getParent() while parent_node and parent_node.callDecoration("isGroup"): current_node = parent_node parent_node = current_node.getParent() if current_node is None: return rotate_operation = RotateOperation(current_node, rotation_quaternion, rotation_point_vector) operation.addOperation(rotate_operation) operation.push()
def test_normalize(self): vector = Vector(10, 10, 10) assert vector.normalized().length() == 1
def setByAngleAxis(self, angle: float, axis: Vector) -> None: a = axis.normalized().getData() halfAngle = angle / 2.0 self._data[3] = math.cos(halfAngle) self._data[0:3] = a * math.sin(halfAngle) self.normalize()