249 lines
7.8 KiB
C++
249 lines
7.8 KiB
C++
#include "viewer/OsgWidget.h"
|
|
|
|
|
|
#include <QWindow>
|
|
#include <QGridLayout>
|
|
#include <QMessageBox>
|
|
#include <QScreen>
|
|
#include <QDragEnterEvent>
|
|
#include <QDropEvent>
|
|
#include <QMimeData>
|
|
#include <QDebug>
|
|
#include <osgDB/ReadFile>
|
|
#include <osgEarthUtil/EarthManipulator>
|
|
|
|
#include <osgViewer/ViewerEventHandlers>
|
|
#include <osgGA/StateSetManipulator>
|
|
|
|
#include "OsgView.h"
|
|
#include "OsgViewer.h"
|
|
#include "common/SpdLogger.h"
|
|
#include "scene/OEScene.h"
|
|
#include "ui/MainFrame.h"
|
|
#include "workspace/WorkSpaceManager.h"
|
|
#include "workspace/WorkSpace.h"
|
|
#include "scutcheon/osgScutcheon.h"
|
|
|
|
static void ConfigureView( osgViewer::View* view ) {
|
|
view->addEventHandler(new osgViewer::StatsHandler());
|
|
view->addEventHandler(new osgViewer::WindowSizeHandler());
|
|
view->addEventHandler(new osgViewer::ThreadingHandler());
|
|
view->addEventHandler(new osgViewer::LODScaleHandler());
|
|
view->addEventHandler(new osgGA::StateSetManipulator(view->getCamera()->getOrCreateStateSet()));
|
|
view->addEventHandler(new osgViewer::RecordCameraPathHandler());
|
|
view->addEventHandler(new osgViewer::ScreenCaptureHandler());
|
|
}
|
|
|
|
|
|
OsgWidget::OsgWidget(QWidget* parent, Qt::WindowFlags f)
|
|
: QWidget(parent, f)
|
|
{
|
|
// setAttribute(Qt::WA_PaintOnScreen, true);
|
|
// setAttribute(Qt::WA_StaticContents, true);
|
|
// setAttribute(Qt::WA_NoSystemBackground, true);
|
|
//setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
// setAttribute(Qt::WA_DontCreateNativeAncestors, false);
|
|
|
|
setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
|
setMouseTracking(true);
|
|
setKeyEventSetsDone(0);
|
|
|
|
// 启用拖拽接收
|
|
setAcceptDrops(true);
|
|
|
|
connect( &timer_, SIGNAL(timeout()), this, SLOT(update()) );
|
|
timer_.start( 10 );
|
|
|
|
setMinimumSize(100, 100);
|
|
LOG_INFO("OsgWidget::OsgWidget");
|
|
}
|
|
|
|
OsgWidget::~OsgWidget() {
|
|
LOG_INFO("OsgWidget::~OsgWidget");
|
|
if (nullptr != workspace_) {
|
|
workspace_->Unlaod();
|
|
}
|
|
if (nullptr != viewUI_) {
|
|
viewUI_->RemoveUI(activeScene_->GetOrCreateSceneUI());
|
|
viewUI_ = nullptr;
|
|
}
|
|
}
|
|
|
|
void OsgWidget::Initialize() {
|
|
LOG_INFO("OsgWidget::Initialize");
|
|
QHBoxLayout* layout = new QHBoxLayout(this);
|
|
activeScene_ = new OEScene;
|
|
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged, [this](WorkSpace* workspace) {
|
|
if (nullptr == workspace) {
|
|
LOG_WARN("workspace is nullptr");
|
|
return;
|
|
}
|
|
|
|
activeScene_->SetHomeViewpoint(workspace->GetHomeViewpoint(), 3.0);
|
|
}
|
|
);
|
|
QWidget* widget = addViewWidget( createGraphicsWindow(0,0,100,100));
|
|
layout->addWidget(widget);
|
|
|
|
viewUI_ = new OsgViewUI(view_, 100,100);
|
|
viewUI_->AddUI(activeScene_->GetOrCreateSceneUI());
|
|
|
|
//osgScutcheonManager::instance()->Init(view_.get(), activeScene_);
|
|
}
|
|
|
|
void OsgWidget::Uninitialize() {
|
|
LOG_INFO("OsgWidget::Uninitialize");
|
|
if (nullptr != viewUI_) {
|
|
viewUI_->RemoveUI(activeScene_->GetOrCreateSceneUI());
|
|
viewUI_ = nullptr;
|
|
}
|
|
if (nullptr != activeScene_) {
|
|
activeScene_->DetachView(view_);
|
|
activeScene_ = nullptr;
|
|
}
|
|
if (nullptr != view_) {
|
|
removeView(view_);
|
|
view_ = nullptr;
|
|
}
|
|
}
|
|
|
|
void OsgWidget::LoadDefaultScene() {
|
|
dyt_check(nullptr != activeScene_);
|
|
if (nullptr == WorkSpaceManager::Get().LoadDefaultWorkspace(activeScene_)) {
|
|
LOG_ERROR("load default workspace failed");
|
|
//QMessageBox::warning(this, tr("warning"), tr("default workspace failed"));
|
|
}
|
|
}
|
|
|
|
void OsgWidget::OnLoadDyt(const QString& path) {
|
|
LOG_INFO("load dyt path:{}", path.toStdString());
|
|
WorkSpace* workSpace = WorkSpaceManager::Get().LoadDyt(path);
|
|
if (nullptr == workSpace) {
|
|
QMessageBox::warning(&MainFrame::Get(), tr("warning"),
|
|
tr("open dyt file failed"), QMessageBox::Ok);
|
|
return;
|
|
}
|
|
|
|
const QString& name = workSpace->GetName();
|
|
const QString windowTitle = MainFrame::Get().windowTitle();
|
|
|
|
MainFrame::Get().setWindowTitle(windowTitle + "-" + name);
|
|
WorkSpaceManager::Get().SetCurrent(workSpace);
|
|
if (nullptr != workspace_ && workspace_ != workSpace) {
|
|
workspace_->Unlaod();
|
|
}
|
|
|
|
workspace_ = workSpace;
|
|
|
|
emit signalResetWorkSpace();
|
|
}
|
|
|
|
osgQt::GraphicsWindowQt* OsgWidget::createGraphicsWindow(int x, int y, int w, int h, const std::string& name,
|
|
bool windowDecoration) {
|
|
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
|
|
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
|
traits->windowName = name;
|
|
traits->windowDecoration = windowDecoration;
|
|
traits->x = x;
|
|
traits->y = y;
|
|
traits->width = w;
|
|
traits->height = h;
|
|
traits->doubleBuffer = true;
|
|
traits->alpha = ds->getMinimumNumAlphaBits();
|
|
traits->stencil = ds->getMinimumNumStencilBits();
|
|
traits->sampleBuffers = ds->getMultiSamples();
|
|
traits->samples = ds->getNumMultiSamples();
|
|
|
|
return new osgQt::GraphicsWindowQt(traits.get());
|
|
}
|
|
|
|
QWidget* OsgWidget::addViewWidget(osgQt::GraphicsWindowQt* gw) {
|
|
view_ = new osgViewer::View;
|
|
addView( view_ );
|
|
ConfigureView(view_);
|
|
|
|
osg::Camera* camera = view_->getCamera();
|
|
camera->setGraphicsContext( gw );
|
|
|
|
const osg::GraphicsContext::Traits* traits = gw->getTraits();
|
|
|
|
camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.6f, 1.0) );
|
|
camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
|
|
camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
|
|
|
|
activeScene_->AttachView(view_);
|
|
return gw->getGLWidget();
|
|
}
|
|
|
|
void OsgWidget::resizeEvent(QResizeEvent* event) {
|
|
QWidget::resizeEvent(event);
|
|
|
|
if (nullptr == view_) {
|
|
return;
|
|
}
|
|
qreal devicePixelRatio = screen()->devicePixelRatio();
|
|
const QSize& size = event->size();
|
|
viewUI_->Resize(size.width() * devicePixelRatio, size.height() * devicePixelRatio);
|
|
}
|
|
|
|
void OsgWidget::paintEvent(QPaintEvent*) {
|
|
frame();
|
|
}
|
|
|
|
void OsgWidget::dragEnterEvent(QDragEnterEvent* event) {
|
|
// 检查是否是预制模型拖拽
|
|
if (event->mimeData()->hasFormat("application/x-preset-model")) {
|
|
event->acceptProposedAction();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void OsgWidget::dragMoveEvent(QDragMoveEvent* event) {
|
|
// 检查是否是预制模型拖拽
|
|
if (event->mimeData()->hasFormat("application/x-preset-model")) {
|
|
event->acceptProposedAction();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void OsgWidget::dropEvent(QDropEvent* event) {
|
|
// 检查是否是预制模型拖拽
|
|
if (event->mimeData()->hasFormat("application/x-preset-model")) {
|
|
QByteArray data = event->mimeData()->data("application/x-preset-model");
|
|
QString modelInfo = QString::fromUtf8(data);
|
|
|
|
// 解析模型信息 (格式: "modelType|modelName")
|
|
QStringList parts = modelInfo.split("|");
|
|
if (parts.size() == 2) {
|
|
QString modelType = parts[0];
|
|
QString modelName = parts[1];
|
|
|
|
// 获取拖拽位置
|
|
QPointF position = event->posF();
|
|
|
|
// 处理预制模型拖拽
|
|
OnPresetModelDropped(modelType, modelName, position);
|
|
|
|
event->acceptProposedAction();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void OsgWidget::OnPresetModelDropped(const QString& modelType, const QString& modelName, const QPointF& position) {
|
|
// TODO: 实现预制模型拖拽处理逻辑
|
|
// 1. 将屏幕坐标转换为世界坐标
|
|
// 2. 创建对应的Entity和MeshComponent
|
|
// 3. 添加到场景中
|
|
|
|
qDebug() << "预制模型拖拽:" << modelType << modelName << "位置:" << position;
|
|
|
|
// 这里暂时只是输出调试信息,后续需要集成实体系统
|
|
}
|
|
|