Qt Quick 3D Physics - CharacterController Example

 // Copyright (C) 2023 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
 import QtQuick
 import QtQuick3D
 import QtQuick3D.Physics
 import QtQuick3D.Particles3D

 Node {
     property bool inGravityField: false
     signal teleporterTriggered

     PrincipledMaterial {
         id: wallMateriall
         baseColor: "#ff776644"
         roughness: 0.7
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }
     PrincipledMaterial {
         id: triggerMaterial
         baseColor: "#66aaff"
         roughness: 0.5
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }
     PrincipledMaterial {
         id: doorMaterial
         baseColor: "#ff10670e"
         roughness: 0.5
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }

     PrincipledMaterial {
         id: whiteMaterial
         baseColor: "white"
         roughness: 0.8
     }

     Texture {
         id: tileColor_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tiles107_1K_Color.jpg"
     }
     Texture {
         id: tileNormal_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tiles107_1K_NormalGL.jpg"
     }
     Texture {
         id: tileRoughness_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tiles107_1K_Roughness.jpg"
     }

     Texture {
         id: blackTileColor_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tiles108_1K_Color.jpg"
     }

     PrincipledMaterial {
         id: internalWallMaterial
         baseColorMap: tileColor_texture
         roughnessMap: tileRoughness_texture
         roughness: 1
         normalMap: tileNormal_texture
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }

     PrincipledMaterial {
         id: testFloor
         baseColorMap: blackTileColor_texture
         roughnessMap: tileRoughness_texture
         roughness: 1
         normalMap: tileNormal_texture
         normalStrength: 0.5
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }

     Texture {
         id: warningColor_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tape001_1K_Color.jpg"
     }
     Texture {
         id: warningNormal_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tape001_1K_NormalGL.jpg"
     }
     Texture {
         id: warningRoughness_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         source: "maps/Tape001_1K_Roughness.jpg"
     }

     PrincipledMaterial {
         id: warningMaterial
         baseColorMap: warningColor_texture
         roughnessMap: warningRoughness_texture
         roughness: 1
         normalMap: warningNormal_texture
         cullMode: PrincipledMaterial.NoCulling
         alphaMode: PrincipledMaterial.Opaque
     }

     StaticRigidBody {
         id: building
         position: Qt.vector3d(-165.234, -99.9, -443.476)
         collisionShapes: TriangleMeshShape {
             source: "meshes/building.mesh"
         }
         Model {
             source: "meshes/building.mesh"
             materials: [testFloor, internalWallMaterial, whiteMaterial, warningMaterial]
         }
     }

     TriggerBody {
         id: trigger
         position: Qt.vector3d(-162.316, -16.3654, -743.701)
         scale: "13.26, 8.33, 5.58"
         collisionShapes: BoxShape {}
         Model {
             source: "#Cube"
             materials: triggerMaterial
             opacity: 0.1
         }
         onBodyEntered: inGravityField = true
         onBodyExited: inGravityField = false
     }

     Timer {
         id: teleportTriggerDelay
         interval: 250
         onTriggered: teleporterTriggered() // emit signal
     }

     TriggerBody {
         id: teleportTrigger
         position: Qt.vector3d(-762.058, 100, 424.581)
         scale: Qt.vector3d(1, 4, 1)
         collisionShapes: BoxShape {}
         Model {
             source: "#Cylinder"
             materials: PrincipledMaterial {
                 baseColor: "red"
             }
             opacity: 0.2
         }
         onBodyEntered: teleportTriggerDelay.start()
         onBodyExited: teleportTriggerDelay.stop()
     }

     ParticleSystem3D {
         id: psystem

         startTime: 5000

         SpriteParticle3D {
             id: spriteParticle
             sprite: Texture {
                 source: "maps/sphere.png"
             }
             maxAmount: 10000
             color: "#aaccff"
             colorVariation: Qt.vector4d(0.0, 0.0, 0.0, 0.5)
             fadeInDuration: 1000
             fadeOutDuration: 1000
             billboard: true
         }

         ParticleEmitter3D {
             id: emitter
             particle: spriteParticle
             position: Qt.vector3d(-200, -600, -750)
             depthBias: -100
             scale: Qt.vector3d(12.0, 0.5, 5.0)
             shape: ParticleShape3D {
                 type: ParticleShape3D.Cube
             }
             particleScale: 2.0
             particleScaleVariation: 1.0
             velocity: VectorDirection3D {
                 direction: Qt.vector3d(0, 100, 0)
                 directionVariation: Qt.vector3d(20, 50, 20)
             }
             emitRate: 1000
             lifeSpan: 10000
         }

         SpriteParticle3D {
             id: teleportParticle
             sprite: Texture {
                 source: "maps/sphere.png"
             }
             maxAmount: 5000
             color: "#ffccaa"
             colorVariation: Qt.vector4d(0.2, 0.2, 0.2, 0.5)
             fadeInDuration: 500
             fadeOutDuration: 500
             billboard: true
         }

         ParticleEmitter3D {
             id: teleportEmitter
             particle: teleportParticle
             position: Qt.vector3d(-712.058, 100, 424.581)
             depthBias: -100
             scale: Qt.vector3d(0.1, 4, 1)
             shape: ParticleShape3D {
                 type: ParticleShape3D.Cube
             }
             particleScale: 0.5
             particleScaleVariation: 1.0
             velocity: VectorDirection3D {
                 direction: Qt.vector3d(-100, 0, 0)
                 directionVariation: Qt.vector3d(20, 50, 20)
             }
             emitRate: 5000
             lifeSpan: 1000
         }
     }

     TriggerBody {
         id: doorTrigger
         position: Qt.vector3d(864.5, 200.4, -461)
         scale: Qt.vector3d(1.5, 2, 3)
         collisionShapes: BoxShape {}
         onBodyEntered: door.open = true
         onBodyExited: door.open = false
     }

     Node {
         id: doorNode
         position: Qt.vector3d(864.5, 200, -461)
         DynamicRigidBody {
             id: door
             property bool open: false
             isKinematic: true
             scale: Qt.vector3d(0.8, 2, 0.1)
             kinematicPosition.x: open ? 79 : 0
             collisionShapes: BoxShape {}
             Model {
                 source: "#Cube"
                 materials: doorMaterial
             }
             Behavior on kinematicPosition.x {
                 NumberAnimation {
                     duration: 1000
                     easing.type: Easing.InOutQuad
                 }
             }
         }
     }

     Texture {
         id: sign_texture
         generateMipmaps: true
         mipFilter: Texture.Linear
         flipV: true
         flipU: true
         source: "maps/sign.png"
     }

     PrincipledMaterial {
         id: sign_material
         baseColorMap: sign_texture
     }

     Model {
         id: sign

         position: Qt.vector3d(704.498, 269.974, -476.206)
         rotation: Qt.quaternion(0, 1, 0, 0)
         scale: Qt.vector3d(1.8, 1, 0.0687316)
         source: "#Cube"
         materials: sign_material
     }
 }