Пример #1
0
def createScene():
    # Root entity.
    rootEntity = QEntity()

    # Material.
    material = QPhongMaterial(rootEntity)

    # Torus.
    torusEntity = QEntity(rootEntity)
    torusMesh = QTorusMesh()
    torusMesh.setRadius(5)
    torusMesh.setMinorRadius(1)
    torusMesh.setRings(100)
    torusMesh.setSlices(20)

    torusTransform = QTransform()
    torusTransform.setScale3D(QVector3D(1.5, 1.0, 0.5))
    torusTransform.setRotation(
        QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0))

    torusEntity.addComponent(torusMesh)
    torusEntity.addComponent(torusTransform)
    torusEntity.addComponent(material)

    # Sphere.
    sphereEntity = QEntity(rootEntity)
    sphereMesh = QSphereMesh()
    sphereMesh.setRadius(3)

    sphereTransform = QTransform()
    controller = OrbitTransformController(sphereTransform)
    controller.target = sphereTransform
    controller.radius = 20.0

    sphereRotateTransformAnimation = QPropertyAnimation(sphereTransform)
    sphereRotateTransformAnimation.setTargetObject(controller)
    sphereRotateTransformAnimation.setPropertyName(b'angle')
    sphereRotateTransformAnimation.setStartValue(0)
    sphereRotateTransformAnimation.setEndValue(360)
    sphereRotateTransformAnimation.setDuration(10000)
    sphereRotateTransformAnimation.setLoopCount(-1)
    sphereRotateTransformAnimation.start()

    sphereEntity.addComponent(sphereMesh)
    sphereEntity.addComponent(sphereTransform)
    sphereEntity.addComponent(material)

    return rootEntity
Пример #2
0
    def createScene(self):
        root = QEntity()
        # Material
        material = QPhongMaterial(root)
        material.setAmbient(QColor(100, 100, 0))
        material.setDiffuse(QColor(100, 0, 100))

        cube_E = QEntity(root)
        cube_mesh = QCuboidMesh()
        cube_mesh.setXExtent(2)
        cube_mesh.setYExtent(2)
        cube_mesh.setZExtent(2)

        cube_tr = QTransform()
        cube_tr.setScale3D(QVector3D(2, 2, 2))

        cube_E.addComponent(cube_mesh)
        cube_E.addComponent(cube_tr)
        cube_E.addComponent(material)

        return root
Пример #3
0
diffuseMapMaterial = QDiffuseMapMaterial()
diffuseMapMaterial.setSpecular(QColor.fromRgbF(0.2, 0.2, 0.2, 1.0))
diffuseMapMaterial.setShininess(2.0)

chestDiffuseImage = QTextureImage()
chestDiffuseImage.setSource(QUrl.fromLocalFile('assets/chest/diffuse.webp'))
diffuseMapMaterial.diffuse().addTextureImage(chestDiffuseImage)

chest.addComponent(diffuseMapMaterial)

# Trefoil Knot.
trefoil = RotatingTrefoilKnot(sceneRoot)
trefoil.position = QVector3D(0.0, 3.5, 0.0)
trefoil.scale = 0.5

phongMaterial = QPhongMaterial()
phongMaterial.setDiffuse(QColor(204, 205, 75))
phongMaterial.setSpecular(Qt.white)

trefoil.addComponent(phongMaterial)

# Barrels.
basicBarrel = Barrel(sceneRoot)
basicBarrel.transform().setTranslation(QVector3D(8.0, 0.0, 0.0))

rustyBarrel = Barrel(sceneRoot)
rustyBarrel.setDiffuse(Barrel.RustDiffuse)
rustyBarrel.setSpecular(Barrel.RustSpecular)
rustyBarrel.setBumps(Barrel.HardBumps)
rustyBarrel.transform().setTranslation(QVector3D(10.0, 0.0, 0.0))
Пример #4
0
class Animation(object):
    """
    Abstract class for setting up a 3D scene and animating it.
    """
    def __init__(self, title, frame_rate, run_time):
        """
        Create a new Animation.

        Arguments:
            title: str, the window title
            frame_rate: float, the number of frames to display per second
            run_time: float, the number of seconds to run the animation
        """
        self.title = title
        assert 0 < frame_rate < 1000
        self.frame_rate = frame_rate
        assert run_time > 0
        self.run_time = run_time

        self.frame = 0
        self.prev_update_time = None

        # import OpenGL so Qt can use it for rendering
        from OpenGL import GL
        # create the 3D window
        self.view = Qt3DWindow()
        self.view.setX(100)
        self.view.setY(100)

        self.view.setTitle(self.title)

        self.qml_engine = QQmlEngine(self.view)

    def load_qml(self, path, parent):
        """
        Helper method to load an object using Qt's QML system.

        Arguments:
            path: str, a path to a QML file
            parent: QObject, the parent of the object to be loaded

        Returns:
            the loaded QObject
        """
        component = QQmlComponent(self.qml_engine, path, parent)
        obj = component.create()
        if obj is None:
            print('Error loading {}'.format(path))
            for error in component.errors():
                print(error.toString())
            exit()
        return obj

    def add_light(self, position, intensity=1.0, color=util.hsl(0, 0, 100)):
        """
        Helper method to add a simple point light to the scene.

        Arguments:
            position: QVector3D, the position of the light in the scene
            intensity: float, the intensity of the light
            color: QColor, the color of the light
        """
        light_entity = QEntity(self.scene)
        light = QPointLight(light_entity)
        light.setColor(color)
        light.setIntensity(intensity)
        light_transform = QTransform(self.scene)
        light_transform.setTranslation(position)
        light_entity.addComponent(light)
        light_entity.addComponent(light_transform)

    def add_rgb_cube(self, w, h, d):
        """
        Helper method to add an RGB-textured cube to the scene.

        Arguments:
            w: float, the width of the cube
            h: float, the height of the cube
            d: float, the depth of the cube

        Returns:
            the QTransform of the cube
        """
        cube_entity = QEntity(self.scene)
        cube_mesh = QCuboidMesh()
        cube_mesh.setXExtent(w)
        cube_mesh.setYExtent(h)
        cube_mesh.setZExtent(d)
        cube_entity.addComponent(cube_mesh)
        cube_transform = QTransform(self.scene)
        cube_entity.addComponent(cube_transform)
        if not hasattr(self, 'rgb_cube_material'):
            # load material definition from QML
            # this was the easiest way I could find to create a custom shader in Qt3D...
            self.rgb_cube_material = self.load_qml(
                os.path.join(os.path.dirname(__file__), 'RGBCubeMaterial.qml'),
                self.scene)
        cube_entity.addComponent(self.rgb_cube_material)

        return cube_transform

    def add_sphere(self, r):
        """
        Helper method to add a sphere to the scene.

        Arguments:
            r: float, the radius of the sphere

        Returns:
            the QTransform of the sphere
        """
        sphere_entity = QEntity(self.scene)
        sphere_mesh = QSphereMesh()
        sphere_mesh.setRadius(r)
        sphere_entity.addComponent(sphere_mesh)
        sphere_transform = QTransform(self.scene)
        sphere_entity.addComponent(sphere_transform)
        if not hasattr(self, 'sphere_material'):
            self.sphere_material = QPhongMaterial(self.scene)
            self.sphere_material.setAmbient(util.hsl(0, 0, 50))
        sphere_entity.addComponent(self.sphere_material)

        return sphere_transform

    def add_path(self, *pts):
        """
        Helper method to add a path to the scene.

        Arguments:
            pts: list of QVector3D's, the points in the path

        Returns:
            a list of the entities added to the scene
        """
        # make a bunch of cylinder objects aligned along the path
        entities = []
        prev_pt = None
        for pt in pts:
            if prev_pt is not None:
                if prev_pt != pt:
                    # for each adjacent pair of points that are different
                    # make a cylinder
                    path_entity = QEntity(self.scene)
                    path_mesh = QCylinderMesh()
                    path_mesh.setRadius(0.05)  # very thin
                    path_mesh.setLength((prev_pt - pt).length(
                    ))  # length is the distance between the points
                    path_entity.addComponent(path_mesh)
                    path_transform = QTransform(self.scene)
                    path_transform.setRotation(
                        QQuaternion.fromDirection(
                            QVector3D(0, 0, -1),
                            prev_pt - pt))  # rotate to point along path
                    path_transform.setTranslation(
                        (pt + prev_pt) / 2)  # center between points
                    path_entity.addComponent(path_transform)
                    if not hasattr(self, 'path_material'):
                        self.path_material = QPhongMaterial(self.scene)
                        self.path_material.setAmbient(util.hsl(0, 0, 50))
                    path_entity.addComponent(self.path_material)
                    entities.append(path_entity)
            prev_pt = pt
        return entities

    def setup_scene(self, background_color, camera_position, camera_lookat):
        """
        Sets up the scene. Should be called before running the animation.

        Arguments:
            background_color: QColor, background color of the scene
            camera_position: QVector3D, the position of the camera in the scene
            camera_lookat: QVector3D, the point that the camera should be pointing at in the scene
        """
        # clear color is the background color
        self.view.defaultFrameGraph().setClearColor(background_color)

        self.scene = QEntity()

        # let subclass populate scene
        self.make_scene()

        # set up camera
        camera = self.view.camera()
        camera.setPosition(camera_position)
        camera.setViewCenter(camera_lookat)

        self.view.setRootEntity(self.scene)

    def make_scene(self):
        """
        Abstract method. Populates the scene with objects.
        """
        raise NotImplementedError()

    def _update(self):
        """
        Updates the animation, rendering the next frame.
        """
        # current animation time in seconds
        t = util.lerp(self.frame, 0, self.frame_rate, 0, 1)
        # change in time since the last frame
        dt = 1 / self.frame_rate if self.prev_update_time is None else t - self.prev_update_time
        # call subclass's frame update
        self.update(self.frame, t, dt)

        # stop the animation and close the window if run past run_time
        if t >= self.run_time:
            self.animation_timer.stop()
            self.view.close()

        self.prev_update_time = t
        self.frame += 1

    def update(self, frame, t, dt):
        """
        Abstract method. Updates one frame of the animation.

        Arguments:
            frame: int, the current frame number
            t: float, the current animation time in seconds
            dt: float, the number of seconds since the last update
        """
        raise NotImplementedError()

    def run(self):
        """
        Runs the animation asynchronously. The animation runs in the background for self.run_time seconds.
        """
        self.animation_timer = QTimer(self.view)
        # timer interval in msecs
        self.animation_timer.setInterval(1000 / self.frame_rate)
        # call update on each timeout of the timer
        self.animation_timer.timeout.connect(self._update)
        self.animation_timer.start()

        # show the main window
        self.view.show()
Пример #5
0
    def __init__(self, rootEntity):
        super(SceneModifier, self).__init__()

        self.m_rootEntity = rootEntity

        # Torus shape data.
        self.m_torus = QTorusMesh()
        self.m_torus.setRadius(1.0)
        self.m_torus.setMinorRadius(0.4)
        self.m_torus.setRings(100)
        self.m_torus.setSlices(20)

        # TorusMesh transform.
        torusTransform = QTransform()
        torusTransform.setScale(2.0)
        torusTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(0.0, 1.0, 0.0), 25.0))
        torusTransform.setTranslation(QVector3D(5.0, 4.0, 0.0))

        torusMaterial = QPhongMaterial()
        torusMaterial.setDiffuse(QColor(0xbeb32b))

        # Torus.
        self.m_torusEntity = QEntity(self.m_rootEntity)
        self.m_torusEntity.addComponent(self.m_torus)
        self.m_torusEntity.addComponent(torusMaterial)
        self.m_torusEntity.addComponent(torusTransform)

        # Cone shape data.
        cone = QConeMesh()
        cone.setTopRadius(0.5)
        cone.setBottomRadius(1)
        cone.setLength(3)
        cone.setRings(50)
        cone.setSlices(20)

        # ConeMesh transform.
        coneTransform = QTransform()
        coneTransform.setScale(1.5)
        coneTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0))
        coneTransform.setTranslation(QVector3D(0.0, 4.0, -1.5))

        coneMaterial = QPhongMaterial()
        coneMaterial.setDiffuse(QColor(0x928327))

        # Cone.
        self.m_coneEntity = QEntity(self.m_rootEntity)
        self.m_coneEntity.addComponent(cone)
        self.m_coneEntity.addComponent(coneMaterial)
        self.m_coneEntity.addComponent(coneTransform)

        # Cylinder shape data.
        cylinder = QCylinderMesh()
        cylinder.setRadius(1)
        cylinder.setLength(3)
        cylinder.setRings(100)
        cylinder.setSlices(20)

        # CylinderMesh transform.
        cylinderTransform = QTransform()
        cylinderTransform.setScale(1.5)
        cylinderTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0))
        cylinderTransform.setTranslation(QVector3D(-5.0, 4.0, -1.5))

        cylinderMaterial = QPhongMaterial()
        cylinderMaterial.setDiffuse(QColor(0x928327))

        # Cylinder.
        self.m_cylinderEntity = QEntity(self.m_rootEntity)
        self.m_cylinderEntity.addComponent(cylinder)
        self.m_cylinderEntity.addComponent(cylinderMaterial)
        self.m_cylinderEntity.addComponent(cylinderTransform)

        # Cuboid shape data.
        cuboid = QCuboidMesh()

        # CuboidMesh transform.
        cuboidTransform = QTransform()
        cuboidTransform.setScale(4.0)
        cuboidTransform.setTranslation(QVector3D(5.0, -4.0, 0.0))

        cuboidMaterial = QPhongMaterial()
        cuboidMaterial.setDiffuse(QColor(0x665423))

        # Cuboid.
        self.m_cuboidEntity = QEntity(self.m_rootEntity)
        self.m_cuboidEntity.addComponent(cuboid)
        self.m_cuboidEntity.addComponent(cuboidMaterial)
        self.m_cuboidEntity.addComponent(cuboidTransform)

        # Plane shape data.
        planeMesh = QPlaneMesh()
        planeMesh.setWidth(2)
        planeMesh.setHeight(2)

        # Plane mesh transform.
        planeTransform = QTransform()
        planeTransform.setScale(1.3)
        planeTransform.setRotation(
            QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0))
        planeTransform.setTranslation(QVector3D(0.0, -4.0, 0.0))

        planeMaterial = QPhongMaterial()
        planeMaterial.setDiffuse(QColor(0xa69929))

        # Plane.
        self.m_planeEntity = QEntity(self.m_rootEntity)
        self.m_planeEntity.addComponent(planeMesh)
        self.m_planeEntity.addComponent(planeMaterial)
        self.m_planeEntity.addComponent(planeTransform)

        # Sphere shape data.
        sphereMesh = QSphereMesh()
        sphereMesh.setRings(20)
        sphereMesh.setSlices(20)
        sphereMesh.setRadius(2)

        # Sphere mesh transform.
        sphereTransform = QTransform()
        sphereTransform.setScale(1.3)
        sphereTransform.setTranslation(QVector3D(-5.0, -4.0, 0.0))

        sphereMaterial = QPhongMaterial()
        sphereMaterial.setDiffuse(QColor(0xa69929))

        # Sphere.
        self.m_sphereEntity = QEntity(self.m_rootEntity)
        self.m_sphereEntity.addComponent(sphereMesh)
        self.m_sphereEntity.addComponent(sphereMaterial)
        self.m_sphereEntity.addComponent(sphereTransform)