1. 程式人生 > >Qt文件閱讀筆記-最簡單的動態3D圓環例項

Qt文件閱讀筆記-最簡單的動態3D圓環例項

程式的邏輯如下:

正常顯示邏輯:

1.場景中要存在一個根實體; 2.為根實體載入材質; 3.在根實體下新增其他實體; 4.為其他實體新增額外的資料(比如畫圓環等); 5.放置攝像機,設定前景等屬性。

攝像機視覺方面的邏輯: 1.放置攝像機,設定前景等屬性; 2.建立攝像機軌道控制類,設定移動速度等屬性;

物體實現動態功能的邏輯: 1.建立一個類,這個類完成對某一3D模型“動態”資料提取; 2.生成一個單位矩陣,並對這個單位矩陣進行操作(旋轉,轉化等); 3.把這個單位矩陣放到目標物體上; 4.使用QPropertyAnimation對某一屬性名,實現動態效果;

程式執行截圖如下:

原始碼如下:

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();
}