Qt 5.15.2 三维显示功能

Qt 5.15.2 三维显示功能

三维显示效果:
在这里插入图片描述

.pro项目文件

QT       += core gui opengl 3dcore 3drender 3dinput 3dextras

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    dialog_fbx2glb.cpp \
    dialog_osgb_to_b3dm.cpp \
    main.cpp \
    mainwindow.cpp \
    scene.cpp

HEADERS += \
    dialog_fbx2glb.h \
    dialog_osgb_to_b3dm.h \
    mainwindow.h \
    scene.h

FORMS += \
    dialog_fbx2glb.ui \
    dialog_osgb_to_b3dm.ui \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${
    
    TARGET}/bin
else: unix:!android: target.path = /opt/$${
    
    TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES += \
    images/211.ico \
    images/Clear2.ico \
    images/File.ico \
    images/Open.ico \
    images/opendir.png \
    images/openfile.png

Scene.h

#ifndef SCENE_H
#define SCENE_H

#include <QObject>
#include <QWidget>

#include <Qt3DCore/QEntity>
#include <Qt3DRender/QMesh>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QPointLight>
#include <Qt3DRender/QDirectionalLight>
#include <Qt3DCore/QTransform>
#include <Qt3DWindow>
#include <QOrbitCameraController>
#include <QFirstPersonCameraController>

#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QSphereMesh>

#include <QKeyEvent>
#include <QTransform>
#include <QComponent>
#include <QQuaternion>
#include <QInputAspect>


class Scene : public QObject
{
    
    
    Q_OBJECT
public:
    Qt3DCore::QEntity *rootEntity;
    Qt3DCore::QEntity *model;
    Qt3DCore::QTransform *transform;
    Qt3DRender::QDirectionalLight *light;
    //
    explicit Scene(Qt3DExtras::Qt3DWindow *, QObject *parent=nullptr);
    void SetupMesh(Qt3DRender::QMesh *mesh);
    void StartScene();
    void Camera(Qt3DExtras::Qt3DWindow *view);
    void setCameraCenterPoint(QVector3D center);
    Qt3DCore::QEntity* findChildQEntity(QString objName,Qt3DCore::QEntity* rootEnt);
    QVector3D computCenterPoint(Qt3DCore::QEntity* first);


    void initOrbitCameraController(Qt3DCore::QEntity *ent);
    void initFirstPersonCameraController(Qt3DCore::QEntity *ent);

    void init3d(Qt3DExtras::Qt3DWindow *view);
    void NewScene(Qt3DRender::QMesh *);
    void NewScene2(Qt3DRender::QMesh *mesh);
    void SetupTransformRoot(Qt3DCore::QEntity* model);
    void SetupTransform(Qt3DCore::QEntity* modelPrivate);
    void SetupMaterial(Qt3DCore::QEntity* model);
    void SetupLighting();
    //添加新实体
    Qt3DCore::QEntity* addMeshEntity(Qt3DRender::QMesh *mesh);
    Qt3DCore::QEntity* addEntity(Qt3DCore::QComponent *comp);
    //
    Qt3DCore::QEntity* addNewEntity();
    //
    void KeyControls(QKeyEvent *event);
    void wheelControls(QWheelEvent *event);
    void mouseControls(QMouseEvent *event);
    void mousePressControls(QMouseEvent *event);
    void paintALL();



public slots:
    void LightXChanged(int angle);
    void LightYChanged(int angle);
    void LightZChanged(int angle);

private:
    Qt3DExtras::Qt3DWindow *view;
    unsigned int backgroudColor=0x42f4bc;    //0xffffff;  0x42f4bc
    //
    QPoint m_qpRotPosOld;
    int m_iScloe; //滚动放大缩小尺寸

    //旋转
    double m_dRotX;
    double m_dRotY;
    double m_dRotZ;

    //位移
    double m_dMoveX;
    double m_dMoveY;
    double m_dMoveZ;
    //


};

#endif // SCENE_H

scene.cpp

#include "scene.h"
#include <cmath>

Scene::Scene(Qt3DExtras::Qt3DWindow *view, QObject *parent) : QObject (parent)
{
    
    
    this->view=view;
    rootEntity = new Qt3DCore::QEntity();
    SetupTransformRoot(rootEntity);
    //
    view->setRootEntity(rootEntity);
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(this->backgroudColor)));   //0x42f4bc
    Camera(view);
    StartScene();
    //
    this->initOrbitCameraController(rootEntity);
    //this->initFirstPersonCameraController();
}

void Scene::Camera(Qt3DExtras::Qt3DWindow *view)
{
    
    
    //其中camera是新建的camera实体,lens表示了镜头,这个函数有着四个参数,
    //第一个参数是视觉域,   45.0f
    //第二个是分辨率(这里选择了16比9),  16.0f/9.0f
    //第三个参数是近面摆放位置,   0.1f
    //最后一个是远面放置位置,    3000.0f
    //后两个参数的选择当中要特别注意,只有在远近面之间的物体才会显示,所以要是想全部显示出所加入的实体,
    //那么近面就要足够近,远面就要足够远。
    // Camera
    //Qt3DRender::QCamera *cameraEntity = view->camera();
    Qt3DRender::QCamera *camera = view->camera();
    camera->lens()->setPerspectiveProjection(45.0f,16.0f/9.0f, 0.1f, 3000.0f);   //近面板0.1f,远面板1000.0f
    camera->setViewCenter(QVector3D(-789, -2343, 10));    //0, 0, 0
    camera->setPosition(QVector3D(-789, -2343, 200));   //0,0,40  -200  5000  相机高度

    Qt3DInput::QInputAspect *input = new Qt3DInput::QInputAspect();
    view->registerAspect(input);
    //input->setCamera(cameraEntity);//使摄像机能左右转动
}

void Scene::setCameraCenterPoint(QVector3D center)
{
    
    
    Qt3DRender::QCamera *camera = view->camera();
    camera->lens()->setPerspectiveProjection(45.0f,16.0f/9.0f, 0.1f, 3000.0f);   //近面板0.1f,远面板1000.0f
    camera->setViewCenter(QVector3D(center.x()*1.5, center.y()*1.5, abs(center.z())));    //0, 0, 0
    camera->setPosition(QVector3D(center.x()*1.5, center.y()*1.5, abs(center.z())*1.5+50));   //0,0,40  -200  5000  相机高度
    qDebug()<<"camera point="<<camera->position();
    //
    Qt3DInput::QInputAspect *input = new Qt3DInput::QInputAspect();
    view->registerAspect(input);
}

Qt3DCore::QEntity* Scene::findChildQEntity(QString objName,Qt3DCore::QEntity* rootEnt)
{
    
    
    for (Qt3DCore::QNode* childNode : rootEnt->childNodes())
    {
    
    
        QString itemName="";
        Qt3DCore::QEntity* testObj=dynamic_cast<Qt3DCore::QEntity*>(childNode);
        if(testObj)
        {
    
    
            itemName=testObj->objectName();
            if(objName==itemName)
            {
    
    
                return testObj;
            }
        }
    }
    return nullptr;
}

QVector3D Scene::computCenterPoint(Qt3DCore::QEntity* first)
{
    
    
    QVector3D center(0, 0, 0);
    if(first!=nullptr)
    {
    
    
        // Now iterate over all the components and calculate the center point
        int totalSize=0;
        //
        for (Qt3DCore::QNode* childNode : first->childNodes())
        {
    
    
            Qt3DCore::QTransform* tranobj=dynamic_cast<Qt3DCore::QTransform*>(childNode);
            if(tranobj)
            {
    
    
                center += tranobj->translation();
                totalSize+=1;
            }
            Qt3DRender::QMesh* meshobj=dynamic_cast<Qt3DRender::QMesh*>(childNode);
            if(meshobj)
            {
    
    
                center += meshobj->geometry()->minExtent();
                center += meshobj->geometry()->maxExtent();
                totalSize+=2;
            }
        }
        //
        center /= totalSize; // compute the center point
        //定位相机
        //scene->setCameraCenterPoint(center);
        //
    }
    return center;
}


void Scene::init3d(Qt3DExtras::Qt3DWindow *view)
{
    
    
    delete model;
    //
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(this->backgroudColor)));
    Camera(view);
    this->StartScene();
}

void Scene::StartScene()
{
    
    
    model = new Qt3DCore::QEntity(rootEntity);
    model->setObjectName("救生圈场景模型");

    //救生圈场景 模型   这个尺寸大小影响显示
    Qt3DExtras::QTorusMesh *torusMesh = new Qt3DExtras::QTorusMesh(model);
    torusMesh->setRadius(5);
    torusMesh->setMinorRadius(1);
    torusMesh->setRings(100);
    torusMesh->setSlices(20);
    model->addComponent(torusMesh);
    /*
    Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh(model);
    sphereMesh->setRadius(5);
    model->addComponent(sphereMesh);


    QString filename="C:/data/obj/Tile_+005_+006_OBJ/Tile_+005_+006/Tile_+005_+006.obj";
    //filename="D:\\data\\data3d\fbx\\HCZ.fbx";
    Qt3DRender::QMesh *mesh = new Qt3DRender::QMesh(model);
    mesh->setSource(QUrl::fromLocalFile(filename));
    mesh->setMeshName("objMesh");
    //mesh->setSource(QUrl("qrc:/data/obj/Tile_+005_+006_OBJ/Tile_+005_+006/Tile_+005_+006.obj"));
    //mesh->setSource(QUrl(filename));   //file:///
    model->addComponent(mesh);*/
    //
    SetupTransform(model);
    SetupMaterial(model);
    SetupLighting();

}

void Scene::NewScene(Qt3DRender::QMesh *mesh)
{
    
    
    delete model;
    model = new Qt3DCore::QEntity(rootEntity);

    SetupMesh(mesh);
    SetupTransform(model);
    SetupMaterial(model);
    SetupLighting();
}
void Scene::NewScene2(Qt3DRender::QMesh *mesh)
{
    
    
    delete model;
    model = new Qt3DCore::QEntity(rootEntity);

    SetupMesh(mesh);
    SetupTransform(model);
    SetupMaterial(model);
    SetupLighting();
}
Qt3DCore::QEntity* Scene::addMeshEntity(Qt3DRender::QMesh *mesh)
{
    
    
    Qt3DCore::QEntity* newEnt = new Qt3DCore::QEntity(rootEntity);
    newEnt->addComponent(mesh);
    return newEnt;
}

Qt3DCore::QEntity* Scene::addEntity(Qt3DCore::QComponent *comp)
{
    
    
    Qt3DCore::QEntity* newEnt = new Qt3DCore::QEntity(rootEntity);
    newEnt->addComponent(comp);
    return newEnt;
}

Qt3DCore::QEntity* Scene::addNewEntity()
{
    
    
    return new Qt3DCore::QEntity(rootEntity);
}

void Scene::SetupMesh(Qt3DRender::QMesh *mesh)
{
    
    
    model->addComponent(mesh);
}

void Scene::SetupTransformRoot(Qt3DCore::QEntity* model)
{
    
    
    transform = new Qt3DCore::QTransform(model);
    transform->setScale3D(QVector3D(1, 1, 1));
    transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 0));
    //transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), 0));
    //transform->setScale(1.0f);
    //transform->setTranslation(QVector3D(-700.0f,-2100.0f,10.0f));

    model->addComponent(transform);
}
void Scene::SetupTransform(Qt3DCore::QEntity* modelPrivate)
{
    
    
    Qt3DCore::QTransform* tf = new Qt3DCore::QTransform(modelPrivate);
    tf->setScale3D(QVector3D(1, 1, 1));
    tf->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 0), 0));
    //tf->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), 0));
    //tf->setScale(1.0f);
    //tf->setTranslation(QVector3D(-700.0f,-2100.0f,10.0f));

    modelPrivate->addComponent(tf);
}

void Scene::SetupMaterial(Qt3DCore::QEntity* model)
{
    
    
    Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(model);
    model->addComponent(material);
}

void Scene::SetupLighting()
{
    
    
    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
    light = new Qt3DRender::QDirectionalLight(lightEntity);
    light->setColor("white");
    light->setIntensity(1);
    light->setWorldDirection(QVector3D(0,0,-1));

    lightEntity->addComponent(light);
}

//接管相机的鼠标操作 盘旋操作
void Scene::initOrbitCameraController(Qt3DCore::QEntity *ent)
{
    
    
    Qt3DExtras::QOrbitCameraController *controller = new Qt3DExtras::QOrbitCameraController(ent);
    controller->setCamera(view->camera());

}
//接管相机的鼠标操作  第一人操作
void Scene::initFirstPersonCameraController(Qt3DCore::QEntity *ent)
{
    
    
    Qt3DExtras::QFirstPersonCameraController *controller=new Qt3DExtras::QFirstPersonCameraController(ent);
    controller->setCamera(view->camera());
}

void Scene::paintALL()
{
    
    
    //对rootEntity 整体操作
    transform->setTranslation(QVector3D(m_dMoveX,m_dMoveY,m_iScloe));
    transform->setRotation(QQuaternion(sqrt(m_dRotX*m_dRotX+m_dRotY*m_dRotY),m_dRotX,m_dRotY,m_dRotZ));

}

//mouse wheel +/-  放大/缩小 功能
void Scene::wheelControls(QWheelEvent *event)
{
    
    
    float scale=2;
    if(event->angleDelta().x() >0 || event->angleDelta().y()>0){
    
    
        //放大
        //scale=1.1f;
        transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y(),transform->translation().z()+scale));
    }
    else
    {
    
       //缩小
        //scale=0.9f;
        transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y(),transform->translation().z()-scale));
    }

    /*
    if (event->delta() < 0) {
        //m_iScloe--;
        m_iScloe=event->delta();
        this->paintALL();
    }
    else if (event->delta() > 0) {
        //m_iScloe++;
        m_iScloe=event->delta();
        this->paintALL();
    }*/

}

void Scene::mousePressControls(QMouseEvent *event)
{
    
    
    if(event->button()==Qt::LeftButton)
    {
    
    

    }
}

void Scene::mouseControls(QMouseEvent *event)
{
    
    
    QPoint pos = event->pos();

    //左键按下+move=>旋转
    if( event->buttons() & Qt::LeftButton)
    {
    
    

        if (pos.x()  > m_qpRotPosOld.x())
        {
    
    
            m_dRotX += 1;
        }
        else if(pos.x()  < m_qpRotPosOld.x())
        {
    
    
            m_dRotX -= 1;
        }
        if(pos.y()  > m_qpRotPosOld.y())
        {
    
    
            m_dRotY += 1;
        }
        else if(pos.y()  < m_qpRotPosOld.y())
        {
    
    
            m_dRotY -= 1;
        }
        //this->paintALL();
    }
    if( event->buttons() & Qt::RightButton)             //右键
    {
    
       //右键按下+move=>移动
        if (pos.x()  > m_qpRotPosOld.x())
        {
    
    
            m_dMoveX += 1;
        }
        else if(pos.x()  < m_qpRotPosOld.x())
        {
    
    
            m_dMoveX -= 1;
        }
        if(pos.y()  > m_qpRotPosOld.y())
        {
    
    
            m_dMoveY -= 1;
        }
        else if(pos.y()  < m_qpRotPosOld.y())
        {
    
    
            m_dMoveY += 1;
        }
        //this->paintALL();
    }

    //rotate
    if(event->button() & Qt::RightButton)
    {
    
       //mouse right press and moveing
        //if(event->type()==QEvent::MouseMove)
        {
    
    
            //event->MouseButtonPress
            int dy=pos.y()-m_qpRotPosOld.y();
            int dx=pos.x()-m_qpRotPosOld.x();
            if(dy>0){
    
    
                transform->setRotationY(transform->rotationY()+1);
            }
            else if(dy<0)
            {
    
    
                transform->setRotationY(transform->rotationY()-1);
            }
            //
            if(dx>0){
    
    
                transform->setRotationX(transform->rotationX()+1);
            }
            else if(dx<0)
            {
    
    
                transform->setRotationX(transform->rotationX()-1);
            }
        }
    }
    /**/
    //move
    if(event->button() & Qt::LeftButton)
    {
    
       //mouse right press and moveing
        //if(event->type()==QEvent::MouseMove)
        {
    
    
            //event->MouseButtonPress
            int dy=pos.y()-m_qpRotPosOld.y();
            int dx=pos.x()-m_qpRotPosOld.x();
            if(dy>0){
    
    
                transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y()-2,transform->translation().z()));
            }
            else if(dy<0)
            {
    
    
                transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y()+2,transform->translation().z()));
            }
            if(dx>0){
    
    
                transform->setTranslation(QVector3D(transform->translation().x()-2,transform->translation().y(),transform->translation().z()));
            }
            else if(dx<0)
            {
    
    
                transform->setTranslation(QVector3D(transform->translation().x()+2,transform->translation().y(),transform->translation().z()));
            }
        }
    }
    //旋转显示窗口
    //glTranslatef(m_dMoveX, m_dMoveY, m_iScloe);
    //glRotatef(sqrt(m_dRotX*m_dRotX+m_dRotY*m_dRotY), m_dRotY,m_dRotX,m_dRotZ);
    m_qpRotPosOld = pos;
}

void Scene::KeyControls(QKeyEvent *event){
    
    
    if (event->modifiers().testFlag(Qt::ControlModifier)){
    
    
        //ctrl+方向键
        if(event->key()==Qt::Key_Up){
    
    
            transform->setRotationX(transform->rotationX()-6);
        }
        if(event->key()==Qt::Key_Down){
    
    
            transform->setRotationX(transform->rotationX()+6);
        }
        if(event->key()==Qt::Key_Left){
    
    
            transform->setRotationY(transform->rotationY()-6);
        }
        if(event->key()==Qt::Key_Right){
    
    
            transform->setRotationY(transform->rotationY()+6);
        }
    }else if (event->modifiers().testFlag(Qt::ShiftModifier)) {
    
    
        //shift+方向键 上/下
        if(event->key()==Qt::Key_Up){
    
      //放大
            transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y(),transform->translation().z()-2));
        }
        if(event->key()==Qt::Key_Down){
    
      //缩小
            transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y(),transform->translation().z()+2));
        }
    }else{
    
    
        //方向键  move
        if(event->key()==Qt::Key_Up){
    
    
            transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y()+1,transform->translation().z()));
        }
        if(event->key()==Qt::Key_Down){
    
    
            transform->setTranslation(QVector3D(transform->translation().x(),transform->translation().y()-1,transform->translation().z()));
        }
        if(event->key()==Qt::Key_Left){
    
    
            transform->setTranslation(QVector3D(transform->translation().x()-1,transform->translation().y(),transform->translation().z()));
        }
        if(event->key()==Qt::Key_Right){
    
    
            transform->setTranslation(QVector3D(transform->translation().x()+1,transform->translation().y(),transform->translation().z()));
        }
    }
}

void Scene::LightXChanged(int angle)
{
    
    
    light->setWorldDirection(QVector3D(angle,light->worldDirection().y(),light->worldDirection().z()));
}

void Scene::LightYChanged(int angle)
{
    
    
    light->setWorldDirection(QVector3D(light->worldDirection().x(),angle,light->worldDirection().z()));
}

void Scene::LightZChanged(int angle)
{
    
    
    light->setWorldDirection(QVector3D(light->worldDirection().x(),light->worldDirection().y(),angle));
}

本blog地址:https://blog.csdn.net/hsg77

猜你喜欢

转载自blog.csdn.net/hsg77/article/details/134886071