Kuesa Music Box QML Example
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Input 2.12
import Qt3D.Logic 2.12
import Qt3D.Extras 2.12
import Qt3D.Animation 2.12
import QtQml 2.2
import QtQuick 2.12
import Kuesa 1.2 as Kuesa
import Kuesa.Effects 1.1 as KuesaFX
import MusicBox 1.0 as MusicBox
Kuesa.SceneEntity {
id: scene
QtObject {
id: d
readonly property var robotArmAnimations: [
'ArmTopAction',
'FingerBase3Action',
'armBottomBottomAction',
'armBottomBottomGauge.001Action',
'armBottomBottomGaugeAction',
'armBottomTopAction',
'cogAction',
'elbowPivotAction',
'elbowPivotBaseAction',
'fingerBase2Action',
'fingerKnuckle1Action',
'fingerPivot1.001Action',
'fingerPivot2Action',
'fingerTop1Action',
'fingerTop2Action',
'fingerTop3Action',
'handleAction.001',
'handleCoverAction',
'musicBarrelAction',
'shoulderPivotAction',
'shoulderPivotBaseAction',
'thumbBaseBottomAction',
'thumbKnuckleAction',
'thumbPivotAction',
'thumbTopAction',
'wristPivotAction'
]
readonly property var musicRows: [
'........x.....................',
'...x................x.........',
'................x.............',
'............x.................',
'........x.....................',
'....x.................x.......',
'................x.............',
'..............x...............',
'........x.....................',
'.....x....x............x......',
'..................x...........',
'......x........x..............',
'.......x......................',
'......x...x.............x.....',
'..................x...........',
'................x.............',
'........x.....................',
'.........x...............x....',
'.......x.........x..x.........',
'.....x......x..x..............',
'...x..........................',
'....x.................x.......',
'......x.......x..x.x..........',
'........x..x..x...............',
'.........x....................',
'........x.........x.......x...',
'..................x...x.......',
'................x.x...........',
'..........x...................',
'....x.x.x.......x.......x.....',
'................x..x..x.......',
'............x..x..............',
'.......x......................',
'..x....x.x.........x......x...',
'...................x...x......',
'...........x...x.x.x..........',
'.......x......................',
'...x...x..x.........x......x..',
'....................x..x......',
'...............x....x..x......',
'.......x......................',
'....x....x.x..........x.....x.',
'.................x.x..x.......',
'.....x...x.x..x..x.x..........',
'......x..x.x.....x.x..x.......',
'.....x...x...x.........x.....x',
'.................x...x...x....',
'...............x.x............',
'.......x......................',
'........x...............x.....',
'......x.........x..x..........',
'....x......x..x...............',
'..x...........................',
'.x................x..x........',
'x.............................',
'...x.................x.x......',
'.....x........................',
'....x..x...x..............x...',
'...................x..........',
'.......x...x...x.......x......',
'.........................x....',
'...........x.....x.x......x...',
'.............................x',
'..........................x...'
]
readonly property var prongAnimations: [
prong29Action,
prong28Action,
prong27Action,
prong26Action,
prong25Action,
prong24Action,
prong23Action,
prong22Action,
prong21Action,
prong20Action,
prong19Action,
prong18Action,
prong17Action,
prong16Action,
prong15Action,
prong14Action,
prong13Action,
prong12Action,
prong11Action,
prong10Action,
prong09Action,
prong08Action,
prong07Action,
prong06Action,
prong05Action,
prong04Action,
prong03Action,
prong02Action,
prong01Action,
prong00Action,
]
property bool animationRunning: false
}
components: [
RenderSettings {
activeFrameGraph: Kuesa.ForwardRenderer {
id: frameGraph
camera: mainCamera
backToFrontSorting: true
toneMappingAlgorithm: KuesaFX.ToneMappingAndGammaCorrectionEffect.Reinhard
}
},
InputSettings { },
Kuesa.DirectionalLight {
direction: frameGraph.camera ? frameGraph.camera.viewVector : Qt.vector3d(0, -1, 0)
intensity: 0.05
},
EnvironmentLight {
irradiance: TextureLoader {
source: "pink_sunrise_16f_irradiance" + ((!scene.es2) ? ".dds" : "_es2.dds")
wrapMode {
x: WrapMode.ClampToEdge
y: WrapMode.ClampToEdge
}
generateMipMaps: false
}
specular: TextureLoader {
source: "pink_sunrise_16f_specular" + ((!scene.es2) ? ".dds" : "_es2.dds")
wrapMode {
x: WrapMode.ClampToEdge
y: WrapMode.ClampToEdge
}
generateMipMaps: false
}
},
FrameAction {
property var curRow: -1;
readonly property var prongAngleOffset: 0.5 * Math.PI;
onTriggered: {
if (!d.animationRunning)
return;
var matrix = scene.transformForEntity('musicBarrel').matrix;
var c = matrix.m22;
var s = matrix.m32;
var angle = -Math.atan2(s, c);
if (angle < 0)
angle += 2 * Math.PI;
var prongAngle = angle + prongAngleOffset;
var row = Math.floor(prongAngle * d.musicRows.length / (2 * Math.PI)) % d.musicRows.length;
if (row != curRow) {
curRow = row;
var rowNotes = d.musicRows[curRow];
for (var i = 0; i < d.prongAnimations.length; ++i) {
if (rowNotes.charAt(i) == 'x') {
var animation = d.prongAnimations[i];
animation.setNormalizedTime(0);
animation.start();
sampler.note(i, 0.5);
}
}
}
}
}
]
Camera {
id: mainCamera
fieldOfView: 35
position: Qt.vector3d(-3, 2, -3)
upVector: Qt.vector3d(0, 1, 0)
viewCenter: Qt.vector3d(-1.37, -0.112, 1.964)
}
CameraController {
camera: mainCamera
}
Kuesa.GLTF2Importer {
id: importer
sceneEntity: scene
source: "qrc:/RobotArm.gltf"
onStatusChanged: {
if (status == Kuesa.GLTF2Importer.Ready) {
actionPlayers.model = d.robotArmAnimations;
var musicBarrelTransform = scene.transformForEntity('musicBarrel');
musicBarrelTransform.defaultPropertyTrackingMode = Node.TrackAllValues;
d.animationRunning = true
}
}
}
Kuesa.Skybox {
id: skybox
baseName: "qrc:/pink_sunrise_skybox"
extension: ".dds"
}
NodeInstantiator {
id: actionPlayers
model: []
delegate: Kuesa.AnimationPlayer {
sceneEntity: scene
clip: modelData
loops: Kuesa.AnimationPlayer.Infinite
running: d.animationRunning
}
}
Kuesa.AnimationPlayer { id: prong00Action; sceneEntity: scene; clip: 'Prong00Action' }
Kuesa.AnimationPlayer { id: prong01Action; sceneEntity: scene; clip: 'Prong01Action' }
Kuesa.AnimationPlayer { id: prong02Action; sceneEntity: scene; clip: 'Prong02Action' }
Kuesa.AnimationPlayer { id: prong03Action; sceneEntity: scene; clip: 'Prong03Action' }
Kuesa.AnimationPlayer { id: prong04Action; sceneEntity: scene; clip: 'Prong04Action' }
Kuesa.AnimationPlayer { id: prong05Action; sceneEntity: scene; clip: 'Prong05Action' }
Kuesa.AnimationPlayer { id: prong06Action; sceneEntity: scene; clip: 'Prong06Action' }
Kuesa.AnimationPlayer { id: prong07Action; sceneEntity: scene; clip: 'Prong07Action' }
Kuesa.AnimationPlayer { id: prong08Action; sceneEntity: scene; clip: 'Prong08Action' }
Kuesa.AnimationPlayer { id: prong09Action; sceneEntity: scene; clip: 'Prong09Action' }
Kuesa.AnimationPlayer { id: prong10Action; sceneEntity: scene; clip: 'Prong10Action' }
Kuesa.AnimationPlayer { id: prong11Action; sceneEntity: scene; clip: 'Prong11Action' }
Kuesa.AnimationPlayer { id: prong12Action; sceneEntity: scene; clip: 'Prong12Action' }
Kuesa.AnimationPlayer { id: prong13Action; sceneEntity: scene; clip: 'Prong13Action' }
Kuesa.AnimationPlayer { id: prong14Action; sceneEntity: scene; clip: 'Prong14Action' }
Kuesa.AnimationPlayer { id: prong15Action; sceneEntity: scene; clip: 'Prong15Action' }
Kuesa.AnimationPlayer { id: prong16Action; sceneEntity: scene; clip: 'Prong16Action' }
Kuesa.AnimationPlayer { id: prong17Action; sceneEntity: scene; clip: 'Prong17Action' }
Kuesa.AnimationPlayer { id: prong18Action; sceneEntity: scene; clip: 'Prong18Action' }
Kuesa.AnimationPlayer { id: prong19Action; sceneEntity: scene; clip: 'Prong19Action' }
Kuesa.AnimationPlayer { id: prong20Action; sceneEntity: scene; clip: 'Prong20Action' }
Kuesa.AnimationPlayer { id: prong21Action; sceneEntity: scene; clip: 'Prong21Action' }
Kuesa.AnimationPlayer { id: prong22Action; sceneEntity: scene; clip: 'Prong22Action' }
Kuesa.AnimationPlayer { id: prong23Action; sceneEntity: scene; clip: 'Prong23Action' }
Kuesa.AnimationPlayer { id: prong24Action; sceneEntity: scene; clip: 'Prong24Action' }
Kuesa.AnimationPlayer { id: prong25Action; sceneEntity: scene; clip: 'Prong25Action' }
Kuesa.AnimationPlayer { id: prong26Action; sceneEntity: scene; clip: 'Prong26Action' }
Kuesa.AnimationPlayer { id: prong27Action; sceneEntity: scene; clip: 'Prong27Action' }
Kuesa.AnimationPlayer { id: prong28Action; sceneEntity: scene; clip: 'Prong28Action' }
Kuesa.AnimationPlayer { id: prong29Action; sceneEntity: scene; clip: 'Prong29Action' }
MusicBox.Sampler {
id: sampler
notes: [
"samples/114.wav",
"samples/112.wav",
"samples/110.wav",
"samples/109.wav",
"samples/107.wav",
"samples/105.wav",
"samples/103.wav",
"samples/102.wav",
"samples/100.wav",
"samples/98.wav",
"samples/97.wav",
"samples/95.wav",
"samples/94.wav",
"samples/93.wav",
"samples/91.wav",
"samples/90.wav",
"samples/88.wav",
"samples/86.wav",
"samples/85.wav",
"samples/83.wav",
"samples/82.wav",
"samples/81.wav",
"samples/79.wav",
"samples/78.wav",
"samples/76.wav",
"samples/74.wav",
"samples/71.wav",
"samples/70.wav",
"samples/67.wav",
"samples/66.wav"
]
property real previousRms:0.;
property real previousPeak: 0.;
onAudioSignal: {
var newRms = Math.log(1. + rms * previousRms) / 200.
var newPeak = Math.log(1. + peak * previousPeak) / 200.
previousRms = rms
previousPeak = peak
soundFxRadius = newRms
}
}
property real soundFxRadius: 0.
Kuesa.MetallicRoughnessMaterial {
id: material
effect: Kuesa.MetallicRoughnessEffect { }
materialProperties: Kuesa.MetallicRoughnessProperties {
baseColorFactor: "gray"
}
}
Entity {
Transform {
id: torus1Transform
translation: Qt.vector3d(-0.6, 0.35, 1.95)
scale3D: Qt.vector3d(300. * soundFxRadius, 300. * soundFxRadius, 300. * soundFxRadius)
Behavior on scale3D {
Vector3dAnimation { }
}
rotationY: 100
}
TorusMesh {
id: torus1Mesh
radius: 0.1
minorRadius: 0.01
rings: 100
slices: 20
}
components: [ torus1Mesh, material, torus1Transform ]
}
Entity {
Transform {
id: torus2Transform
translation: Qt.vector3d(-0.7, 0.35, 1.95)
scale3D: Qt.vector3d(200. * soundFxRadius, 200. * soundFxRadius, 200. * soundFxRadius)
Behavior on scale3D {
Vector3dAnimation { }
}
rotationY: 100
}
TorusMesh {
id: torus2Mesh
radius: 0.1
minorRadius: 0.02
rings: 100
slices: 20
}
components: [ torus2Mesh, material, torus2Transform ]
}
Entity {
Transform {
id: torus3transform
translation: Qt.vector3d(-.8, 0.35, 1.95)
scale3D: Qt.vector3d(100. * soundFxRadius, 100. * soundFxRadius, 100. * soundFxRadius)
Behavior on scale3D {
Vector3dAnimation { }
}
rotationY: 100
}
TorusMesh {
id: torus3Mesh
radius: 0.1
minorRadius: 0.05
rings: 100
slices: 20
}
components: [ torus3Mesh, material, torus3transform ]
}
}