Qt Quick 3D - Particles 3D Testbed Example
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick3D
import QtQuick3D.Particles3D
Item {
id: mainWindow
anchors.fill: parent
View3D {
anchors.fill: parent
environment: SceneEnvironment {
clearColor: "#202020"
backgroundMode: SceneEnvironment.Color
antialiasingMode: settings.antialiasingMode
antialiasingQuality: settings.antialiasingQuality
}
PerspectiveCamera {
id: camera
position: Qt.vector3d(0, 0, 600)
}
PointLight {
position: Qt.vector3d(0, 400, 0)
brightness: 10
ambientColor: Qt.rgba(0.3, 0.3, 0.3, 1.0)
}
// Model shared between particles
Component {
id: particleComponent
Model {
source: "#Cube"
scale: Qt.vector3d(0.02, 0.02, 0.15)
materials: DefaultMaterial {
lighting: DefaultMaterial.NoLighting
}
}
}
Model {
id: emittingSphere
source: "#Sphere"
scale: Qt.vector3d(0.5, 0.5, 0.5)
materials: DefaultMaterial {
opacity: 0.4
}
position: Qt.vector3d(-200, 100, 0)
SequentialAnimation on x {
running: true
loops: Animation.Infinite
NumberAnimation {
to: -100
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: -200
duration: 2000
easing.type: Easing.InOutQuad
}
}
// Emitters, one per particle
ParticleEmitter3D {
system: psystem
particle: particleRed
shape: ParticleShape3D {
type: ParticleShape3D.Sphere
fill: true
}
emitRate: 200
lifeSpan: 2000
}
ParticleEmitter3D {
id: emitter2
system: psystem
particle: particleGreen
shape: ParticleShape3D {
type: ParticleShape3D.Sphere
fill: true
}
emitRate: 200
lifeSpan: 5000
velocity: VectorDirection3D {
direction: Qt.vector3d(200, 200, 0)
directionVariation: Qt.vector3d(50, 50, 50)
}
particleRotationVelocityVariation: Qt.vector3d(500.0, 500.0, 500.0)
}
ParticleEmitter3D {
system: psystem
particle: particleWhite
shape: ParticleShape3D {
type: ParticleShape3D.Sphere
fill: true
}
emitRate: 200
lifeSpan: 2000
depthBias: 10
}
}
Model {
id: targetSphere
source: "#Sphere"
materials: DefaultMaterial {
opacity: 0.2
}
y: -200
SequentialAnimation on x {
running: true
loops: Animation.Infinite
NumberAnimation {
to: 200
duration: 3500
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 0
duration: 3500
easing.type: Easing.InOutQuad
}
}
Attractor3D {
system: psystem
particles: [particleRed]
// Attract into a position
positionVariation: Qt.vector3d(10, 10, 10)
duration: sliderDuration2.sliderValue
durationVariation: sliderDuration2Variation.sliderValue
hideAtEnd: checkBoxHide2.checked
}
Attractor3D {
system: psystem
particles: [particleGreen]
// Attract into a shape
shape: ParticleShape3D {
type: ParticleShape3D.Sphere
fill: false
}
duration: sliderDuration1.sliderValue
durationVariation: sliderDuration1Variation.sliderValue
hideAtEnd: checkBoxHide1.checked
useCachedPositions: false
SequentialAnimation on scale {
running: true
loops: Animation.Infinite
Vector3dAnimation {
to: Qt.vector3d(2, 2, 2)
duration: 3500
easing.type: Easing.InOutQuad
}
Vector3dAnimation {
to: Qt.vector3d(0.1, 0.1, 0.1)
duration: 3500
easing.type: Easing.InOutQuad
}
}
}
}
ParticleSystem3D {
id: psystem
// Particles
ModelParticle3D {
id: particleRed
delegate: particleComponent
maxAmount: 400
color: "#ff0000"
colorVariation: Qt.vector4d(0, 0, 0, 0.5)
alignMode: Particle3D.AlignTowardsTarget
alignTargetPosition: targetSphere.position
}
ModelParticle3D {
id: particleGreen
delegate: particleComponent
maxAmount: 1000
color: "#00ff00"
colorVariation: Qt.vector4d(0, 0, 0, 0.5)
}
SpriteParticle3D {
id: particleWhite
sprite: Texture {
source: "images/dot.png"
}
maxAmount: 400
color: "#ffffff"
colorVariation: Qt.vector4d(0, 0, 0, 0.5)
}
// Attractor inside ParticleSystem
Attractor3D {
particles: [particleWhite]
// Attract into a position
position: Qt.vector3d(-100, -250, 0)
positionVariation: Qt.vector3d(100, 10, 10)
duration: 1500
}
Wander3D {
particles: [particleGreen]
uniqueAmount: Qt.vector3d(10, 10, 10)
uniquePace: Qt.vector3d(1, 1, 1)
uniqueAmountVariation: 8
uniquePaceVariation: 0.8
fadeInDuration: 500
fadeOutDuration: 2000
}
}
}
SettingsView {
CustomLabel {
text: "Attractor 1: Duration"
}
CustomSlider {
id: sliderDuration1
sliderValue: 3000
fromValue: 1000
toValue: 5000
}
CustomLabel {
text: "Attractor 1: Duration Variation"
}
CustomSlider {
id: sliderDuration1Variation
sliderValue: 500
fromValue: 0
toValue: 2000
}
CustomCheckBox {
id: checkBoxHide1
text: "Attractor 1: Hide at end"
checked: false
}
Item {
width: 1
height: 40
}
CustomLabel {
text: "Attractor 2: Duration"
}
CustomSlider {
id: sliderDuration2
sliderValue: 1500
fromValue: 1000
toValue: 5000
}
CustomLabel {
text: "Attractor 2: Duration Variation"
}
CustomSlider {
id: sliderDuration2Variation
sliderValue: 500
fromValue: 0
toValue: 2000
}
CustomCheckBox {
id: checkBoxHide2
text: "Attractor 2: Hide at end"
checked: false
}
}
LoggingView {
anchors.bottom: parent.bottom
particleSystems: [psystem]
}
}