DYTSrouce/src/viewer/OsgView.cpp
2025-01-21 23:35:37 +08:00

212 lines
6.3 KiB
C++

#include "viewer/OsgView.h"
#include <osgGA/TrackballManipulator>
#include <osg/PositionAttitudeTransform>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
#include <osg/ShapeDrawable>
#include <osg/Group>
#include <osgManipulator/Dragger>
#include <osgManipulator/TranslateAxisDragger>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/api/Win32/GraphicsWindowWin32>
#include <osgDB/ReadFile>
#include <osg/LightModel>
#include "config.h"
#include "common/SpdLogger.h"
#include "viewer/KeyMapQtOsg.h"
#include "viewer/OsgCameraManipulator.h"
#include "viewer/OsgViewUI.h"
enum KeyboardModifier {
NoModifier = 0x00000000,
ShiftModifier = 0x02000000,
ControlModifier = 0x04000000,
AltModifier = 0x08000000,
MetaModifier = 0x10000000,
KeypadModifier = 0x20000000,
GroupSwitchModifier = 0x40000000,
KeyboardModifierMask = 0xfe000000
};
OsgView::OsgView(QObject* parent) noexcept
: QObject(parent) {
LOG_INFO("actor, self={}", fmt::ptr(this));
}
OsgView::~OsgView() {
LOG_INFO("dctor, self={}", fmt::ptr(this));
}
void OsgView::InitGraphiceWindow(int x, int y, int width, int height,
WId windowHandle, const char* name, bool windowDecoration) {
#ifdef _WIN32
osg::Referenced* windata = new osgViewer::GraphicsWindowWin32::WindowData(HWND(windowHandle));
#endif // _WIN32
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits(ds);
traits->windowName = name;
traits->x = x;
traits->y = y;
traits->width = width;
traits->height = height;
traits->alpha = ds->getMinimumNumAlphaBits();
traits->stencil = ds->getMinimumNumStencilBits();
traits->sampleBuffers = ds->getMultiSamples();
traits->samples = ds->getNumMultiSamples();
traits->windowDecoration = windowDecoration;
traits->doubleBuffer = true;
traits->sharedContext = nullptr;
traits->setInheritedWindowPixelFormat = true;
#ifdef _WIN32
traits->inheritedWindowData = windata;
#endif
graphiceWindow_ = osg::GraphicsContext::createGraphicsContext(traits);
#if USE_OCEAN
graphiceWindow_->getState()->setUseModelViewAndProjectionUniforms(false);
graphiceWindow_->getState()->setUseVertexAttributeAliasing(true);
#endif
}
void OsgView::InitView(osgViewer::View* pView) {
if (nullptr == pView || nullptr == graphiceWindow_) {
return;
}
osg::Camera* pCamera = pView->getCamera();
pCamera->setGraphicsContext(graphiceWindow_);
const osg::GraphicsContext::Traits* traits = graphiceWindow_->getTraits();
pCamera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
#if USE_OCEAN
pCamera->setProjectionMatrixAsPerspective(45.0,
static_cast<double>(traits->width) /
static_cast<double>(traits->height),
0.1, 1000.0);
pCamera->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
#endif
view_ = pView;
}
osgViewer::View* OsgView::GetView() const {
return view_.get();
}
void OsgView::Resize(int x, int y, int width, int height) {
if (nullptr != graphiceWindow_) {
graphiceWindow_->resized(x, y, width, height);
GetEventQueue()->windowResize(x, y, width, height);
}
if (!view_.valid()) {
LOG_INFO("m_pView is not valid");
return;
}
osg::Camera* pCamera = view_->getCamera();
pCamera->setViewport(new osg::Viewport(x, y, width, height));
#if USE_OCEAN
pCamera->setProjectionMatrixAsPerspective(45.0,
static_cast<double>(width) / static_cast<double>(height),
0.1, 1000.0);
#endif
if (viewUI_) {
viewUI_->Resize(width, height);
}
view_->requiresRedraw();
}
void OsgView::MouseMotion(int x, int y) {
Q_UNUSED(x);
Q_UNUSED(y);
}
void OsgView::MousePress(int x, int y, unsigned int button) {
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(button);
}
void OsgView::MouseRelease(int x, int y, unsigned int button) {
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(button);
}
void OsgView::MouseWheel(int wheel) {
Q_UNUSED(wheel);
}
void OsgView::KeyPress(QKeyEvent* keyInput) {
int osgKey = KeyMapQtOsg::RemapKey(keyInput->key());
GetEventQueue()->keyPress(osgKey);
}
void OsgView::KeyRelease(QKeyEvent* keyInput) {
int osgKey = KeyMapQtOsg::RemapKey(keyInput->key());
GetEventQueue()->keyRelease(osgKey);
}
void OsgView::SetKeyModifiers(int mask) {
int keyMask = 0;
if (mask & ShiftModifier) keyMask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
if (mask & ControlModifier) keyMask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
if (mask & AltModifier) keyMask |= osgGA::GUIEventAdapter::MODKEY_ALT;
GetEventQueue()->getCurrentEventState()->setModKeyMask(keyMask);
}
void OsgView::Initialize(OsgCameraManipulator* cameraManipulator) {
if (initialized_) {
return;
}
if (nullptr != cameraManipulator) {
cameraManipulator->Initialize();
SetCameraManipulator(cameraManipulator);
}
if (!viewUI_.valid()) {
const osg::Viewport* viewport = view_->getCamera()->getViewport();
osg::Viewport::value_type width = viewport->width();
osg::Viewport::value_type height = viewport->height();
viewUI_ = new OsgViewUI(view_, width, height);
osg::Group* root = view_->getSceneData()->asGroup();
dyt_check(nullptr != root);
root->addChild(viewUI_.get());
}
view_->addEventHandler(new osgViewer::StatsHandler);
view_->addEventHandler(new osgGA::StateSetManipulator(view_->getCamera()->getOrCreateStateSet()));
initialized_ = true;
}
void OsgView::Uninitialize(void) {
if (!initialized_) {
return;
}
initialized_ = false;
if (nullptr != graphiceWindow_) {
graphiceWindow_->clear();
}
}
bool OsgView::SetCameraManipulator(OsgCameraManipulator* cameraManipulator) {
assert(view_.valid());
if (cameraManipulator_ == cameraManipulator) {
return false;
}
osgGA::CameraManipulator* cameraMainp = cameraManipulator->GetManipulator();
if (nullptr == cameraMainp) {
return false;
}
cameraManipulator_ = cameraManipulator;
view_->setCameraManipulator(cameraMainp);
return true;
}
osgGA::EventQueue* OsgView::GetEventQueue() const {
assert(nullptr != view_);
return view_->getEventQueue();
}