KDAB / kuesa

Professional 3D asset creation and integration workflow for Qt
https://www.kuesa.com/
139 stars 27 forks source link

Kuesa's AnimationPlayer working in QML but not working in C++ #146

Closed ssooffiiaannee closed 4 years ago

ssooffiiaannee commented 4 years ago

Here are implementations of AnimationPlayer, in qml and c++. The animation in qml works, the rendering works in c++, but not the animation, although these are the same implementation for the same animation with different languages.

image

The animation is not running in c++.

image

I suspect the use of Scene3D, in qml, having a scene3D for 3D rendering is mandatory.

image

I did not implement Scene3D in c++, I could not find It in c++.

lemirep commented 4 years ago

Since you are using C++, did you register the Animation/Logic aspects on your QAspectEngine?

ssooffiiaannee commented 4 years ago

No, I couldn't figure out how to do it. Any suggestions ?

lemirep commented 4 years ago

Which window class are you using? Qt3DWindow? Qt3DQuickWindow?

ssooffiiaannee commented 4 years ago

I'm using Qt3DWindow.

lemirep commented 4 years ago

.pro -> QT += 3danimation

main.cpp

include <Qt3DAnimation/QAnimationAspect>

window.registerAspect(new Qt3DAnimation::QAnimationAspect());

ssooffiiaannee commented 4 years ago

It's still not working, I get a steady image of the object. I instantiated everything as in my working qml example, unless I'm missing something that should be implemented differently in c++. Following is my entire code : image image

lemirep commented 4 years ago

Hmm not sure what is wrong, could you try to check if the status property changes on the AnimationPlayer? A few things to try would be: 1) register the QLogicAspect 2) connect to the statusChanged signal of the GLTF2Importer before setting the clip on the AnimationPlayer

ssooffiiaannee commented 4 years ago

Still no animation. I've added : qt += 3dlogic view->registerAspect(new Qt3DLogic::QLogicAspect()); QObject::connect(animationPlayer, &Kuesa::AnimationPlayer::statusChanged, function); void function() { qDebug() << "status changed" ;} apparently status never changes. I apologize for asking too much, but Could you suggest a very small working prototype containing an animation in c++?, all the examples I come across are qml examples.

lemirep commented 4 years ago

I think you forgot to set the sceneEntity on the GLTF2Importer so the animation never makes it into the AnimationCollection of the SceneEntity and therefore the AnimationPlayer doesn't work.

I tried with a small scene and it worked fine for me. Note: I've set the clip on the player only once the scene is loaded, this avoids the player outputting a message about the clip not existing at the time the name is set on it.

`#include <Kuesa/SceneEntity>

include <Kuesa/ForwardRenderer>

include <Kuesa/AnimationPlayer>

include <Kuesa/GLTF2Importer>

include <Qt3DAnimation/QAnimationAspect>

include <Qt3DExtras/Qt3DWindow>

include <Qt3DExtras/QOrbitCameraController>

include <Qt3DRender/QRenderSettings>

include

using namespace Kuesa;

int main(int argc, char *argv[]) { QGuiApplication app(argc, argv);

Qt3DExtras::Qt3DWindow view;
view.registerAspect(new Qt3DAnimation::QAnimationAspect());

Kuesa::SceneEntity *root = new Kuesa::SceneEntity();
Kuesa::ForwardRenderer *fg = new Kuesa::ForwardRenderer();

fg->setClearColor(QColor(Qt::white));
fg->setCamera(view.camera());
view.renderSettings()->setActiveFrameGraph(fg);

Qt3DExtras::QOrbitCameraController *ctrl = new Qt3DExtras::QOrbitCameraController(root);
ctrl->setCamera(view.camera());

Kuesa::AnimationPlayer *animation = new Kuesa::AnimationPlayer(root);
animation->setSceneEntity(root);
animation->setLoopCount(Kuesa::AnimationPlayer::Infinite);
animation->setRunning(true);

Kuesa::GLTF2Importer *importer = new Kuesa::GLTF2Importer(root);
importer->setSceneEntity(root);
importer->setSource(QUrl("file:///" ASSETS "manual/assets/AnimatedCubes/glTF/AnimatedCubes.gltf"));

QObject::connect(importer, &Kuesa::GLTF2Importer::statusChanged, [&] (Kuesa::GLTF2Importer::Status s){
    if (s == Kuesa::GLTF2Importer::Ready) {
        qDebug() << Q_FUNC_INFO << s;
    }
});
QObject::connect(root, &Kuesa::SceneEntity::loadingDone, [&] (){
    qDebug() << Q_FUNC_INFO;
    animation->setClip(QStringLiteral("animation_AnimatedCube"));
    view.camera()->viewAll();
});

view.setRootEntity(root);
view.resize(1920, 1080);
view.show();

return app.exec();

}`

lemirep commented 4 years ago

I'll prepare a patch for the next Kuesa release where if the parent provided in the ctor of GLTF2Importer is a SceneEntity, we automatically set it as the sceneEntity

ssooffiiaannee commented 4 years ago

@lemirep Yep, I the sceneEntity of the gltfImporter is exactly what was missing, it worked now. Thank you.