Qt 5.15.2 三维显示功能
三维显示效果:
.pro项目文件
QT += core gui opengl 3dcore 3drender 3dinput 3dextrasgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \dialog_fbx2glb.cpp \dialog_osgb_to_b3dm.cpp \main.cpp \mainwindow.cpp \scene.cppHEADERS += \dialog_fbx2glb.h \dialog_osgb_to_b3dm.h \mainwindow.h \scene.hFORMS += \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 += targetDISTFILES += \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))); //0x42f4bcCamera(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.0fcamera->setViewCenter(QVector3D(-789, -2343, 10)); //0, 0, 0camera->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.0fcamera->setViewCenter(QVector3D(center.x()*1.5, center.y()*1.5, abs(center.z()))); //0, 0, 0camera->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 pointint 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();}//rotateif(event->button() & Qt::RightButton){ //mouse right press and moveing//if(event->type()==QEvent::MouseMove){//event->MouseButtonPressint 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);}}}/**///moveif(event->button() & Qt::LeftButton){ //mouse right press and moveing//if(event->type()==QEvent::MouseMove){//event->MouseButtonPressint 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{//方向键 moveif(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