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
}
}