I'm currently struggling to play the animation of a gltf-file with Qt3D/QML.
Model I want to use:
https://sketchfab.com/3d-models/plane-cedc8a07370747f7b0d14400cdf2faf9
Code I have so far:
Entity {
id: root
Transform {
id: planeTransform
scale: 0.1
}
components: [
planeClip,
planeTransform,
planeScene
]
SceneLoader{
id:planeScene
source: "qrc:/Modells/3DModelle/plane/scene.gltf"
}
AnimationClipLoader{
id: planeClipLoader
source: "qrc:/Modells/3DModelle/plane/scene.gltf"
}
ClipAnimator{
id: planeClip
clip: planeClipLoader
channelMapper: ChannelMapper {
mappings: [ ] // Dont know where to get this
}
loops: Animation.Infinite
running: true
}
}
I use the SceneLoader to check if the gltf can be even loaded (it works, I can see the plane). But I'm struggling to start the animation because I don't know where I get the ChannelMapper from.
When I open the file with 3DViewer on Windows, it plays the Animation correctly, so I suppose it should work without much insider knowledge of the file itself.
Anyone here familiar with playing gltf animations?
Thanks for the help!
To do this you need to traverse the tree of Entity
(s) build by SceneLoader
and find the appropriate component to initialize ClipAnimator
with.
It's going to look something like this:
SceneLoader {
id: planeScene
source: "qrc:/Modells/3DModelle/plane/scene.gltf"
onStatusChanged: {
console.log("SceneLoader status=" + status);
if (status != SceneLoader.Ready)
return;
// retrieve a list of all the Entity(s) in the scene
var entityNames = planeScene.entityNames();
console.log("SceneLoader: entityNames=" + entityNames);
// traverse the Entity tree
for (var i = 0; i < entityNames.length; ++i) {
var entityName = entityNames[i];
var entityVar = planeScene.entity(entityName);
console.log("SceneLoader: entity=" + entityName + " components.length=" + entityVar.components.length);
// iterate on the components of this Entity
for (var j = 0; j < entityVar.components.length; ++j) {
var cmp = entityVar.components[j];
if (!cmp)
continue;
var cmp_class = cmp.toString();
console.log("SceneLoader: -> " + cmp_class);
// compare the type of this component to whatever type
// you are looking for. On this silly example, its QPhongMaterial:
if (cmp_class.indexOf("QPhongMaterial") >= 0) {
// initialize ClipAnimator with this data
}
}
}
}
}
I'm sharing the generic procedure here as I don't have a way to test this right now and figure out the data type you need to initialize ClipAnimator
correctly.