Qt文档阅读笔记-最简单的动态3D圆环实例

程序的逻辑如下:

正常显示逻辑:

1.场景中要存在一个根实体;
2.为根实体加载材质;
3.在根实体下添加其他实体;
4.为其他实体添加额外的数据(比如画圆环等);
5.放置摄像机,设置前景等属性。


摄像机视觉方面的逻辑:
1.放置摄像机,设置前景等属性;
2.创建摄像机轨道控制类,设置移动速度等属性;


物体实现动态功能的逻辑:
1.创建一个类,这个类完成对某一3D模型“动态”数据提取;
2.生成一个单位矩阵,并对这个单位矩阵进行操作(旋转,转化等);
3.把这个单位矩阵放到目标物体上;
4.使用QPropertyAnimation对某一属性名,实现动态效果;

 

程序运行截图如下:

Qt文档阅读笔记-最简单的动态3D圆环实例

 

源码如下:

animationcontroller.h

#ifndef ANIMATIONCONTROLLER_H
#define ANIMATIONCONTROLLER_H

#include <QObject>
#include <QMatrix4x4>

namespace Qt3DCore {
class QTransform;
}

class AnimationController : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Qt3DCore::QTransform* target READ target WRITE setTarget NOTIFY targetChanged)
    Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
    Q_PROPERTY(float angle READ angle WRITE setAngle NOTIFY angleChanged)
public:
    AnimationController(QObject *parent = 0);

    void setTarget(Qt3DCore::QTransform *target);
    Qt3DCore::QTransform *target()const;

    void setRadius(float radius);
    float radius()const;

    void setAngle(float angle);
    float angle()const;

signals:
    void targetChanged();
    void radiusChanged();
    void angleChanged();

protected:
    void updateMatrix();

private:
    QMatrix4x4 m_matrix;
    Qt3DCore::QTransform *m_target;
    float m_radius;
    float m_angle;
};

#endif // ANIMATIONCONTROLLER_H

animationcontroller.cpp

#include "animationcontroller.h"
#include <QTransform>

AnimationController::AnimationController(QObject *parent)
    : QObject(parent)
    , m_target(nullptr)
    , m_matrix()
    , m_radius(1.0f)
    , m_angle(0.0f)

{

}

void AnimationController::setTarget(Qt3DCore::QTransform *target)
{
    if(m_target != target){
        m_target = target;
        emit targetChanged();
    }
}

Qt3DCore::QTransform *AnimationController::target() const
{
    return m_target;
}

void AnimationController::setRadius(float radius)
{
    if(!qFuzzyCompare(radius, m_radius)){
        m_radius = radius;
        updateMatrix();
        emit radiusChanged();
    }
}

float AnimationController::radius() const
{
    return m_radius;
}

void AnimationController::setAngle(float angle)
{
    if(!qFuzzyCompare(angle, m_angle)){
        m_angle = angle;
        updateMatrix();
        emit angleChanged();
    }
}

float AnimationController::angle() const
{
    return m_angle;
}

void AnimationController::updateMatrix()
{
    m_matrix.setToIdentity();
    m_matrix.rotate(m_angle, QVector3D(1.0f, 0.0f, 0.0f));
    m_matrix.translate(m_radius, 0.0f, 0.0f);
    m_target->setMatrix(m_matrix);
}

main.cpp

#include <Qt3DCore>
#include <QApplication>
#include <Qt3DRender>
#include <Qt3DInput>
#include <Qt3DExtras>
#include <QPropertyAnimation>
#include "animationcontroller.h"

Qt3DCore::QEntity *createScene(){

    // Root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;

    // Material
    Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
    static_cast<Qt3DExtras::QPhongMaterial*>(material)->setAmbient(QColor(Qt::blue));

    Qt3DCore::QEntity *torusEntity = new Qt3DCore::QEntity(rootEntity);

    // Torus
    Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh;
    torusMesh->setRadius(10);
    torusMesh->setMinorRadius(1);
    torusMesh->setRings(100);
    torusMesh->setSlices(20);


    Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform;
    AnimationController *animationController = new AnimationController(sphereTransform);
    animationController->setTarget(sphereTransform);
    animationController->setRadius(20.0f);

    QPropertyAnimation *rotateAnimation = new QPropertyAnimation(sphereTransform);
    rotateAnimation->setTargetObject(animationController);
    rotateAnimation->setPropertyName("angle");
    rotateAnimation->setStartValue(QVariant::fromValue(0));
    rotateAnimation->setEndValue(QVariant::fromValue(360));
    rotateAnimation->setDuration(10000);
    rotateAnimation->setLoopCount(-1);
    rotateAnimation->start();



    torusEntity->addComponent(torusMesh);
    torusEntity->addComponent(sphereTransform);
    torusEntity->addComponent(material);

    return rootEntity;

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Qt3DExtras::Qt3DWindow view;
    Qt3DCore::QEntity *scene = createScene();

    Qt3DRender::QCamera *camera = view.camera();
    camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    camera->setPosition(QVector3D(0, 0, 40.0f));
    camera->setViewCenter(QVector3D(0, 0, 0));

    Qt3DExtras::QOrbitCameraController *camController =  new Qt3DExtras::QOrbitCameraController(scene);
    camController->setLinearSpeed(50.0f);
    camController->setLookSpeed(180.0f);
    camController->setCamera(camera);


    view.setRootEntity(scene);
    view.show();
    return a.exec();
}