Qt3D模型运动

本文描述了一个新手如何在紧迫交付时间内使用Qt3D进行3D模型显示,介绍了基本概念如坐标轴和模型运动,特别是旋转部分的四元数应用,以及一个简单的模型动画实现的代码片段。
摘要由CSDN通过智能技术生成

1. 前言

        这段时间有一个大概类似数字孪生的任务,大概就是一个同事负责采集数据,我负责3d模型的显示,当然刚入职的我自然是什么都不会的。随后,问了下前辈,结果他推荐的方式是qt+opengl,那我岂不是更不会了。考虑到交付时间比较紧,就打算用qt3d来实现,结果相关方面度娘的资料也很少。最后写的不算完善吧,但是功能大概能用了。就打算记录一下,给后来的人留点东西。

2.基础概念

        首先需要知道的一点小知识,

1.坐标轴

        qt3d的坐标轴,z轴从屏幕穿出指向用户,x轴平行与屏幕指向右手边方向,y轴平行于屏幕指向头顶方向。

2. 模型运动

        模型运动可拆解为:“缩放,平移,旋转”这三种。在代码中缩放与平移这两个一般比较好搞,主要是模型旋转这块。

        旋转这边推荐去看四元数,或许有感觉对实际编写有点用?

演示视频

3.代码

//1.模型头文件
#pragma once

#include <QObject>
#include <qwidget.h>
#include <QtWidgets>
#include <QtGui>
#include <QGuiApplication>
#include <Qt3DCore>
#include <Qt3DExtras>
#include <Qt3DInput>
#include <Qt3DRender>

class MyWidget  : public QWidget
{
	Q_OBJECT

public slots:
	void GetXDataAndYData(float x, float y);
public:
	MyWidget(QWidget *parent = nullptr);
	~MyWidget();
private:
	Qt3DExtras::Qt3DWindow* p_window_view_;
	QWidget* p_widget_container_;
	QSize screen_size_;
	Qt3DCore::QEntity* p_entity_root_;
	Qt3DRender::QCamera* p_camera_;
	Qt3DCore::QEntity* p_entity_light_;
	Qt3DRender::QPointLight* p_point_light_;
	Qt3DCore::QTransform* p_transform_light_;
	Qt3DCore::QEntity* p_entity_airplane_;
	Qt3DCore::QEntity* p_entity_lampstand_;
	Qt3DRender::QMesh* p_mesh_;
	Qt3DRender::QMesh* p_mesh_one_;
	Qt3DExtras::QPhongMaterial* p_material_;
	Qt3DExtras::QFirstPersonCameraController* p_camera_controller_;
	Qt3DCore::QTransform* p_transform_mesh_;
	Qt3DCore::QTransform* p_transform_airplane_;
	QPropertyAnimation* p_animation_;
	QVector3D now_loaction_,next_loaction_;

	QVBoxLayout* p_layout_;
};



//模型实现
#include "mywidget.h"

MyWidget::MyWidget(QWidget *parent): QWidget(parent)
{
	p_window_view_ = new Qt3DExtras::Qt3DWindow();
	p_window_view_->defaultFrameGraph()->setClearColor(Qt::white);

	p_widget_container_ = QWidget::createWindowContainer(p_window_view_);
	screen_size_ = p_window_view_->screen()->size();
	p_widget_container_->setMaximumSize(screen_size_);
	p_widget_container_->setMinimumSize(QSize(200, 100));

	p_entity_root_ = new Qt3DCore::QEntity();


	p_camera_ = p_window_view_->camera();
	p_camera_->lens()->setPerspectiveProjection(45.0, 16.0 / 9.0, 0.1, 1000.0);
	p_camera_->setPosition(QVector3D(0, 0, 10));
	p_camera_->setUpVector(QVector3D(0, 1, 0));
	p_camera_->setViewCenter(QVector3D(0, 0, 0));
	
	p_entity_light_ = new Qt3DCore::QEntity(p_entity_root_);
	p_point_light_ = new Qt3DRender::QPointLight(p_entity_light_);
	
	p_point_light_->setColor(Qt::white);
	p_point_light_->setIntensity(0.8);
	p_entity_light_->addComponent(p_point_light_);

	p_transform_light_ = new Qt3DCore::QTransform(p_entity_root_);
	p_transform_light_->setTranslation(p_camera_->position());
	p_entity_light_->addComponent(p_transform_light_);

	p_entity_airplane_ = new Qt3DCore::QEntity(p_entity_root_);
	p_mesh_ = new Qt3DRender::QMesh();

	p_mesh_->setSource(QUrl::fromLocalFile("./res/1.obj"));

	p_entity_airplane_->addComponent(p_mesh_);

	this->p_entity_lampstand_ = new Qt3DCore::QEntity(p_entity_root_);
	p_mesh_one_ = new Qt3DRender::QMesh();

	p_mesh_one_->setSource(QUrl::fromLocalFile("./res/2.obj"));
	p_entity_lampstand_->addComponent(p_mesh_one_);
	
	p_material_ = new Qt3DExtras::QPhongMaterial(p_entity_root_);
	p_material_->setDiffuse(Qt::yellow);
	p_material_->setShininess(0.0);
	p_entity_airplane_->addComponent(p_material_);
	p_entity_lampstand_->addComponent(p_material_);

	p_transform_airplane_ = new Qt3DCore::QTransform(p_entity_root_);

	p_transform_mesh_ = new Qt3DCore::QTransform(p_entity_root_);
	
	now_loaction_.setX(0);
	now_loaction_.setY(1);
	now_loaction_.setZ(0);
	QQuaternion pal = QQuaternion::rotationTo(QVector3D(1, 0, 0), now_loaction_);

	p_transform_airplane_->setScale(0.1);
	p_transform_mesh_->setScale(0.1);
	p_entity_airplane_->addComponent(p_transform_airplane_);


	p_entity_lampstand_->addComponent(p_transform_mesh_);
	p_window_view_->setRootEntity(p_entity_root_);

	p_layout_ = new QVBoxLayout;
	QLineEdit* p_x_pos_, * p_z_pos_;
	p_x_pos_ = new QLineEdit;
	p_z_pos_ = new QLineEdit;
	QPushButton* p_button_ = new QPushButton;
	p_layout_->addWidget(p_widget_container_);
	p_layout_->addWidget(p_x_pos_);
	p_layout_->addWidget(p_z_pos_);
	p_layout_->addWidget(p_button_);
	connect(p_button_, &QPushButton::clicked, this, \
		[=]()\
	{\
		float x = p_x_pos_->text().toFloat(); \
		float z = p_z_pos_->text().toFloat(); \
		if (x * x + z * z <= 1)\
		{\
			float y = sqrt(1 - x * x - z * z); \
			next_loaction_.setX(x); \
			next_loaction_.setY(y); \
			next_loaction_.setZ(z); \
			QQuaternion pal = QQuaternion::rotationTo(QVector3D(0, 1, 0), next_loaction_); \
			now_loaction_ = next_loaction_; \
			p_transform_airplane_->setRotation(pal); \
			p_transform_airplane_->setTranslation(QVector3D(-0.405*x,0.405*(1-y), -0.4*z)); \
		}\
	}\
	);
	this->setLayout(p_layout_);
	this->resize(1200, 800);
	
}
void MyWidget::GetXDataAndYData(float x, float y)
{
	float x_pos = x;
	float z_pos = y;
	if (x_pos * x_pos + z_pos * z_pos <= 1)
	{
		float y_pos = sqrt(1 - x_pos * x_pos - z_pos * z_pos); 
		next_loaction_.setX(x_pos); 
		next_loaction_.setY(y_pos);
		next_loaction_.setZ(z_pos);
		QQuaternion pal = QQuaternion::rotationTo(QVector3D(0, 1, 0), next_loaction_); 

		now_loaction_ = next_loaction_; 
		p_transform_airplane_->setRotation(pal);
	}
}
//记得自己实现析构函数,这里我偷个懒
MyWidget::~MyWidget()
{}

写的很菜,如果有什么不对的地方希望大家斧正。当然如果真要写3d部分还是推荐去看opengl,这个只能算是救急加参考。

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于Qt3D模型交互界面,您可以使用Qt3D模块来创建具有交互性的3D界面。以下是一些基本步骤和示例代码来帮助您入门: 1. 引入Qt3D模块:在您的Qt项目中,首先需要在.pro文件中添加Qt3D模块的引用,如下所示: ``` QT += 3dcore 3drender 3dinput ``` 2. 创建Qt3D视图:在您的应用程序中创建一个Qt3D视图,用于显示3D模型和处理用户交互。可以通过以下方式创建一个简单的Qt3D视图: ```cpp #include <Qt3DExtras/Qt3DWindow> #include <Qt3DExtras/QOrbitCameraController> #include <Qt3DRender/QRenderAspect> #include <Qt3DInput/QInputAspect> #include <Qt3DCore/QEntity> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建Qt3D视图 Qt3DExtras::Qt3DWindow view; view.defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f))); // 创建实体(entity)和场景(scene) Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); view.setRootEntity(rootEntity); // 设置相机控制器 Qt3DExtras::QOrbitCameraController *cameraController = new Qt3DExtras::QOrbitCameraController(rootEntity); cameraController->setCamera(view.camera()); // 显示Qt3D视图 view.show(); return app.exec(); } ``` 3. 加载和显示模型:您可以使用Qt3D的QMesh组件来加载和显示3D模型。以下是一个加载模型并将其添加到场景中的示例代码: ```cpp #include <Qt3DExtras/QPhongMaterial> #include <Qt3DRender/QMesh> // ... // 创建模型实体 Qt3DCore::QEntity *modelEntity = new Qt3DCore::QEntity(rootEntity); // 创建模型网格 Qt3DRender::QMesh *modelMesh = new Qt3DRender::QMesh(modelEntity); modelMesh->setSource(QUrl::fromLocalFile("path/to/model.obj")); // 创建模型材质 Qt3DExtras::QPhongMaterial *modelMaterial = new Qt3DExtras::QPhongMaterial(modelEntity); modelMaterial->setDiffuse(QColor(0, 255, 0)); // 设置模型颜色 // 设置模型实体的网格和材质 modelEntity->addComponent(modelMesh); modelEntity->addComponent(modelMaterial); ``` 4. 处理用户交互:您可以使用Qt3D的输入组件(QInputAspect)来处理用户交互。例如,您可以使用QFirstPersonCameraController来实现基于鼠标和键盘的相机控制,或者使用QMouseDevice和QKeyboardDevice来处理其他类型的用户输入。 这只是一个基本的入门指南,帮助您开始使用Qt3D创建交互式3D界面。您可以根据需要进一步扩展和自定义您的界面。希望对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值