600 lines
18 KiB
C
600 lines
18 KiB
C
|
|
#ifndef OBJLOADER_H
|
|||
|
|
#define OBJLOADER_H
|
|||
|
|
|
|||
|
|
#include <QObject>
|
|||
|
|
|
|||
|
|
#include <QVector>
|
|||
|
|
#include <QVector2D>
|
|||
|
|
#include <QVector3D>
|
|||
|
|
|
|||
|
|
#include <Qt3DCore>
|
|||
|
|
#include <Qt3DRender>
|
|||
|
|
#include <Qt3DExtras>
|
|||
|
|
|
|||
|
|
#include <QString>
|
|||
|
|
#include <QMap>
|
|||
|
|
#include <QColor>
|
|||
|
|
#include <QWidget>
|
|||
|
|
#include <QTimer>
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 顶点索引结构
|
|||
|
|
* 用于存储OBJ文件中面的顶点索引,关联位置、纹理坐标和法向量
|
|||
|
|
*/
|
|||
|
|
struct VertexIndex {
|
|||
|
|
/**
|
|||
|
|
* @brief 位置索引
|
|||
|
|
* 对应m_positions中的顶点位置数据索引
|
|||
|
|
*/
|
|||
|
|
int position;
|
|||
|
|
/**
|
|||
|
|
* @brief 纹理坐标索引
|
|||
|
|
* 对应m_texCoords中的纹理坐标数据索引
|
|||
|
|
*/
|
|||
|
|
int texCoord;
|
|||
|
|
/**
|
|||
|
|
* @brief 法向量索引
|
|||
|
|
* 对应m_normals中的法向量数据索引
|
|||
|
|
*/
|
|||
|
|
int normal;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 默认构造函数
|
|||
|
|
* 初始化索引为-1(表示未使用)
|
|||
|
|
*/
|
|||
|
|
VertexIndex() : position(-1), texCoord(-1), normal(-1) {}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 带参构造函数
|
|||
|
|
* @param p 位置索引
|
|||
|
|
* @param t 纹理坐标索引
|
|||
|
|
* @param n 法向量索引
|
|||
|
|
*/
|
|||
|
|
VertexIndex(int p, int t, int n) : position(p), texCoord(t), normal(n) {}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 材质结构
|
|||
|
|
* 存储从MTL文件解析的材质属性
|
|||
|
|
*/
|
|||
|
|
struct Material {
|
|||
|
|
/**
|
|||
|
|
* @brief 材质名称
|
|||
|
|
* 用于标识材质的唯一名称
|
|||
|
|
*/
|
|||
|
|
QString name;
|
|||
|
|
/**
|
|||
|
|
* @brief 环境光颜色
|
|||
|
|
* 对应MTL文件中的Ka属性,物体反射环境光的颜色
|
|||
|
|
*/
|
|||
|
|
QColor ambient;
|
|||
|
|
/**
|
|||
|
|
* @brief 漫反射颜色
|
|||
|
|
* 对应MTL文件中的Kd属性,物体漫反射的颜色
|
|||
|
|
*/
|
|||
|
|
QColor diffuse;
|
|||
|
|
/**
|
|||
|
|
* @brief 高光颜色
|
|||
|
|
* 对应MTL文件中的Ks属性,物体高光反射的颜色
|
|||
|
|
*/
|
|||
|
|
QColor specular;
|
|||
|
|
/**
|
|||
|
|
* @brief 高光光泽度
|
|||
|
|
* 对应MTL文件中的Ns属性,控制高光区域的大小,值越大高光越集中
|
|||
|
|
*/
|
|||
|
|
float shininess;
|
|||
|
|
/**
|
|||
|
|
* @brief 漫反射纹理贴图路径
|
|||
|
|
* 对应MTL文件中的map_Kd属性,漫反射纹理图片的路径
|
|||
|
|
*/
|
|||
|
|
QString diffuseMap;
|
|||
|
|
/**
|
|||
|
|
* @brief 透明度
|
|||
|
|
* 对应MTL文件中的d参数,值范围0.0-1.0,1.0表示完全不透明
|
|||
|
|
*/
|
|||
|
|
float opacity;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 面结构
|
|||
|
|
* 存储OBJ文件中的一个面,包含组成面的顶点索引和使用的材质名称
|
|||
|
|
*/
|
|||
|
|
struct Face {
|
|||
|
|
/**
|
|||
|
|
* @brief 组成面的顶点索引列表
|
|||
|
|
* 存储构成当前面的所有顶点的索引信息(位置、纹理、法向量)
|
|||
|
|
*/
|
|||
|
|
QVector<VertexIndex> vertices;
|
|||
|
|
/**
|
|||
|
|
* @brief 面使用的材质名称
|
|||
|
|
* 指向该面所应用的材质在m_materials中的名称
|
|||
|
|
*/
|
|||
|
|
QString materialName;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 器件信息结构
|
|||
|
|
* 存储3D场景中一个器件(模型)的所有属性和关联对象
|
|||
|
|
*/
|
|||
|
|
struct Device {
|
|||
|
|
/**
|
|||
|
|
* @brief 器件名称
|
|||
|
|
* 用于唯一标识一个器件的名称
|
|||
|
|
*/
|
|||
|
|
QString name;
|
|||
|
|
/**
|
|||
|
|
* @brief 器件实体(外层)
|
|||
|
|
* 器件的外层实体,主要用于控制器件在世界坐标系中的整体位置
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QEntity* entity;
|
|||
|
|
/**
|
|||
|
|
* @brief 模型子实体(内层)
|
|||
|
|
* 器件的内层实体,嵌套在外层实体中,用于控制模型的旋转和缩放
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QEntity* modelEntity;
|
|||
|
|
/**
|
|||
|
|
* @brief 外层变换组件
|
|||
|
|
* 关联到外层实体,用于控制器件在世界坐标系中的位置变换
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QTransform* transform;
|
|||
|
|
/**
|
|||
|
|
* @brief 内层变换组件
|
|||
|
|
* 关联到内层实体,用于控制模型的旋转、缩放以及预中心化处理
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QTransform* modelTransform;
|
|||
|
|
/**
|
|||
|
|
* @brief 世界坐标系中的位置
|
|||
|
|
* 记录器件在世界坐标系中的当前位置
|
|||
|
|
*/
|
|||
|
|
QVector3D worldPosition;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始位置
|
|||
|
|
* 记录器件加载时的初始位置,用于重置功能
|
|||
|
|
*/
|
|||
|
|
QVector3D originalPosition;
|
|||
|
|
/**
|
|||
|
|
* @brief 当前旋转角度
|
|||
|
|
* 记录器件当前绕X、Y、Z轴的旋转角度,单位为度
|
|||
|
|
*/
|
|||
|
|
QVector3D currentRotation;
|
|||
|
|
/**
|
|||
|
|
* @brief 模型几何中心
|
|||
|
|
* 模型在自身局部坐标系中的几何中心坐标
|
|||
|
|
*/
|
|||
|
|
QVector3D modelCenter;
|
|||
|
|
/**
|
|||
|
|
* @brief 缩放因子
|
|||
|
|
* 模型的缩放比例,默认值为1.0(原始大小)
|
|||
|
|
*/
|
|||
|
|
float scale;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始化标志
|
|||
|
|
* 标识器件是否已成功加载并初始化,true表示初始化完成
|
|||
|
|
*/
|
|||
|
|
bool isInitialized;
|
|||
|
|
|
|||
|
|
// 父子模型关联字段
|
|||
|
|
/**
|
|||
|
|
* @brief 父模型名称
|
|||
|
|
* 记录当前器件的父级器件名称,为空表示无父级
|
|||
|
|
*/
|
|||
|
|
QString parentDeviceName;
|
|||
|
|
/**
|
|||
|
|
* @brief 相对于父模型的位置偏移
|
|||
|
|
* 固定的位置偏移量,用于计算子器件相对于父器件的位置
|
|||
|
|
*/
|
|||
|
|
QVector3D offsetToParent;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始世界位置
|
|||
|
|
* 记录器件初始状态下在世界坐标系中的位置,用于复位操作
|
|||
|
|
*/
|
|||
|
|
QVector3D initialWorldPosition;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始外层变换矩阵
|
|||
|
|
* 记录外层实体初始状态下的变换矩阵,用于复位操作
|
|||
|
|
*/
|
|||
|
|
QMatrix4x4 initialTransformMatrix;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始内层变换矩阵
|
|||
|
|
* 记录内层实体初始状态下的变换矩阵,用于复位操作
|
|||
|
|
*/
|
|||
|
|
QMatrix4x4 initialModelTransformMatrix;
|
|||
|
|
/**
|
|||
|
|
* @brief 初始旋转角度
|
|||
|
|
* 记录器件相对于父设备的初始旋转角度
|
|||
|
|
*/
|
|||
|
|
QVector3D initialRotation;
|
|||
|
|
/**
|
|||
|
|
* @brief 局部坐标系下的旋转中心
|
|||
|
|
* 器件在自身局部坐标系中的旋转中心,默认值为{0,0,0}
|
|||
|
|
*/
|
|||
|
|
QVector3D localPivot;
|
|||
|
|
/**
|
|||
|
|
* @brief 自定义旋转点
|
|||
|
|
* 在世界坐标系中指定的旋转中心点坐标
|
|||
|
|
*/
|
|||
|
|
QVector3D rotationCenter;
|
|||
|
|
/**
|
|||
|
|
* @brief 是否启用自定义旋转点
|
|||
|
|
* 标识是否使用自定义的旋转点进行旋转,默认值为false
|
|||
|
|
*/
|
|||
|
|
bool useCustomRotationCenter;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief OBJ模型加载器类
|
|||
|
|
* 负责3D场景初始化、OBJ/MTL文件加载、器件管理(位置/旋转/缩放控制)等功能
|
|||
|
|
*/
|
|||
|
|
class ObjLoader : public QObject
|
|||
|
|
{
|
|||
|
|
Q_OBJECT
|
|||
|
|
public:
|
|||
|
|
/**
|
|||
|
|
* @brief 构造函数
|
|||
|
|
* @param parent 父对象
|
|||
|
|
*/
|
|||
|
|
explicit ObjLoader(QObject *parent = nullptr);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 析构函数
|
|||
|
|
* 释放所有3D资源和动态分配的对象
|
|||
|
|
*/
|
|||
|
|
~ObjLoader();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief ObjLoader::setEnDebug 是否启用qDebug打印信息
|
|||
|
|
* @param En True=启用,False=禁用;
|
|||
|
|
*/
|
|||
|
|
void setEnDebug(bool En);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 初始化3D场景
|
|||
|
|
* @param containerWidget 用于显示3D场景的窗口容器
|
|||
|
|
*/
|
|||
|
|
void init3DScene(QWidget *containerWidget);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 初始化3D场景
|
|||
|
|
* 创建3D窗口、根实体、相机、光源和控制器,支持透明背景、场景占满容器、尺寸同步
|
|||
|
|
* @param containerWidget 用于显示3D场景的窗口容器(如QFrame)
|
|||
|
|
* @param enableTransparent 是否启用场景背景透明(true=透明,false=纯色背景)
|
|||
|
|
* @return 初始化成功返回true,失败返回false(可通过lastError()获取错误信息)
|
|||
|
|
*/
|
|||
|
|
bool init3DScene(QWidget *containerWidget, bool enableTransparent);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 加载器件(独立模型)
|
|||
|
|
* 创建双层实体结构(外层控制位置,内层控制旋转/缩放),解析并应用MTL材质
|
|||
|
|
* 加载完成后自动调整相机位置,确保模型可见
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param filePath OBJ文件路径
|
|||
|
|
* @param position 初始位置
|
|||
|
|
* @return 加载成功返回true
|
|||
|
|
*/
|
|||
|
|
bool loadModel(const QString &deviceName, const QString &filePath, const QVector3D &position = QVector3D(0,0,0));
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 加载器件(独立模型,无父级)
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param filePath OBJ文件路径
|
|||
|
|
* @param position 初始位置(世界坐标)
|
|||
|
|
* @return 加载成功返回true,失败返回false
|
|||
|
|
*/
|
|||
|
|
bool loadDevice(const QString &deviceName, const QString &filePath, const QVector3D &position = QVector3D(0,0,0));
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 加载子器件(挂载到父器件下)
|
|||
|
|
* 确保子器件与父器件的初始相对位置正确,并继承父器件的变换
|
|||
|
|
* @param childDeviceName 子器件名称
|
|||
|
|
* @param filePath OBJ文件路径
|
|||
|
|
* @param parentDeviceName 父器件名称
|
|||
|
|
* @param offsetDir 相对父器件的偏移方向
|
|||
|
|
* @param diffuse 材质
|
|||
|
|
* @return 加载成功返回true
|
|||
|
|
*/
|
|||
|
|
bool loadChildDevice(
|
|||
|
|
const QString &childDeviceName,
|
|||
|
|
const QString &filePath,
|
|||
|
|
const QString &parentDeviceName,
|
|||
|
|
const QVector3D &offsetDir = QVector3D(0, 0, 0),
|
|||
|
|
const QColor &diffuse = QColor(255, 255, 255,30)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从OBJ文件计算模型的包围球半径
|
|||
|
|
* 解析OBJ文件中的顶点数据,计算模型几何中心到最远顶点的距离,作为模型的包围球半径
|
|||
|
|
* 该半径用于确定相机与模型的合适距离,确保模型能完整显示在视野中
|
|||
|
|
* @param filePath OBJ模型文件的路径
|
|||
|
|
* @return 模型包围球半径(单位与模型顶点坐标一致),若文件解析失败则返回1.0f默认值
|
|||
|
|
*/
|
|||
|
|
float calculateModelRadiusFromFile(const QString &filePath);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取器件指针
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @return 成功返回Device指针,失败返回nullptr
|
|||
|
|
*/
|
|||
|
|
Device* getDevice(const QString &deviceName);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 旋转器件(绕自身中心)
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param xAngle X轴旋转角度(度)
|
|||
|
|
* @param yAngle Y轴旋转角度(度)
|
|||
|
|
* @param zAngle Z轴旋转角度(度)
|
|||
|
|
*/
|
|||
|
|
void rotateDevice(const QString &deviceName, float xAngle, float yAngle, float zAngle);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 移动器件(相对偏移)
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param offset 偏移量(世界坐标)
|
|||
|
|
*/
|
|||
|
|
void moveDevice(const QString &deviceName, const QVector3D &offset);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置器件位置(绝对位置)
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param targetPos 目标位置(世界坐标)
|
|||
|
|
*/
|
|||
|
|
void setDevicePos(const QString &deviceName, const QVector3D &targetPos);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 缩放器件
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
* @param scaleFactor 缩放因子(>0)
|
|||
|
|
*/
|
|||
|
|
void scaleDevice(const QString &deviceName, float scaleFactor);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 重置器件到初始状态
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
*/
|
|||
|
|
void resetDevice(const QString &deviceName);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从数据映射更新多个器件的属性
|
|||
|
|
* @param deviceData 器件数据映射(键:器件名称,值:属性键值对)
|
|||
|
|
*/
|
|||
|
|
void updateDevicesFromData(const QMap<QString, QMap<QString, float>> &deviceData);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 重置相机到默认位置
|
|||
|
|
*/
|
|||
|
|
void resetCamera();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置相机控制速度
|
|||
|
|
* @param lookSpeed 旋转速度
|
|||
|
|
* @param linearSpeed 移动速度
|
|||
|
|
*/
|
|||
|
|
void setCameraSpeed(float lookSpeed, float linearSpeed);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 添加坐标轴 gizmo(辅助3D定位)
|
|||
|
|
* @param parent 父实体(默认使用根实体)
|
|||
|
|
* @param length 坐标轴长度
|
|||
|
|
*/
|
|||
|
|
void addAxisGizmo(Qt3DCore::QEntity *parent = nullptr, float length = 5.0f);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 调整子器件相对父器件的偏移
|
|||
|
|
* @param childDeviceName 子器件名称
|
|||
|
|
* @param newOffset 新的偏移量
|
|||
|
|
*/
|
|||
|
|
void adjustChildDeviceOffset(const QString &childDeviceName, const QVector3D &newOffset);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置父器件位置(同时影响子器件)
|
|||
|
|
* @param deviceName 父器件名称
|
|||
|
|
* @param position 目标位置(世界坐标)
|
|||
|
|
*/
|
|||
|
|
void setParentDevicePosition(const QString &deviceName, const QVector3D &position);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 打印器件的世界坐标信息
|
|||
|
|
* @param deviceName 器件名称
|
|||
|
|
*/
|
|||
|
|
void printDeviceWorldPos(const QString &deviceName);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取相机设备
|
|||
|
|
* @return 当前相机对象指针
|
|||
|
|
*/
|
|||
|
|
Qt3DRender::QCamera* getCamera();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 解析OBJ文件计算模型中心
|
|||
|
|
* @param filePath OBJ文件路径
|
|||
|
|
* @return 模型中心坐标(局部坐标系)
|
|||
|
|
*/
|
|||
|
|
QVector3D parseObjCenter(const QString &filePath);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 计算顶点集合的包围盒中心
|
|||
|
|
* @param vertices 顶点列表
|
|||
|
|
* @return 包围盒中心坐标
|
|||
|
|
*/
|
|||
|
|
QVector3D calculateBoundingBoxCenter(const QVector<QVector3D>& vertices);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 摇臂围绕自身局部原点旋转到绝对Z轴角度
|
|||
|
|
* @param deviceName 摇臂名称
|
|||
|
|
* @param targetZAngle 目标角度(度)
|
|||
|
|
*/
|
|||
|
|
void rotateArmToAbsoluteZAngle(const QString &deviceName, float targetZAngle);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 摇臂围绕自身局部原点绕X轴旋转,带动子设备
|
|||
|
|
* 首次调用记录初始状态,0°时复位,其他角度计算旋转矩阵并应用
|
|||
|
|
* @param deviceName 摇臂名称
|
|||
|
|
* @param targetXAngle 目标X轴角度(度)
|
|||
|
|
*/
|
|||
|
|
void rotateArmToAbsoluteXAngle(const QString &deviceName, float targetXAngle);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 摇臂围绕自身局部原点绕Y轴旋转,带动子设备
|
|||
|
|
* 首次调用记录初始状态,0°时复位,其他角度计算旋转矩阵并应用
|
|||
|
|
* @param deviceName 摇臂名称
|
|||
|
|
* @param targetYAngle 目标Y轴角度(度)
|
|||
|
|
*/
|
|||
|
|
void rotateArmToAbsoluteYAngle(const QString &deviceName, float targetYAngle);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 将摇臂的局部坐标系原点移动到世界坐标目标点
|
|||
|
|
* @param deviceName 摇臂名称
|
|||
|
|
* @param targetWorldPos 目标世界坐标
|
|||
|
|
*/
|
|||
|
|
void moveArmLocalOriginTo(const QString &deviceName, const QVector3D &targetWorldPos);
|
|||
|
|
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
/**
|
|||
|
|
* @brief 计算整体模型的中心
|
|||
|
|
*/
|
|||
|
|
void calculateModelCenter();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取指定父器件的所有子器件
|
|||
|
|
* @param parentDevice 父器件指针
|
|||
|
|
* @return 子器件列表
|
|||
|
|
*/
|
|||
|
|
QList<Device*> getAllChildren(Device *parentDevice);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 计算模型的包围球半径
|
|||
|
|
* @return 半径值
|
|||
|
|
*/
|
|||
|
|
float calculateModelRadius();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 解析MTL材质文件
|
|||
|
|
* @param filePath MTL文件路径
|
|||
|
|
* @return 解析成功返回true,失败返回false
|
|||
|
|
*/
|
|||
|
|
bool parseMtlFile(const QString &filePath);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 字符串分割工具函数
|
|||
|
|
* @param s 待分割字符串
|
|||
|
|
* @param sep 分隔符(默认空格)
|
|||
|
|
* @return 分割后的字符串列表
|
|||
|
|
*/
|
|||
|
|
static QVector<QString> splitStr(const QString &s, const QString &sep = " ");
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 创建场景光源
|
|||
|
|
*/
|
|||
|
|
void createSceneLights();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 更新整体模型(重建实体和变换)
|
|||
|
|
*/
|
|||
|
|
void updateWholeModel();
|
|||
|
|
private:
|
|||
|
|
/**
|
|||
|
|
* @brief m_3dView 3D渲染窗口,负责3D场景的渲染输出
|
|||
|
|
*/
|
|||
|
|
Qt3DExtras::Qt3DWindow *m_3dView;
|
|||
|
|
/**
|
|||
|
|
* @brief m_viewContainer 3D窗口容器,用于将3D渲染窗口嵌入到Qt Widget界面中
|
|||
|
|
*/
|
|||
|
|
QWidget *m_viewContainer;
|
|||
|
|
/**
|
|||
|
|
* @brief m_rootEntity 场景根实体,是所有3D实体的父节点,构成场景的基础结构
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QEntity *m_rootEntity;
|
|||
|
|
/**
|
|||
|
|
* @brief m_mainCamera 主相机(备用),用于观察3D场景的视角设备
|
|||
|
|
*/
|
|||
|
|
Qt3DRender::QCamera *m_mainCamera;
|
|||
|
|
/**
|
|||
|
|
* @brief m_cameraCtrl 相机控制器,提供对相机的交互控制(如旋转、平移等)
|
|||
|
|
*/
|
|||
|
|
Qt3DExtras::QOrbitCameraController *m_cameraCtrl;
|
|||
|
|
/**
|
|||
|
|
* @brief light 方向光源,为3D场景提供照明,影响物体的可见性和渲染效果
|
|||
|
|
*/
|
|||
|
|
Qt3DRender::QDirectionalLight *light;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief m_wholeModelEntity 整体模型实体,包含整体模型的所有组件
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QEntity *m_wholeModelEntity;
|
|||
|
|
/**
|
|||
|
|
* @brief m_wholeModelMesh 整体模型网格,存储整体模型的几何顶点数据
|
|||
|
|
*/
|
|||
|
|
Qt3DRender::QMesh *m_wholeModelMesh;
|
|||
|
|
/**
|
|||
|
|
* @brief m_wholeModelTrans 整体模型变换,控制整体模型的位置、旋转和缩放
|
|||
|
|
*/
|
|||
|
|
Qt3DCore::QTransform *m_wholeModelTrans;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief m_deviceMap 器件映射表,通过器件名称快速查找对应的Device对象
|
|||
|
|
*/
|
|||
|
|
QMap<QString, Device> m_deviceMap;
|
|||
|
|
/**
|
|||
|
|
* @brief m_animTimer 动画定时器,用于驱动3D场景中的动画更新
|
|||
|
|
*/
|
|||
|
|
QTimer *m_animTimer;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief m_positions 顶点位置列表,存储模型所有顶点的3D坐标
|
|||
|
|
*/
|
|||
|
|
QVector<QVector3D> m_positions;
|
|||
|
|
/**
|
|||
|
|
* @brief m_texCoords 纹理坐标列表,存储顶点对应的2D纹理映射坐标
|
|||
|
|
*/
|
|||
|
|
QVector<QVector2D> m_texCoords;
|
|||
|
|
/**
|
|||
|
|
* @brief m_normals 法向量列表,存储顶点的法向量信息,用于光照计算
|
|||
|
|
*/
|
|||
|
|
QVector<QVector3D> m_normals;
|
|||
|
|
/**
|
|||
|
|
* @brief m_faces 面列表,存储模型的面信息,每个面由多个顶点索引组成
|
|||
|
|
*/
|
|||
|
|
QVector<Face> m_faces;
|
|||
|
|
/**
|
|||
|
|
* @brief m_materials 材质映射表,通过材质名称快速查找对应的Material对象
|
|||
|
|
*/
|
|||
|
|
QMap<QString, Material> m_materials;
|
|||
|
|
/**
|
|||
|
|
* @brief m_tempVertices 临时顶点存储,用于在计算模型中心等操作时临时存放顶点数据
|
|||
|
|
*/
|
|||
|
|
QVector<QVector3D> m_tempVertices;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief m_wholeModelCenter 整体模型中心,存储整体模型的几何中心坐标
|
|||
|
|
*/
|
|||
|
|
QVector3D m_wholeModelCenter;
|
|||
|
|
/**
|
|||
|
|
* @brief m_wholeModelRadius 整体模型包围球半径,用于确定模型的大致尺寸范围
|
|||
|
|
*/
|
|||
|
|
float m_wholeModelRadius;
|
|||
|
|
/**
|
|||
|
|
* @brief m_currentMaterial 当前使用的材质名称,记录当前正在应用的材质
|
|||
|
|
*/
|
|||
|
|
QString m_currentMaterial;
|
|||
|
|
/**
|
|||
|
|
* @brief m_lastError 最后一次错误信息,存储最近发生的错误描述
|
|||
|
|
*/
|
|||
|
|
QString m_lastError;
|
|||
|
|
/**
|
|||
|
|
* @brief m_cameraEntity 主相机实体,场景中实际使用的主相机对象
|
|||
|
|
*/
|
|||
|
|
Qt3DRender::QCamera *m_cameraEntity;
|
|||
|
|
/**
|
|||
|
|
* @brief EnDebug 是否激活打印qDebug调试信息
|
|||
|
|
*/
|
|||
|
|
bool EnDebug = false;
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#endif // OBJLOADER_H
|