aboutsummaryrefslogtreecommitdiffstats
path: root/examples/3d/simple3d.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/3d/simple3d.py')
-rw-r--r--examples/3d/simple3d.py164
1 files changed, 164 insertions, 0 deletions
diff --git a/examples/3d/simple3d.py b/examples/3d/simple3d.py
new file mode 100644
index 000000000..a34d19821
--- /dev/null
+++ b/examples/3d/simple3d.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the PySide examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""PySide2 port of the qt3d/simple-cpp example from Qt v5.x"""
+
+import sys
+from PySide2.QtCore import(Property, QObject, QPropertyAnimation, Signal, Slot)
+from PySide2.QtGui import (QGuiApplication, QMatrix4x4, QQuaternion, QVector3D, QWindow)
+from PySide2.Qt3DCore import (Qt3DCore)
+from PySide2.Qt3DRender import (Qt3DRender)
+from PySide2.Qt3DExtras import (Qt3DExtras)
+
+class OrbitTransformController(QObject):
+ def __init__(self, parent):
+ super(OrbitTransformController, self).__init__(parent)
+ self._target = None
+ self._matrix = QMatrix4x4()
+ self._radius = 1
+ self._angle = 0
+
+ def setTarget(self, t):
+ self._target = t
+
+ def getTarget(self):
+ return self._target
+
+ def setRadius(self, radius):
+ if self._radius != radius:
+ self._radius = radius
+ self.updateMatrix()
+ self.radiusChanged.emit()
+
+ def getRadius(self):
+ return self._radius
+
+ def setAngle(self, angle):
+ if self._angle != angle:
+ self._angle = angle
+ self.updateMatrix()
+ self.angleChanged.emit()
+
+ def getAngle(self):
+ return self._angle
+
+ def updateMatrix(self):
+ self._matrix.setToIdentity();
+ self._matrix.rotate(self._angle, QVector3D(0, 1, 0))
+ self._matrix.translate(self._radius, 0, 0)
+ if self._target is not None:
+ self._target.setMatrix(self._matrix)
+
+ angleChanged = Signal()
+ radiusChanged = Signal()
+ angle = Property(float, getAngle, setAngle, notify=angleChanged)
+ radius = Property(float, getRadius, setRadius, notify=radiusChanged)
+
+class Window(Qt3DExtras.Qt3DWindow):
+ def __init__(self):
+ super(Window, self).__init__()
+
+ # Camera
+ self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000)
+ self.camera().setPosition(QVector3D(0, 0, 40))
+ self.camera().setViewCenter(QVector3D(0, 0, 0))
+
+ # For camera controls
+ self.createScene()
+ self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity)
+ self.camController.setLinearSpeed(50)
+ self.camController.setLookSpeed(180)
+ self.camController.setCamera(self.camera())
+
+ self.setRootEntity(self.rootEntity)
+
+ def createScene(self):
+ # Root entity
+ self.rootEntity = Qt3DCore.QEntity()
+
+ # Material
+ self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)
+
+ # Torus
+ self.torusEntity = Qt3DCore.QEntity(self.rootEntity)
+ self.torusMesh = Qt3DExtras.QTorusMesh()
+ self.torusMesh.setRadius(5)
+ self.torusMesh.setMinorRadius(1)
+ self.torusMesh.setRings(100)
+ self.torusMesh.setSlices(20)
+
+ self.torusTransform = Qt3DCore.QTransform()
+ self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5))
+ self.torusTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45))
+
+ self.torusEntity.addComponent(self.torusMesh)
+ self.torusEntity.addComponent(self.torusTransform)
+ self.torusEntity.addComponent(self.material)
+
+ # Sphere
+ self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
+ self.sphereMesh = Qt3DExtras.QSphereMesh()
+ self.sphereMesh.setRadius(3)
+
+ self.sphereTransform = Qt3DCore.QTransform()
+ self.controller = OrbitTransformController(self.sphereTransform)
+ self.controller.setTarget(self.sphereTransform)
+ self.controller.setRadius(20)
+
+ self.sphereRotateTransformAnimation = QPropertyAnimation(self.sphereTransform)
+ self.sphereRotateTransformAnimation.setTargetObject(self.controller)
+ self.sphereRotateTransformAnimation.setPropertyName("angle")
+ self.sphereRotateTransformAnimation.setStartValue(0)
+ self.sphereRotateTransformAnimation.setEndValue(360)
+ self.sphereRotateTransformAnimation.setDuration(10000)
+ self.sphereRotateTransformAnimation.setLoopCount(-1)
+ self.sphereRotateTransformAnimation.start()
+
+ self.sphereEntity.addComponent(self.sphereMesh)
+ self.sphereEntity.addComponent(self.sphereTransform)
+ self.sphereEntity.addComponent(self.material)
+
+if __name__ == '__main__':
+ app = QGuiApplication(sys.argv)
+ view = Window()
+ view.show()
+ sys.exit(app.exec_())