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, 100, 600)
}
ParticleSystem3D {
id: psystem
// Particles
SpriteParticle3D {
id: animated
sprite: Texture {
source: "images/bear_black.png"
}
spriteSequence: SpriteSequence3D {
frameCount: 13
interpolate: false
duration: 2000
durationVariation: 1500
}
maxAmount: 4
billboard: true
blendMode: SpriteParticle3D.Screen
}
SpriteParticle3D {
id: blended
sprite: Texture {
source: "images/explosion_01_strip13.png"
}
spriteSequence: SpriteSequence3D {
frameCount: 13
interpolate: true
}
maxAmount: 26
billboard: true
blendMode: SpriteParticle3D.Screen
}
SpriteParticle3D {
id: numberParticle
sprite: Texture {
source: "images/sprite_09.png"
}
spriteSequence: SpriteSequence3D {
id: numberParticleSequence
frameCount: 10
frameIndex: sliderFrameIndex.sliderValue
animationDirection: sliderAnimationDirection.sliderValue
interpolate: checkBoxInterpolate.checked
randomStart: checkBoxRandom.checked
duration: sliderDuration.sliderValue
durationVariation: sliderDurationVariation.sliderValue
}
maxAmount: 10
billboard: true
blendMode: SpriteParticle3D.Screen
}
// Emitters, one per particle
ParticleEmitter3D {
id: emitter1
particle: animated
particleScale: 10
position: Qt.vector3d(-300, 0, 0)
emitRate: 1
lifeSpan: 4000
shape: ParticleShape3D {
fill: true
}
Node {
y: -140
x: -100
Text {
anchors.verticalCenter: parent.verticalCenter
text: "Animated + durationVariation"
font.pointSize: settings.fontSizeLarge
color: "#ffffff"
}
}
}
ParticleEmitter3D {
id: emitter2
particle: blended
position: Qt.vector3d(300, -100, 0)
particleScale: 20
velocity: VectorDirection3D {
direction: Qt.vector3d(0, 100, 0)
directionVariation: Qt.vector3d(50, 50, 50)
}
emitRate: 12
lifeSpan: 2000
lifeSpanVariation: 200
Node {
y: -40
x: -100
Text {
anchors.verticalCenter: parent.verticalCenter
text: "Animated + interpolated"
font.pointSize: settings.fontSizeLarge
color: "#ffffff"
}
}
}
ParticleEmitter3D {
id: emitter3
particle: numberParticle
particleScale: 8
position: Qt.vector3d(0, 350, 0)
emitRate: 2
lifeSpan: 5000
velocity: VectorDirection3D {
direction: Qt.vector3d(0, -100, 0)
}
Node {
y: 40
x: -50
Text {
anchors.verticalCenter: parent.verticalCenter
text: "Controlled"
font.pointSize: settings.fontSizeLarge
color: "#ffffff"
}
}
}
}
}
SettingsView {
CustomLabel {
property var enumStrings: ["Normal", "Reverse", "Alternate", "AlternateReverse", "SingleFrame"]
text: "Animation Direction: " + enumStrings[numberParticleSequence.animationDirection]
}
CustomSlider {
id: sliderAnimationDirection
sliderValue: 0
fromValue: 0
toValue: 4
sliderStepSize: 1
}
CustomLabel {
text: "Duration"
}
CustomSlider {
id: sliderDuration
sliderValue: -1
fromValue: -1
toValue: 8000
}
CustomLabel {
text: "Duration Variation"
}
CustomSlider {
id: sliderDurationVariation
sliderValue: 0
fromValue: 0
toValue: 2000
}
CustomCheckBox {
id: checkBoxInterpolate
text: "Interpolate"
checked: false
}
CustomCheckBox {
id: checkBoxRandom
text: "Random Start"
checked: false
}
CustomLabel {
text: "Frame Index"
opacity: checkBoxRandom.checked ? 0.4 : 1.0
}
CustomSlider {
id: sliderFrameIndex
sliderValue: 0
fromValue: 0
toValue: 9
sliderEnabled: !checkBoxRandom.checked
sliderStepSize: 1
}
}
LoggingView {
anchors.bottom: parent.bottom
particleSystems: [psystem]
}
}