class OrbitTransformController(QTransform): targetChanged = pyqtSignal() angleChanged = pyqtSignal() radiusChanged = pyqtSignal() def __init__(self, parent): QTransform.__init__(self, parent) self.m_target = QTransform() self.m_matrix = QMatrix4x4() self.m_radius = 1.0 self.m_angle = 0.0 def target(self): return self.m_target def setTarget(self, target): if self.m_target == target: return self.m_target = target self.targetChanged.emit() def setRadius(self, radius): if fuzzyCompareDouble(radius, self.m_radius): return self.m_radius = radius self.radiusChanged.emit() def radius(self, ): return self.m_radius def setAngle(self, angle): if fuzzyCompareDouble(angle, self.m_angle): return self.m_angle = angle self.updateMatrix() self.angleChanged.emit() def angle(self): return self.m_angle def updateMatrix(self, ): self.m_matrix.setToIdentity() self.m_matrix.rotate(self.m_angle, QVector3D(0.0, 1.0, 0.0)) self.m_matrix.translate(self.m_radius, 0.0, 0.0) self.m_target.setMatrix(self.m_matrix) angle = pyqtProperty(float, fget=angle, fset=setAngle, notify=angleChanged) radius = pyqtProperty(float, fget=radius, fset=setRadius, notify=radiusChanged) target = pyqtProperty(QTransform, fget=target, fset=setTarget, notify=angleChanged)
class OrbitTransformController(QObject): def __init__(self, parent): super(OrbitTransformController, self).__init__(parent) self.m_target = QTransform() self.m_matrix = QMatrix4x4() self.m_radius = 1.0 self.m_angle = 0 def getTarget(self): return self.m_target def setTarget(self, target): if self.m_target != target: self.m_target = target self.targetChanged.emit() def getRadius(self): return self.m_radius def setRadius(self, radius): if not QtCore.qFuzzyCompare(self.m_radius, radius): self.m_radius = radius self.updateMatrix() self.radiusChanged.emit() def getAngle(self): return self.m_angle def setAngle(self, angle): if not QtCore.qFuzzyCompare(angle, self.m_angle): self.m_angle = angle self.updateMatrix() self.angleChanged.emit() def updateMatrix(self): self.m_matrix.setToIdentity() self.m_matrix.rotate(self.m_angle, QVector3D(0, 1, 0)) self.m_matrix.translate(self.m_radius, 0, 0) self.m_target.setMatrix(self.m_matrix) # QSignal targetChanged = pyqtSignal() radiusChanged = pyqtSignal() angleChanged = pyqtSignal() # Qt properties target = pyqtProperty(QTransform, fget=getTarget, fset=setTarget) radius = pyqtProperty(float, fget=getRadius, fset=setRadius) angle = pyqtProperty(float, fget=getAngle, fset=setAngle)
class TrefoilKnot(QEntity): def __init__(self, parent=None): super(TrefoilKnot, self).__init__(parent) self.m_mesh = QMesh() self.m_transform = QTransform() self.m_theta = 0.0 self.m_phi = 0.0 self.m_position = QVector3D() self.m_scale = 1.0 self.m_mesh.setSource(QUrl.fromLocalFile('assets/obj/trefoil.obj')) self.addComponent(self.m_mesh) self.addComponent(self.m_transform) def updateTransform(self): m = QMatrix4x4() m.translate(self.m_position) m.rotate(self.m_phi, QVector3D(1.0, 0.0, 0.0)) m.rotate(self.m_phi, QVector3D(0.0, 1.0, 0.0)) m.scale(self.m_scale) self.m_transform.setMatrix(m) thetaChanged = pyqtSignal(float) @pyqtProperty(float, notify=thetaChanged) def theta(self): return self.m_theta @theta.setter def theta(self, value): if self.m_theta != value: self.m_theta = value self.thetaChanged.emit(value) self.updateTransform() phiChanged = pyqtSignal(float) @pyqtProperty(float, notify=phiChanged) def phi(self): return self.m_phi @phi.setter def phi(self, value): if self.m_phi != value: self.m_phi = value self.phiChanged.emit(value) self.updateTransform() scaleChanged = pyqtSignal(float) @pyqtProperty(float, notify=scaleChanged) def scale(self): return self.m_scale @scale.setter def scale(self, value): if self.m_scale != value: self.m_scale = value self.scaleChanged.emit(value) self.updateTransform() positionChanged = pyqtSignal(QVector3D) @pyqtProperty(QVector3D, notify=positionChanged) def position(self): return self.m_position @position.setter def position(self, value): if self.m_position != value: self.m_position = value self.positionChanged.emit(value) self.updateTransform()