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
Item
{
id
:
mainWindow
readonly property
real
meterTicksAngle
:
300
readonly property
bool
particleNeedle
:
checkBoxParticlesNeedle.checked
property
real
separation
:
sliderElementSeparation.sliderValue
anchors.fill
:
parent
Behavior
on
separation {
SmoothedAnimation
{
velocity
:
0.2
duration
:
1000
}
}
View3D {
id
:
view3D
anchors.fill
:
parent
environment
:
SceneEnvironment {
clearColor
:
"#161610"
backgroundMode
:
SceneEnvironment.Color
antialiasingMode
:
settings.antialiasingMode
antialiasingQuality
:
settings.antialiasingQuality
}
PerspectiveCamera {
position
:
Qt.vector3d(0
, 100
, 600
-
separation *
100
)
}
PointLight {
position
:
Qt.vector3d(200
, 400
, 300
)
brightness
:
5
ambientColor
:
Qt.rgba(0.3, 0.3, 0.3, 1.0)
}
// Background
Model {
source
:
"#Rectangle"
scale
:
Qt.vector3d(25
, 15
, 0
)
z
:
-
300
materials
:
PrincipledMaterial {
baseColor
:
"#505040"
}
}
Node {
id
:
speedometerComponent
position
:
Qt.vector3d(0
, 100
, 0
)
eulerRotation.x
:
90
-
separation *
75
// Light which follows the needle
PointLight {
// Calculates the direction of the needle
function
getNeedleAngle(startAngle) {
return Math.sin
(
startAngle +
(-(
180
/
360
) +
(-
gaugeItem.
value *
meterTicksAngle /
360
) +
(
meterTicksAngle /
2
+
180
) /
360
) *
2
*
Math.
PI);
}
readonly property
real
lightRadius
:
120
readonly property
real
posX
:
getNeedleAngle(Math.PI) *
lightRadius
readonly property
real
posY
:
getNeedleAngle(Math.PI /
2
) *
lightRadius
position
:
Qt.vector3d(posX, 40
, -
posY)
color
:
Qt.rgba(1.0, 0.8, 0.4, 1.0)
brightness
:
sliderNeedleBrightness.sliderValue
quadraticFade
:
4.0
}
Model {
y
:
-
4
-
separation *
100
source
:
"meshes/meter_background.mesh"
scale
:
Qt.vector3d(30
, 30
, 30
)
materials
:
PrincipledMaterial {
baseColor
:
"#505050"
metalness
:
1.0
roughness
:
0.6
normalMap
:
Texture {
source
:
"images/leather_n.png"
}
normalStrength
:
0.4
}
}
Model {
y
:
-
35
-
separation *
100
source
:
"#Sphere"
scale
:
Qt.vector3d(1.6, 0.2, 1.6)
materials
:
PrincipledMaterial {
baseColor
:
"#606060"
}
}
Model {
y
:
-
separation *
60
source
:
"#Cylinder"
scale
:
Qt.vector3d(0.2, 0.8, 0.2)
materials
:
PrincipledMaterial {
baseColor
:
"#606060"
}
}
Model {
y
:
30
-
separation *
60
source
:
"#Sphere"
scale
:
Qt.vector3d(0.4, 0.1, 0.4)
materials
:
PrincipledMaterial {
baseColor
:
"#f0f0f0"
}
}
// Speedometer labels
Model {
y
:
25
+
separation *
20
source
:
"#Rectangle"
scale
:
Qt.vector3d(4
, 4
, 4
)
eulerRotation.x
:
-
90
materials
:
PrincipledMaterial {
alphaMode
:
PrincipledMaterial.Blend
baseColorMap
:
Texture {
source
:
"images/speedometer_labels.png"
}
}
}
Model {
y
:
separation *
60
source
:
"meshes/meter_edge.mesh"
scale
:
Qt.vector3d(30
, 30
, 30
)
materials
:
PrincipledMaterial {
baseColor
:
"#b0b0b0"
}
}
Node {
id
:
gaugeItem
property
real
value
:
0
property
real
needleSize
:
180
SequentialAnimation
on
value
{
running
:
checkBoxAnimateSpeed.checked
loops
:
Animation.Infinite
NumberAnimation
{
duration
:
8000
to
:
1
easing.type
:
Easing.InOutQuad
}
NumberAnimation
{
duration
:
8000
to
:
0
easing.type
:
Easing.InOutQuad
}
}
y
:
20
-
separation *
60
eulerRotation.z
:
90
eulerRotation.y
:
-
meterTicksAngle *
value
+
(meterTicksAngle/
2
-
90
)
Model {
position.y
:
gaugeItem.needleSize /
2
source
:
"#Cylinder"
scale
:
Qt.vector3d(0.05, gaugeItem.needleSize *
0.01, 0.2)
materials
:
PrincipledMaterial {
baseColor
:
"#606060"
opacity
:
particleNeedle ? 0.0 :
1.0
}
ParticleEmitter3D {
system
:
psystemGauge
particle
:
particleSpark
y
:
10
scale
:
Qt.vector3d(0.1, 0.8, 0.1)
shape
:
ParticleShape3D {
type
:
ParticleShape3D.Cube
}
particleScale
:
2.0
particleScaleVariation
:
1.0
particleRotationVariation
:
Qt.vector3d(0
, 0
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(20
, 20
, 200
);
emitRate
:
500
lifeSpan
:
2000
lifeSpanVariation
:
1000
}
// Needle particle system
// This system rotates together with the needle
ParticleSystem3D {
id
:
psystemNeedle
running
:
particleNeedle
visible
:
running
SpriteParticle3D {
id
:
needleParticle
sprite
:
Texture {
source
:
"images/dot.png"
}
maxAmount
:
500
fadeInDuration
:
50
fadeOutDuration
:
200
color
:
"#40808020"
colorVariation
:
Qt.vector4d(0.2, 0.2, 0.0, 0.2)
blendMode
:
SpriteParticle3D.Screen
}
ParticleEmitter3D {
particle
:
needleParticle
y
:
-
50
scale
:
Qt.vector3d(0.2, 0.0, 0.2)
shape
:
ParticleShape3D {
type
:
ParticleShape3D.Cube
}
particleScale
:
4.0
particleScaleVariation
:
2.0
particleEndScale
:
1.0
particleEndScaleVariation
:
0.5
velocity
:
VectorDirection3D {
direction
:
Qt.vector3d(0
, 110
, 0
)
directionVariation
:
Qt.vector3d(10
, 10
, 10
)
}
emitRate
:
sliderNeedleEmitrate.sliderValue
lifeSpan
:
1000
}
}
}
}
// Gauge particle system
ParticleSystem3D {
id
:
psystemGauge
// Particles coming under the needle
SpriteParticle3D {
id
:
particleSpark
sprite
:
Texture {
source
:
"images/star3.png"
}
maxAmount
:
1500
fadeInEffect
:
SpriteParticle3D.FadeNone
fadeOutDuration
:
200
color
:
"#40ff0000"
colorVariation
:
Qt.vector4d(0.4, 0.2, 0.2, 0.2)
unifiedColorVariation
:
true
blendMode
:
SpriteParticle3D.Screen
}
// Particles rotating the gauge
SpriteParticle3D {
id
:
particleSpark2
sprite
:
Texture {
source
:
"images/star3.png"
}
maxAmount
:
30
fadeInDuration
:
1000
fadeOutDuration
:
1000
color
:
"#20ffffff"
colorVariation
:
Qt.vector4d(0.2, 0.2, 0.5, 0.1)
blendMode
:
SpriteParticle3D.Screen
}
ParticleEmitter3D {
y
:
40
+
separation *
60
particle
:
particleSpark2
scale
:
Qt.vector3d(3.8, 0
, 3.8)
shape
:
ParticleShape3D {
type
:
ParticleShape3D.Cylinder
}
emitRate
:
10
lifeSpan
:
3000
particleScale
:
4.0
particleScaleVariation
:
3.0
particleRotationVariation
:
Qt.vector3d(20
, 20
, 180
)
particleRotationVelocityVariation
:
Qt.vector3d(10
, 10
, 50
)
}
Wander3D {
uniqueAmount
:
Qt.vector3d(10
, 0
, 10
)
uniquePace
:
Qt.vector3d(0.1, 0.1, 0.1)
fadeInDuration
:
2000
}
PointRotator3D {
particles
:
particleSpark2
magnitude
:
-
20
}
}
}
}
SettingsView {
CustomCheckBox {
id
:
checkBoxAnimateSpeed
text
:
"Animate Speed"
checked
:
true
}
CustomLabel {
text
:
"Speed"
opacity
:
!
checkBoxAnimateSpeed.checked ? 1.0 :
0.4
}
CustomSlider {
id
:
sliderSpeedValue
sliderValue
:
gaugeItem.value
sliderEnabled
:
!
checkBoxAnimateSpeed.checked
fromValue
:
0
toValue
:
1
onSliderValueChanged
:
gaugeItem.value =
sliderValue;
}
CustomCheckBox {
id
:
checkBoxParticlesNeedle
text
:
"Particles Needle"
checked
:
true
}
CustomLabel {
text
:
"Needle emitRate"
opacity
:
checkBoxParticlesNeedle.checked ? 1.0 :
0.4
}
CustomSlider {
id
:
sliderNeedleEmitrate
sliderValue
:
200
sliderEnabled
:
checkBoxParticlesNeedle.checked
fromValue
:
50
toValue
:
500
}
CustomLabel {
text
:
"Needle Brightness"
}
CustomSlider {
id
:
sliderNeedleBrightness
sliderValue
:
10
fromValue
:
0
toValue
:
50
}
CustomLabel {
text
:
"Elements Separation"
}
CustomSlider {
id
:
sliderElementSeparation
sliderValue
:
0
fromValue
:
0
toValue
:
1
}
}
LoggingView {
anchors.bottom
:
parent.bottom
particleSystems
:
[psystemGauge, psystemNeedle]
}
}