Qt Quick 3D - Particles 3D Testbed Example▲
Sélectionnez
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import
QtQuick
import
QtQuick3D
import
QtQuick3D.Particles3D
import
QtQuick.Controls
Item
{
id
:
mainWindow
readonly property
int
burstCount
:
300
readonly property
int
maxEmitterCount
:
10
readonly property
int
trailEmitRate
:
10
property
var modelEmitters
:
[]
property
int
modelEmittersAmount
:
0
property
var spriteEmitters
:
[]
property
int
spriteEmittersAmount
:
0
function
createModelEmitter() {
var newObject =
modelEmitterComponent.createObject
(
psystem);
modelEmitters.push
(
newObject);
modelEmittersAmount =
modelEmitters.
length;
}
function
createSpriteEmitter() {
var newObject =
spriteEmitterComponent.createObject
(
psystem);
spriteEmitters.push
(
newObject);
spriteEmittersAmount =
spriteEmitters.
length;
}
anchors.fill
:
parent
Component.onCompleted
: {
createModelEmitter
(
);
createSpriteEmitter
(
);
}
View3D {
id
:
view3D
anchors.fill
:
parent
camera
:
camera
environment
:
SceneEnvironment {
clearColor
:
"#202020"
backgroundMode
:
SceneEnvironment.Color
antialiasingMode
:
settings.antialiasingMode
antialiasingQuality
:
settings.antialiasingQuality
}
PerspectiveCamera {
id
:
camera
position
:
Qt.vector3d(0
, 100
, 600
)
}
PointLight {
position
:
Qt.vector3d(0
, 400
, 100
)
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.2, 0.2, 0.2)
materials
:
DefaultMaterial {
}
}
}
Component
{
id
:
modelEmitterComponent
Model {
source
:
"#Cylinder"
materials
:
DefaultMaterial {}
position
:
Qt.vector3d(Math.random() *
250
-
300
, -
150
, 0
)
scale
:
Qt.vector3d(0.5, 0.1, 0.5)
ParticleEmitter3D {
system
:
psystem
particle
:
particleWhite
particleScaleVariation
:
0.4
particleRotationVariation
:
Qt.vector3d(180
, 180
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(200
, 200
, 200
);
velocity
:
VectorDirection3D {
direction
:
Qt.vector3d(0
, 400
, 0
)
directionVariation
:
Qt.vector3d(40
, 40
, 0
)
}
emitRate
:
2
lifeSpan
:
4000
}
}
}
Component
{
id
:
spriteEmitterComponent
Model {
source
:
"#Cylinder"
materials
:
DefaultMaterial {
diffuseColor
:
"#ffff00"
}
position
:
Qt.vector3d(Math.random() *
250
+
50
, -
150
, 0
)
scale
:
Qt.vector3d(0.5, 0.1, 0.5)
ParticleEmitter3D {
system
:
psystem
particle
:
particleSprite
particleScaleVariation
:
0.4
particleRotationVariation
:
Qt.vector3d(180
, 180
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(200
, 200
, 200
);
velocity
:
VectorDirection3D {
direction
:
Qt.vector3d(0
, 400
, 0
)
directionVariation
:
Qt.vector3d(40
, 40
, 0
)
}
emitRate
:
2
lifeSpan
:
4000
}
}
}
ParticleSystem3D {
id
:
psystem
useRandomSeed
:
checkBoxRandomize.checked
onTimeChanged
: {
if (
time &
gt;
9500
)
psystem.
paused =
true;
}
// Particles
ModelParticle3D {
id
:
particleTrailModel
delegate
:
particleComponent
maxAmount
:
maxEmitterCount *
8
*
trailEmitRate
fadeInDuration
:
200
fadeOutDuration
:
500
color
:
"#808080"
colorVariation
:
Qt.vector4d(0.2, 0.2, 0.2, 0.5)
unifiedColorVariation
:
true
}
ModelParticle3D {
id
:
particleWhite
delegate
:
particleComponent
maxAmount
:
maxEmitterCount *
8
color
:
"#ffffff"
}
ModelParticle3D {
id
:
particleRed
delegate
:
particleComponent
maxAmount
:
burstCount *
3
color
:
"#ff0000"
}
SpriteParticle3D {
id
:
particleSprite
sprite
:
Texture {
source
:
"images/star2.png"
}
maxAmount
:
maxEmitterCount *
8
color
:
"#ffff00"
particleScale
:
30.0
}
SpriteParticle3D {
id
:
particleTrailSprite
sprite
:
Texture {
source
:
"images/star2.png"
}
maxAmount
:
maxEmitterCount *
8
*
trailEmitRate
fadeInDuration
:
200
fadeOutDuration
:
500
color
:
"#999900"
particleScale
:
15.0
}
// Emitters, one per particle
TrailEmitter3D {
id
:
modelTrailEmitter
particle
:
particleTrailModel
follow
:
particleWhite
particleScale
:
0.5
particleScaleVariation
:
0.2
particleRotationVariation
:
Qt.vector3d(180
, 180
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(100
, 100
, 100
);
velocity
:
VectorDirection3D {
directionVariation
:
Qt.vector3d(20
, 20
, 20
)
}
emitRate
:
trailEmitRate
lifeSpan
:
1000
}
TrailEmitter3D {
id
:
spriteTrailEmitter
particle
:
particleTrailSprite
follow
:
particleSprite
particleScaleVariation
:
0.2
particleRotationVariation
:
Qt.vector3d(180
, 180
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(100
, 100
, 100
);
velocity
:
VectorDirection3D {
directionVariation
:
Qt.vector3d(20
, 20
, 20
)
}
emitRate
:
trailEmitRate
lifeSpan
:
1000
}
ParticleEmitter3D {
id
:
burstEmitter
particle
:
particleRed
scale
:
Qt.vector3d(0.5, 0.5, 0.5)
particleScale
:
0.2
particleEndScale
:
0.4
particleRotationVariation
:
Qt.vector3d(180
, 180
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(200
, 200
, 200
);
shape
:
ParticleShape3D {
type
:
ParticleShape3D.Sphere
fill
:
false
}
velocity
:
TargetDirection3D {
position
:
burstEmitter.position
magnitude
:
-
4.0
}
lifeSpan
:
1000
lifeSpanVariation
:
500
}
Gravity3D {
direction
:
Qt.vector3d(0
, 1
, 0
)
magnitude
:
-
200
}
}
}
MouseArea
{
anchors.fill
:
parent
onClicked
: {
var pos =
view3D.mapTo3DScene
(
Qt.vector3d
(
mouseX,
mouseY,
camera.
z));
burstEmitter.setPosition
(
pos);
burstEmitter.burst
(
burstCount);
}
}
SettingsView {
Row
{
spacing
:
10
anchors.horizontalCenter
:
parent.horizontalCenter
Button
{
text
:
psystem.running ? qsTr("Stop"
) :
qsTr("Start"
)
font.pointSize
:
settings.fontSizeSmall
onClicked
: {
psystem.
running =
!
psystem.
running;
}
}
Button
{
text
:
psystem.paused ? qsTr("Continue"
) :
qsTr("Pause"
)
font.pointSize
:
settings.fontSizeSmall
enabled
:
psystem.running
onClicked
: {
psystem.
paused =
!
psystem.
paused;
}
}
}
Item
{
width
:
1
height
:
10
}
CustomLabel {
text
:
"ParticleSystem time"
opacity
:
timeSlider.sliderEnabled ? 1.0 :
0.4
}
CustomSlider {
id
:
timeSlider
sliderValue
:
psystem.time
sliderEnabled
:
psystem.paused
fromValue
:
0
toValue
:
10000
onSliderValueChanged
:
psystem.setTime(sliderValue);
}
Item
{
width
:
1
height
:
10
}
CustomLabel {
text
:
"ParticleSystem seed: "
+
psystem.seed
}
CustomCheckBox {
id
:
checkBoxRandomize
text
:
"Use random seed"
checked
:
true
}
CustomLabel {
text
:
"Custom seed"
opacity
:
psystem.useRandomSeed ? 0.4 :
1.0
}
CustomSlider {
sliderValue
:
0
sliderEnabled
:
!
psystem.useRandomSeed
fromValue
:
0
toValue
:
99
sliderStepSize
:
1
onSliderValueChanged
:
psystem.setSeed(sliderValue);
}
Item
{
width
:
1
; height
:
20
}
CustomLabel {
anchors.horizontalCenter
:
parent.horizontalCenter
text
:
"Model Emitters: "
+
modelEmittersAmount
}
Item
{
width
:
1
; height
:
5
}
Row
{
spacing
:
10
anchors.horizontalCenter
:
parent.horizontalCenter
Button
{
text
:
qsTr("Add"
)
font.pointSize
:
settings.fontSizeSmall
enabled
:
modelEmittersAmount &
lt; 10
onClicked
:
createModelEmitter();
}
Button
{
text
:
qsTr("Remove"
)
font.pointSize
:
settings.fontSizeSmall
enabled
:
modelEmittersAmount &
gt; 0
onClicked
: {
let instance =
modelEmitters.pop
(
);
instance.destroy
(
);
modelEmittersAmount =
modelEmitters.
length;
}
}
}
Item
{
width
:
1
; height
:
20
}
CustomLabel {
anchors.horizontalCenter
:
parent.horizontalCenter
text
:
"Sprite Emitters: "
+
spriteEmittersAmount
}
Item
{
width
:
1
; height
:
5
}
Row
{
spacing
:
10
anchors.horizontalCenter
:
parent.horizontalCenter
Button
{
text
:
qsTr("Add"
)
font.pointSize
:
settings.fontSizeSmall
enabled
:
spriteEmittersAmount &
lt; 10
onClicked
:
createSpriteEmitter();
}
Button
{
text
:
qsTr("Remove"
)
font.pointSize
:
settings.fontSizeSmall
enabled
:
spriteEmittersAmount &
gt; 0
onClicked
: {
let instance =
spriteEmitters.pop
(
);
instance.destroy
(
);
spriteEmittersAmount =
spriteEmitters.
length;
}
}
}
}
LoggingView {
anchors.bottom
:
parent.bottom
particleSystems
:
[psystem]
}
}