Qt assimp使用骨骼动画代码
时间: 2024-05-07 16:23:52 浏览: 125
使用 Qt 和 Assimp 库加载带有骨骼动画的模型并播放动画的代码示例如下:
```c++
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DAnimation/QAnimationClip>
#include <Qt3DAnimation/QSkeleton>
#include <Qt3DAnimation/QSkeletonLoader>
#include <Qt3DAnimation/QSkeletonMapping>
#include <Qt3DAnimation/QChannelMapping>
#include <Qt3DAnimation/QAnimationAspect>
#include <Qt3DAnimation/QAnimationClipLoader>
#include <Qt3DAnimation/QAnimationStateMachine>
#include <Qt3DAnimation/QAnimationState>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Create the Qt3D window
Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow;
view->defaultFrameGraph()->setClearColor(QColor("#4d4d4f"));
// Create the Qt3D scene
Qt3DCore::QEntity *scene = new Qt3DCore::QEntity;
// Create the camera
Qt3DRender::QCamera *camera = view->camera();
camera->setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection);
camera->setPosition(QVector3D(0, 0, 10));
camera->setViewCenter(QVector3D(0, 0, 0));
// Create the light
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(scene);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor(Qt::white);
light->setIntensity(1);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(0, 0, 20));
lightEntity->addComponent(lightTransform);
// Load the model with Assimp
Assimp::Importer importer;
const aiScene *sceneData = importer.ReadFile("model.dae", aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_LimitBoneWeights);
if (!sceneData) {
qDebug() << "Error loading model:" << importer.GetErrorString();
return -1;
}
// Create the mesh
Qt3DCore::QEntity *modelEntity = new Qt3DCore::QEntity(scene);
Qt3DExtras::QSphereMesh *mesh = new Qt3DExtras::QSphereMesh(modelEntity);
mesh->setRings(20);
mesh->setSlices(20);
mesh->setRadius(0.5f);
Qt3DExtras::QPhongMaterial *material = new Qt3DExtras::QPhongMaterial(modelEntity);
material->setDiffuse(QColor("#c0c0c0"));
modelEntity->addComponent(mesh);
modelEntity->addComponent(material);
// Create the skeleton
Qt3DAnimation::QAnimationClip *animationClip = new Qt3DAnimation::QAnimationClip(modelEntity);
animationClip->setClipData(sceneData->mAnimations[0]);
animationClip->setName("Animation");
Qt3DAnimation::QSkeleton *skeleton = new Qt3DAnimation::QSkeleton(modelEntity);
Qt3DAnimation::QSkeletonLoader *skeletonLoader = new Qt3DAnimation::QSkeletonLoader(skeleton);
skeletonLoader->setData(sceneData);
skeletonLoader->setSource(Qt3DAnimation::QSkeletonLoader::SceneData);
skeletonLoader->setScene(sceneData);
Qt3DAnimation::QChannelMapping *channelMapping = new Qt3DAnimation::QChannelMapping(skeleton);
channelMapping->setChannelName("transform");
channelMapping->setTargetJoint(skeleton->jointNames().at(0));
channelMapping->setProperty("matrix");
channelMapping->setDataType(Qt3DAnimation::QChannelMapping::Mat4x4);
channelMapping->setStride(sizeof(aiMatrix4x4));
channelMapping->setOffset(0);
channelMapping->setCount(skeleton->jointNames().count());
channelMapping->setScene(sceneData);
Qt3DAnimation::QAnimationClipLoader *animationClipLoader = new Qt3DAnimation::QAnimationClipLoader(animationClip);
animationClipLoader->setData(animationClip->clipData());
animationClipLoader->setSource(Qt3DAnimation::QAnimationClipLoader::ClipData);
animationClipLoader->setTargetNode(skeleton);
animationClipLoader->setChannelMapping(channelMapping);
Qt3DAnimation::QAnimationStateMachine *stateMachine = new Qt3DAnimation::QAnimationStateMachine(modelEntity);
Qt3DAnimation::QAnimationState *state = new Qt3DAnimation::QAnimationState(stateMachine);
state->setClip(animationClip);
stateMachine->setInitialState(state);
stateMachine->start();
// Create the skeleton mapping
Qt3DAnimation::QSkeletonMapping *skeletonMapping = new Qt3DAnimation::QSkeletonMapping(modelEntity);
skeletonMapping->setSkeleton(skeleton);
skeletonMapping->setJointNames(skeleton->jointNames());
skeletonMapping->setBindPoses(QVariant::fromValue(QMatrix4x4()));
skeletonMapping->setScene(sceneData);
skeletonMapping->setChannelMappings(QVariant::fromValue(QList<Qt3DAnimation::QChannelMapping *>() << channelMapping));
// Add the entities to the scene
scene->addComponent(skeleton);
scene->addComponent(skeletonMapping);
scene->addComponent(animationClip);
modelEntity->addComponent(skeletonMapping);
modelEntity->addComponent(animationClip);
// Set the root entity and show the window
view->setRootEntity(scene);
view->show();
return app.exec();
}
```
这个示例是一个简单的球体模型,你可以将其替换为你想要加载的模型。该示例的关键点是使用 `QSkeletonLoader` 和 `QAnimationClipLoader` 加载带有骨骼动画的场景数据,并使用 `QSkeletonMapping` 和 `QChannelMapping` 进行骨骼动画绑定。最后,在 `QAnimationStateMachine` 中播放动画。
阅读全文