Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
4acbf05ae0 | |||
8a15b09464 | |||
65cbe121bf | |||
9b47b518d5 | |||
ea260fcaaa |
@ -4,7 +4,7 @@ set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
SET(CMAKE_CXX_STANDARD 17)
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
@ -85,8 +85,9 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${Thirdparty}/spdlog/include
|
||||
${Thirdparty}/breakpad/include
|
||||
${Thirdparty}/3rdParty_x64/include
|
||||
${Thirdparty}/OpenSceneGraph-3.6.5/include
|
||||
${Thirdparty}/3rdparty_vc15/include
|
||||
${Thirdparty}/OSG-3.5.1/include
|
||||
${Thirdparty}/OSGEARTH-2.8/include
|
||||
${Thirdparty}/TritonSDK/PublicHeaders
|
||||
${Thirdparty}/matlab/include
|
||||
# ${Thirdparty}/Python39/include
|
||||
@ -94,8 +95,9 @@ INCLUDE_DIRECTORIES(
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
${Thirdparty}/spdlog/lib
|
||||
${Thirdparty}/3rdParty_x64/lib
|
||||
${Thirdparty}/OpenSceneGraph-3.6.5/lib
|
||||
${Thirdparty}/3rdparty_vc15/lib
|
||||
${Thirdparty}/OSG-3.5.1/lib
|
||||
${Thirdparty}/OSGEARTH-2.8/lib
|
||||
${Thirdparty}/matlab/lib/win64/microsoft
|
||||
${Thirdparty}/TritonSDK/lib/vc143/x64
|
||||
# ${Thirdparty}/Python39/libs
|
||||
@ -167,6 +169,7 @@ target_link_libraries(
|
||||
osgWidget
|
||||
osgText
|
||||
osgEarth
|
||||
osgEarthUtil
|
||||
Triton-MT-DLL
|
||||
libeng
|
||||
libmx
|
||||
|
@ -16,7 +16,6 @@ Application::Application(int& argc, char** argv, int /*= ApplicationFlags*/)
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
Uninit();
|
||||
}
|
||||
|
||||
QString Application::GetWorkSpacePath() {
|
||||
@ -26,7 +25,7 @@ QString Application::GetWorkSpacePath() {
|
||||
|
||||
void Application::Init() {
|
||||
Singleton<MeshManager>::Create(this);
|
||||
Singleton<OsgViewer>::Create(this);
|
||||
//Singleton<OsgViewer>::Create(this);
|
||||
Singleton<RecourceHelper>::Create(this);
|
||||
Singleton<EntitiesManager>::Create(this);
|
||||
Singleton<WorkSpaceManager>::Create(this);
|
||||
@ -40,6 +39,6 @@ void Application::Uninit() {
|
||||
Singleton<WorkSpaceManager>::Destory();
|
||||
Singleton<EntitiesManager>::Destory();
|
||||
Singleton<RecourceHelper>::Destory();
|
||||
Singleton<OsgViewer>::Destory();
|
||||
//Singleton<OsgViewer>::Destory();
|
||||
Singleton<MeshManager>::Destory();
|
||||
}
|
||||
|
@ -10,8 +10,7 @@ public:
|
||||
~Application() override;
|
||||
|
||||
static QString GetWorkSpacePath();
|
||||
|
||||
void Uninit();
|
||||
protected:
|
||||
void Init();
|
||||
void Uninit();
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
#include "CrashHandler.h"
|
||||
|
||||
#if 0
|
||||
#include <QCoreApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
@ -79,7 +80,6 @@ std::unique_ptr<google_breakpad::ExceptionHandler> exceptionHandler;
|
||||
#endif
|
||||
bool InstallCrashHandler() {
|
||||
#if NDEBUG
|
||||
FindFileForDelete("D:/pcm");
|
||||
QString appDirPath = QCoreApplication::applicationDirPath() + "/crash";
|
||||
QDir dir;
|
||||
if (!dir.exists(appDirPath)) {
|
||||
@ -94,7 +94,7 @@ bool InstallCrashHandler() {
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
exceptionHandler.reset(new google_breakpad::ExceptionHandler(
|
||||
appDirPath.toStdWString(), NULL, OnMinidumpCallback, NULL,
|
||||
appDirPath.toStdWString(), nullptr, OnMinidumpCallback, nullptr,
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL));
|
||||
#else
|
||||
exceptionHandler.reset(new google_breakpad::ExceptionHandler(
|
||||
@ -106,7 +106,10 @@ bool InstallCrashHandler() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestCrash() {
|
||||
volatile int* a = (int*)(nullptr);
|
||||
*a = 1;
|
||||
#else
|
||||
|
||||
bool InstallCrashHandler() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2,4 +2,3 @@
|
||||
|
||||
|
||||
bool InstallCrashHandler();
|
||||
void TestCrash();
|
@ -239,7 +239,9 @@ void ConeWave::CreateTexturedCone(osg::Geode* geode) {
|
||||
// baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
|
||||
// stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
||||
// stateset->addUniform(baseColorUniform_);
|
||||
// // stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||
// // stateset->osg::ref_ptr<osg::Program> program = new osg::Program();
|
||||
program->addShader(vertexShader);
|
||||
program->addShader(fragmentShader);(program, osg::StateAttribute::ON);
|
||||
// // stateset->setAttributeAndModes(new osg::Depth(osg::Depth::LESS, 0.0, 1.0, false));
|
||||
//
|
||||
// levelCountUniform_ = new osg::Uniform("num", float(levelCount_));
|
||||
@ -256,7 +258,8 @@ void ConeWave::CreateTexturedCone(osg::Geode* geode) {
|
||||
#include <osgFX/Outline>
|
||||
#include <osgFX/Scribe>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osgEarth/Ellipsoid>
|
||||
#include <osg/Texture2D>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include "scene/SceneContent.h"
|
||||
|
||||
@ -326,7 +329,6 @@ void WaveBeamConeCallBack::operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
||||
osg::Matrix mConeRate = osg::Matrix::rotate(osg::Vec3d(0, 1, 0), (mTarget*m).getTrans());
|
||||
mtCone->setMatrix(mConeRate);//mTarget*m
|
||||
|
||||
//更改cone的形状----------------------------------------
|
||||
double length = (mTarget*m).getTrans().length();
|
||||
|
||||
double angle = osg::DegreesToRadians(m_angle);
|
||||
@ -334,7 +336,6 @@ void WaveBeamConeCallBack::operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
||||
int splitCount = 20;
|
||||
double angleStep = osg::PI * 2.0 / splitCount;
|
||||
|
||||
//侧面
|
||||
for (int i = 1; i <= splitCount + 1; i++) {
|
||||
double tempAngle = (i - 1)*angleStep;
|
||||
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
||||
@ -343,7 +344,6 @@ void WaveBeamConeCallBack::operator()(osg::Node *node, osg::NodeVisitor *nv) {
|
||||
|
||||
m_pointVector->at(splitCount + 2) = osg::Vec3(0, length, 0);
|
||||
|
||||
//底面
|
||||
for (int i = splitCount + 3; i <= splitCount + 3 + splitCount; i++) {
|
||||
double tempAngle = (i - splitCount - 3) *angleStep;
|
||||
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
||||
@ -383,10 +383,11 @@ void ConeWave::createWaveBeamCone(osg::MatrixTransform* node, double angle, doub
|
||||
osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array;
|
||||
osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array;
|
||||
osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt = new osg::DrawElementsUInt(GL_TRIANGLE_FAN);
|
||||
osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt2 = new osg::DrawElementsUInt(GL_TRIANGLE_FAN);
|
||||
// osg::ref_ptr<osg::DrawElementsUInt> drawElemUInt2 = new osg::DrawElementsUInt(GL_TRIANGLE_FAN);
|
||||
geom->setVertexArray(vertex);
|
||||
geom->setNormalArray(normal);
|
||||
geode->addDrawable(geom);
|
||||
geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
|
||||
vertex->push_back(osg::Vec3(0, 0, 0));
|
||||
drawElemUInt->push_back(0);
|
||||
@ -395,7 +396,7 @@ void ConeWave::createWaveBeamCone(osg::MatrixTransform* node, double angle, doub
|
||||
//侧面
|
||||
for (int i = 0; i <= splitCount; i++) {
|
||||
double tempAngle = i*angleStep;
|
||||
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
||||
osg::Vec3 pos(radius * cos(tempAngle), radius * sin(tempAngle) + 3, length);
|
||||
vertex->push_back(osg::Vec3(pos));
|
||||
|
||||
pos.normalize();
|
||||
@ -403,46 +404,52 @@ void ConeWave::createWaveBeamCone(osg::MatrixTransform* node, double angle, doub
|
||||
drawElemUInt->push_back(i + 1);
|
||||
}
|
||||
|
||||
//底面
|
||||
int indexBegin = vertex->size();
|
||||
vertex->push_back(osg::Vec3(0, length, 0));
|
||||
drawElemUInt2->push_back(indexBegin);
|
||||
normal->push_back(osg::Vec3(0, 1, 0));
|
||||
for (int i = 0; i <= splitCount; i++) {
|
||||
double tempAngle = i*angleStep;
|
||||
osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
||||
vertex->push_back(osg::Vec3(pos));
|
||||
|
||||
normal->push_back(osg::Vec3(0, 1, 0));
|
||||
drawElemUInt2->push_back(indexBegin + i + 1);
|
||||
}
|
||||
// //底面
|
||||
// int indexBegin = vertex->size();
|
||||
// vertex->push_back(osg::Vec3(0, length, 0));
|
||||
// drawElemUInt2->push_back(indexBegin);
|
||||
// normal->push_back(osg::Vec3(0, 1, 0));
|
||||
// for (int i = 0; i <= splitCount; i++) {
|
||||
// double tempAngle = i*angleStep;
|
||||
// osg::Vec3 pos(radius * cos(tempAngle), length, radius * sin(tempAngle) + 3);
|
||||
// vertex->push_back(osg::Vec3(pos));
|
||||
//
|
||||
// normal->push_back(osg::Vec3(0, 1, 0));
|
||||
// drawElemUInt2->push_back(indexBegin + i + 1);
|
||||
// }
|
||||
|
||||
|
||||
geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
geom->addPrimitiveSet(drawElemUInt);
|
||||
geom->addPrimitiveSet(drawElemUInt2);
|
||||
// geom->addPrimitiveSet(drawElemUInt2);
|
||||
|
||||
//创建材质对象
|
||||
osg::ref_ptr<osg::Material> mat = new osg::Material;
|
||||
//设置正面散射颜色
|
||||
mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
||||
//设置正面镜面颜色
|
||||
mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.0, 0.0, 0.0, 0.3));//1.0, 0.0, 0.0, 0.3
|
||||
|
||||
geode->getOrCreateStateSet()->setAttribute(mat.get());
|
||||
geode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
|
||||
//设置透明效果
|
||||
|
||||
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
//设置渲染顺序 仿真模型被波束遮盖 ,1000000-指的是若有1000000个Node 则此节点最后一个被渲染
|
||||
geode->getOrCreateStateSet()->setRenderBinDetails(12, "RenderBin");
|
||||
|
||||
osg::ref_ptr<osg::MatrixTransform> mtCone = new osg::MatrixTransform;
|
||||
// mtCone->addChild(nodeFX);
|
||||
mtCone->addChild(geode);
|
||||
|
||||
const char* path = "D:/Project/DYTSrouce/bin/Release/resources/textures/block.png";
|
||||
osg::Image* image = osgDB::readImageFile(path);
|
||||
osg::ref_ptr<osg::Texture2D> pTexture2D = new osg::Texture2D;
|
||||
pTexture2D->setImage(image);
|
||||
pTexture2D->setWrap(osg::Texture::WRAP_S , osg::Texture::CLAMP_TO_EDGE);
|
||||
pTexture2D->setWrap(osg::Texture::WRAP_T , osg::Texture::REPEAT);
|
||||
pTexture2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
|
||||
pTexture2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
|
||||
geode->getOrCreateStateSet()->setTextureAttribute(0, pTexture2D);
|
||||
geode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
|
||||
|
||||
//给callback中赋值
|
||||
WaveBeamConeCallBack* coneCallBack = new WaveBeamConeCallBack;
|
||||
coneCallBack->m_angle = angle;
|
||||
coneCallBack->m_length = length;
|
||||
@ -454,7 +461,6 @@ void ConeWave::createWaveBeamCone(osg::MatrixTransform* node, double angle, doub
|
||||
coneCallBack->m_geom = geom;
|
||||
coneCallBack->m_pointVector = vertex;
|
||||
|
||||
//添加到模型中
|
||||
// osg::MatrixTransform* mtR = dynamic_cast<osg::MatrixTransform*>(node->getChild(0));
|
||||
// osg::MatrixTransform* mtS = dynamic_cast<osg::MatrixTransform*>(mtR->getChild(0));
|
||||
// mtR->addChild(mtCone);
|
||||
@ -514,8 +520,9 @@ void ConeWave::changeWaveBeamConeAppearance( osg::Vec4 color, osg::Vec4 lineColo
|
||||
_waveBeamCone->removeChild(coneCallBack->m_geode);
|
||||
_waveBeamCone->addChild(coneCallBack->m_nodeFX);
|
||||
|
||||
|
||||
coneCallBack->m_nodeFX->setWireframeColor(lineColor);
|
||||
coneCallBack->m_nodeFX->setWireframeLineWidth(lineWidth);
|
||||
coneCallBack->m_nodeFX->setWireframeLineWidth(static_cast<float>(lineWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ private:
|
||||
#include <osg/MatrixTransform>
|
||||
#include "viewer/UpdateRenderStd.h"
|
||||
|
||||
//三维实体的圆锥波束
|
||||
|
||||
class ConeWave : public osg::Geode
|
||||
, public UpdateRenderStd {
|
||||
|
@ -102,7 +102,7 @@ void DashedLine::CreateTexturedCone(osg::Geode* geode) {
|
||||
"#version 330\n"
|
||||
"in vec4 osg_Vertex;\n"
|
||||
"in vec2 osg_MultiTexCoord0;\n"
|
||||
"uniform mat4 osg_ModelViewProjectionMatrix;\n"//当前OSG摄像机的观察矩阵;
|
||||
"uniform mat4 osg_ModelViewProjectionMatrix;\n"//<EFBFBD><EFBFBD>ǰOSG<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ۲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
"uniform float time;\n"
|
||||
"out vec2 texCoord;\n"
|
||||
"void main()\n"
|
||||
@ -151,7 +151,8 @@ void DashedLine::UpdateRotaion() {
|
||||
float height = direction.length();
|
||||
|
||||
cylinder_->setHeight(height);
|
||||
cylinderDrawable_->build();
|
||||
// cylinderDrawable_->b();
|
||||
// cylinderDrawable_-
|
||||
|
||||
osg::Vec3 center = (start_ + end_) * 0.5f;
|
||||
direction.normalize();
|
||||
|
390
src/main.cpp
390
src/main.cpp
@ -1,3 +1,4 @@
|
||||
|
||||
#include "app/Application.h"
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
@ -5,23 +6,396 @@
|
||||
#include "common/CrashHandler.h"
|
||||
|
||||
#include "ui/MainFrame.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "viewer/OsgWidget.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QApplication>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include <osgViewer/CompositeViewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <osgGA/MultiTouchTrackballManipulator>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgEarth/MapNode>
|
||||
#include <osgEarthUtil/ExampleResources>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
// #include <osgEarth/GLUtils>
|
||||
|
||||
#include "osgqt/GraphicsWindowQt.h"
|
||||
#include "scene/ui/CompositeWidgetManager.h"
|
||||
#include "scene/ui/QueryElevationWidget.h"
|
||||
|
||||
#ifndef LC
|
||||
#define LC "DYT"
|
||||
#endif
|
||||
|
||||
const unsigned int MASK_2D = 0xF0000000;
|
||||
std::string path = "D:\\Project\\DYT\\Source\\bin\\Release\\data\\";
|
||||
|
||||
bool scrollWindow(osgWidget::Event& ev) {
|
||||
// The first thing we need to do is make sure we have a Frame object...
|
||||
osgWidget::Frame* frame = dynamic_cast<osgWidget::Frame*>(ev.getWindow());
|
||||
|
||||
if(!frame) return false;
|
||||
|
||||
// And now we need to make sure our Frame has a valid internal EmbeddedWindow widget.
|
||||
osgWidget::Window::EmbeddedWindow* ew =
|
||||
dynamic_cast<osgWidget::Window::EmbeddedWindow*>(frame->getEmbeddedWindow())
|
||||
;
|
||||
|
||||
if(!ew) return false;
|
||||
|
||||
// Lets get the visible area so that we can use it to make sure our scrolling action
|
||||
// is necessary in the first place.
|
||||
const osgWidget::Quad& va = ew->getWindow()->getVisibleArea();
|
||||
|
||||
// The user wants to scroll up; make sure that the visible area's Y origin isn't already
|
||||
// at 0.0f, 0.0f.
|
||||
if(ev.getWindowManager()->isMouseScrollingUp() && va[1] != 0.0f)
|
||||
ew->getWindow()->addVisibleArea(0, -20)
|
||||
;
|
||||
|
||||
else if(va[1] <= (ew->getWindow()->getHeight() - ew->getHeight()))
|
||||
ew->getWindow()->addVisibleArea(0, 20)
|
||||
;
|
||||
|
||||
// We need to manually call update to make sure the visible area scissoring is done
|
||||
// properly.
|
||||
frame->update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool changeTheme(osgWidget::Event& ev) {
|
||||
std::string theme;
|
||||
|
||||
if(ev.key == osgGA::GUIEventAdapter::KEY_Right)
|
||||
theme = "osgWidget/theme-1.png"
|
||||
;
|
||||
|
||||
else if(ev.key == osgGA::GUIEventAdapter::KEY_Left)
|
||||
theme = "osgWidget/theme-2.png"
|
||||
;
|
||||
|
||||
else return false;
|
||||
|
||||
osgWidget::Frame* frame = dynamic_cast<osgWidget::Frame*>(ev.getWindow());
|
||||
|
||||
if(!frame) return false;
|
||||
|
||||
// This is just one way to access all our Widgets; we could just as well have used:
|
||||
//
|
||||
// for(osgWidget::Frame::Iterator i = frame.begin(); i != frame.end() i++) {}
|
||||
//
|
||||
// ...and it have worked, too.
|
||||
for(unsigned int row = 0; row < 3; row++) {
|
||||
for(unsigned int col = 0; col < 3; col++) {
|
||||
frame->getByRowCol(row, col)->setImage(theme);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
osg::Node* createUiExample(osgViewer::View* viewer, osgWidget::WindowManager* wm) {
|
||||
if(!wm) return nullptr;
|
||||
|
||||
// viewer.setUpViewInWindow(
|
||||
// 50,
|
||||
// 50,
|
||||
// static_cast<int>(wm->getWidth()),
|
||||
// static_cast<int>(wm->getHeight())
|
||||
// );
|
||||
|
||||
osg::Group* group = new osg::Group();
|
||||
osg::Camera* camera = wm->createParentOrthoCamera();
|
||||
|
||||
group->addChild(camera);
|
||||
|
||||
viewer->addEventHandler(new osgWidget::MouseHandler(wm));
|
||||
viewer->addEventHandler(new osgWidget::KeyboardHandler(wm));
|
||||
viewer->addEventHandler(new osgWidget::ResizeHandler(wm, camera));
|
||||
viewer->addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera));
|
||||
viewer->addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer->addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
viewer->addEventHandler(new osgGA::StateSetManipulator(
|
||||
viewer->getCamera()->getOrCreateStateSet()
|
||||
));
|
||||
|
||||
wm->resizeAllWindows();
|
||||
return group;
|
||||
}
|
||||
|
||||
void creatWidget(osgViewer::View* viewer, osg::Group* root) {
|
||||
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
|
||||
viewer,
|
||||
1280.0f,
|
||||
1024.0f,
|
||||
MASK_2D,
|
||||
osgWidget::WindowManager::WM_PICK_DEBUG
|
||||
//osgWidget::WindowManager::WM_NO_INVERT_Y
|
||||
);
|
||||
|
||||
osgWidget::Frame* frame = osgWidget::Frame::createSimpleFrameFromTheme(
|
||||
"frame",
|
||||
osgDB::readRefImageFile("osgWidget/theme.png"),
|
||||
40.0f,
|
||||
40.0f,
|
||||
osgWidget::Frame::FRAME_ALL
|
||||
);
|
||||
osgWidget::Box* box = new osgWidget::Box("images", osgWidget::Box::VERTICAL);
|
||||
osgWidget::Widget* img1 = new osgWidget::Widget("im1", 512.0f, 512.0f);
|
||||
osgWidget::Widget* img2 = new osgWidget::Widget("im2", 512.0f, 512.0f);
|
||||
osgWidget::Widget* img3 = new osgWidget::Widget("im3", 512.0f, 512.0f);
|
||||
osgWidget::Widget* img4 = new osgWidget::Widget("im4", 512.0f, 512.0f);
|
||||
|
||||
img1->setImage(path + "osgWidget/scrolled1.jpg", true);
|
||||
img2->setImage(path + "osgWidget/scrolled2.jpg", true);
|
||||
img3->setImage(path + "osgWidget/scrolled3.jpg", true);
|
||||
img4->setImage(path + "osgWidget/scrolled4.jpg", true);
|
||||
|
||||
img1->setMinimumSize(10.0f, 10.0f);
|
||||
img2->setMinimumSize(10.0f, 10.0f);
|
||||
img3->setMinimumSize(10.0f, 10.0f);
|
||||
img4->setMinimumSize(10.0f, 10.0f);
|
||||
|
||||
box->addWidget(img1);
|
||||
box->addWidget(img2);
|
||||
box->addWidget(img3);
|
||||
box->addWidget(img4);
|
||||
box->setEventMask(osgWidget::EVENT_NONE);
|
||||
|
||||
//frame->getEmbeddedWindow()->setWindow(box);
|
||||
frame->setWindow(box);
|
||||
frame->getEmbeddedWindow()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
frame->resize(300.0f, 300.0f);
|
||||
frame->addCallback(new osgWidget::Callback(&scrollWindow, osgWidget::EVENT_MOUSE_SCROLL));
|
||||
frame->addCallback(new osgWidget::Callback(&changeTheme, osgWidget::EVENT_KEY_DOWN));
|
||||
|
||||
wm->addChild(frame);
|
||||
|
||||
osg::Node* ui = createUiExample(viewer, wm);
|
||||
root->addChild(ui);
|
||||
}
|
||||
|
||||
void configureView( osgViewer::View* view )
|
||||
{
|
||||
// default uniform values:
|
||||
// GLUtils::setGlobalDefaults(view->getCamera()->getOrCreateStateSet());
|
||||
|
||||
// add some stock OSG handlers:
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
osg::Node* LoadEarth(const std::string& earth, osgViewer::CompositeViewer* viewer) {
|
||||
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(earth);
|
||||
|
||||
osg::ref_ptr<osgEarth::MapNode> mapNode = osgEarth::MapNode::get(node.get());
|
||||
if ( !mapNode.valid() )
|
||||
{
|
||||
OE_WARN << LC << "Loaded scene graph does not contain a MapNode - aborting" << std::endl;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// collect the views
|
||||
osgViewer::Viewer::Views views;
|
||||
if (viewer)
|
||||
{
|
||||
viewer->getViews(views);
|
||||
}
|
||||
|
||||
// warn about not having an earth manip
|
||||
for (osgViewer::Viewer::Views::iterator view = views.begin(); view != views.end(); ++view)
|
||||
{
|
||||
osgEarth::Util::EarthManipulator* manip = dynamic_cast<osgEarth::Util::EarthManipulator*>((*view)->getCameraManipulator());
|
||||
if ( manip == 0L )
|
||||
{
|
||||
OE_WARN << LC << "Helper used before installing an EarthManipulator" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// a root node to hold everything:
|
||||
osg::Group* root = new osg::Group();
|
||||
|
||||
root->addChild( node );
|
||||
|
||||
// parses common cmdline arguments and apply to the first view:
|
||||
// if ( !views.empty() )
|
||||
// {
|
||||
// parse( mapNode.get(), args, views.front(), root, userContainer );
|
||||
//
|
||||
// float lodscale;
|
||||
// if (args.read("--lodscale", lodscale))
|
||||
// {
|
||||
// LODScaleGroup* g = new LODScaleGroup();
|
||||
// g->setLODScaleFactor(osg::maximum(lodscale, 0.0001f));
|
||||
// osgEarth::insertGroup(g, mapNode->getParent(0));
|
||||
// OE_NOTICE << "LOD Scale set to: " << lodscale << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// configures each view with some stock goodies
|
||||
for (osgViewer::Viewer::Views::iterator view = views.begin(); view != views.end(); ++view)
|
||||
{
|
||||
configureView( *view );
|
||||
}
|
||||
|
||||
#ifdef OSG_GL3_AVAILABLE
|
||||
if (viewer)
|
||||
{
|
||||
viewer->setRealizeOperation(new GL3RealizeOperation());
|
||||
}
|
||||
#endif
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
|
||||
{
|
||||
public:
|
||||
ViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
|
||||
{
|
||||
setThreadingModel(threadingModel);
|
||||
|
||||
// disable the default setting of viewer.done() by pressing Escape.
|
||||
setKeyEventSetsDone(0);
|
||||
|
||||
std::string earthPath = "D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth";
|
||||
// osg::Node* node = osgDB::readNodeFile();
|
||||
osg::Node* node =LoadEarth(earthPath, this);
|
||||
if ( !node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Group to hold all our annotation elements.
|
||||
// osg::Group* annoGroup = new osg::Group();
|
||||
// osgEarth::MapNode::get(node)->addChild( annoGroup );
|
||||
|
||||
QWidget* widget1 = addViewWidget( createGraphicsWindow(0,0,100,100), node);
|
||||
// QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("glider.osgt") );
|
||||
// QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("axes.osgt") );
|
||||
// QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("fountain.osgt") );
|
||||
// QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readRefNodeFile("dumptruck.osgt") );
|
||||
// popupWidget->show();
|
||||
|
||||
|
||||
|
||||
QGridLayout* grid = new QGridLayout;
|
||||
grid->addWidget( widget1, 0, 0 );
|
||||
// grid->addWidget( widget2, 0, 1 );
|
||||
// grid->addWidget( widget3, 1, 0 );
|
||||
// grid->addWidget( widget4, 1, 1 );
|
||||
setLayout( grid );
|
||||
|
||||
connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
|
||||
_timer.start( 10 );
|
||||
}
|
||||
|
||||
QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene )
|
||||
{
|
||||
osgViewer::View* view = new osgViewer::View;
|
||||
addView( view );
|
||||
view->setCameraManipulator( new osgEarth::Util::EarthManipulator() );
|
||||
configureView(view);
|
||||
|
||||
osg::Camera* camera = view->getCamera();
|
||||
camera->setGraphicsContext( gw );
|
||||
|
||||
const osg::GraphicsContext::Traits* traits = gw->getTraits();
|
||||
|
||||
camera->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 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 );
|
||||
|
||||
creatWidget(view, scene->asGroup());
|
||||
|
||||
osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode(scene);
|
||||
if ( !mapNode )
|
||||
return gw->getGLWidget();
|
||||
|
||||
auto skyDome_ = osgEarth::Util::SkyNode::create(mapNode);
|
||||
if (!mapNode) {
|
||||
LOG_WARN("eart map node is nullptr");
|
||||
return gw->getGLWidget();
|
||||
}
|
||||
skyDome_->attach(view);
|
||||
skyDome_->getSunLight()->setAmbient(osg::Vec4(0.5,0.5,0.5,1.0));
|
||||
scene->asGroup()->addChild(skyDome_);
|
||||
|
||||
skyDome_->setDateTime(osgEarth::DateTime(2024, 12, 24, 3));
|
||||
|
||||
view->setSceneData( scene );
|
||||
view->addEventHandler( new osgViewer::StatsHandler );
|
||||
// view->setCameraManipulator( new osgGA::MultiTouchTrackballManipulator );
|
||||
gw->setTouchEventsEnabled( true );
|
||||
return gw->getGLWidget();
|
||||
}
|
||||
|
||||
osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false )
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
virtual void paintEvent( QPaintEvent* /*event*/ )
|
||||
{ frame(); }
|
||||
|
||||
protected:
|
||||
|
||||
QTimer _timer;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
SpdLogger logger("logs/log.txt", 5);
|
||||
|
||||
//
|
||||
Application::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
|
||||
////
|
||||
Application app(argc, argv);
|
||||
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
InstallCrashHandler();
|
||||
|
||||
// InstallCrashHandler();
|
||||
//
|
||||
RecourceHelper::ChangeSkin("default");
|
||||
|
||||
int ret = 0;
|
||||
|
||||
MainFrame mainWindow;
|
||||
mainWindow.showMaximized();
|
||||
//
|
||||
int ret = app.exec();
|
||||
app.Uninit();
|
||||
return ret;
|
||||
|
||||
ret = app.exec();
|
||||
return ret;
|
||||
//osg::ArgumentParser arguments(&argc, argv);
|
||||
|
||||
//QMainWindow* mainWindow = new QMainWindow;
|
||||
//OsgWidget* viewWidget = new OsgWidget(nullptr, Qt::Widget);
|
||||
//mainWindow->setCentralWidget(viewWidget);
|
||||
//// ViewerWidget* viewWidget = new ViewerWidget(nullptr, Qt::Widget, threadingModel);
|
||||
////viewWidget->setGeometry( 100, 100, 800, 600 );
|
||||
//viewWidget->Initialize();
|
||||
//mainWindow->show();
|
||||
//return app.exec();
|
||||
}
|
||||
|
1066
src/osgqt/GraphicsWindowQt.cpp
Normal file
1066
src/osgqt/GraphicsWindowQt.cpp
Normal file
File diff suppressed because it is too large
Load Diff
195
src/osgqt/GraphicsWindowQt.h
Normal file
195
src/osgqt/GraphicsWindowQt.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Wang Rui
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGVIEWER_GRAPHICSWINDOWQT
|
||||
#define OSGVIEWER_GRAPHICSWINDOWQT
|
||||
|
||||
#define USE_NO_STATIC_REGISTRATION 1
|
||||
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QEvent>
|
||||
#include <QQueue>
|
||||
#include <QSet>
|
||||
#include <QGLWidget>
|
||||
|
||||
class QInputEvent;
|
||||
class QGestureEvent;
|
||||
|
||||
namespace osgViewer {
|
||||
class ViewerBase;
|
||||
}
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
// forward declarations
|
||||
class GraphicsWindowQt;
|
||||
|
||||
#if USE_NO_STATIC_REGISTRATION
|
||||
/// The function sets the WindowingSystem to Qt.
|
||||
void initQtWindowingSystem();
|
||||
#endif
|
||||
|
||||
/** The function sets the viewer that will be used after entering
|
||||
* the Qt main loop (QCoreApplication::exec()).
|
||||
*
|
||||
* The function also initializes internal structures required for proper
|
||||
* scene rendering.
|
||||
*
|
||||
* The method must be called from main thread. */
|
||||
void setViewer( osgViewer::ViewerBase *viewer );
|
||||
|
||||
|
||||
class GLWidget : public QGLWidget
|
||||
{
|
||||
typedef QGLWidget inherited;
|
||||
|
||||
public:
|
||||
|
||||
GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
virtual ~GLWidget();
|
||||
|
||||
inline void setGraphicsWindow( GraphicsWindowQt* gw ) { _gw = gw; }
|
||||
inline GraphicsWindowQt* getGraphicsWindow() { return _gw; }
|
||||
inline const GraphicsWindowQt* getGraphicsWindow() const { return _gw; }
|
||||
|
||||
inline bool getForwardKeyEvents() const { return _forwardKeyEvents; }
|
||||
virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; }
|
||||
|
||||
inline bool getTouchEventsEnabled() const { return _touchEventsEnabled; }
|
||||
void setTouchEventsEnabled( bool e );
|
||||
|
||||
void setKeyboardModifiers( QInputEvent* event );
|
||||
|
||||
virtual void keyPressEvent( QKeyEvent* event );
|
||||
virtual void keyReleaseEvent( QKeyEvent* event );
|
||||
virtual void mousePressEvent( QMouseEvent* event );
|
||||
virtual void mouseReleaseEvent( QMouseEvent* event );
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent* event );
|
||||
virtual void mouseMoveEvent( QMouseEvent* event );
|
||||
virtual void wheelEvent( QWheelEvent* event );
|
||||
virtual bool gestureEvent( QGestureEvent* event );
|
||||
|
||||
protected:
|
||||
|
||||
int getNumDeferredEvents()
|
||||
{
|
||||
QMutexLocker lock(&_deferredEventQueueMutex);
|
||||
return _deferredEventQueue.count();
|
||||
}
|
||||
void enqueueDeferredEvent(QEvent::Type eventType, QEvent::Type removeEventType = QEvent::None)
|
||||
{
|
||||
QMutexLocker lock(&_deferredEventQueueMutex);
|
||||
|
||||
if (removeEventType != QEvent::None)
|
||||
{
|
||||
if (_deferredEventQueue.removeOne(removeEventType))
|
||||
_eventCompressor.remove(eventType);
|
||||
}
|
||||
|
||||
if (_eventCompressor.find(eventType) == _eventCompressor.end())
|
||||
{
|
||||
_deferredEventQueue.enqueue(eventType);
|
||||
_eventCompressor.insert(eventType);
|
||||
}
|
||||
}
|
||||
void processDeferredEvents();
|
||||
|
||||
friend class GraphicsWindowQt;
|
||||
GraphicsWindowQt* _gw;
|
||||
|
||||
QMutex _deferredEventQueueMutex;
|
||||
QQueue<QEvent::Type> _deferredEventQueue;
|
||||
QSet<QEvent::Type> _eventCompressor;
|
||||
|
||||
bool _touchEventsEnabled;
|
||||
|
||||
bool _forwardKeyEvents;
|
||||
qreal _devicePixelRatio;
|
||||
|
||||
virtual void resizeEvent( QResizeEvent* event );
|
||||
virtual void moveEvent( QMoveEvent* event );
|
||||
virtual void glDraw();
|
||||
virtual bool event( QEvent* event );
|
||||
};
|
||||
|
||||
class GraphicsWindowQt : public osgViewer::GraphicsWindow
|
||||
{
|
||||
public:
|
||||
GraphicsWindowQt( osg::GraphicsContext::Traits* traits, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0 );
|
||||
GraphicsWindowQt( GLWidget* widget );
|
||||
virtual ~GraphicsWindowQt();
|
||||
|
||||
inline GLWidget* getGLWidget() { return _widget; }
|
||||
inline const GLWidget* getGLWidget() const { return _widget; }
|
||||
|
||||
/// deprecated
|
||||
inline GLWidget* getGraphWidget() { return _widget; }
|
||||
/// deprecated
|
||||
inline const GLWidget* getGraphWidget() const { return _widget; }
|
||||
|
||||
struct WindowData : public osg::Referenced
|
||||
{
|
||||
WindowData( GLWidget* widget = NULL, QWidget* parent = NULL ): _widget(widget), _parent(parent) {}
|
||||
GLWidget* _widget;
|
||||
QWidget* _parent;
|
||||
};
|
||||
|
||||
bool init( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f );
|
||||
|
||||
static QGLFormat traits2qglFormat( const osg::GraphicsContext::Traits* traits );
|
||||
static void qglFormat2traits( const QGLFormat& format, osg::GraphicsContext::Traits* traits );
|
||||
static osg::GraphicsContext::Traits* createTraits( const QGLWidget* widget );
|
||||
|
||||
virtual bool setWindowRectangleImplementation( int x, int y, int width, int height );
|
||||
virtual void getWindowRectangle( int& x, int& y, int& width, int& height );
|
||||
virtual bool setWindowDecorationImplementation( bool windowDecoration );
|
||||
virtual bool getWindowDecoration() const;
|
||||
virtual void grabFocus();
|
||||
virtual void grabFocusIfPointerInWindow();
|
||||
virtual void raiseWindow();
|
||||
virtual void setWindowName( const std::string& name );
|
||||
virtual std::string getWindowName();
|
||||
virtual void useCursor( bool cursorOn );
|
||||
virtual void setCursor( MouseCursor cursor );
|
||||
inline bool getTouchEventsEnabled() const { return _widget->getTouchEventsEnabled(); }
|
||||
virtual void setTouchEventsEnabled( bool e ) { _widget->setTouchEventsEnabled(e); }
|
||||
|
||||
|
||||
virtual bool valid() const;
|
||||
virtual bool realizeImplementation();
|
||||
virtual bool isRealizedImplementation() const;
|
||||
virtual void closeImplementation();
|
||||
virtual bool makeCurrentImplementation();
|
||||
virtual bool releaseContextImplementation();
|
||||
virtual void swapBuffersImplementation();
|
||||
virtual void runOperations();
|
||||
|
||||
virtual void requestWarpPointer( float x, float y );
|
||||
|
||||
protected:
|
||||
|
||||
friend class GLWidget;
|
||||
GLWidget* _widget;
|
||||
bool _ownsWidget;
|
||||
QCursor _currentCursor;
|
||||
bool _realized;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
149
src/osgqt/QFontImplementation.cpp
Normal file
149
src/osgqt/QFontImplementation.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009-2010 Mathias Froehlich
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include "osgqt/QFontImplementation.h"
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
#ifndef OSGTEXT_GLYPH_INTERNALFORMAT
|
||||
#define OSGTEXT_GLYPH_INTERNALFORMAT GL_LUMINANCE_ALPHA
|
||||
#endif
|
||||
#ifndef OSGTEXT_GLYPH_FORMAT
|
||||
#define OSGTEXT_GLYPH_FORMAT GL_LUMINANCE_ALPHA
|
||||
#endif
|
||||
|
||||
|
||||
namespace osgQt {
|
||||
|
||||
QFontImplementation::QFontImplementation(const QFont& font) :
|
||||
_filename(font.toString().toStdString() + ".qfont"),
|
||||
_font(font)
|
||||
{
|
||||
}
|
||||
|
||||
QFontImplementation::~QFontImplementation()
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
QFontImplementation::getFileName() const
|
||||
{
|
||||
return _filename;
|
||||
}
|
||||
|
||||
osgText::Glyph*
|
||||
QFontImplementation::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode)
|
||||
{
|
||||
unsigned int fontSize = fontRes.second;
|
||||
_font.setPixelSize(fontSize);
|
||||
|
||||
float coord_scale = 1.0f/float(fontSize);
|
||||
|
||||
QFontMetrics fontMetrics(_font);
|
||||
QFontMetricsF fontMetricsF(_font);
|
||||
|
||||
QRect rect = fontMetrics.boundingRect(QChar(charcode));
|
||||
QRectF rectF = fontMetricsF.boundingRect(QChar(charcode));
|
||||
|
||||
int margin = 1;
|
||||
|
||||
int imageWidth = rect.width() + 2*margin;
|
||||
int imageHeight = rect.height() + 2*margin;
|
||||
|
||||
// Now paint the glyph into the image
|
||||
QImage image(imageWidth, imageHeight, QImage::Format_ARGB32);
|
||||
image.fill(0);
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::TextAntialiasing);
|
||||
|
||||
painter.setFont(_font);
|
||||
|
||||
painter.setBackgroundMode(Qt::TransparentMode);
|
||||
painter.setBrush(Qt::white);
|
||||
painter.setPen(Qt::white);
|
||||
|
||||
painter.drawText(margin - rect.left(), imageHeight - 1 - (margin + rect.bottom()), QString(QChar(charcode)));
|
||||
painter.end();
|
||||
|
||||
// Transfer the rendered image to osg
|
||||
osg::ref_ptr<osgText::Glyph> glyph = new osgText::Glyph(_facade, charcode);
|
||||
|
||||
unsigned int dataSize = imageWidth*imageHeight;
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
|
||||
// copy the qimage into the texture memory
|
||||
for (int x = 0; x < imageWidth; ++x)
|
||||
{
|
||||
for (int y = 0; y < imageHeight; ++y)
|
||||
{
|
||||
data[x + y*imageWidth] = qAlpha(image.pixel(x, imageHeight - 1 - y));
|
||||
}
|
||||
}
|
||||
|
||||
// the glyph texture in osg
|
||||
glyph->setImage(imageWidth, imageHeight, 1,
|
||||
OSGTEXT_GLYPH_INTERNALFORMAT,
|
||||
OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE,
|
||||
data,
|
||||
osg::Image::USE_NEW_DELETE,
|
||||
1);
|
||||
glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT);
|
||||
|
||||
glyph->setWidth((float)imageWidth * coord_scale);
|
||||
glyph->setHeight((float)imageHeight * coord_scale);
|
||||
|
||||
// Layout parameters
|
||||
float leftBearing = fontMetricsF.leftBearing(QChar(charcode));
|
||||
float rightBearing = fontMetricsF.rightBearing(QChar(charcode));
|
||||
|
||||
// for horizonal layout
|
||||
osg::Vec2 bottomLeft(leftBearing - margin, - rectF.bottom() - margin);
|
||||
glyph->setHorizontalBearing(bottomLeft * coord_scale);
|
||||
glyph->setHorizontalAdvance(fontMetricsF.width(QChar(charcode)) * coord_scale);
|
||||
|
||||
// for vertical layout
|
||||
osg::Vec2 topMiddle(- margin + 0.5*(leftBearing - rect.width() - rightBearing),
|
||||
rectF.top() - margin);
|
||||
glyph->setVerticalBearing(topMiddle * coord_scale);
|
||||
glyph->setVerticalAdvance((rectF.height() + fontMetricsF.overlinePos() - fontMetricsF.xHeight()) * coord_scale);
|
||||
|
||||
// ... ready
|
||||
//addGlyph(fontRes, charcode, glyph.get());
|
||||
|
||||
return glyph.release();
|
||||
}
|
||||
|
||||
//osg::Vec2
|
||||
//QFontImplementation::getKerning(const osgText::FontResolution& /*fontRes*/, unsigned int /*leftcharcode*/, unsigned int /*rightcharcode*/, osgText::KerningType /*kerningType*/)
|
||||
//{
|
||||
// return osg::Vec2(0, 0);
|
||||
//}
|
||||
|
||||
osg::Vec2 QFontImplementation::getKerning(unsigned int leftcharcode, unsigned int rightcharcode, osgText::KerningType kerningType) {
|
||||
return osg::Vec2(0, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
QFontImplementation::hasVertical() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
52
src/osgqt/QFontImplementation.h
Normal file
52
src/osgqt/QFontImplementation.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009-2010 Mathias Froehlich
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#ifndef QFontImplementation_H
|
||||
#define QFontImplementation_H
|
||||
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <QtGui/QFont>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace osgQt {
|
||||
|
||||
class QFontImplementation : public osgText::Font::FontImplementation
|
||||
{
|
||||
public:
|
||||
QFontImplementation(const QFont& font);
|
||||
virtual ~QFontImplementation();
|
||||
|
||||
virtual std::string getFileName() const;
|
||||
|
||||
virtual bool supportsMultipleFontResolutions() const { return true; }
|
||||
|
||||
virtual osgText::Glyph* getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode);
|
||||
|
||||
//virtual osgText::Glyph3D* getGlyph3D(const osgText::FontResolution& /*fontRes*/, unsigned int /*charcode*/) { return 0; }
|
||||
virtual osgText::Glyph3D* getGlyph3D(unsigned int charcode) { return 0; }
|
||||
|
||||
//virtual osg::Vec2 getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode, unsigned int rightcharcode, osgText::KerningType kerningType);
|
||||
virtual osg::Vec2 getKerning(unsigned int leftcharcode, unsigned int rightcharcode, osgText::KerningType kerningType);
|
||||
|
||||
virtual bool hasVertical() const;
|
||||
|
||||
protected:
|
||||
|
||||
std::string _filename;
|
||||
QFont _font;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
613
src/osgqt/QGraphicsViewAdapter.cpp
Normal file
613
src/osgqt/QGraphicsViewAdapter.cpp
Normal file
@ -0,0 +1,613 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include "osgqt/QGraphicsViewAdapter.h"
|
||||
#include "osgqt/QWidgetImage.h"
|
||||
|
||||
#include <QtOpenGL/QGLWidget>
|
||||
|
||||
#include <osg/Version>
|
||||
#include <osgGA/GUIEventAdapter>
|
||||
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/io_utils>
|
||||
#include <QGraphicsItem>
|
||||
#include <QGraphicsProxyWidget>
|
||||
|
||||
#define MYQKEYEVENT 2000
|
||||
#define MYQPOINTEREVENT 2001
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
QCoreApplication* getOrCreateQApplication()
|
||||
{
|
||||
if (QApplication::instance()==0)
|
||||
{
|
||||
static char** argv = 0;
|
||||
static int argc = 0;
|
||||
static QApplication app(argc,argv);
|
||||
}
|
||||
return QApplication::instance();
|
||||
}
|
||||
|
||||
class MyQKeyEvent : public QEvent
|
||||
{
|
||||
public:
|
||||
MyQKeyEvent( int key, bool down ):
|
||||
QEvent( QEvent::Type(MYQKEYEVENT) ),
|
||||
_key(key), _down(down) {}
|
||||
|
||||
int _key;
|
||||
bool _down;
|
||||
};
|
||||
|
||||
struct MyQPointerEvent : public QEvent
|
||||
{
|
||||
MyQPointerEvent(int x, int y, unsigned int buttonMask):
|
||||
QEvent( QEvent::Type(MYQPOINTEREVENT) ),
|
||||
_x(x), _y(y),_buttonMask(buttonMask) {}
|
||||
|
||||
int _x, _y;
|
||||
unsigned int _buttonMask;
|
||||
};
|
||||
|
||||
|
||||
const QImage::Format s_imageFormat = QImage::Format_ARGB32_Premultiplied;
|
||||
|
||||
QGraphicsViewAdapter::QGraphicsViewAdapter(osg::Image* image, QWidget* widget):
|
||||
_image(image),
|
||||
_backgroundWidget(0),
|
||||
_previousButtonMask(0),
|
||||
_previousMouseX(-1),
|
||||
_previousMouseY(-1),
|
||||
_previousQtMouseX(-1),
|
||||
_previousQtMouseY(-1),
|
||||
_previousSentEvent(false),
|
||||
_requiresRendering(false),
|
||||
_qtKeyModifiers(Qt::NoModifier),
|
||||
_backgroundColor(255, 255, 255),
|
||||
_widget(widget)
|
||||
{
|
||||
// make sure we have a valid QApplication before we start creating widgets.
|
||||
getOrCreateQApplication();
|
||||
|
||||
|
||||
setUpKeyMap();
|
||||
|
||||
_graphicsScene = new QGraphicsScene;
|
||||
_graphicsScene->addWidget(widget);
|
||||
|
||||
_graphicsView = new QGraphicsView;
|
||||
_graphicsView->setScene(_graphicsScene);
|
||||
_graphicsView->viewport()->setParent(0);
|
||||
|
||||
#if (QT_VERSION_CHECK(4, 5, 0) <= QT_VERSION)
|
||||
_graphicsScene->setStickyFocus(true);
|
||||
#endif
|
||||
|
||||
_width = static_cast<int>(_graphicsScene->width());
|
||||
_height = static_cast<int>(_graphicsScene->height());
|
||||
|
||||
_qimages[0] = QImage(QSize(_width, _height), s_imageFormat);
|
||||
_qimages[1] = QImage(QSize(_width, _height), s_imageFormat);
|
||||
_qimages[2] = QImage(QSize(_width, _height), s_imageFormat);
|
||||
|
||||
_currentRead = 0;
|
||||
_currentWrite = 1;
|
||||
_previousWrite = 2;
|
||||
_previousFrameNumber = osg::UNINITIALIZED_FRAME_NUMBER;
|
||||
_newImageAvailable = false;
|
||||
|
||||
connect(_graphicsScene, SIGNAL(changed(const QList<QRectF> &)),
|
||||
this, SLOT(repaintRequestedSlot(const QList<QRectF> &)));
|
||||
connect(_graphicsScene, SIGNAL(sceneRectChanged(const QRectF &)),
|
||||
this, SLOT(repaintRequestedSlot(const QRectF &)));
|
||||
|
||||
assignImage(0);
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::repaintRequestedSlot(const QList<QRectF>&)
|
||||
{
|
||||
// OSG_NOTICE<<"QGraphicsViewAdapter::repaintRequestedSlot"<<std::endl;
|
||||
_requiresRendering = true;
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::repaintRequestedSlot(const QRectF&)
|
||||
{
|
||||
// OSG_NOTICE<<"QGraphicsViewAdapter::repaintRequestedSlot"<<std::endl;
|
||||
_requiresRendering = true;
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::customEvent ( QEvent * event )
|
||||
{
|
||||
if (event->type()==MYQKEYEVENT)
|
||||
{
|
||||
MyQKeyEvent* keyEvent = (MyQKeyEvent*)event;
|
||||
handleKeyEvent(keyEvent->_key, keyEvent->_down);
|
||||
}
|
||||
else if (event->type()==MYQPOINTEREVENT)
|
||||
{
|
||||
MyQPointerEvent* pointerEvent = (MyQPointerEvent*)event;
|
||||
handlePointerEvent(pointerEvent->_x, pointerEvent->_y, pointerEvent->_buttonMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGraphicsViewAdapter::setUpKeyMap()
|
||||
{
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_BackSpace] = Qt::Key_Backspace;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Tab] = Qt::Key_Tab;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Linefeed] = Qt::Key_Return; // No LineFeed in Qt!
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Clear] = Qt::Key_Clear;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Return] = Qt::Key_Return;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Pause] = Qt::Key_Pause;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Scroll_Lock] = Qt::Key_ScrollLock;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Sys_Req] = Qt::Key_SysReq;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Escape] = Qt::Key_Escape;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Delete] = Qt::Key_Delete;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Home] = Qt::Key_Home;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Left] = Qt::Key_Left;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Up] = Qt::Key_Up;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Right] = Qt::Key_Right;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Down] = Qt::Key_Down;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Prior] = Qt::Key_Left; // no Prior in Qt
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Page_Up] = Qt::Key_PageUp;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Next] = Qt::Key_Right; // No Next in Qt
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Page_Down] = Qt::Key_PageDown;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_End] = Qt::Key_End;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Begin] = Qt::Key_Home; // No Begin in Qt
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Select] = Qt::Key_Select;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Print] = Qt::Key_Print;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Execute] = Qt::Key_Execute;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Insert] = Qt::Key_Insert;
|
||||
//_keyMap[osgGA::GUIEventAdapter::KEY_Undo] = Qt::Key_; // no Undo
|
||||
//_keyMap[osgGA::GUIEventAdapter::KEY_Redo] = Qt::Key_; // no Redo
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Menu] = Qt::Key_Menu;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Find] = Qt::Key_Search; // no Qt Find
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Cancel] = Qt::Key_Cancel;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Help] = Qt::Key_Help;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Break] = Qt::Key_Escape; // no break
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Mode_switch] = Qt::Key_Mode_switch;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Script_switch] = Qt::Key_Mode_switch; // no Script switch
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Num_Lock] = Qt::Key_NumLock;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Shift_L] = Qt::Key_Shift;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Shift_R] = Qt::Key_Shift;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Control_L] = Qt::Key_Control;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Control_R] = Qt::Key_Control;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Caps_Lock] = Qt::Key_CapsLock;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Shift_Lock] = Qt::Key_CapsLock;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Meta_L] = Qt::Key_Meta; // Qt doesn't have a Meta L
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Meta_R] = Qt::Key_Meta; // Qt doesn't have a Meta R
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Alt_L] = Qt::Key_Alt; // Qt doesn't have a Alt L
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Alt_R] = Qt::Key_Alt; // Qt doesn't have a Alt R
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Super_L] = Qt::Key_Super_L;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Super_R] = Qt::Key_Super_R;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Hyper_L] = Qt::Key_Hyper_L;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_Hyper_R] = Qt::Key_Hyper_R;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Space] = Qt::Key_Space;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Tab] = Qt::Key_Tab;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Enter] = Qt::Key_Enter;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_F1] = Qt::Key_F1;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_F2] = Qt::Key_F2;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_F3] = Qt::Key_F3;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_F4] = Qt::Key_F4;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Home] = Qt::Key_Home;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Left] = Qt::Key_Left;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Up] = Qt::Key_Up;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Right] = Qt::Key_Right;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Down] = Qt::Key_Down;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Prior] = Qt::Key_Left;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Up] = Qt::Key_PageUp;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Next] = Qt::Key_Right;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Page_Down] = Qt::Key_PageDown;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_End] = Qt::Key_End;
|
||||
|
||||
// _keyMap[osgGA::GUIEventAdapter::KEY_KP_Begin] = Qt::Key_Begin;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Insert] = Qt::Key_Insert;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Delete] = Qt::Key_Delete;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Equal] = Qt::Key_Equal;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Multiply] = Qt::Key_Asterisk;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Add] = Qt::Key_Plus;
|
||||
//_keyMap[osgGA::GUIEventAdapter::KEY_KP_Separator] = Qt::Key_;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Subtract] = Qt::Key_Minus;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Decimal] = Qt::Key_Period;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_Divide] = Qt::Key_division;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_0] = Qt::Key_0;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_1] = Qt::Key_1;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_2] = Qt::Key_2;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_3] = Qt::Key_3;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_4] = Qt::Key_4;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_5] = Qt::Key_5;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_6] = Qt::Key_6;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_7] = Qt::Key_7;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_8] = Qt::Key_8;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_KP_9] = Qt::Key_9;
|
||||
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F1] = Qt::Key_F1;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F2] = Qt::Key_F2;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F3] = Qt::Key_F3;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F4] = Qt::Key_F4;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F5] = Qt::Key_F5;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F6] = Qt::Key_F6;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F7] = Qt::Key_F7;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F8] = Qt::Key_F8;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F9] = Qt::Key_F9;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F10] = Qt::Key_F10;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F11] = Qt::Key_F11;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F12] = Qt::Key_F12;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F13] = Qt::Key_F13;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F14] = Qt::Key_F14;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F15] = Qt::Key_F15;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F16] = Qt::Key_F16;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F17] = Qt::Key_F17;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F18] = Qt::Key_F18;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F19] = Qt::Key_F19;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F20] = Qt::Key_F20;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F21] = Qt::Key_F21;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F22] = Qt::Key_F22;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F23] = Qt::Key_F23;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F24] = Qt::Key_F24;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F25] = Qt::Key_F25;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F26] = Qt::Key_F26;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F27] = Qt::Key_F27;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F28] = Qt::Key_F28;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F29] = Qt::Key_F29;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F30] = Qt::Key_F30;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F31] = Qt::Key_F31;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F32] = Qt::Key_F32;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F33] = Qt::Key_F33;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F34] = Qt::Key_F34;
|
||||
_keyMap[osgGA::GUIEventAdapter::KEY_F35] = Qt::Key_F35;
|
||||
|
||||
}
|
||||
|
||||
QWidget* QGraphicsViewAdapter::getWidgetAt(const QPoint& pos)
|
||||
{
|
||||
QWidget* childAt = _graphicsView->childAt(pos);
|
||||
if(childAt)
|
||||
{
|
||||
return childAt;
|
||||
}
|
||||
|
||||
QGraphicsItem* item = _graphicsView->itemAt(pos);
|
||||
if(item /*&& item->contains(item->mapFromScene(pos))*/)
|
||||
{
|
||||
QGraphicsProxyWidget* p = qgraphicsitem_cast<QGraphicsProxyWidget*>(item);
|
||||
if(p)
|
||||
{
|
||||
childAt = p->widget();
|
||||
QWidget* c;
|
||||
while( (c = childAt->childAt(childAt->mapFromGlobal(pos)))!=0 )
|
||||
{
|
||||
childAt = c;
|
||||
}
|
||||
|
||||
// Widgets like QTextEdit will automatically add child scroll area widgets
|
||||
// that will be selected by childAt(), we have to change to parents at that moment
|
||||
// Hardcoded by the internal widget's name 'qt_scrollarea_viewport' at present
|
||||
if (childAt->objectName() == "qt_scrollarea_viewport")
|
||||
{
|
||||
childAt = childAt->parentWidget();
|
||||
}
|
||||
return childAt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool QGraphicsViewAdapter::sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
_previousQtMouseX = x;
|
||||
_previousQtMouseY = _graphicsView->size().height() - y;
|
||||
|
||||
QPoint pos(_previousQtMouseX, _previousQtMouseY);
|
||||
|
||||
QWidget* targetWidget = getWidgetAt(pos);
|
||||
OSG_INFO << "Get " << (targetWidget ? targetWidget->metaObject()->className() : std::string("NULL"))
|
||||
<< " at global pos " << x << ", " << y << std::endl;
|
||||
|
||||
if (_backgroundWidget && _backgroundWidget == targetWidget)
|
||||
{
|
||||
// Mouse is at background widget, so ignore such events
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetWidget != NULL || (_previousSentEvent && buttonMask != 0))
|
||||
{
|
||||
QCoreApplication::postEvent(this, new MyQPointerEvent(x,y,buttonMask));
|
||||
OSG_INFO<<"sendPointerEvent("<<x<<", "<<y<<") sent"<<std::endl;
|
||||
_previousSentEvent = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
OSG_INFO<<"sendPointerEvent("<<x<<", "<<y<<") not sent"<<std::endl;
|
||||
_previousSentEvent = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QGraphicsViewAdapter::handlePointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
OSG_INFO<<"dispatchPointerEvent("<<x<<", "<<y<<", "<<buttonMask<<")"<<std::endl;
|
||||
|
||||
y = _graphicsView->size().height()-y;
|
||||
|
||||
bool leftButtonPressed = (buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)!=0;
|
||||
bool middleButtonPressed = (buttonMask & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)!=0;
|
||||
bool rightButtonPressed = (buttonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)!=0;
|
||||
|
||||
bool prev_leftButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)!=0;
|
||||
bool prev_middleButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON)!=0;
|
||||
bool prev_rightButtonPressed = (_previousButtonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)!=0;
|
||||
|
||||
OSG_INFO<<"leftButtonPressed "<<leftButtonPressed<<std::endl;
|
||||
OSG_INFO<<"middleButtonPressed "<<middleButtonPressed<<std::endl;
|
||||
OSG_INFO<<"rightButtonPressed "<<rightButtonPressed<<std::endl;
|
||||
|
||||
Qt::MouseButtons qtMouseButtons =
|
||||
(leftButtonPressed ? Qt::LeftButton : Qt::NoButton) |
|
||||
(middleButtonPressed ? Qt::MidButton : Qt::NoButton) |
|
||||
(rightButtonPressed ? Qt::RightButton : Qt::NoButton);
|
||||
|
||||
const QPoint globalPos(x, y);
|
||||
QWidget* targetWidget = getWidgetAt(globalPos);
|
||||
|
||||
if (buttonMask != _previousButtonMask)
|
||||
{
|
||||
Qt::MouseButton qtButton = Qt::NoButton;
|
||||
QEvent::Type eventType = QEvent::None;
|
||||
if (leftButtonPressed != prev_leftButtonPressed)
|
||||
{
|
||||
qtButton = Qt::LeftButton;
|
||||
eventType = leftButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
|
||||
}
|
||||
else if (middleButtonPressed != prev_middleButtonPressed)
|
||||
{
|
||||
qtButton = Qt::MidButton;
|
||||
eventType = middleButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
|
||||
}
|
||||
else if (rightButtonPressed != prev_rightButtonPressed)
|
||||
{
|
||||
qtButton = Qt::RightButton;
|
||||
eventType = rightButtonPressed ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease ;
|
||||
if(!rightButtonPressed)
|
||||
{
|
||||
if(targetWidget)
|
||||
{
|
||||
QPoint localPos = targetWidget->mapFromGlobal(globalPos);
|
||||
QContextMenuEvent* cme = new QContextMenuEvent(QContextMenuEvent::Mouse, localPos, globalPos);
|
||||
QCoreApplication::postEvent(targetWidget, cme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (eventType==QEvent::MouseButtonPress)
|
||||
{
|
||||
_image->sendFocusHint(true);
|
||||
if (targetWidget) targetWidget->setFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
QMouseEvent event(eventType, globalPos, qtButton, qtMouseButtons, 0);
|
||||
QCoreApplication::sendEvent(_graphicsView->viewport(), &event);
|
||||
|
||||
_previousButtonMask = buttonMask;
|
||||
}
|
||||
else if (x != _previousMouseX || y != _previousMouseY)
|
||||
{
|
||||
QMouseEvent event(QEvent::MouseMove, globalPos, Qt::NoButton, qtMouseButtons, 0);
|
||||
QCoreApplication::sendEvent(_graphicsView->viewport(), &event);
|
||||
|
||||
_previousMouseX = x;
|
||||
_previousMouseY = y;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QGraphicsViewAdapter::sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
QPoint pos(_previousQtMouseX, _previousQtMouseY);
|
||||
QWidget* targetWidget = getWidgetAt(pos);
|
||||
if (_backgroundWidget && _backgroundWidget == targetWidget)
|
||||
{
|
||||
// Mouse is at background widget, so ignore such events
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetWidget != NULL)
|
||||
{
|
||||
QCoreApplication::postEvent(this, new MyQKeyEvent(key,keyDown));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QGraphicsViewAdapter::handleKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
QEvent::Type eventType = keyDown ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
|
||||
OSG_INFO<<"sendKeyEvent("<<key<<", "<<keyDown<<")"<<std::endl;
|
||||
|
||||
if (key==Qt::Key_Shift)
|
||||
{
|
||||
_qtKeyModifiers = (_qtKeyModifiers & ~Qt::ShiftModifier) | (keyDown ? Qt::ShiftModifier : Qt::NoModifier);
|
||||
}
|
||||
|
||||
if (key==Qt::Key_Control)
|
||||
{
|
||||
_qtKeyModifiers = (_qtKeyModifiers & ~Qt::ControlModifier) | (keyDown ? Qt::ControlModifier : Qt::NoModifier);
|
||||
}
|
||||
|
||||
if (key==Qt::Key_Alt || key==Qt::Key_AltGr)
|
||||
{
|
||||
_qtKeyModifiers = (_qtKeyModifiers & ~Qt::ControlModifier) | (keyDown ? Qt::ControlModifier : Qt::NoModifier);
|
||||
}
|
||||
|
||||
if (key==Qt::Key_Meta)
|
||||
{
|
||||
_qtKeyModifiers = (_qtKeyModifiers & ~Qt::MetaModifier) | (keyDown ? Qt::MetaModifier : Qt::NoModifier);
|
||||
}
|
||||
|
||||
Qt::Key qtkey;
|
||||
QChar input;
|
||||
|
||||
KeyMap::iterator itr = _keyMap.find(key);
|
||||
if (itr != _keyMap.end())
|
||||
{
|
||||
qtkey = itr->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
qtkey = (Qt::Key)key;
|
||||
input = QChar(key);
|
||||
}
|
||||
|
||||
QKeyEvent event(eventType, qtkey, _qtKeyModifiers, input);
|
||||
QCoreApplication::sendEvent(_graphicsScene.data(), &event);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::setFrameLastRendered(const osg::FrameStamp* frameStamp)
|
||||
{
|
||||
OSG_INFO<<"setFrameLastRendered("<<frameStamp->getFrameNumber()<<")"<<std::endl;
|
||||
|
||||
if (_newImageAvailable && _previousFrameNumber!=frameStamp->getFrameNumber())
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
|
||||
|
||||
// make sure that _previousFrameNumber hasn't been updated by another thread since we entered this branch.
|
||||
if (_previousFrameNumber==frameStamp->getFrameNumber()) return;
|
||||
_previousFrameNumber = frameStamp->getFrameNumber();
|
||||
|
||||
std::swap(_currentRead, _previousWrite);
|
||||
_newImageAvailable = false;
|
||||
}
|
||||
|
||||
assignImage(_currentRead);
|
||||
}
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::clearWriteBuffer()
|
||||
{
|
||||
QImage& image = _qimages[_currentWrite];
|
||||
image.fill(_backgroundColor.rgba ());
|
||||
image = QGLWidget::convertToGLFormat(image);
|
||||
|
||||
// swap the write buffers in a thread safe way
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
|
||||
std::swap(_currentWrite, _previousWrite);
|
||||
_newImageAvailable = true;
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::render()
|
||||
{
|
||||
OSG_INFO<<"Current write = "<<_currentWrite<<std::endl;
|
||||
QImage& image = _qimages[_currentWrite];
|
||||
_requiresRendering = false;
|
||||
|
||||
// If we got a resize, act on it, first by resizing the view, then the current image
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qresizeMutex);
|
||||
if (_graphicsView->size().width() != _width || _graphicsView->size().height() != _height)
|
||||
{
|
||||
_graphicsView->setGeometry(0, 0, _width, _height);
|
||||
_graphicsView->viewport()->setGeometry(0, 0, _width, _height);
|
||||
|
||||
_widget->setGeometry(0, 0, _width, _height);
|
||||
}
|
||||
|
||||
if (image.width() != _width || image.height() != _height)
|
||||
{
|
||||
_qimages[_currentWrite] = QImage(_width, _height, s_imageFormat);
|
||||
image = _qimages[_currentWrite];
|
||||
}
|
||||
OSG_INFO << "render image " << _currentWrite << " with size (" << _width << "," << _height << ")" <<std::endl;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// paint the image with the graphics view
|
||||
QPainter painter(&image);
|
||||
|
||||
// Clear the image otherwise there are artifacts for some widgets that overpaint.
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
painter.fillRect(0, 0, image.width(), image.height(), _backgroundColor);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
QRectF destinationRect(0, 0, image.width(), image.height());
|
||||
QRect sourceRect(0, 0, image.width(), image.height());
|
||||
_graphicsView->render(&painter, destinationRect, sourceRect, Qt::IgnoreAspectRatio);
|
||||
painter.end();
|
||||
#elif 0
|
||||
QPixmap pixmap(QPixmap::grabWidget(_graphicsView.data(), QRect(0, 0, image.width(), image.height())));
|
||||
image = pixmap.toImage();
|
||||
#else
|
||||
// paint the image with the graphics view
|
||||
QPixmap pixmap(image.width(), image.height());
|
||||
// Clear the image otherwise there are artifacts for some widgets that overpaint.
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
|
||||
QRectF destinationRect(0, 0, image.width(), image.height());
|
||||
QRect sourceRect(0, 0, image.width(), image.height());
|
||||
_graphicsView->render(&painter, destinationRect, _graphicsView->viewport()->rect());
|
||||
painter.end();
|
||||
|
||||
image = pixmap.toImage();
|
||||
#endif
|
||||
|
||||
// convert into OpenGL format - flipping around the Y axis and swizzling the pixels
|
||||
image = QGLWidget::convertToGLFormat(image);
|
||||
|
||||
// swap the write buffers in a thread safe way
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qimagesMutex);
|
||||
std::swap(_currentWrite, _previousWrite);
|
||||
_newImageAvailable = true;
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::assignImage(unsigned int i)
|
||||
{
|
||||
QImage& image = _qimages[i];
|
||||
unsigned char* data = image.bits();
|
||||
|
||||
OSG_INFO<<"assignImage("<<i<<") image = "<<&image<<" size = ("<<image.width()<<","<<image.height()<<") data = "<<(void*)data<<std::endl;
|
||||
|
||||
_image->setImage(image.width(), image.height(), 1,
|
||||
4, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
data, osg::Image::NO_DELETE, 1);
|
||||
}
|
||||
|
||||
void QGraphicsViewAdapter::resize(int width, int height)
|
||||
{
|
||||
OSG_INFO << "resize to (" << width << "," << height << ")" <<std::endl;
|
||||
|
||||
// Save the new width and height which will take effect on the next render() (in the Qt thread).
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_qresizeMutex);
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
// Force an update so render() will be called.
|
||||
_graphicsScene->update(_graphicsScene->sceneRect());
|
||||
}
|
||||
|
||||
}
|
122
src/osgqt/QGraphicsViewAdapter.h
Normal file
122
src/osgqt/QGraphicsViewAdapter.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef QGRAPHICSVIEWADAPTER
|
||||
#define QGRAPHICSVIEWADAPTER
|
||||
|
||||
#include <QGLWidget>
|
||||
|
||||
#include <osg/Image>
|
||||
#include <osg/observer_ptr>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QtEvents>
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
extern QCoreApplication* getOrCreateQApplication();
|
||||
|
||||
class QGraphicsViewAdapter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
QGraphicsViewAdapter(osg::Image* image, QWidget* widget);
|
||||
|
||||
void setUpKeyMap();
|
||||
|
||||
bool sendPointerEvent(int x, int y, int buttonMask);
|
||||
|
||||
|
||||
bool sendKeyEvent(int key, bool keyDown);
|
||||
|
||||
|
||||
void setFrameLastRendered(const osg::FrameStamp* frameStamp);
|
||||
|
||||
void clearWriteBuffer();
|
||||
|
||||
bool requiresRendering() const { return _requiresRendering; }
|
||||
void render();
|
||||
|
||||
void assignImage(unsigned int i);
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
void setBackgroundColor(QColor color) { _backgroundColor = color; }
|
||||
QColor getBackgroundColor() const { return _backgroundColor; }
|
||||
|
||||
/** The 'background widget' will ignore mouse/keyboard events and let following handlers handle them
|
||||
It is mainly used for integrating scene graph and full-screen UIs
|
||||
*/
|
||||
void setBackgroundWidget(QWidget* w) { _backgroundWidget = w; }
|
||||
QWidget* getBackgroundWidget() { return _backgroundWidget; }
|
||||
|
||||
QGraphicsView* getQGraphicsView() { return _graphicsView; }
|
||||
QGraphicsScene* getQGraphicsScene() { return _graphicsScene; }
|
||||
|
||||
protected:
|
||||
|
||||
bool handlePointerEvent(int x, int y, int buttonMask);
|
||||
bool handleKeyEvent(int key, bool keyDown);
|
||||
QWidget* getWidgetAt(const QPoint& pos);
|
||||
|
||||
osg::observer_ptr<osg::Image> _image;
|
||||
QWidget* _backgroundWidget;
|
||||
|
||||
int _previousButtonMask;
|
||||
int _previousMouseX;
|
||||
int _previousMouseY;
|
||||
int _previousQtMouseX;
|
||||
int _previousQtMouseY;
|
||||
bool _previousSentEvent;
|
||||
bool _requiresRendering;
|
||||
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
typedef std::map<int, Qt::Key> KeyMap;
|
||||
KeyMap _keyMap;
|
||||
Qt::KeyboardModifiers _qtKeyModifiers;
|
||||
|
||||
QColor _backgroundColor;
|
||||
QPointer<QGraphicsView> _graphicsView;
|
||||
QPointer<QGraphicsScene> _graphicsScene;
|
||||
QPointer<QWidget> _widget;
|
||||
|
||||
OpenThreads::Mutex _qimagesMutex;
|
||||
OpenThreads::Mutex _qresizeMutex;
|
||||
unsigned int _previousFrameNumber;
|
||||
bool _newImageAvailable;
|
||||
unsigned int _currentRead;
|
||||
unsigned int _currentWrite;
|
||||
unsigned int _previousWrite;
|
||||
QImage _qimages[3];
|
||||
|
||||
virtual void customEvent ( QEvent * event ) ;
|
||||
|
||||
private slots:
|
||||
|
||||
void repaintRequestedSlot(const QList<QRectF> ®ions);
|
||||
void repaintRequestedSlot(const QRectF ®ion);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
108
src/osgqt/QWebViewImage.h
Normal file
108
src/osgqt/QWebViewImage.h
Normal file
@ -0,0 +1,108 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef QWEBVIEWIMAGE
|
||||
#define QWEBVIEWIMAGE
|
||||
|
||||
// make sure this header isn't built as par of osgQt, leaving it to applications to build
|
||||
#if !defined(OSGQT_LIBRARY) && !defined(OSG_LIBRARY_STATIC)
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtWebKitWidgets>
|
||||
#else
|
||||
# include <QtWebKit>
|
||||
#endif
|
||||
|
||||
|
||||
#include <osgWidget/Browser>
|
||||
#include "osgqt/QGraphicsViewAdapter.h"
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
class QWebViewImage : public osgWidget::BrowserImage
|
||||
{
|
||||
public:
|
||||
|
||||
QWebViewImage()
|
||||
{
|
||||
// make sure we have a valid QApplication before we start creating widgets.
|
||||
getOrCreateQApplication();
|
||||
|
||||
_webView = new QWebView;
|
||||
|
||||
_webPage = new QWebPage;
|
||||
_webPage->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
|
||||
_webPage->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
|
||||
|
||||
_webView->setPage(_webPage);
|
||||
|
||||
_adapter = new QGraphicsViewAdapter(this, _webView.data());
|
||||
}
|
||||
|
||||
virtual void navigateTo(const std::string& url)
|
||||
{
|
||||
_webView->load(QUrl(url.c_str()));
|
||||
}
|
||||
|
||||
QWebView* getQWebView() { return _webView; }
|
||||
QWebPage* getQWebPage() { return _webPage; }
|
||||
QGraphicsViewAdapter* getQGraphicsViewAdapter() { return _adapter; }
|
||||
|
||||
void clearWriteBuffer()
|
||||
{
|
||||
_adapter->clearWriteBuffer();
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
if (_adapter->requiresRendering()) _adapter->render();
|
||||
}
|
||||
|
||||
virtual bool requiresUpdateCall() const { return true; }
|
||||
virtual void update( osg::NodeVisitor* nv ) { render(); }
|
||||
|
||||
virtual bool sendFocusHint(bool focus)
|
||||
{
|
||||
QFocusEvent event(focus ? QEvent::FocusIn : QEvent::FocusOut, Qt::OtherFocusReason);
|
||||
QCoreApplication::sendEvent(_webPage, &event);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
return _adapter->sendPointerEvent(x,y,buttonMask);
|
||||
}
|
||||
|
||||
virtual bool sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
return QWebViewImage::_adapter->sendKeyEvent(key, keyDown);
|
||||
}
|
||||
|
||||
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp)
|
||||
{
|
||||
_adapter->setFrameLastRendered(frameStamp);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
QPointer<QGraphicsViewAdapter> _adapter;
|
||||
QPointer<QWebView> _webView;
|
||||
QPointer<QWebPage> _webPage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
66
src/osgqt/QWidgetImage.cpp
Normal file
66
src/osgqt/QWidgetImage.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include "osgqt/QWidgetImage.h"
|
||||
#include <QLayout>
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
QWidgetImage::QWidgetImage( QWidget* widget )
|
||||
{
|
||||
// make sure we have a valid QApplication before we start creating widgets.
|
||||
getOrCreateQApplication();
|
||||
|
||||
_widget = widget;
|
||||
_adapter = new QGraphicsViewAdapter(this, _widget.data());
|
||||
}
|
||||
|
||||
bool QWidgetImage::sendFocusHint(bool focus)
|
||||
{
|
||||
QFocusEvent event(focus ? QEvent::FocusIn : QEvent::FocusOut, Qt::OtherFocusReason);
|
||||
QCoreApplication::sendEvent(_widget, &event);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QWidgetImage::clearWriteBuffer()
|
||||
{
|
||||
_adapter->clearWriteBuffer();
|
||||
}
|
||||
|
||||
void QWidgetImage::render()
|
||||
{
|
||||
if (_adapter->requiresRendering()) _adapter->render();
|
||||
}
|
||||
|
||||
void QWidgetImage::scaleImage(int s,int t,int /*r*/, GLenum /*newDataType*/)
|
||||
{
|
||||
_adapter->resize(s, t);
|
||||
}
|
||||
|
||||
void QWidgetImage::setFrameLastRendered(const osg::FrameStamp* frameStamp)
|
||||
{
|
||||
_adapter->setFrameLastRendered(frameStamp);
|
||||
}
|
||||
|
||||
bool QWidgetImage::sendPointerEvent(int x, int y, int buttonMask)
|
||||
{
|
||||
return _adapter->sendPointerEvent(x,y,buttonMask);
|
||||
}
|
||||
|
||||
bool QWidgetImage::sendKeyEvent(int key, bool keyDown)
|
||||
{
|
||||
return _adapter->sendKeyEvent(key, keyDown);
|
||||
}
|
||||
|
||||
}
|
60
src/osgqt/QWidgetImage.h
Normal file
60
src/osgqt/QWidgetImage.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef QWIDGETIMAGE
|
||||
#define QWIDGETIMAGE
|
||||
|
||||
#include <osg/Image>
|
||||
|
||||
#include "osgQt/QGraphicsViewAdapter.h"
|
||||
|
||||
namespace osgQt
|
||||
{
|
||||
|
||||
class QWidgetImage : public osg::Image
|
||||
{
|
||||
public:
|
||||
|
||||
QWidgetImage( QWidget* widget=0 );
|
||||
|
||||
QWidget* getQWidget() { return _widget; }
|
||||
QGraphicsViewAdapter* getQGraphicsViewAdapter() { return _adapter; }
|
||||
|
||||
virtual bool requiresUpdateCall() const { return true; }
|
||||
virtual void update( osg::NodeVisitor* /*nv*/ ) { render(); }
|
||||
|
||||
void clearWriteBuffer();
|
||||
|
||||
void render();
|
||||
|
||||
/// Overridden scaleImage used to catch cases where the image is
|
||||
/// fullscreen and the window is resized.
|
||||
virtual void scaleImage(int s,int t,int r, GLenum newDataType);
|
||||
|
||||
virtual bool sendFocusHint(bool focus);
|
||||
|
||||
virtual bool sendPointerEvent(int x, int y, int buttonMask);
|
||||
|
||||
virtual bool sendKeyEvent(int key, bool keyDown);
|
||||
|
||||
virtual void setFrameLastRendered(const osg::FrameStamp* frameStamp);
|
||||
|
||||
protected:
|
||||
|
||||
QPointer<QGraphicsViewAdapter> _adapter;
|
||||
QPointer<QWidget> _widget;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
66
src/osgqt/ReaderQFont.cpp
Normal file
66
src/osgqt/ReaderQFont.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009-2010 Mathias Froehlich
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include "osgqt/QFontImplementation.h"
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QApplication>
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QFontDatabase>
|
||||
|
||||
namespace osgQFont {
|
||||
|
||||
class ReaderQFont : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderQFont()
|
||||
{
|
||||
supportsExtension("qfont", "Qt font meta loader");
|
||||
}
|
||||
|
||||
virtual const char* className() const { return "QFont Font Reader"; }
|
||||
|
||||
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* /*options*/) const
|
||||
{
|
||||
if (!acceptsExtension(osgDB::getLowerCaseFileExtension(file)))
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
if (!QApplication::instance())
|
||||
{
|
||||
OSG_WARN << "Trying to load qfont \"" << file << "\" from within a non qt application!" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!QFontDatabase::supportsThreadedFontRendering() && QApplication::instance()->thread() != QThread::currentThread())
|
||||
{
|
||||
OSG_WARN << "Trying to load qfont \"" << file << "\" from a non gui thread "
|
||||
"within qt application without threaded font rendering!" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
QFont font;
|
||||
if (!font.fromString(QString::fromStdString(osgDB::getNameLessExtension(file))))
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
return new osgText::Font(new osgQt::QFontImplementation(font));
|
||||
}
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
REGISTER_OSGPLUGIN(qfont, ReaderQFont)
|
||||
|
||||
}
|
@ -6,8 +6,8 @@
|
||||
#include <osg/Program>
|
||||
#include <osg/LightSource>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgEarth/GLUtils>
|
||||
#include <osgEarth/EarthManipulator>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
|
||||
#include <osgShadow/ShadowedScene>
|
||||
#include <osgShadow/ViewDependentShadowMap>
|
||||
@ -25,161 +25,77 @@
|
||||
|
||||
const osgEarth::SpatialReference* g_srs_{ nullptr };
|
||||
|
||||
|
||||
OEScene::OEScene() {
|
||||
osgDB::FilePathList& pathList = osgDB::Registry::instance()->getDataFilePathList();
|
||||
const std::string& basePath = RecourceHelper::Get().GetBasePath().toStdString();
|
||||
pathList.push_back(basePath + "/resources/earth/");
|
||||
pathList.push_back(basePath + "/resources/textures/");
|
||||
root_ = new osg::Group;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
void OEScene::InitEventHandle(class OsgView* view) {
|
||||
if (nullptr == view) {
|
||||
LOG_WARN("view is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
//view->GetView()->addEventHandler(new osgEarth::Util::EarthManipulator());
|
||||
|
||||
view->GetView()->addEventHandler(new osgViewer::HelpHandler);
|
||||
view->GetView()->addEventHandler(new osgViewer::StatsHandler);
|
||||
}
|
||||
|
||||
void OEScene::AttachView(OsgView* view) {
|
||||
if (nullptr == view) {
|
||||
LOG_WARN("view is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Node* rootNode = view->GetView()->getSceneData();
|
||||
if (nullptr != rootNode) {
|
||||
int parantCount = rootNode->getNumParents();
|
||||
for (int i = 0; i < parantCount; ++i) {
|
||||
rootNode->getParent(i)->removeChild(rootNode);
|
||||
}
|
||||
root_->addChild(rootNode);
|
||||
}
|
||||
|
||||
view->GetView()->setSceneData(root_);
|
||||
|
||||
earthRootNode_ = osgDB::readNodeFile("triton.earth");
|
||||
void OEScene::AttachView(osgViewer::View* view) {
|
||||
dyt_check(nullptr != earthRootNode_);
|
||||
logarithmicDepthBuffer_ = std::make_unique<osgEarth::Util::LogarithmicDepthBuffer>();
|
||||
|
||||
earthMapNode_ = osgEarth::MapNode::get(earthRootNode_);
|
||||
dyt_check(nullptr != earthMapNode_);
|
||||
LOG_INFO("earth map node get success: {}", earthMapNode_.valid());
|
||||
g_srs_ = earthMapNode_->getMapSRS();
|
||||
|
||||
entityRoot_ = new osg::Group;
|
||||
root_->addChild(entityRoot_);
|
||||
|
||||
skyDome_ = osgEarth::SkyNode::create();
|
||||
skyDome_ = osgEarth::Util::SkyNode::create(earthMapNode_);
|
||||
if (!earthMapNode_) {
|
||||
LOG_WARN("eart map node is nullptr");
|
||||
return;
|
||||
}
|
||||
root_->addChild(skyDome_);
|
||||
skyDome_->addChild(earthMapNode_);
|
||||
skyDome_->attach(view->GetView());
|
||||
|
||||
skyDome_->setAtmosphereVisible(true);
|
||||
skyDome_->setSunVisible(true);
|
||||
skyDome_->setMoonVisible(true);
|
||||
skyDome_->setStarsVisible(true);
|
||||
dyt_check(nullptr != earthManipulator_);
|
||||
view->setCameraManipulator(earthManipulator_);
|
||||
skyDome_->attach(view);
|
||||
skyDome_->getSunLight()->setAmbient(osg::Vec4(0.5,0.5,0.5,1.0));
|
||||
addChild(skyDome_);
|
||||
|
||||
view->setCameraManipulator( new osgEarth::Util::EarthManipulator() );
|
||||
|
||||
skyDome_->setDateTime(osgEarth::DateTime(2024, 12, 24, 3));
|
||||
skyDome_->setSimulationTimeTracksDateTime(true);
|
||||
|
||||
logarithmicDepthBuffer_->install(view->GetView()->getCamera());
|
||||
|
||||
ConeWave* coneWave = new ConeWave;
|
||||
|
||||
osgEarth::GeoTransform *geo = new osgEarth::GeoTransform;
|
||||
entityRoot_->addChild(geo);
|
||||
|
||||
osgEarth::GeoPoint pos(g_srs_, 120.000000,25.000000,600.000000);
|
||||
geo->setPosition(pos);
|
||||
coneWave->createWaveBeamCone(geo, 45, 6000, osg::Vec4(1.0, 0.0, 0.0, 0.3),
|
||||
osg::Vec4(1.0, 1.0, 0.0, 0.3), 30);
|
||||
osg::MatrixTransform* mt =coneWave->getWaveBeamCone();
|
||||
geo->addChild(mt);
|
||||
view->setSceneData(this);
|
||||
curentView_ = view;
|
||||
}
|
||||
|
||||
void OEScene::DetachView(OsgView* view) {
|
||||
if (nullptr != earthRootNode_) {
|
||||
std::vector<osg::Group*> parents = earthRootNode_->getParents();
|
||||
for (const auto& parent : parents) {
|
||||
parent->removeChild(earthRootNode_);
|
||||
}
|
||||
}
|
||||
logarithmicDepthBuffer_->uninstall(view->GetView()->getCamera());
|
||||
view->GetView()->setSceneData(nullptr);
|
||||
|
||||
void OEScene::DetachView(osgViewer::View* view) {
|
||||
view->setSceneData(nullptr);
|
||||
}
|
||||
|
||||
#define USE_CUSTOM_SHADER
|
||||
|
||||
osg::ref_ptr<osg::TextureCubeMap> OEScene::LoadCubeMapTextures(const std::string& dir) {
|
||||
enum {
|
||||
POS_X, NEG_X, POS_Y, NEG_Y, POS_Z, NEG_Z
|
||||
};
|
||||
|
||||
std::string filenames[6];
|
||||
|
||||
std::string basePath = RecourceHelper::Get().GetBasePath().toStdString();
|
||||
|
||||
filenames[POS_X] = basePath + "/resources/textures/" + dir + "/east.png";
|
||||
filenames[NEG_X] = basePath + "/resources/textures/" + dir + "/west.png";
|
||||
filenames[POS_Z] = basePath + "/resources/textures/" + dir + "/north.png";
|
||||
filenames[NEG_Z] = basePath + "/resources/textures/" + dir + "/south.png";
|
||||
filenames[POS_Y] = basePath + "/resources/textures/" + dir + "/down.png";
|
||||
filenames[NEG_Y] = basePath + "/resources/textures/" + dir + "/up.png";
|
||||
|
||||
osg::ref_ptr<osg::TextureCubeMap> cubeMap = new osg::TextureCubeMap;
|
||||
cubeMap->setInternalFormat(GL_RGBA);
|
||||
|
||||
cubeMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
|
||||
cubeMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||
cubeMap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubeMap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_X, osgDB::readImageFile(filenames[NEG_X]));
|
||||
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_X, osgDB::readImageFile(filenames[POS_X]));
|
||||
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Y, osgDB::readImageFile(filenames[NEG_Y]));
|
||||
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Y, osgDB::readImageFile(filenames[POS_Y]));
|
||||
cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Z, osgDB::readImageFile(filenames[NEG_Z]));
|
||||
cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Z, osgDB::readImageFile(filenames[POS_Z]));
|
||||
|
||||
return cubeMap;
|
||||
}
|
||||
|
||||
osg::Group* OEScene::GetData() {
|
||||
return root_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OEScene::AddToScene(osg::Node* node) {
|
||||
bool OEScene::AddToScene(osg::Node* node) const {
|
||||
dyt_check(nullptr != entityRoot_);
|
||||
entityRoot_->addChild(node);
|
||||
/* osgOcean::OceanScene* oceanScene = GetOceanScene();
|
||||
if (nullptr == oceanScene) {
|
||||
LOG_WARN("oceanScene is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
node->setNodeMask(oceanScene->getNormalSceneMask() |
|
||||
oceanScene->getReflectedSceneMask() |
|
||||
oceanScene->getRefractedSceneMask() |
|
||||
CAST_SHADOW | RECEIVE_SHADOW);
|
||||
oceanScene->addChild(node);*/
|
||||
/* osg::Group* root = GetScene();
|
||||
root->addChild(node);*/
|
||||
return entityRoot_->addChild(node);
|
||||
}
|
||||
|
||||
void OEScene::SetHomeViewpoint(const osgEarth::Viewpoint& viewpoint, double duration_s) {
|
||||
dyt_check(nullptr != earthManipulator_);
|
||||
earthManipulator_->setViewpoint(viewpoint, duration_s);
|
||||
earthManipulator_->setHomeViewpoint(viewpoint, duration_s);
|
||||
}
|
||||
|
||||
//
|
||||
// void OEScene::InitEventHandle(osgViewer::View* view) {
|
||||
// if (nullptr == view) {
|
||||
// LOG_WARN("view is nullptr");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// //view->GetView()->addEventHandler(new osgEarth::Util::EarthManipulator());
|
||||
//
|
||||
// view->addEventHandler(new osgViewer::HelpHandler);
|
||||
// view->addEventHandler(new osgViewer::StatsHandler);
|
||||
// }
|
||||
|
||||
// void OEScene::DetachView(osgViewer::View* view) {
|
||||
// if (nullptr != earthRootNode_) {
|
||||
// std::vector<osg::Group*> parents = earthRootNode_->getParents();
|
||||
// for (const auto& parent : parents) {
|
||||
// parent->removeChild(earthRootNode_);
|
||||
// }
|
||||
// }
|
||||
// logarithmicDepthBuffer_->uninstall(view->getCamera());
|
||||
// view->setSceneData(nullptr);
|
||||
//
|
||||
// }
|
||||
|
||||
OESceneUI* OEScene::GetOrCreateSceneUI() {
|
||||
if (sceneUI_) {
|
||||
LOG_INFO("scene ui is already attached");
|
||||
@ -189,3 +105,32 @@ OESceneUI* OEScene::GetOrCreateSceneUI() {
|
||||
sceneUI_ = new OESceneUI(this);
|
||||
return sceneUI_.get();
|
||||
}
|
||||
|
||||
osg::Viewport* OEScene::GetViewport() const {
|
||||
dyt_check(nullptr != curentView_);
|
||||
|
||||
return curentView_->getCamera()->getViewport();
|
||||
}
|
||||
|
||||
const osgEarth::SpatialReference* OEScene::GetSrs() {
|
||||
dyt_check(nullptr != g_srs_);
|
||||
return g_srs_;
|
||||
}
|
||||
|
||||
void OEScene::Init() {
|
||||
std::string earthPath = "D:/Project/DYT/Tool/TritonSample/TritonSample/triton.earth";
|
||||
// earthRootNode_ = osgDB::readNodeFile("triton.earth");
|
||||
earthRootNode_ = osgDB::readNodeFile(earthPath);
|
||||
dyt_check(nullptr != earthRootNode_);
|
||||
addChild(earthRootNode_);
|
||||
|
||||
earthMapNode_ = osgEarth::MapNode::get(earthRootNode_);
|
||||
dyt_check(nullptr != earthMapNode_);
|
||||
LOG_INFO("earth map node get success: {}", earthMapNode_.valid());
|
||||
g_srs_ = earthMapNode_->getMapSRS();
|
||||
|
||||
earthManipulator_ = new osgEarth::Util::EarthManipulator();
|
||||
|
||||
entityRoot_ = new osg::Group;
|
||||
addChild(entityRoot_);
|
||||
}
|
||||
|
@ -1,56 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <osg/Switch>
|
||||
#include <osg/TextureCubeMap>
|
||||
|
||||
#include <osgText/Text>
|
||||
#include <osgEarth/ModelNode>
|
||||
#include <osgEarth/Sky>
|
||||
#include <osgEarth/LogarithmicDepthBuffer>
|
||||
|
||||
//#include "scene/SkyDome.h"
|
||||
#include <osgEarth/MapNode>
|
||||
#include <osgEarthUtil/Sky>
|
||||
#include <osgEarth/Viewpoint>
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
#include "config.h"
|
||||
#include "scene/ui/OESceneUI.h"
|
||||
|
||||
class OsgView;
|
||||
|
||||
class OEScene : public osg::Referenced {
|
||||
namespace osgEarth {
|
||||
namespace Util {
|
||||
class EarthManipulator;
|
||||
}
|
||||
}
|
||||
|
||||
class OEScene : public osg::Group {
|
||||
public:
|
||||
OEScene();
|
||||
void InitEventHandle(OsgView* view);
|
||||
void AttachView(OsgView* view);
|
||||
void DetachView(OsgView* view);
|
||||
void AttachView(osgViewer::View* view);
|
||||
void DetachView(osgViewer::View* view);
|
||||
|
||||
osg::ref_ptr<osg::TextureCubeMap> LoadCubeMapTextures(const std::string& dir);
|
||||
|
||||
inline osg::Vec4f IntColor(unsigned r, unsigned g, unsigned b, unsigned a = 255) {
|
||||
float div = 1.f / 255.f;
|
||||
return osg::Vec4f(div * (float)r, div * (float)g, div * float(b), div * (float)a);
|
||||
}
|
||||
|
||||
osg::Group* GetData();
|
||||
|
||||
inline osg::Group* GetScene(void) {
|
||||
return root_.get();
|
||||
}
|
||||
bool AddToScene(osg::Node* node) const;
|
||||
void SetHomeViewpoint(const osgEarth::Viewpoint& viewpoint, double duration_s);
|
||||
|
||||
osgEarth::MapNode* GetMapNode(void) const {
|
||||
dyt_check(earthMapNode_.valid());
|
||||
return earthMapNode_;
|
||||
}
|
||||
|
||||
void AddToScene(osg::Node* node);
|
||||
|
||||
OESceneUI* GetOrCreateSceneUI();
|
||||
osgEarth::Util::EarthManipulator* GetManipulater() const {
|
||||
return earthManipulator_.get();
|
||||
}
|
||||
|
||||
osg::Viewport* GetViewport() const;
|
||||
|
||||
static const osgEarth::SpatialReference* GetSrs();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Group> root_;
|
||||
osg::ref_ptr<osg::Node> earthRootNode_;
|
||||
osg::ref_ptr<osgEarth::Util::EarthManipulator> earthManipulator_;
|
||||
osg::ref_ptr<osgEarth::MapNode> earthMapNode_;
|
||||
osg::ref_ptr<osg::Group> entityRoot_;
|
||||
osg::ref_ptr<osgEarth::SkyNode> skyDome_;
|
||||
std::unique_ptr<osgEarth::Util::LogarithmicDepthBuffer> logarithmicDepthBuffer_;
|
||||
osg::ref_ptr<osgEarth::Util::SkyNode> skyDome_;
|
||||
osg::ref_ptr<OESceneUI> sceneUI_;
|
||||
osgViewer::View* curentView_ {nullptr};
|
||||
};
|
||||
|
@ -1,114 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonAPIWrapper.h"
|
||||
#include <Triton.h>
|
||||
|
||||
#define LC "[TritonAPI] "
|
||||
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
#define SETGET_EXPLICIT(NS, SETTER, GETTER, TYPE) \
|
||||
void NS :: SETTER (TYPE value) { HANDLE-> SETTER (value); } \
|
||||
TYPE NS :: GETTER () const { return HANDLE -> GETTER (); }
|
||||
|
||||
#define SETGET(NS, FUNC, TYPE) \
|
||||
SETGET_EXPLICIT(NS, Set##FUNC, Get##FUNC, TYPE)
|
||||
|
||||
#define TOVEC3(X) ::Triton::Vector3(X.x(),X.y(),X.z())
|
||||
#define FROMVEC3(X) osg::Vec3(X.x,X.y,X.z)
|
||||
|
||||
//................................
|
||||
#undef HANDLE
|
||||
#define HANDLE ((::Triton::BreakingWavesParameters*)_handle)
|
||||
|
||||
SETGET(BreakingWavesParameters, Steepness, float);
|
||||
SETGET(BreakingWavesParameters, Wavelength, float);
|
||||
|
||||
//................................
|
||||
#undef HANDLE
|
||||
#define HANDLE ((::Triton::Environment*)_handle)
|
||||
|
||||
BreakingWavesParameters Environment::GetBreakingWavesParameters() const {
|
||||
return BreakingWavesParameters((uintptr_t)&HANDLE->GetBreakingWavesParameters());
|
||||
}
|
||||
void Environment::SetDirectionalLight(const osg::Vec3& dir, const osg::Vec3& color) {
|
||||
HANDLE->SetDirectionalLight(TOVEC3(dir), TOVEC3(color));
|
||||
}
|
||||
osg::Vec3 Environment::GetLightDirection() const {
|
||||
const ::Triton::Vector3& v = HANDLE->GetLightDirection();
|
||||
return FROMVEC3(v);
|
||||
}
|
||||
osg::Vec3 Environment::GetDirectionalLightColor() const {
|
||||
const ::Triton::Vector3& v = HANDLE->GetDirectionalLightColor();
|
||||
return FROMVEC3(v);
|
||||
}
|
||||
void Environment::SetAmbientLight(const osg::Vec3& color) {
|
||||
HANDLE->SetAmbientLight(TOVEC3(color));
|
||||
}
|
||||
osg::Vec3 Environment::GetAmbientLightColor() const {
|
||||
const ::Triton::Vector3& v = HANDLE->GetAmbientLightColor();
|
||||
return FROMVEC3(v);
|
||||
}
|
||||
void Environment::SimulateSeaState(double bscale, double winddir) {
|
||||
HANDLE->SimulateSeaState(bscale, winddir);
|
||||
}
|
||||
void Environment::SetAboveWaterVisibility(double visibility, osg::Vec3 fog_color) {
|
||||
HANDLE->SetAboveWaterVisibility(visibility, TOVEC3(fog_color));
|
||||
}
|
||||
void Environment::GetAboveWaterVisibility(double &visibility, osg::Vec3 &fog_color) const {
|
||||
::Triton::Vector3 triton_fog_col;
|
||||
HANDLE->GetAboveWaterVisibility(visibility, triton_fog_col);
|
||||
fog_color = FROMVEC3(triton_fog_col);
|
||||
}
|
||||
void Environment::SetEnvironmentMap(GLuint cubeMap, const osg::Matrixd &textureMatrix) {
|
||||
::Triton::Matrix3 triton_tex_mat(
|
||||
textureMatrix(0, 0), textureMatrix(0, 1), textureMatrix(0, 2),
|
||||
textureMatrix(1, 0), textureMatrix(1, 1), textureMatrix(1, 2),
|
||||
textureMatrix(2, 0), textureMatrix(2, 1), textureMatrix(2, 2));
|
||||
::Triton::TextureHandle tex_handle = (::Triton::TextureHandle)(static_cast<size_t>(cubeMap));
|
||||
HANDLE->SetEnvironmentMap(tex_handle, triton_tex_mat);
|
||||
}
|
||||
GLuint Environment::GetEnvironmentMap() const {
|
||||
::Triton::TextureHandle tex_handle = HANDLE->GetEnvironmentMap();
|
||||
return static_cast<GLuint>((size_t)tex_handle);
|
||||
}
|
||||
osg::Matrixd Environment::GetEnvironmentMapMatrix() const {
|
||||
::Triton::Matrix3 m = HANDLE->GetEnvironmentMapMatrix();
|
||||
osg::Matrixd env_map_matrix(
|
||||
m.elem[0][0], m.elem[0][1], m.elem[0][2], 0,
|
||||
m.elem[1][0], m.elem[1][1], m.elem[1][2], 0,
|
||||
m.elem[2][0], m.elem[2][1], m.elem[2][2], 0,
|
||||
0, 0, 0, 1);
|
||||
return env_map_matrix;
|
||||
}
|
||||
SETGET(Environment, SunIntensity, float);
|
||||
|
||||
//................................
|
||||
#undef HANDLE
|
||||
#define HANDLE ((::Triton::Ocean*)_handle)
|
||||
|
||||
SETGET(Ocean, Choppiness, float);
|
||||
//SETGET(Ocean, MaximumWavePeriod, double);
|
||||
SETGET_EXPLICIT(Ocean, EnableSpray, SprayEnabled, bool);
|
||||
SETGET_EXPLICIT(Ocean, EnableGodRays, GodRaysEnabled, bool);
|
||||
SETGET(Ocean, GodRaysFade, float);
|
||||
|
||||
void Ocean::EnableWireframe(bool wireframe) { HANDLE->EnableWireframe(wireframe); }
|
||||
void Ocean::SetQuality(OceanQuality value) { HANDLE->SetQuality((::Triton::OceanQuality)value); }
|
||||
OceanQuality Ocean::GetQuality() const { return (OceanQuality)HANDLE->GetQuality(); }
|
@ -1,112 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_API_WRAPPER
|
||||
#define OSGEARTH_TRITON_API_WRAPPER 1
|
||||
|
||||
//#include "Common"
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/GL>
|
||||
#include <stdint.h> // for uintptr_t
|
||||
|
||||
namespace osgEarth {
|
||||
namespace Util {
|
||||
class OceanNode;
|
||||
}
|
||||
}
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/** Enumerates the ocean quality settings used in Ocean::SetQuality() */
|
||||
enum OceanQuality {
|
||||
GOOD,
|
||||
BETTER,
|
||||
BEST
|
||||
};
|
||||
|
||||
class BreakingWavesParameters
|
||||
{
|
||||
public:
|
||||
void SetSteepness(float);
|
||||
float GetSteepness() const;
|
||||
|
||||
void SetWavelength(float);
|
||||
float GetWavelength() const;
|
||||
|
||||
public:
|
||||
BreakingWavesParameters(uintptr_t handle) : _handle(handle) { }
|
||||
uintptr_t _handle;
|
||||
};
|
||||
|
||||
class Environment
|
||||
{
|
||||
public:
|
||||
void SetDirectionalLight(const osg::Vec3& dir, const osg::Vec3& color);
|
||||
osg::Vec3 GetLightDirection() const;
|
||||
osg::Vec3 GetDirectionalLightColor() const;
|
||||
|
||||
void SetAmbientLight(const osg::Vec3& color);
|
||||
osg::Vec3 GetAmbientLightColor() const;
|
||||
|
||||
void SetSunIntensity(float intensity);
|
||||
float GetSunIntensity() const;
|
||||
|
||||
BreakingWavesParameters GetBreakingWavesParameters() const;
|
||||
|
||||
void SimulateSeaState(double bs, double winddir);
|
||||
|
||||
void SetAboveWaterVisibility(double visibility, osg::Vec3 fog_color);
|
||||
void GetAboveWaterVisibility(double &visibility, osg::Vec3 &fog_color) const;
|
||||
|
||||
void SetEnvironmentMap(GLuint id, const osg::Matrixd &textureMatrix = osg::Matrixd());
|
||||
GLuint GetEnvironmentMap() const;
|
||||
osg::Matrixd GetEnvironmentMapMatrix() const;
|
||||
public:
|
||||
Environment(uintptr_t handle) : _handle(handle) { }
|
||||
uintptr_t _handle;
|
||||
};
|
||||
|
||||
class Ocean
|
||||
{
|
||||
public:
|
||||
void SetChoppiness(float);
|
||||
float GetChoppiness() const;
|
||||
|
||||
void EnableWireframe(bool wireframe);
|
||||
|
||||
void SetQuality(OceanQuality value);
|
||||
OceanQuality GetQuality() const;
|
||||
|
||||
void EnableSpray(bool enabled);
|
||||
bool SprayEnabled() const;
|
||||
|
||||
void EnableGodRays(bool enabled);
|
||||
bool GodRaysEnabled() const;
|
||||
|
||||
void SetGodRaysFade(float fadeAmount);
|
||||
float GetGodRaysFade() const;
|
||||
|
||||
public:
|
||||
Ocean(uintptr_t handle) : _handle(handle) { }
|
||||
uintptr_t _handle;
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::SilverLining
|
||||
|
||||
#endif // OSGEARTH_TRITON_API_WRAPPER
|
@ -1,39 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_CALLBACK_H
|
||||
#define OSGEARTH_TRITON_CALLBACK_H 1
|
||||
|
||||
#include "TritonAPIWrapper.h"
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/**
|
||||
* A callback that lets you execute code in the proper context.
|
||||
*/
|
||||
class Callback : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
virtual void onInitialize(Environment& env, Ocean& ocean) { }
|
||||
|
||||
virtual void onDrawOcean(Environment& env, Ocean& ocean) { }
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::Triton
|
||||
|
||||
#endif // OSGEARTH_TRITON_CALLBACK_H
|
@ -1,229 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonContext.h"
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Math>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgEarth/SpatialReference>
|
||||
#include <cstdlib>
|
||||
#include <QApplication>
|
||||
|
||||
#define LC "[TritonContext] "
|
||||
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
|
||||
TritonContext::TritonContext(const TritonLayer::Options& options) :
|
||||
_options ( options ),
|
||||
_initAttempted ( false ),
|
||||
_initFailed ( false ),
|
||||
_resourceLoader ( 0L ),
|
||||
_environment ( 0L ),
|
||||
_environmentWrapper ( 0L ),
|
||||
_ocean ( 0L ),
|
||||
_oceanWrapper ( 0L )
|
||||
{
|
||||
//nop
|
||||
}
|
||||
|
||||
TritonContext::~TritonContext()
|
||||
{
|
||||
if (_oceanWrapper)
|
||||
delete _oceanWrapper;
|
||||
|
||||
if (_environmentWrapper)
|
||||
delete _environmentWrapper;
|
||||
}
|
||||
|
||||
void
|
||||
TritonContext::setSRS(const osgEarth::SpatialReference* srs)
|
||||
{
|
||||
_srs = srs;
|
||||
}
|
||||
|
||||
void
|
||||
TritonContext::setCallback(Callback* callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
bool
|
||||
TritonContext::passHeightMapToTriton() const
|
||||
{
|
||||
return _options.useHeightMap() == true;
|
||||
}
|
||||
|
||||
int
|
||||
TritonContext::getHeightMapSize() const
|
||||
{
|
||||
return osg::clampBetween(_options.heightMapSize().get(), 64u, 2048u);
|
||||
}
|
||||
|
||||
const std::string&
|
||||
TritonContext::getMaskLayerName() const
|
||||
{
|
||||
return _options.maskLayer().externalLayerName().get();
|
||||
}
|
||||
|
||||
void
|
||||
TritonContext::initialize(osg::RenderInfo& renderInfo)
|
||||
{
|
||||
if ( !_initAttempted && !_initFailed )
|
||||
{
|
||||
// lock/double-check:
|
||||
std::lock_guard<std::mutex> excl(_initMutex);
|
||||
if ( !_initAttempted && !_initFailed )
|
||||
{
|
||||
_initAttempted = true;
|
||||
|
||||
std::string resourcePath = _options.resourcePath().get();
|
||||
if (resourcePath.empty() && ::getenv("TRITON_PATH"))
|
||||
{
|
||||
resourcePath = osgDB::concatPaths(::getenv("TRITON_PATH"), "Resources");
|
||||
}
|
||||
|
||||
if ( resourcePath.empty() )
|
||||
{
|
||||
const QString dir = QString("%1/TritonResources").arg(QApplication::applicationDirPath());
|
||||
resourcePath = dir.toStdString();
|
||||
}
|
||||
|
||||
_resourceLoader = new ::Triton::ResourceLoader(resourcePath.c_str());
|
||||
|
||||
_environment = new ::Triton::Environment();
|
||||
|
||||
_environmentWrapper = new Environment((uintptr_t)_environment);
|
||||
|
||||
_environment->SetLicenseCode(
|
||||
_options.user()->c_str(),
|
||||
_options.licenseCode()->c_str() );
|
||||
|
||||
// "WGS84" is used to represent any ellipsoid.
|
||||
::Triton::CoordinateSystem cs =
|
||||
_srs->isGeographic() ? ::Triton::WGS84_ZUP :
|
||||
::Triton::FLAT_ZUP;
|
||||
|
||||
// Set the ellipsoid to match the one in our map's SRS.
|
||||
if ( _srs->isGeographic() )
|
||||
{
|
||||
const Ellipsoid& ellipsoid = _srs->getEllipsoid();
|
||||
|
||||
std::string eqRadius = Stringify() << ellipsoid.getRadiusEquator();
|
||||
std::string poRadius = Stringify() << ellipsoid.getRadiusPolar();
|
||||
|
||||
_environment->SetConfigOption( "equatorial-earth-radius-meters", eqRadius.c_str() );
|
||||
_environment->SetConfigOption( "polar-earth-radius-meters", poRadius.c_str() );
|
||||
}
|
||||
|
||||
//_environment->SetConfigOption("avoid-opengl-stalls", "yes");
|
||||
//_environment->SetConfigOption("fft-texture-update-frame-delayed", "yes");
|
||||
|
||||
float openGLVersion = osg::getGLVersionNumber();
|
||||
enum ::Triton::Renderer tritonOpenGlVersion = ::Triton::OPENGL_2_0;
|
||||
#ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE
|
||||
if( openGLVersion >= 4.1 )
|
||||
tritonOpenGlVersion = ::Triton::OPENGL_4_1;
|
||||
else if( openGLVersion >= 4.0 )
|
||||
tritonOpenGlVersion = ::Triton::OPENGL_4_0;
|
||||
else if( openGLVersion >= 3.2 )
|
||||
tritonOpenGlVersion = ::Triton::OPENGL_3_2;
|
||||
#endif
|
||||
|
||||
::Triton::EnvironmentError err = _environment->Initialize(
|
||||
cs,
|
||||
tritonOpenGlVersion,
|
||||
_resourceLoader );
|
||||
|
||||
if ( err == ::Triton::SUCCEEDED )
|
||||
{
|
||||
::Triton::WindFetch wf;
|
||||
wf.SetWind( 10.0, 0.0 );
|
||||
_environment->AddWindFetch( wf );
|
||||
|
||||
_ocean = ::Triton::Ocean::Create(
|
||||
_environment,
|
||||
::Triton::JONSWAP,
|
||||
true ); // enableHeightTests - activated GetHeight for intersections
|
||||
}
|
||||
|
||||
if ( _ocean )
|
||||
{
|
||||
_oceanWrapper = new Ocean((uintptr_t)_ocean);
|
||||
|
||||
// fire init callback if available
|
||||
if (_callback.valid())
|
||||
{
|
||||
_callback->onInitialize(getEnvironmentWrapper(), getOceanWrapper());
|
||||
}
|
||||
|
||||
OE_INFO << LC << "Triton initialized OK!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
_initFailed = true;
|
||||
OE_WARN << LC << "Triton initialization failed- err=" << err << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TritonContext::intersect(const osg::Vec3d& start, const osg::Vec3d& dir, float& out_height, osg::Vec3f& out_normal) const
|
||||
{
|
||||
::Triton::Vector3 p(start.ptr());
|
||||
::Triton::Vector3 d(dir.ptr());
|
||||
::Triton::Vector3 normal;
|
||||
bool ok = _ocean->GetHeight(p, d, out_height, normal);
|
||||
out_normal.set(normal.x, normal.y, normal.z);
|
||||
return ok;
|
||||
}
|
||||
|
||||
void
|
||||
TritonContext::resizeGLObjectBuffers(unsigned maxSize)
|
||||
{
|
||||
osg::Object::resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
void
|
||||
TritonContext::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
osg::Object::releaseGLObjects(state);
|
||||
|
||||
OE_DEBUG << LC << "Triton shutting down - releasing GL resources\n";
|
||||
if (state)
|
||||
{
|
||||
if ( _ocean )
|
||||
{
|
||||
delete _ocean;
|
||||
_ocean = 0L;
|
||||
}
|
||||
|
||||
if ( _environment )
|
||||
{
|
||||
delete _environment;
|
||||
_environment = 0L;
|
||||
}
|
||||
|
||||
if ( _resourceLoader )
|
||||
{
|
||||
delete _resourceLoader;
|
||||
_resourceLoader = 0L;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_CONTEXT_H
|
||||
#define OSGEARTH_TRITON_CONTEXT_H
|
||||
|
||||
#include <Triton.h>
|
||||
#include <Camera.h> // Triton
|
||||
#include "TritonLayer.h"
|
||||
#include "TritonAPIWrapper.h"
|
||||
#include "TritonCallback.h"
|
||||
#include <osg/Referenced>
|
||||
#include <osg/Light>
|
||||
#include <osgEarth/Threading>
|
||||
|
||||
namespace osgEarth {
|
||||
class SpatialReference;
|
||||
}
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/**
|
||||
* Contains all the Triton SDK handles.
|
||||
*/
|
||||
class TritonContext : public osg::Object
|
||||
{
|
||||
public:
|
||||
META_Object(osgEarth, TritonContext);
|
||||
|
||||
TritonContext(const TritonLayer::Options&);
|
||||
|
||||
/** Sets the spatial reference system of the map */
|
||||
void setSRS(const osgEarth::SpatialReference* srs);
|
||||
|
||||
/** Sets the user callback */
|
||||
void setCallback(Callback* callback);
|
||||
Callback* getCallback() const { return _callback.get(); }
|
||||
|
||||
public: // accessors
|
||||
|
||||
bool ready() const { return _initAttempted && !_initFailed; }
|
||||
|
||||
/** Spatial reference of the map */
|
||||
const osgEarth::SpatialReference* getSRS() const { return _srs.get(); }
|
||||
|
||||
void initialize(osg::RenderInfo& renderInfo);
|
||||
|
||||
bool intersect(const osg::Vec3d& start, const osg::Vec3d& dir, float& out_height, osg::Vec3f& out_normal) const;
|
||||
|
||||
::Triton::Environment* getEnvironment() { return _environment; }
|
||||
Environment& getEnvironmentWrapper() const { return *_environmentWrapper; }
|
||||
|
||||
::Triton::Ocean* getOcean() { return _ocean; }
|
||||
Ocean& getOceanWrapper() const { return *_oceanWrapper; }
|
||||
|
||||
bool passHeightMapToTriton() const;
|
||||
|
||||
int getHeightMapSize() const;
|
||||
|
||||
const std::string& getMaskLayerName() const;
|
||||
|
||||
public: // osg::Object
|
||||
|
||||
void resizeGLObjectBuffers(unsigned maxSize);
|
||||
|
||||
/** If State is non-zero, this function releases any associated OpenGL objects for
|
||||
* the specified graphics context. Otherwise, releases OpenGL objects
|
||||
* for all graphics contexts. */
|
||||
void releaseGLObjects(osg::State* state) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TritonContext();
|
||||
|
||||
// hidden ctors (for META_Object)
|
||||
TritonContext() { }
|
||||
TritonContext(const TritonContext&, const osg::CopyOp&) { }
|
||||
|
||||
private:
|
||||
TritonLayer::Options _options;
|
||||
|
||||
bool _initAttempted;
|
||||
bool _initFailed;
|
||||
std::mutex _initMutex;
|
||||
|
||||
osg::ref_ptr<const osgEarth::SpatialReference> _srs;
|
||||
|
||||
mutable ::Triton::ResourceLoader* _resourceLoader;
|
||||
mutable ::Triton::Environment* _environment;
|
||||
mutable ::Triton::Ocean* _ocean;
|
||||
|
||||
Environment* _environmentWrapper;
|
||||
Ocean* _oceanWrapper;
|
||||
|
||||
osg::ref_ptr<Callback> _callback;
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::Triton
|
||||
|
||||
#endif // OSGEARTH_TRITON_CONTEXT_H
|
@ -1,330 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonContext.h"
|
||||
#include "TritonDrawable.h"
|
||||
#include "TritonHeightMap.h"
|
||||
#include <Version.h>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/FrameBufferObject>
|
||||
#include <osg/Depth>
|
||||
|
||||
#include <osgEarth/SpatialReference>
|
||||
#include <osgEarth/VirtualProgram>
|
||||
#include <osgEarth/MapNode>
|
||||
#include <osgEarth/TerrainEngineNode>
|
||||
#include <osgEarth/Random>
|
||||
#include <osgEarth/GLUtils>
|
||||
|
||||
#undef LC
|
||||
#define LC "[TritonDrawable] "
|
||||
|
||||
//#define DEBUG_HEIGHTMAP
|
||||
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
|
||||
TritonDrawable::TritonDrawable(TritonContext* TRITON) :
|
||||
_TRITON(TRITON)
|
||||
{
|
||||
// call this to ensure draw() gets called every frame.
|
||||
setSupportsDisplayList( false );
|
||||
setUseVertexBufferObjects( false );
|
||||
|
||||
// dynamic variance prevents update/cull overlap when drawing this
|
||||
setDataVariance( osg::Object::DYNAMIC );
|
||||
|
||||
_wgs84 = SpatialReference::get("wgs84");
|
||||
_ecef = _wgs84->getGeocentricSRS();
|
||||
}
|
||||
|
||||
TritonDrawable::~TritonDrawable()
|
||||
{
|
||||
//nop
|
||||
}
|
||||
|
||||
void
|
||||
TritonDrawable::setMaskLayer(const osgEarth::ImageLayer* layer)
|
||||
{
|
||||
_maskLayer = layer;
|
||||
}
|
||||
|
||||
void
|
||||
TritonDrawable::setHeightMapGenerator(TritonHeightMap* value)
|
||||
{
|
||||
_heightMapGenerator = value;
|
||||
}
|
||||
|
||||
void
|
||||
TritonDrawable::setPlanarReflectionMap(osg::Texture2D* map)
|
||||
{
|
||||
_planarReflectionMap = map;
|
||||
}
|
||||
|
||||
void
|
||||
TritonDrawable::setPlanarReflectionProjection(osg::RefMatrix* proj)
|
||||
{
|
||||
_planarReflectionProjection = proj;
|
||||
}
|
||||
|
||||
osg::BoundingBox
|
||||
TritonDrawable::computeBoundingBox() const
|
||||
{
|
||||
return osg::BoundingBox();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Wrapper around Ocean->GetShaderObject() to account for API changes from Triton 3.x to 4.x
|
||||
GLint
|
||||
getOceanShader(::Triton::Ocean* ocean, ::Triton::Shaders shaderProgram, void* context, const ::Triton::Camera* camera)
|
||||
{
|
||||
#if (TRITON_MAJOR_VERSION >= 4)
|
||||
return (GLint)ocean->GetShaderObject( shaderProgram, context, camera );
|
||||
#else
|
||||
return (GLint)ocean->GetShaderObject( shaderProgram );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
TritonDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
OE_GL_ZONE;
|
||||
|
||||
osg::State* state = renderInfo.getState();
|
||||
|
||||
state->disableAllVertexArrays();
|
||||
|
||||
_TRITON->initialize( renderInfo );
|
||||
if ( !_TRITON->ready() )
|
||||
return;
|
||||
|
||||
// Configure the height map generator.
|
||||
// If configuration fails, attempt to continue without a heightmap.
|
||||
if (_heightMapGenerator.valid())
|
||||
{
|
||||
bool configOK = _heightMapGenerator->configure(_TRITON->getHeightMapSize(), *state);
|
||||
if (configOK == false)
|
||||
{
|
||||
_heightMapGenerator = 0L;
|
||||
OE_WARN << LC << "Failed to establish a legal FBO configuration; disabling height map generator!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
::Triton::Environment* environment = _TRITON->getEnvironment();
|
||||
|
||||
// Find or create the Triton camera for this OSG camera:
|
||||
CameraLocal& local = _local.get(renderInfo.getCurrentCamera());
|
||||
if (local._tritonCam == 0L)
|
||||
{
|
||||
local._tritonCam = environment->CreateCamera();
|
||||
local._tritonCam->SetName(renderInfo.getCurrentCamera()->getName().c_str());
|
||||
}
|
||||
::Triton::Camera* tritonCam = local._tritonCam;
|
||||
|
||||
auto cid = GLUtils::getSharedContextID(*state);
|
||||
osgEarth::NativeProgramAdapterCollection& adapters = _adapters[cid];
|
||||
if ( adapters.empty() )
|
||||
{
|
||||
OE_DEBUG << LC << "Initializing Triton program adapters" << std::endl;
|
||||
const std::vector<const char*> prefixes = { "osg_", "oe_" };
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE, 0L, tritonCam), prefixes, "WATER_SURFACE"));
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_SURFACE_PATCH, 0L, tritonCam), prefixes, "WATER_SURFACE_PATCH"));
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::GOD_RAYS, 0L, tritonCam), prefixes, "GOD_RAYS"));
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::SPRAY_PARTICLES, 0L, tritonCam), prefixes, "SPRAY_PARTICLES"));
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WAKE_SPRAY_PARTICLES, 0L, tritonCam), prefixes, "WAKE_SPRAY_PARTICLES"));
|
||||
#if 0
|
||||
// In older Triton (3.91), this line causes problems in Core profile and prevents the ocean from drawing. In newer Triton (4.01),
|
||||
// this line causes a crash because there is no context passed in to GetShaderObject(), resulting in multiple NULL references.
|
||||
adapters.push_back( new osgEarth::NativeProgramAdapter(state, getOceanShader(_TRITON->getOcean(), ::Triton::WATER_DECALS, 0L, tritonCam), prefixes, "WATER_DECALS"));
|
||||
#endif
|
||||
}
|
||||
adapters.apply( state );
|
||||
|
||||
|
||||
// Pass the final view and projection matrices into Triton.
|
||||
if ( environment )
|
||||
{
|
||||
tritonCam->SetCameraMatrix(state->getModelViewMatrix().ptr());
|
||||
tritonCam->SetProjectionMatrix(state->getProjectionMatrix().ptr());
|
||||
}
|
||||
|
||||
// Calculate sea level based on the camera:
|
||||
if (_verticalDatum.valid())
|
||||
{
|
||||
GeoPoint cam(_ecef, osg::Vec3d(0, 0, 0) * state->getInitialInverseViewMatrix(), ALTMODE_ABSOLUTE);
|
||||
cam.transformInPlace(_wgs84);
|
||||
auto msl = _verticalDatum->hae2msl(cam.y(), cam.x(), 0.0);
|
||||
environment->SetSeaLevel(-msl);
|
||||
}
|
||||
|
||||
if (_heightMapGenerator.valid())
|
||||
{
|
||||
GLint texName;
|
||||
osg::Matrix hMM;
|
||||
if (_heightMapGenerator->getTextureAndMatrix(renderInfo, texName, hMM))
|
||||
{
|
||||
// copy the OSG matrix to a Triton matrix:
|
||||
::Triton::Matrix4 texMat(
|
||||
hMM(0, 0), hMM(0, 1), hMM(0, 2), hMM(0, 3),
|
||||
hMM(1, 0), hMM(1, 1), hMM(1, 2), hMM(1, 3),
|
||||
hMM(2, 0), hMM(2, 1), hMM(2, 2), hMM(2, 3),
|
||||
hMM(3, 0), hMM(3, 1), hMM(3, 2), hMM(3, 3));
|
||||
|
||||
environment->SetHeightMap((::Triton::TextureHandle)texName, texMat, 0L, tritonCam);
|
||||
|
||||
//OE_DEBUG << LC << "Updating height map, FN=" << renderInfo.getState()->getFrameStamp()->getFrameNumber() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
state->dirtyAllVertexArrays();
|
||||
|
||||
// Now light and draw the ocean:
|
||||
if ( environment )
|
||||
{
|
||||
// User pre-draw callback:
|
||||
if (_TRITON->getCallback())
|
||||
{
|
||||
_TRITON->getCallback()->onDrawOcean(
|
||||
_TRITON->getEnvironmentWrapper(),
|
||||
_TRITON->getOceanWrapper());
|
||||
}
|
||||
|
||||
osg::Light* light = renderInfo.getView() ? renderInfo.getView()->getLight() : NULL;
|
||||
|
||||
// This is the light attached to View so there are no transformations above..
|
||||
// But in general case you would need to accumulate all transforms above the light into this matrix
|
||||
osg::Matrix lightLocalToWorldMatrix = osg::Matrix::identity();
|
||||
|
||||
// If you don't know where the sun lightsource is attached and don't know its local to world matrix you may use
|
||||
// following elaborate scheme to grab the light source while drawing Triton ocean:
|
||||
// - Install cull callback to catch CullVisitor and record pointer to its associated RenderStage
|
||||
// I was hoping RenderStage can be found from renderInfo in drawImplementation but I didn't figure how ...
|
||||
// - When TritonDrawable::drawImplementation is called all lights will be already applied to OpenGL
|
||||
// then just find proper infinite directional light by scanning renderStage->PositionalStateContainer.
|
||||
// - Note that we canot scan for the lights inside cull because they may not be traversed before Triton drawable
|
||||
// - When you found interesting ligt source that can work as Sun, read its modelview matrix and lighting params
|
||||
// Multiply light position by ( modelview * inverse camera view ) and pass this to Triton with lighting colors
|
||||
|
||||
if ( light && light->getPosition().w() == 0 )
|
||||
{
|
||||
osg::Vec4 ambient = light->getAmbient();
|
||||
osg::Vec4 diffuse = light->getDiffuse();
|
||||
osg::Vec4 position = light->getPosition();
|
||||
|
||||
// Compute light position/direction in the world
|
||||
position = position * lightLocalToWorldMatrix;
|
||||
|
||||
// Diffuse direction and color
|
||||
environment->SetDirectionalLight(
|
||||
::Triton::Vector3( position[0], position[1], position[2] ),
|
||||
::Triton::Vector3( diffuse[0], diffuse[1], diffuse[2] ) );
|
||||
|
||||
// Sun-based ambient value:
|
||||
osg::Vec3d up = osg::Vec3d(0,0,0) * renderInfo.getCurrentCamera()->getInverseViewMatrix();
|
||||
up.normalize();
|
||||
osg::Vec3d pos3 = osg::Vec3d(position.x(), position.y(), position.z());
|
||||
pos3.normalize();
|
||||
float dot = osg::clampAbove(up*pos3, 0.0); dot*=dot;
|
||||
float sunAmbient = (float)osg::clampBetween( dot, 0.0f, 0.88f );
|
||||
float fa = osg::maximum(sunAmbient, ambient[0]);
|
||||
|
||||
// Ambient color based on the zenith color in the cube map
|
||||
environment->SetAmbientLight( ::Triton::Vector3(fa, fa, fa) );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
environment->SetDirectionalLight( ::Triton::Vector3(0,0,1), ::Triton::Vector3(1,1,1) );
|
||||
environment->SetAmbientLight( ::Triton::Vector3(0.88f, 0.88f, 0.88f) );
|
||||
}
|
||||
|
||||
if ( _cubeMap.valid() )
|
||||
{
|
||||
// Build transform from our cube map orientation space to native Triton orientation
|
||||
// See worldToCubeMap function used in SkyBox to orient sky texture so that sky is up and earth is down
|
||||
osg::Matrix m = osg::Matrix::rotate( osg::PI_2, osg::X_AXIS ); // = worldToCubeMap
|
||||
|
||||
::Triton::Matrix3 transformFromYUpToZUpCubeMapCoords(
|
||||
m(0,0), m(0,1), m(0,2),
|
||||
m(1,0), m(1,1), m(1,2),
|
||||
m(2,0), m(2,1), m(2,2) );
|
||||
|
||||
// Grab the cube map from our sky box and give it to Triton to use as an _environment map
|
||||
// GLenum texture = renderInfo.getState()->getLastAppliedTextureAttribute( _stage, osg::StateAttribute::TEXTURE );
|
||||
environment->SetEnvironmentMap(
|
||||
(::Triton::TextureHandle)_cubeMap->getTextureObject(cid)->id(),
|
||||
transformFromYUpToZUpCubeMapCoords );
|
||||
|
||||
if( _planarReflectionMap.valid() && _planarReflectionProjection.valid() )
|
||||
{
|
||||
osg::Matrix & p = *_planarReflectionProjection;
|
||||
|
||||
::Triton::Matrix3 planarProjection(
|
||||
p(0,0), p(0,1), p(0,2),
|
||||
p(1,0), p(1,1), p(1,2),
|
||||
p(2,0), p(2,1), p(2,2) );
|
||||
|
||||
environment->SetPlanarReflectionMap(
|
||||
(::Triton::TextureHandle)_planarReflectionMap->getTextureObject(cid)->id(),
|
||||
planarProjection,
|
||||
0.125 );
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the ocean for the current time sample
|
||||
if ( _TRITON->getOcean() )
|
||||
{
|
||||
osg::GLExtensions* ext = osg::GLExtensions::Get(cid, true);
|
||||
|
||||
bool writeDepth = true;
|
||||
const osg::Depth* depth = static_cast<const osg::Depth*>(state->getLastAppliedAttribute(osg::StateAttribute::DEPTH));
|
||||
if (depth)
|
||||
writeDepth = depth->getWriteMask();
|
||||
|
||||
double simTime = renderInfo.getView()->getFrameStamp()->getSimulationTime();
|
||||
simTime = fmod(simTime, 86400.0);
|
||||
|
||||
_TRITON->getOcean()->Draw(
|
||||
simTime,
|
||||
writeDepth, // depth writes
|
||||
true, // draw water
|
||||
true, // draw particles
|
||||
NULL, // optional context
|
||||
tritonCam);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Put GL back in a state that won't confuse the OSG state tracking:
|
||||
state->dirtyAllVertexArrays();
|
||||
state->dirtyAllAttributes();
|
||||
state->dirtyAllModes();
|
||||
|
||||
#ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE
|
||||
// Keep OSG from reapplying GL_LIGHTING on next state change after dirtyAllModes().
|
||||
state->setModeValidity(GL_LIGHTING, false);
|
||||
#endif
|
||||
|
||||
// Keep an eye on this.
|
||||
// I had to remove something similar in another module (Rex engine) because it was causing
|
||||
// positional attributes (like clip planes) to re-apply with an incorrect MVM. -gw
|
||||
state->apply();
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_DRAWABLE_H
|
||||
#define OSGEARTH_TRITON_DRAWABLE_H
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/RenderInfo>
|
||||
#include <osg/TextureCubeMap>
|
||||
#include <osg/Version>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/buffered_value>
|
||||
|
||||
#include <osgEarth/Terrain>
|
||||
#include <osgEarth/NativeProgramAdapter>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include <osgEarth/VerticalDatum>
|
||||
|
||||
const unsigned int TRITON_OCEAN_MASK = 0x4; // 0100
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
class TritonContext;
|
||||
class TritonHeightMap;
|
||||
|
||||
/**
|
||||
* Custom drawable for rendering the Triton ocean effects
|
||||
*/
|
||||
class TritonDrawable : public osg::Drawable
|
||||
{
|
||||
public:
|
||||
TritonDrawable(TritonContext* TRITON);
|
||||
|
||||
//! Layer to use as an ocean rendering mask
|
||||
void setMaskLayer(const osgEarth::ImageLayer* maskLayer);
|
||||
|
||||
//! Height map generator to use to mask out the ocean where the
|
||||
//! terrain has positive elevation
|
||||
void setHeightMapGenerator(TritonHeightMap* heightMap);
|
||||
|
||||
//! Vertical datum to use to calculate sea level
|
||||
void setVerticalDatum(VerticalDatum* value) {
|
||||
_verticalDatum = value;
|
||||
}
|
||||
|
||||
//! Gets the Triton Camera associated with an osg Camera
|
||||
::Triton::Camera* getTritonCam(const osg::Camera* cam) {
|
||||
return _local.get(cam)._tritonCam;
|
||||
}
|
||||
|
||||
void setPlanarReflectionMap(osg::Texture2D* map);
|
||||
|
||||
void setPlanarReflectionProjection(osg::RefMatrix* proj);
|
||||
|
||||
public: // osg::Drawable
|
||||
|
||||
void drawImplementation(osg::RenderInfo& ri) const override;
|
||||
|
||||
osg::BoundingBox computeBoundingBox() const override;
|
||||
|
||||
protected:
|
||||
virtual ~TritonDrawable();
|
||||
|
||||
osg::observer_ptr<TritonContext> _TRITON;
|
||||
osg::observer_ptr<const osgEarth::ImageLayer> _maskLayer;
|
||||
osg::ref_ptr<osg::TextureCubeMap> _cubeMap;
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> _planarReflectionMap;
|
||||
osg::ref_ptr<osg::RefMatrix> _planarReflectionProjection;
|
||||
|
||||
mutable osg::ref_ptr<TritonHeightMap> _heightMapGenerator;
|
||||
|
||||
osg::ref_ptr<VerticalDatum> _verticalDatum;
|
||||
osg::ref_ptr<const SpatialReference> _wgs84, _ecef;
|
||||
|
||||
mutable osg::buffered_object<osgEarth::NativeProgramAdapterCollection> _adapters;
|
||||
|
||||
struct CameraLocal
|
||||
{
|
||||
::Triton::Camera* _tritonCam = nullptr;
|
||||
};
|
||||
mutable PerObjectFastMap<const osg::Camera*, CameraLocal> _local;
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::Triton
|
||||
|
||||
#endif // OSGEARTH_TRITON_DRAWABLE_H
|
@ -1,434 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonHeightMap.h"
|
||||
#include "TritonContext.h"
|
||||
#include <osgEarth/CullingUtils>
|
||||
#include <osgEarth/VirtualProgram>
|
||||
#include <osgEarth/TerrainEngineNode>
|
||||
#include <osgEarth/Utils>
|
||||
|
||||
#define LC "[TritonHeightMap] "
|
||||
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* vertexShader =
|
||||
"#pragma import_defines(OE_TRITON_MASK_MATRIX);\n"
|
||||
|
||||
"// terrain SDK:\n"
|
||||
"float oe_terrain_getElevation(); \n"
|
||||
|
||||
"out float oe_triton_elev;\n"
|
||||
|
||||
"#ifdef OE_TRITON_MASK_MATRIX\n"
|
||||
"out vec2 maskCoords;\n"
|
||||
"uniform mat4 OE_TRITON_MASK_MATRIX;\n"
|
||||
"vec4 oe_layer_tilec;\n"
|
||||
"#endif\n"
|
||||
|
||||
"void oe_triton_setupHeightMap(inout vec4 unused) \n"
|
||||
"{ \n"
|
||||
" oe_triton_elev = oe_terrain_getElevation(); \n"
|
||||
"#ifdef OE_TRITON_MASK_MATRIX\n"
|
||||
" maskCoords = (OE_TRITON_MASK_MATRIX * oe_layer_tilec).st;\n"
|
||||
"#endif\n"
|
||||
"} \n";
|
||||
|
||||
// The fragment shader simply takes the texture index that we generated
|
||||
// in the vertex shader and does a texture lookup. In this case we're
|
||||
// just wholesale replacing the color, so if the map had any existing
|
||||
// imagery, this will overwrite it.
|
||||
|
||||
const char* fragmentShader =
|
||||
"#pragma import_defines(OE_TRITON_MASK_SAMPLER);\n"
|
||||
|
||||
"in float oe_triton_elev;\n"
|
||||
|
||||
"#ifdef OE_TRITON_MASK_SAMPLER\n"
|
||||
"in vec2 maskCoords;\n"
|
||||
"uniform sampler2D OE_TRITON_MASK_SAMPLER;\n"
|
||||
"#endif\n"
|
||||
|
||||
"out vec4 out_height; \n"
|
||||
|
||||
"void oe_triton_drawHeightMap(inout vec4 unused) \n"
|
||||
"{ \n"
|
||||
#ifdef DEBUG_HEIGHTMAP
|
||||
// Map to black = -500m, white = +500m
|
||||
" float nHeight = clamp(oe_triton_elev / 1000.0 + 0.5, 0.0, 1.0);\n"
|
||||
#else
|
||||
" float nHeight = oe_triton_elev;\n"
|
||||
|
||||
"#ifdef OE_TRITON_MASK_SAMPLER\n"
|
||||
" float mask = texture(OE_TRITON_MASK_SAMPLER, maskCoords).a;\n"
|
||||
" nHeight *= mask; \n"
|
||||
"#endif\n"
|
||||
|
||||
#endif
|
||||
" out_height = vec4( nHeight, 0.0, 0.0, 1.0 ); \n"
|
||||
"} \n";
|
||||
|
||||
struct TerrainDirtyCallback : public osgEarth::TerrainCallback
|
||||
{
|
||||
osg::observer_ptr<TritonHeightMap> _hm;
|
||||
TerrainDirtyCallback(TritonHeightMap* hm) : _hm(hm) { }
|
||||
void onTileUpdate(const osgEarth::TileKey&, osg::Node*, osgEarth::TerrainCallbackContext&)
|
||||
{
|
||||
osg::ref_ptr<TritonHeightMap> hm;
|
||||
if (_hm.lock(hm))
|
||||
hm->dirty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TritonHeightMap::TritonHeightMap() :
|
||||
_texSize(0u),
|
||||
_internalFormat((GLint)0),
|
||||
_sourceFormat((GLenum)0)
|
||||
{
|
||||
setCullingActive(false);
|
||||
}
|
||||
|
||||
TritonHeightMap::~TritonHeightMap()
|
||||
{
|
||||
osgEarth::TerrainEngineNode* t = dynamic_cast<osgEarth::TerrainEngineNode*>(_terrain.get());
|
||||
if (t)
|
||||
{
|
||||
t->getTerrain()->removeTerrainCallback(static_cast<TerrainDirtyCallback*>(_terrainCallback.get()));
|
||||
_terrainCallback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::setTerrain(osg::Node* node)
|
||||
{
|
||||
_terrain = node;
|
||||
|
||||
osgEarth::TerrainEngineNode* t = dynamic_cast<osgEarth::TerrainEngineNode*>(node);
|
||||
if (t)
|
||||
{
|
||||
TerrainDirtyCallback* cb = new TerrainDirtyCallback(this);
|
||||
t->getTerrain()->addTerrainCallback(cb);
|
||||
_terrainCallback = cb;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::setMaskLayer(const osgEarth::ImageLayer* layer)
|
||||
{
|
||||
_maskLayer = layer;
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::SetDirty::operator()(CameraLocal& local)
|
||||
{
|
||||
local._mvpw.makeIdentity();
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::dirty()
|
||||
{
|
||||
SetDirty setDirty;
|
||||
_local.forEach(setDirty);
|
||||
}
|
||||
|
||||
bool
|
||||
TritonHeightMap::configure(unsigned texSize, osg::State& state)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (_texSize == 0u)
|
||||
{
|
||||
// first time through, single-lane and set up FBO parameters.
|
||||
static std::mutex s_mutex;
|
||||
std::lock_guard<std::mutex> lock(s_mutex);
|
||||
|
||||
if (_texSize == 0u)
|
||||
{
|
||||
_texSize = texSize;
|
||||
if (!getBestFBOConfig(state, _internalFormat, _sourceFormat))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct Format {
|
||||
Format(GLint i, GLenum s, const std::string& n) :
|
||||
internalFormat(i), sourceFormat(s), name(n) { }
|
||||
GLint internalFormat;
|
||||
GLenum sourceFormat;
|
||||
std::string name;
|
||||
};
|
||||
}
|
||||
|
||||
bool
|
||||
TritonHeightMap::getBestFBOConfig(osg::State& state, GLint& out_internalFormat, GLenum& out_sourceFormat)
|
||||
{
|
||||
#ifdef GL_LUMINANCE_FLOAT16_ATI
|
||||
# define GL_LUMINANCE_FLOAT16_ATI 0x881E
|
||||
#endif
|
||||
|
||||
std::vector<Format> formats;
|
||||
|
||||
#ifdef GL_R16F
|
||||
formats.push_back(Format(GL_R16F, GL_RED, "GL_R16F"));
|
||||
#endif
|
||||
#ifdef GL_LUMINANCE16F_ARB
|
||||
formats.push_back(Format(GL_LUMINANCE16F_ARB, GL_LUMINANCE, "GL_LUMINANCE16F_ARB"));
|
||||
#endif
|
||||
#ifdef GL_LUMINANCE_FLOAT16_ATI
|
||||
formats.push_back(Format(GL_LUMINANCE_FLOAT16_ATI, GL_LUMINANCE, "GL_LUMINANCE_FLOAT16_ATI"));
|
||||
#endif
|
||||
#ifdef GL_R32F
|
||||
formats.push_back(Format(GL_R32F, GL_RED, "GL_R32F"));
|
||||
#endif
|
||||
#ifdef GL_LUMINANCE32F_ARB
|
||||
formats.push_back(Format(GL_LUMINANCE32F_ARB, GL_LUMINANCE, "GL_LUMINANCE32F_ARB"));
|
||||
#endif
|
||||
#ifdef GL_RGB16F_ARB
|
||||
formats.push_back(Format(GL_RGB16F_ARB, GL_RGB, "GL_RGB16F_ARB"));
|
||||
#endif
|
||||
#ifdef GL_RGBA16F_ARB
|
||||
formats.push_back(Format(GL_RGBA16F_ARB, GL_RGBA, "GL_RGBA16F_ARB"));
|
||||
#endif
|
||||
#ifdef GL_RGB32F_ARB
|
||||
formats.push_back(Format(GL_RGB32F_ARB, GL_RGB, "GL_RGB32F_ARB"));
|
||||
#endif
|
||||
#ifdef GL_RGBA32F_ARB
|
||||
formats.push_back(Format(GL_RGBA32F_ARB, GL_RGBA, "GL_RGBA32F_ARB"));
|
||||
#endif
|
||||
|
||||
|
||||
auto cid = GLUtils::getSharedContextID(state);
|
||||
osg::GLExtensions* ext = osg::GLExtensions::Get(cid, true);
|
||||
|
||||
osg::State::CheckForGLErrors check = state.getCheckForGLErrors();
|
||||
state.setCheckForGLErrors(state.NEVER_CHECK_GL_ERRORS);
|
||||
|
||||
bool found = false;
|
||||
|
||||
for(int i=0; i<formats.size() && !found; ++i)
|
||||
{
|
||||
const Format& format = formats[i];
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D();
|
||||
tex->setTextureSize(1, 1);
|
||||
tex->setInternalFormat( format.internalFormat );
|
||||
tex->setSourceFormat ( format.sourceFormat );
|
||||
|
||||
osg::ref_ptr<osg::FrameBufferObject> fbo = new osg::FrameBufferObject();
|
||||
fbo->setAttachment( osg::Camera::COLOR_BUFFER0, osg::FrameBufferAttachment(tex.get()) );
|
||||
|
||||
fbo->apply( state );
|
||||
|
||||
GLenum status = ext->glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
fbo->releaseGLObjects( &state );
|
||||
tex->releaseGLObjects( &state );
|
||||
|
||||
if ( status == GL_FRAMEBUFFER_COMPLETE_EXT )
|
||||
{
|
||||
out_internalFormat = format.internalFormat;
|
||||
out_sourceFormat = format.sourceFormat;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
state.setCheckForGLErrors(check);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
TritonHeightMap::isConfigurationComplete() const
|
||||
{
|
||||
return
|
||||
_texSize > 0u &&
|
||||
_internalFormat != (GLint)0 &&
|
||||
_sourceFormat != (GLenum)0;
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::setup(CameraLocal& local, const std::string& name)
|
||||
{
|
||||
// make sure the FBO params are configured:
|
||||
if (!isConfigurationComplete())
|
||||
return;
|
||||
|
||||
local._frameNum = 0u;
|
||||
|
||||
local._tex = new osg::Texture2D();
|
||||
local._tex->setName(Stringify() << "Triton HM (" << name << ")");
|
||||
local._tex->setTextureSize(_texSize, _texSize);
|
||||
local._tex->setInternalFormat( _internalFormat );
|
||||
local._tex->setSourceFormat( _sourceFormat );
|
||||
local._tex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
|
||||
local._tex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
|
||||
|
||||
// Triton prob doesn't need this but it's good practice
|
||||
if (_sourceFormat == GL_RED)
|
||||
{
|
||||
local._tex->setSwizzle(osg::Vec4i(GL_RED, GL_RED, GL_RED, GL_ONE));
|
||||
}
|
||||
|
||||
local._rtt = new osg::Camera();
|
||||
local._rtt->setName(local._tex->getName());
|
||||
local._rtt->setReferenceFrame(osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT);
|
||||
local._rtt->setClearMask(GL_COLOR_BUFFER_BIT); //GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
local._rtt->setClearColor(osg::Vec4(-1000.0, -1000.0, -1000.0, 1.0f));
|
||||
local._rtt->setViewport(0, 0, _texSize, _texSize);
|
||||
local._rtt->setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
local._rtt->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
local._rtt->setImplicitBufferAttachmentMask(0, 0);
|
||||
local._rtt->attach(osg::Camera::COLOR_BUFFER0, local._tex.get());
|
||||
//local._rtt->setCullMask( ~TRITON_OCEAN_MASK );
|
||||
local._rtt->setAllowEventFocus(false);
|
||||
local._rtt->setDrawBuffer(GL_FRONT);
|
||||
local._rtt->setReadBuffer(GL_FRONT);
|
||||
local._rtt->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
// TODO: create this once and just re-use it for all RTT cameras
|
||||
osg::StateSet* rttSS = local._rtt->getOrCreateStateSet();
|
||||
|
||||
osgEarth::VirtualProgram* rttVP = osgEarth::VirtualProgram::getOrCreate(rttSS);
|
||||
rttVP->setName("Triton Height Map");
|
||||
rttVP->setFunction( "oe_triton_setupHeightMap", vertexShader, VirtualProgram::LOCATION_VERTEX_MODEL);
|
||||
rttVP->setFunction( "oe_triton_drawHeightMap", fragmentShader, VirtualProgram::LOCATION_FRAGMENT_OUTPUT);
|
||||
rttVP->setInheritShaders(false);
|
||||
|
||||
osg::StateAttribute::OverrideValue off = osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE;
|
||||
rttSS->setDefine("OE_IS_DEPTH_CAMERA");
|
||||
rttSS->setDefine("OE_TERRAIN_RENDER_IMAGERY", off);
|
||||
rttSS->setDefine("OE_TERRAIN_RENDER_NORMAL_MAP", off);
|
||||
rttSS->setDefine("OE_TERRAIN_BLEND_IMAGERY", off);
|
||||
rttSS->setDefine("OE_TERRAIN_MORPH_GEOMETRY", off);
|
||||
|
||||
osg::ref_ptr<const osgEarth::ImageLayer> maskLayer;
|
||||
if (_maskLayer.lock(maskLayer))
|
||||
{
|
||||
rttSS->setDefine("OE_TRITON_MASK_SAMPLER", maskLayer->getSharedTextureUniformName());
|
||||
rttSS->setDefine("OE_TRITON_MASK_MATRIX", maskLayer->getSharedTextureMatrixUniformName());
|
||||
OE_DEBUG << LC << "Using mask layer \"" << maskLayer->getName() << "\", sampler=" << maskLayer->getSharedTextureUniformName() << ", matrix=" << maskLayer->getSharedTextureMatrixUniformName() << std::endl;
|
||||
}
|
||||
|
||||
if (_terrain.valid())
|
||||
{
|
||||
local._rtt->addChild(_terrain.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
OE_WARN << LC << "Illegal: no terrain set (must call setTerrain)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXABS4(A,B,C,D) \
|
||||
osg::maximum(fabs(A), osg::maximum(fabs(B), osg::maximum(fabs(C),fabs(D))))
|
||||
|
||||
void
|
||||
TritonHeightMap::update(CameraLocal& local, const osg::Camera* cam, osgEarth::Horizon* horizon)
|
||||
{
|
||||
osg::Vec3d eye = osg::Vec3d(0,0,0) * cam->getInverseViewMatrix();
|
||||
|
||||
double hd = horizon->getDistanceToVisibleHorizon();
|
||||
|
||||
local._rtt->setProjectionMatrix(osg::Matrix::ortho(-hd, hd, -hd, hd, 1.0, eye.length()));
|
||||
local._rtt->setViewMatrixAsLookAt(eye, osg::Vec3d(0.0,0.0,0.0), osg::Vec3d(0.0,0.0,1.0));
|
||||
|
||||
static const osg::Matrixd scaleBias(
|
||||
0.5, 0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0, 0.0,
|
||||
0.0, 0.0, 0.5, 0.0,
|
||||
0.5, 0.5, 0.5, 1.0);
|
||||
|
||||
// Matrix that Triton will use to position the heightmap for sampling.
|
||||
local._texMatrix = local._rtt->getViewMatrix() * local._rtt->getProjectionMatrix() * scaleBias;
|
||||
}
|
||||
|
||||
void
|
||||
TritonHeightMap::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
if (nv.getVisitorType() == nv.CULL_VISITOR)
|
||||
{
|
||||
osgUtil::CullVisitor* cv = osgEarth::Culling::asCullVisitor(nv);
|
||||
const osg::Camera* camera = cv->getCurrentCamera();
|
||||
if (camera)
|
||||
{
|
||||
CameraLocal& local = _local.get(camera);
|
||||
|
||||
if (isConfigurationComplete())
|
||||
{
|
||||
// create the RTT for this camera on first encounter:
|
||||
if (!local._rtt.valid())
|
||||
{
|
||||
setup(local, camera->getName());
|
||||
}
|
||||
|
||||
// only update when the MVPW changes.
|
||||
if (local._mvpw != *cv->getMVPW())
|
||||
{
|
||||
// update the RTT based on the current camera:
|
||||
osg::ref_ptr<Horizon> horizon;
|
||||
ObjectStorage::get(&nv, horizon);
|
||||
update(local, camera, horizon);
|
||||
|
||||
// finally, traverse the camera to build the height map.
|
||||
local._rtt->accept(nv);
|
||||
|
||||
local._frameNum = nv.getFrameStamp()->getFrameNumber();
|
||||
local._mvpw = *cv->getMVPW();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//OE_DEBUG << LC << "Configuration not yet complete..." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TritonHeightMap::getTextureAndMatrix(osg::RenderInfo& ri, GLint& out_texName, osg::Matrix& out_matrix)
|
||||
{
|
||||
if (!isConfigurationComplete())
|
||||
return false;
|
||||
|
||||
CameraLocal& local = _local.get(ri.getCurrentCamera());
|
||||
if (!local._tex.valid())
|
||||
return false;
|
||||
|
||||
// did the texture change?
|
||||
//OE_DEBUG << "FN=" << ri.getState()->getFrameStamp()->getFrameNumber() << "; localFN=" << local._frameNum << std::endl;
|
||||
|
||||
if (ri.getState()->getFrameStamp()->getFrameNumber() > local._frameNum)
|
||||
return false;
|
||||
|
||||
auto cid = GLUtils::getSharedContextID(*ri.getState());
|
||||
osg::Texture::TextureObject* obj = local._tex->getTextureObject(cid);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
out_texName = obj->id();
|
||||
out_matrix = local._texMatrix;
|
||||
return true;
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_HEIGHT_MAP
|
||||
#define OSGEARTH_TRITON_HEIGHT_MAP 1
|
||||
|
||||
#include <osgEarth/Containers>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include <osg/Node>
|
||||
#include <osg/Camera>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
namespace osgEarth {
|
||||
class Horizon;
|
||||
}
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/**
|
||||
* Creates a height map that Triton can use to mask out the ocean where
|
||||
* the terrain is above sea level.
|
||||
*/
|
||||
class TritonHeightMap : public osg::Node
|
||||
{
|
||||
public:
|
||||
|
||||
TritonHeightMap();
|
||||
|
||||
//! Sets the root of the terrain scene graph
|
||||
void setTerrain(osg::Node*);
|
||||
|
||||
//! Sets the masking layer
|
||||
void setMaskLayer(const osgEarth::ImageLayer* layer);
|
||||
|
||||
//! Configure the generator; return success t/f
|
||||
bool configure(unsigned texSize, osg::State& state);
|
||||
|
||||
//! Fetch the heightmap texture and matrix generated for a camera.
|
||||
bool getTextureAndMatrix(osg::RenderInfo&, GLint& out_texName, osg::Matrix& out_matrix);
|
||||
|
||||
//! Mark all height maps (for all cameras) for regeneration
|
||||
void dirty();
|
||||
|
||||
public: // osg::Node
|
||||
|
||||
void traverse(osg::NodeVisitor&);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TritonHeightMap();
|
||||
|
||||
private:
|
||||
|
||||
struct CameraLocal
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> _rtt;
|
||||
osg::ref_ptr<osg::Texture2D> _tex;
|
||||
osg::Matrix _texMatrix;
|
||||
osg::Matrix _mvpw;
|
||||
unsigned _frameNum;
|
||||
};
|
||||
|
||||
typedef osgEarth::PerObjectFastMap<const osg::Camera*, CameraLocal> Locals;
|
||||
|
||||
struct SetDirty : public Locals::Functor
|
||||
{
|
||||
void operator()(CameraLocal&);
|
||||
};
|
||||
|
||||
//! Sets up an RTT camera for the first time
|
||||
void setup(CameraLocal& local, const std::string& name);
|
||||
|
||||
//! Updates an RTT camera for the new view/projection matrices of the camera
|
||||
void update(CameraLocal& local, const osg::Camera*, osgEarth::Horizon*);
|
||||
|
||||
//! Whether FBO configuration has happened yet
|
||||
bool isConfigurationComplete() const;
|
||||
|
||||
//! Figures out the best FBO format on this GPU
|
||||
static bool getBestFBOConfig(osg::State& state, GLint& internalFormat, GLenum& sourceFormat);
|
||||
|
||||
|
||||
Locals _local;
|
||||
osg::observer_ptr<osg::Node> _terrain;
|
||||
unsigned _texSize;
|
||||
GLint _internalFormat;
|
||||
GLenum _sourceFormat;
|
||||
osg::observer_ptr<const osgEarth::ImageLayer> _maskLayer;
|
||||
osg::ref_ptr<osg::Referenced> _terrainCallback;
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::Triton
|
||||
|
||||
#endif // OSGEARTH_TRITON_HEIGHT_MAP
|
@ -1,51 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonIntersections.h"
|
||||
|
||||
using namespace osgEarth;
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
TritonIntersections::TritonIntersections() :
|
||||
_maxRange(1.0, Units::KILOMETERS)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TritonIntersections::setAnchor(const GeoPoint& value)
|
||||
{
|
||||
_anchor = value;
|
||||
|
||||
// zero out the other stuff:
|
||||
_anchor.z() = 0.0;
|
||||
_anchor.altitudeMode() = ALTMODE_ABSOLUTE;
|
||||
}
|
||||
|
||||
void
|
||||
TritonIntersections::addLocalPoint(const osg::Vec3d& p)
|
||||
{
|
||||
_input.push_back(p);
|
||||
_heights.resize(_input.size());
|
||||
_normals.resize(_input.size());
|
||||
}
|
||||
|
||||
void
|
||||
TritonIntersections::setMaxRange(const Distance& range)
|
||||
{
|
||||
_maxRange = range;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_INTERSECTIONS
|
||||
#define OSGEARTH_TRITON_INTERSECTIONS 1
|
||||
|
||||
#include <osgEarth/VisibleLayer>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include "TritonCallback.h"
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/**
|
||||
* Pass this structure to TritonLayer and it will automatically
|
||||
* populate the results with ocean wave intersections (local coordinates
|
||||
* and normals.)
|
||||
*/
|
||||
class TritonIntersections : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
//! Construct an empty set
|
||||
TritonIntersections();
|
||||
|
||||
//! Anchor point for intersectsions in this set. Only the X and Y
|
||||
//! components are used. Any local points you add to this set will
|
||||
//! be in the local coordinate system (LTP) around this anchor point.
|
||||
void setAnchor(const GeoPoint& p);
|
||||
|
||||
//! Adds a point to the intersection set. The point should be in the
|
||||
//! local coordinate system of the anchor point.
|
||||
void addLocalPoint(const osg::Vec3d& p);
|
||||
|
||||
//! Maximum range at which to perform intersections. Beyond this
|
||||
//! range Triton will skip this set. Default is 2km.
|
||||
void setMaxRange(const Distance& value);
|
||||
const Distance& getMaxRange() const { return _maxRange; }
|
||||
|
||||
//! Vector of input local points added by addLocalPoint.
|
||||
const std::vector<osg::Vec3d>& getInput() const { return _input; }
|
||||
|
||||
//! Vector of heights resulting from the intersection tests.
|
||||
const std::vector<float>& getHeights() const { return _heights; }
|
||||
|
||||
//! Vector of normals resulting from the intersection tests.
|
||||
const std::vector<osg::Vec3d>& getNormals() const { return _normals; }
|
||||
|
||||
private:
|
||||
GeoPoint _anchor;
|
||||
std::vector<osg::Vec3d> _input;
|
||||
std::vector<float> _heights;
|
||||
std::vector<osg::Vec3d> _normals;
|
||||
Distance _maxRange;
|
||||
friend class TritonLayerNode;
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // OSGEARTH_TRITON_INTERSECTIONS
|
@ -1,386 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "TritonLayer.h"
|
||||
#include "TritonContext.h"
|
||||
#include "TritonDrawable.h"
|
||||
#include "TritonHeightMap.h"
|
||||
#include "TritonCallback.h"
|
||||
|
||||
#include <osgEarth/MapNode>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include <osgEarth/NodeUtils>
|
||||
#include <osgEarth/ElevationLOD>
|
||||
#include <osgEarth/TerrainEngineNode>
|
||||
#include <osgEarth/VerticalDatum>
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#define LC "[TritonLayer] "
|
||||
|
||||
using namespace osgEarth::Triton;
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
class TritonLayerNode : public osg::Group
|
||||
{
|
||||
public:
|
||||
TritonLayerNode(osgEarth::Triton::TritonLayer* layer,
|
||||
LayerReference<osgEarth::ImageLayer>& mask) :
|
||||
_tritonLayer(layer),
|
||||
_maskLayer(mask),
|
||||
_callback(0L),
|
||||
_needsMapNode(true)
|
||||
{
|
||||
// To detect the map node:
|
||||
ADJUST_UPDATE_TRAV_COUNT(this, +1);
|
||||
|
||||
// Disable bounds culling
|
||||
setCullingActive(false);
|
||||
}
|
||||
|
||||
~TritonLayerNode()
|
||||
{
|
||||
//nop
|
||||
}
|
||||
|
||||
void setUserCallback(osgEarth::Triton::Callback* callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
void dirty()
|
||||
{
|
||||
create();
|
||||
}
|
||||
|
||||
/** MapNode to use; will be discovered automatically if not set here */
|
||||
void setMapNode(osgEarth::MapNode* mapNode)
|
||||
{
|
||||
if (!mapNode)
|
||||
{
|
||||
this->removeChildren(0, this->getNumChildren());
|
||||
_drawable = 0L;
|
||||
_TRITON = 0L;
|
||||
_needsMapNode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mapNode = mapNode;
|
||||
create();
|
||||
}
|
||||
}
|
||||
|
||||
void create()
|
||||
{
|
||||
this->removeChildren(0, this->getNumChildren());
|
||||
_drawable = 0L;
|
||||
|
||||
osg::ref_ptr<osgEarth::MapNode> mapNode;
|
||||
if (!_mapNode.lock(mapNode))
|
||||
return;
|
||||
|
||||
const osgEarth::Map* map = mapNode->getMap();
|
||||
|
||||
// create an object to house Triton data and resources.
|
||||
if (!_TRITON.valid())
|
||||
_TRITON = new TritonContext(_tritonLayer->options());
|
||||
|
||||
if (map)
|
||||
_TRITON->setSRS(map->getSRS());
|
||||
|
||||
if (_callback.valid())
|
||||
_TRITON->setCallback(_callback.get());
|
||||
|
||||
TritonDrawable* drawable = new TritonDrawable(_TRITON.get());
|
||||
_drawable = drawable;
|
||||
_drawable->setNodeMask(TRITON_OCEAN_MASK);
|
||||
drawable->setMaskLayer(_maskLayer.getLayer());
|
||||
this->addChild(_drawable);
|
||||
|
||||
// Place in the depth-sorted bin and set a rendering order.
|
||||
// We want Triton to render after the terrain.
|
||||
_drawable->getOrCreateStateSet()->setRenderBinDetails(
|
||||
_tritonLayer->getRenderBinNumber(),
|
||||
"DepthSortedBin");
|
||||
|
||||
// Install a vdatum for sea level calculations:
|
||||
auto vdatum = VerticalDatum::get(_tritonLayer->options().vdatum().value());
|
||||
if (vdatum)
|
||||
drawable->setVerticalDatum(vdatum);
|
||||
|
||||
// If the user requested a height map, install it now.
|
||||
// Configuration of the height map generator will take place later when
|
||||
// we have a valid graphics context.
|
||||
if (_tritonLayer->getUseHeightMap() == true)
|
||||
{
|
||||
TritonHeightMap* heightMapGen = new TritonHeightMap();
|
||||
heightMapGen->setTerrain(mapNode->getTerrainEngine()->getNode());
|
||||
if (_maskLayer.getLayer())
|
||||
heightMapGen->setMaskLayer(_maskLayer.getLayer());
|
||||
this->addChild(heightMapGen);
|
||||
drawable->setHeightMapGenerator(heightMapGen);
|
||||
}
|
||||
}
|
||||
|
||||
void traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
if (nv.getVisitorType() == nv.UPDATE_VISITOR)
|
||||
{
|
||||
// Find a MapNode in the traversal path if necessary:
|
||||
if (_needsMapNode)
|
||||
{
|
||||
osgEarth::MapNode* mapNode = osgEarth::findInNodePath<osgEarth::MapNode>(nv);
|
||||
if (mapNode)
|
||||
{
|
||||
setMapNode(mapNode);
|
||||
_needsMapNode = false;
|
||||
ADJUST_UPDATE_TRAV_COUNT(this, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (nv.getVisitorType() == nv.CULL_VISITOR && _drawable && _TRITON.valid() && _TRITON->getOcean())
|
||||
{
|
||||
// Update any intersections.
|
||||
// For now this is running in the CULL traversal, which is not ideal.
|
||||
// However the Triton Ocean::GetHeight method requires a pointer to the Triton "camera"
|
||||
// and under our framework this is only available in CULL or DRAW.
|
||||
// Running the intersection in eithe CULL or DRAW will result in a frame
|
||||
// incoherency w.r.t the Triton update() call that updates the ocean state.
|
||||
::Triton::Ocean* ocean = _TRITON->getOcean();
|
||||
|
||||
// Find the TritonCam associated with this osg Cam
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
::Triton::Camera* tritonCam = static_cast<TritonDrawable*>(_drawable)->getTritonCam(cv->getCurrentCamera());
|
||||
|
||||
osg::Vec3d eye = osg::Vec3d(0,0,0) * cv->getCurrentCamera()->getInverseViewMatrix();
|
||||
|
||||
for(std::vector<osg::ref_ptr<TritonIntersections> >::iterator i = _isect.begin();
|
||||
i != _isect.end();
|
||||
++i)
|
||||
{
|
||||
TritonIntersections* ir = i->get();
|
||||
|
||||
// allocate enough space for the output:
|
||||
ir->_input.resize(ir->_input.size());
|
||||
ir->_normals.resize(ir->_input.size());
|
||||
|
||||
osg::Matrix local2world;
|
||||
ir->_anchor.createLocalToWorld(local2world);
|
||||
|
||||
// Make sure it's in range so as not to waste cycles:
|
||||
osg::Vec3d anchor = osg::Vec3d(0,0,0) * local2world;
|
||||
double m = ir->getMaxRange().as(Units::METERS);
|
||||
if ((eye-anchor).length2() > (m))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
osg::Matrix world2local;
|
||||
world2local.invert(local2world);
|
||||
|
||||
for(unsigned i=0; i<ir->_input.size(); ++i)
|
||||
{
|
||||
const osg::Vec3d& local = ir->_input[i];
|
||||
|
||||
// transform the ray to world coordinates
|
||||
osg::Vec3d start = local * local2world;
|
||||
osg::Vec3d dir = osg::Matrix::transform3x3(local2world, osg::Vec3d(0,0,1));
|
||||
|
||||
// intersect the ocean
|
||||
float& out_height = ir->_heights[i];
|
||||
::Triton::Vector3 out_normalT;
|
||||
|
||||
bool ok = ocean->GetHeight(
|
||||
::Triton::Vector3(start.x(), start.y(), start.z()),
|
||||
::Triton::Vector3(dir.x(), dir.y(), dir.z()),
|
||||
out_height,
|
||||
out_normalT,
|
||||
true, // visualCorrelation
|
||||
true, // includeWakes
|
||||
true, // highResolution
|
||||
true, // threadSafe,
|
||||
0L, // intersectionPoint,
|
||||
true, // autoFlip
|
||||
tritonCam);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
// populate the output data in local coordinates
|
||||
osg::Vec3d& normal = ir->_normals[i];
|
||||
normal.set(out_normalT.x, out_normalT.y, out_normalT.z);
|
||||
normal = osg::Matrix::transform3x3(normal, world2local);
|
||||
}
|
||||
else
|
||||
{
|
||||
// todo...what?
|
||||
OE_WARN << "GetHeight returned false dude" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osg::Group::traverse(nv);
|
||||
}
|
||||
|
||||
osg::ref_ptr<TritonContext> _TRITON;
|
||||
osg::Drawable* _drawable;
|
||||
LayerReference<osgEarth::ImageLayer>& _maskLayer;
|
||||
osg::observer_ptr<osgEarth::MapNode> _mapNode;
|
||||
osg::observer_ptr<osgEarth::Triton::TritonLayer> _tritonLayer;
|
||||
osg::ref_ptr<Callback> _callback;
|
||||
bool _needsMapNode;
|
||||
std::vector<osg::ref_ptr<TritonIntersections> > _isect;
|
||||
|
||||
};
|
||||
} }
|
||||
|
||||
//........................................................................
|
||||
|
||||
void
|
||||
TritonLayer::Options::fromConfig(const osgEarth::Config& conf)
|
||||
{
|
||||
conf.get("user", _user);
|
||||
conf.get("license_code", _licenseCode);
|
||||
conf.get("resource_path", _resourcePath);
|
||||
conf.get("use_height_map", _useHeightMap);
|
||||
conf.get("height_map_size", _heightMapSize);
|
||||
conf.get("render_bin_number", _renderBinNumber);
|
||||
conf.get("max_altitude", _maxAltitude);
|
||||
conf.get("vdatum", vdatum());
|
||||
maskLayer().get(conf, "mask_layer");
|
||||
}
|
||||
|
||||
osgEarth::Config
|
||||
TritonLayer::Options::getConfig() const
|
||||
{
|
||||
osgEarth::Config conf = osgEarth::VisibleLayer::Options::getConfig();
|
||||
conf.set("user", _user);
|
||||
conf.set("license_code", _licenseCode);
|
||||
conf.set("resource_path", _resourcePath);
|
||||
conf.set("use_height_map", _useHeightMap);
|
||||
conf.set("height_map_size", _heightMapSize);
|
||||
conf.set("render_bin_number", _renderBinNumber);
|
||||
conf.set("max_altitude", _maxAltitude);
|
||||
conf.set("vdatum", vdatum());
|
||||
maskLayer().set(conf, "mask_layer");
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
|
||||
/** Register this layer so it can be used in an earth file */
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
REGISTER_OSGEARTH_LAYER(triton, TritonLayer);
|
||||
REGISTER_OSGEARTH_LAYER(triton_ocean, TritonLayer);
|
||||
} }
|
||||
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, UserName, user);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, LicenseCode, licenseCode);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, ResourcePath, resourcePath);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, bool, UseHeightMap, useHeightMap);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, unsigned, HeightMapSize, heightMapSize);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, int, RenderBinNumber, renderBinNumber);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, float, MaxAltitude, maxAltitude);
|
||||
OE_LAYER_PROPERTY_IMPL(TritonLayer, std::string, VerticalDatum, vdatum);
|
||||
|
||||
void
|
||||
TritonLayer::init()
|
||||
{
|
||||
super::init();
|
||||
|
||||
_seaLevel = 0.0f;
|
||||
|
||||
// Trick to force the VisibleLayer to install its opacity shader,
|
||||
// which a modified Triton user-functions.glsl shader needs in order to control
|
||||
// sea surface opacity.
|
||||
float opacity = getOpacity();
|
||||
setOpacity(0.0f);
|
||||
setOpacity(opacity);
|
||||
|
||||
this->setName("Triton");
|
||||
setRenderType(RENDERTYPE_CUSTOM);
|
||||
|
||||
ElevationLOD* lod = new ElevationLOD();
|
||||
_root = lod;
|
||||
if (options().maxAltitude().isSet())
|
||||
{
|
||||
OE_DEBUG << LC << "Setting max altitude = " << options().maxAltitude().get() << std::endl;
|
||||
lod->setMaxElevation(options().maxAltitude().get());
|
||||
}
|
||||
|
||||
_tritonNode = new TritonLayerNode(this, options().maskLayer());
|
||||
_root->addChild(_tritonNode.get());
|
||||
}
|
||||
|
||||
void
|
||||
TritonLayer::setUserCallback(Callback* callback)
|
||||
{
|
||||
static_cast<TritonLayerNode*>(_tritonNode.get())->setUserCallback(callback);
|
||||
}
|
||||
|
||||
osg::Node*
|
||||
TritonLayer::getNode() const
|
||||
{
|
||||
return _root.get();
|
||||
}
|
||||
|
||||
void
|
||||
TritonLayer::setMaskLayer(osgEarth::ImageLayer* maskLayer)
|
||||
{
|
||||
options().maskLayer().setLayer(maskLayer);
|
||||
static_cast<TritonLayerNode*>(_tritonNode.get())->dirty();
|
||||
}
|
||||
|
||||
osgEarth::ImageLayer*
|
||||
TritonLayer::getMaskLayer() const
|
||||
{
|
||||
return options().maskLayer().getLayer();
|
||||
}
|
||||
|
||||
void
|
||||
TritonLayer::addedToMap(const osgEarth::Map* map)
|
||||
{
|
||||
VisibleLayer::addedToMap(map);
|
||||
options().maskLayer().addedToMap(map);
|
||||
}
|
||||
|
||||
void
|
||||
TritonLayer::removedFromMap(const osgEarth::Map* map)
|
||||
{
|
||||
VisibleLayer::removedFromMap(map);
|
||||
options().maskLayer().removedFromMap(map);
|
||||
setMaskLayer(0L);
|
||||
}
|
||||
|
||||
void
|
||||
TritonLayer::addIntersections(TritonIntersections* value)
|
||||
{
|
||||
TritonLayerNode* node = static_cast<TritonLayerNode*>(_tritonNode.get());
|
||||
node->_isect.push_back(value);
|
||||
}
|
||||
|
||||
osgEarth::Config
|
||||
TritonLayer::getConfig() const
|
||||
{
|
||||
osgEarth::Config c = osgEarth::VisibleLayer::getConfig();
|
||||
return c;
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/* -*-c++-*- */
|
||||
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||||
* Copyright 2020 Pelican Mapping
|
||||
* http://osgearth.org
|
||||
*
|
||||
* osgEarth is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef OSGEARTH_TRITON_LAYER
|
||||
#define OSGEARTH_TRITON_LAYER 1
|
||||
|
||||
#include <osgEarth/VisibleLayer>
|
||||
#include <osgEarth/LayerReference>
|
||||
#include <osgEarth/ImageLayer>
|
||||
#include "TritonCallback.h"
|
||||
#include "TritonIntersections.h"
|
||||
|
||||
namespace osgEarth { namespace Triton
|
||||
{
|
||||
/**
|
||||
* Node that roots the Triton adapter.
|
||||
*/
|
||||
class TritonLayer : public osgEarth::VisibleLayer
|
||||
{
|
||||
public:
|
||||
class Options : public osgEarth::VisibleLayer::Options {
|
||||
public:
|
||||
META_LayerOptions(osgEarth, Options, osgEarth::VisibleLayer::Options);
|
||||
OE_OPTION(std::string, user);
|
||||
OE_OPTION(std::string, licenseCode);
|
||||
OE_OPTION(std::string, resourcePath);
|
||||
OE_OPTION(bool, useHeightMap, true);
|
||||
OE_OPTION(unsigned, heightMapSize, 1024);
|
||||
OE_OPTION(int, renderBinNumber, 12);
|
||||
OE_OPTION(float, maxAltitude, 50000.0f);
|
||||
OE_OPTION(std::string, vdatum, "egm96");
|
||||
OE_OPTION_LAYER(osgEarth::ImageLayer, maskLayer);
|
||||
virtual Config getConfig() const;
|
||||
private:
|
||||
void fromConfig(const Config& conf);
|
||||
};
|
||||
|
||||
public:
|
||||
META_Layer(osgEarth, TritonLayer, Options, osgEarth::VisibleLayer, triton);
|
||||
|
||||
//! Sets the user callback that's invoked when Triton start up
|
||||
void setUserCallback(Triton::Callback* callback);
|
||||
|
||||
//! User name for license
|
||||
void setUserName(const std::string& value);
|
||||
const std::string& getUserName() const;
|
||||
|
||||
//! License code
|
||||
void setLicenseCode(const std::string& value);
|
||||
const std::string& getLicenseCode() const;
|
||||
|
||||
//! Triton resource path
|
||||
void setResourcePath(const std::string& value);
|
||||
const std::string& getResourcePath() const;
|
||||
|
||||
//! Whether to use a height map to fade out the ocean at the coastline
|
||||
void setUseHeightMap(const bool& value);
|
||||
const bool& getUseHeightMap() const;
|
||||
|
||||
//! Size in texels of the height map (each dimension)
|
||||
void setHeightMapSize(const unsigned& value);
|
||||
const unsigned& getHeightMapSize() const;
|
||||
|
||||
//! Render bin number to use for the ocean rendering
|
||||
void setRenderBinNumber(const int& value);
|
||||
const int& getRenderBinNumber() const;
|
||||
|
||||
//! Masking layer for the ocean
|
||||
void setMaskLayer(osgEarth::ImageLayer* maskLayer);
|
||||
osgEarth::ImageLayer* getMaskLayer() const;
|
||||
|
||||
//! Maximum visibility altitude
|
||||
void setMaxAltitude(const float& value);
|
||||
const float& getMaxAltitude() const;
|
||||
|
||||
//! Vertical datum to use to calculate sea level
|
||||
void setVerticalDatum(const std::string& value);
|
||||
const std::string& getVerticalDatum() const;
|
||||
|
||||
//! Adds an intersection set.
|
||||
//! Each frame, Triton will perform intersections against the ocean surface
|
||||
//! (including the waves) and populate the set with the results.
|
||||
void addIntersections(TritonIntersections*);
|
||||
|
||||
public: // Layer
|
||||
|
||||
virtual osg::Node* getNode() const;
|
||||
|
||||
//! Serialize
|
||||
virtual Config getConfig() const;
|
||||
|
||||
protected: // Layer
|
||||
|
||||
virtual void init();
|
||||
|
||||
virtual void addedToMap(const class osgEarth::Map*);
|
||||
|
||||
virtual void removedFromMap(const class osgEarth::Map*);
|
||||
|
||||
private:
|
||||
|
||||
osg::ref_ptr<osg::Group> _root;
|
||||
osg::ref_ptr<osg::Node> _tritonNode;
|
||||
float _seaLevel;
|
||||
float _opacity;
|
||||
};
|
||||
|
||||
} } // namespace osgEarth::Triton
|
||||
|
||||
#endif // OSGEARTH_TRITON_LAYER
|
@ -1,153 +1,73 @@
|
||||
#include "CompositeHandle.h"
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
#include "CompositeWidgetManager.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
CompositeHandle::CompositeHandle(CompositeWidgetManager* cw) :_cw(cw),
|
||||
_operate(cw->GetcanvasO()),
|
||||
_N(cw->GetcanvasN()),
|
||||
_light(cw->GetcanvasFX()),
|
||||
_background(cw->GetcanvasBackGround()),
|
||||
_num(0),
|
||||
_move(false)
|
||||
{
|
||||
#define M_PI 3.14159265358979323846 /* mathematical constant pi */
|
||||
|
||||
///Radian to degree conversion factor
|
||||
static const double RAD2DEG = 180.0 / M_PI;
|
||||
///Degree to radian conversion factor
|
||||
static const double DEG2RAD = M_PI / 180.0;
|
||||
|
||||
inline double angFix360(double in) {
|
||||
in -= 45.0;
|
||||
if ((in < 0.0) || (in >= 360.0)) {
|
||||
in = fmod(in, 360.0);
|
||||
|
||||
if (in < 0.0)
|
||||
in += 360.0;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
CompositeHandle::~CompositeHandle(void)
|
||||
{
|
||||
inline bool areEqual(double a, double b, double t = 1.0e-6) {
|
||||
return fabs(a - b) < t;
|
||||
}
|
||||
|
||||
CompositeHandle::CompositeHandle(CompositeWidgetManager* cw)
|
||||
: _cw(cw),
|
||||
_operate(cw->GetcanvasO()),
|
||||
_N(cw->GetcanvasN()),
|
||||
_light(cw->GetcanvasFX()),
|
||||
_background(cw->GetcanvasBackGround()),
|
||||
_num(0),
|
||||
_move(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool CompositeHandle::handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter& aa)
|
||||
{
|
||||
if (_num != 0)
|
||||
{
|
||||
_cw->_local_y = sin(_angle);
|
||||
_cw->_local_x = cos(_angle);
|
||||
|
||||
_angle = _angle + _num;
|
||||
_cw->SendPosition();
|
||||
|
||||
if ((_num >= 0 && _angle >= osg::PI_2) || (_num < 0 && _angle < osg::PI_2))
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::FRAME) {
|
||||
constexpr double TWO_DECIMAL_PLACES = 1e-02;
|
||||
double heading = 0.0;
|
||||
osgViewer::View* activeView = static_cast<osgViewer::View*>(aa.asView());
|
||||
const osgEarth::Util::EarthManipulator* manip = dynamic_cast<const osgEarth::Util::EarthManipulator*>(activeView->getCameraManipulator());
|
||||
if (manip != NULL)
|
||||
{
|
||||
_cw->_local_y = sin(osg::PI_2);
|
||||
_cw->_local_x = cos(osg::PI_2);
|
||||
|
||||
_cw->SendPosition();
|
||||
|
||||
_num = 0;
|
||||
_cw->_autoHome = false;
|
||||
_cw->_N = false;
|
||||
manip->getCompositeEulerAngles(&heading);
|
||||
// Convert to degrees
|
||||
heading = angFix360(heading * RAD2DEG);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ea.getEventType())
|
||||
else
|
||||
{
|
||||
case osgGA::GUIEventAdapter::DRAG:
|
||||
{
|
||||
if (_cw->_state == CompositeWidgetManager::MOUSE_DRAG)
|
||||
{
|
||||
_cw->SendPosition();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case osgGA::GUIEventAdapter::PUSH:
|
||||
{
|
||||
_cw->_N = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case osgGA::GUIEventAdapter::DOUBLECLICK:
|
||||
{
|
||||
if (_cw->_N == true)
|
||||
{
|
||||
_num = (45 - _N->getRotate())*osg::PI / (100 * 180);
|
||||
|
||||
if (_num != 0)
|
||||
{
|
||||
_angle = (_N->getRotate() - 45)*osg::PI / 180 + osg::PI_2;
|
||||
|
||||
_cw->_autoHome = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (ea.getX() >= _cw->_center_x - 42 &&
|
||||
ea.getX() < _cw->_center_x + 42 &&
|
||||
ea.getY() > _cw->_center_y - 42 &&
|
||||
ea.getY() < _cw->_center_y + 42)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
// Fall back to the viewpoint's heading
|
||||
heading = angFix360(manip->getViewpoint().heading()->as(osgEarth::Units::DEGREES));
|
||||
}
|
||||
|
||||
switch (_cw->_state)
|
||||
{
|
||||
case CompositeWidgetManager::MOUSE_PUSH:
|
||||
{
|
||||
if (_cw->_N != true || _cw->_autoHome == false)
|
||||
{
|
||||
_cw->SendPosition();
|
||||
// make sure that anything equivalent to 0.00 is displayed as 0.00
|
||||
if (areEqual(heading, 0.0, TWO_DECIMAL_PLACES) || areEqual(heading, 360.0, TWO_DECIMAL_PLACES)) {
|
||||
heading = 0.0;
|
||||
}
|
||||
|
||||
if (_cw->_local_y < 0)
|
||||
{
|
||||
if (_cw->_local_x > 0)
|
||||
{
|
||||
_light->setRotate(45 - (180 - 90 * asinf(_cw->_local_x / sqrtf(_cw->_local_x*_cw->_local_x + _cw->_local_y*_cw->_local_y)) / osg::PI_2));
|
||||
}
|
||||
else
|
||||
{
|
||||
_light->setRotate(45 - (-180 - 90 * asinf(_cw->_local_x / sqrtf(_cw->_local_x*_cw->_local_x + _cw->_local_y*_cw->_local_y)) / osg::PI_2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_light->setRotate(45 - 90 * asinf(_cw->_local_x / sqrtf(_cw->_local_x*_cw->_local_x + _cw->_local_y*_cw->_local_y)) / osg::PI_2);
|
||||
}
|
||||
|
||||
_light->getByName("light")->setColor(1, 1, 1, 0.5);
|
||||
_light->resize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CompositeWidgetManager::MOUSE_RELEASE:
|
||||
if (!areEqual(_N->getRotate(), -heading, TWO_DECIMAL_PLACES))
|
||||
{
|
||||
_cw->_state = CompositeWidgetManager::DEFAULT;
|
||||
|
||||
_light->getByName("light")->setColor(1, 1, 1, 0);
|
||||
break;
|
||||
}
|
||||
case CompositeWidgetManager::MOUSE_DRAG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (ea.getX() > _cw->_center_x - 50 &&
|
||||
ea.getY() > _cw->_center_y - 200)
|
||||
{
|
||||
if (_cw->_center == 1)
|
||||
{
|
||||
_operate->getByName("center")->setColor(1, 1, 1, 1);
|
||||
}
|
||||
_background->getByName("backGround4")->setColor(1, 1, 1, 1);
|
||||
}
|
||||
else {
|
||||
if (_cw->_center == 1)
|
||||
{
|
||||
_operate->getByName("center")->setColor(1, 1, 1, 0.1);
|
||||
}
|
||||
_background->getByName("backGround4")->setColor(1, 1, 1, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
_N->setRotate(-heading);
|
||||
_N->update();
|
||||
}
|
||||
}
|
||||
// compass_->update_();
|
||||
|
||||
return false;
|
||||
}
|
@ -14,9 +14,9 @@ class CompositeHandle :public osgGA::GUIEventHandler
|
||||
public:
|
||||
CompositeHandle(CompositeWidgetManager* cw);
|
||||
|
||||
~CompositeHandle(void);
|
||||
~CompositeHandle(void) override = default;
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&);
|
||||
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&) override;
|
||||
|
||||
private:
|
||||
osgWidget::Canvas* _operate;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "CompositeWidgetManager.h"
|
||||
|
||||
#include "BackGroundWidget.h"
|
||||
#include "common/RecourceHelper.h"
|
||||
#include "viewer/OsgViewUI.h"
|
||||
|
||||
@ -114,7 +115,7 @@ void CompositeWidgetManager::ResetCanvasPosition(double x, double y)
|
||||
|
||||
void CompositeWidgetManager::SendPosition()
|
||||
{
|
||||
_mouseDirection = osg::Vec2(_local_x, _local_y);
|
||||
_mouseDirection = osg::Vec2(static_cast<float>(_local_x), static_cast<float>(_local_y));
|
||||
if (_center == 0 && _state != CompositeWidgetManager::MOUSE_DRAG && _autoHome != true)
|
||||
{
|
||||
QVariantList varList;
|
||||
@ -127,13 +128,14 @@ void CompositeWidgetManager::SendPosition()
|
||||
QVariantList varList;
|
||||
varList.push_back(QVariant(_mouseDirection.x()));
|
||||
varList.push_back(QVariant(_mouseDirection.y()));
|
||||
|
||||
//emit signalHeading(QVariant(varList));
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Vec2 pos = _mouseDirection;
|
||||
pos[0] = pos.x()* 0.2;
|
||||
pos[1] = pos.y()* 0.1;
|
||||
pos[0] = pos.x()* 0.2f;
|
||||
pos[1] = pos.y()* 0.1f;
|
||||
|
||||
QVariantList varList;
|
||||
varList.push_back(QVariant(pos.x()));
|
||||
@ -142,8 +144,7 @@ void CompositeWidgetManager::SendPosition()
|
||||
}
|
||||
}
|
||||
|
||||
void CompositeWidgetManager::SetHeading(double angle)
|
||||
{
|
||||
void CompositeWidgetManager::SetHeading(double angle) {
|
||||
_canvasN->setRotate(angle + 45);
|
||||
_canvasN->update();
|
||||
}
|
||||
@ -156,6 +157,13 @@ void CompositeWidgetManager::AttachViewUI(OsgViewUI* ui) {
|
||||
ui->addChild(_canvasBackGround);
|
||||
}
|
||||
|
||||
void CompositeWidgetManager::AttachViewUI(osgWidget::WindowManager* ui) {
|
||||
ui->addChild(_canvasO);
|
||||
ui->addChild(_canvasN);
|
||||
ui->addChild(_canvasFX);
|
||||
ui->addChild(_canvasBackGround);
|
||||
}
|
||||
|
||||
//void CompositeWidgetManager::slotHeading(double angle)
|
||||
//{
|
||||
// SetHeading(angle);
|
||||
|
@ -1,13 +1,9 @@
|
||||
#ifndef CompositeWidgetManager_h__
|
||||
#define CompositeWidgetManager_h__
|
||||
|
||||
#include "BackGroundWidget.h"
|
||||
#include "CompositeHandle.h"
|
||||
|
||||
#include "CompositeWidget.h"
|
||||
#include "ZoomWidget.h"
|
||||
#include "ZoomHandle.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
@ -35,6 +31,7 @@ public:
|
||||
}
|
||||
|
||||
void AttachViewUI(class OsgViewUI* ui);
|
||||
void AttachViewUI(osgWidget::WindowManager* ui);
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -29,13 +29,13 @@ void OESceneUI::InitUI(OsgViewUI* ui) {
|
||||
|
||||
compositeWidgetManager_ = new CompositeWidgetManager();
|
||||
compositeWidgetManager_->AttachViewUI(ui);
|
||||
zoomManager_ = new ZoomManager();
|
||||
zoomManager_->AttachViewUI(ui);
|
||||
//zoomManager_ = new ZoomManager(oeScene_);
|
||||
//zoomManager_->AttachViewUI(ui);
|
||||
|
||||
queryElevationWidget_ = new QueryElevationWidget(oeScene_);
|
||||
queryElevationWidget_->AttachViewUI(ui);
|
||||
|
||||
ui->getView()->addEventHandler(new ZoomHandle(zoomManager_, compositeWidgetManager_));
|
||||
//ui->getView()->addEventHandler(new ZoomHandle(zoomManager_, compositeWidgetManager_));
|
||||
ui->getView()->addEventHandler(new CompositeHandle(compositeWidgetManager_));
|
||||
|
||||
isInit_ = true;
|
||||
@ -44,9 +44,9 @@ void OESceneUI::InitUI(OsgViewUI* ui) {
|
||||
|
||||
void OESceneUI::OnResize(double width, double height) {
|
||||
dyt_check(compositeWidgetManager_);
|
||||
dyt_check(zoomManager_);
|
||||
//dyt_check(zoomManager_);
|
||||
|
||||
compositeWidgetManager_->ResetCanvasPosition(width, height);
|
||||
zoomManager_->ResetCanvasPosition(width, height);
|
||||
//zoomManager_->ResetCanvasPosition(width, height);
|
||||
queryElevationWidget_->ResetCanvasPosition(width, height);
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ private:
|
||||
class OEScene* oeScene_;
|
||||
bool isInit_{ false };
|
||||
osg::ref_ptr<class CompositeWidgetManager> compositeWidgetManager_{ nullptr };
|
||||
osg::ref_ptr<class ZoomManager> zoomManager_{ nullptr };
|
||||
//osg::ref_ptr<class ZoomManager> zoomManager_{ nullptr };
|
||||
osg::ref_ptr<class QueryElevationWidget> queryElevationWidget_{ nullptr };
|
||||
};
|
||||
|
@ -1,11 +1,15 @@
|
||||
#include "ZoomManager.h"
|
||||
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
|
||||
#include "config.h"
|
||||
#include "common/SpdLogger.h"
|
||||
#include "viewer/OsgViewUI.h"
|
||||
#include "common/RecourceHelper.h"
|
||||
#include "scene/OEScene.h"
|
||||
|
||||
ZoomManager::ZoomManager(void)
|
||||
ZoomManager::ZoomManager(OEScene* oeScene)
|
||||
: oeScene_(oeScene)
|
||||
{
|
||||
zoom = 0.0;
|
||||
state = ZoomManager::DEFAULT;
|
||||
@ -17,12 +21,20 @@ ZoomManager::ZoomManager(void)
|
||||
_canvasZoom->setStrata(osgWidget::Window::STRATA_FOREGROUND);
|
||||
|
||||
const std::string texturePath = RecourceHelper::Get().GetResourcesPath().toStdString();
|
||||
_lessen = new ZoomWidget("lessen", 18, 20, texturePath + "/northarrow/zoom_down.png", "lessen", osgWidget::Widget::LAYER_TOP, this);
|
||||
_enlargement = new ZoomWidget("enlargement", 18, 20, texturePath + "/northarrow/zoom_up.png", "enlargement", osgWidget::Widget::LAYER_TOP, this);
|
||||
_zoomBackground = new BackGroundWidget("zoomBackground", 18, 144, texturePath + "/northarrow/zoomactive.png");
|
||||
_bar = new ZoomWidget("bar", 17, 10, texturePath + "/northarrow/zoombar_norm.png", "bar", osgWidget::Widget::LAYER_TOP, this);
|
||||
_bar_ = new BackGroundWidget("bar_", 18, 12, texturePath + "/northarrow/zoombar_norm_.png");
|
||||
_zoomBackground_shadow = new BackGroundWidget("background_shadow", 18, 144, texturePath + "/northarrow/zoombackground.png");
|
||||
_lessen = new ZoomWidget("lessen", 18, 20, texturePath + "/northarrow/zoom_down.png",
|
||||
"lessen", osgWidget::Widget::LAYER_TOP, this);
|
||||
_enlargement = new ZoomWidget("enlargement", 18, 20,
|
||||
texturePath + "/northarrow/zoom_up.png", "enlargement",
|
||||
osgWidget::Widget::LAYER_TOP, this);
|
||||
_zoomBackground = new BackGroundWidget("zoomBackground", 18, 144,
|
||||
texturePath + "/northarrow/zoomactive.png");
|
||||
_bar = new ZoomWidget("bar", 17, 10,
|
||||
texturePath + "/northarrow/zoombar_norm.png", "bar",
|
||||
osgWidget::Widget::LAYER_TOP, this);
|
||||
_bar_ = new BackGroundWidget("bar_", 18, 12,
|
||||
texturePath + "/northarrow/zoombar_norm_.png");
|
||||
_zoomBackground_shadow = new BackGroundWidget("background_shadow", 18, 144,
|
||||
texturePath + "/northarrow/zoombackground.png");
|
||||
|
||||
_canvasZoom->addWidget(_lessen, 0, 0);
|
||||
_canvasZoom->addWidget(_enlargement, 0, 124);
|
||||
@ -54,7 +66,7 @@ void ZoomManager::ResetCanvasPosition(double x, double y)
|
||||
void ZoomManager::SendZoom()
|
||||
{
|
||||
_zoomNum[0] = zoom;
|
||||
|
||||
slotZoom();
|
||||
//emit signalZoom(QVariant(_zoomNum[0]));
|
||||
}
|
||||
|
||||
@ -63,3 +75,51 @@ void ZoomManager::AttachViewUI(OsgViewUI* ui) {
|
||||
|
||||
ui->addChild(_canvasZoom);
|
||||
}
|
||||
|
||||
|
||||
void ZoomManager::slotZoom() {
|
||||
double val = _zoomNum[0];
|
||||
double dx = val*(-1.0)*(0.0005);// dx不起作用
|
||||
double dy = val*(-1.0)*(0.0005);
|
||||
|
||||
return;
|
||||
|
||||
// dx *= getSettings()->getMouseSensitivity();
|
||||
// dy *= getSettings()->getMouseSensitivity();
|
||||
|
||||
double minAlt = 500.0;
|
||||
double maxAlt = 35000000.0;
|
||||
auto em = oeScene_->GetManipulater();
|
||||
auto vp = em->getViewpoint();
|
||||
vp.setRange(vp.getRange() * 1.1);
|
||||
em->setViewpoint(vp);
|
||||
//
|
||||
// double scale = 1.0f + dy;
|
||||
// double distance = em->getDistance() * scale;
|
||||
// distance = std::max(distance, maxAlt);
|
||||
//
|
||||
// // if (!OEScene::GetSrs()->isGeographic())
|
||||
// // {
|
||||
// // osg::Viewport* vp = oeScene_->GetViewport();
|
||||
// // if (vp)
|
||||
// // {
|
||||
// // double ar = vp->width() / vp->height();
|
||||
// // double y = distance * tan(0.5*osg::DegreesToRadians(em->));
|
||||
// // double x = y * ar;
|
||||
// //
|
||||
// // osgEarth::GeoExtent extentMap = oeScene_->getMap()->getProfile()->getExtent();
|
||||
// //
|
||||
// // if ((_center.y() - y) < extentMap.yMin())
|
||||
// // {
|
||||
// // return;
|
||||
// // }
|
||||
// // if ((_center.y() + y) > extentMap.yMax())
|
||||
// // {
|
||||
// // return;
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// em->setDistance(distance);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
class ZoomManager : public osg::Referenced {
|
||||
public:
|
||||
ZoomManager(void);
|
||||
ZoomManager(class OEScene* oeScene);
|
||||
~ZoomManager(void);
|
||||
|
||||
void ResetCanvasPosition(double x, double y);
|
||||
@ -21,12 +21,18 @@ public:
|
||||
osgWidget::Canvas* GetCanvasZoom() {
|
||||
return _canvasZoom;
|
||||
}
|
||||
osgWidget::Widget* GetBar() const {
|
||||
return _bar;
|
||||
}
|
||||
|
||||
void AttachViewUI(class OsgViewUI* ui);
|
||||
//
|
||||
//signals:
|
||||
// void signalZoom(QVariant var);
|
||||
|
||||
protected:
|
||||
void slotZoom();
|
||||
|
||||
private:
|
||||
osgWidget::Canvas* _canvasZoom;
|
||||
|
||||
@ -39,6 +45,8 @@ private:
|
||||
|
||||
int _zoomNum[1];
|
||||
|
||||
class OEScene* oeScene_;
|
||||
|
||||
public:
|
||||
enum STATE {
|
||||
MOUSE_PUSH,
|
||||
|
@ -30,10 +30,6 @@ ZoomWidget::ZoomWidget(std::string name,
|
||||
_pZoomManager = pZoomManager;
|
||||
}
|
||||
|
||||
ZoomWidget::~ZoomWidget(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool ZoomWidget::mousePush(double x, double y, const osgWidget::WindowManager* wm)
|
||||
{
|
||||
_pZoomManager->state = ZoomManager::MOUSE_PUSH;
|
||||
@ -42,11 +38,14 @@ bool ZoomWidget::mousePush(double x, double y, const osgWidget::WindowManager*
|
||||
if ("lessen" == _order)
|
||||
{
|
||||
_pZoomManager->zoom = -43;
|
||||
UpdateBarPosition(_pZoomManager->zoom);
|
||||
}
|
||||
else if ("enlargement" == _order)
|
||||
{
|
||||
_pZoomManager->zoom = 43;
|
||||
UpdateBarPosition(_pZoomManager->zoom);
|
||||
}
|
||||
|
||||
setColor(1, 1, 1, 1);
|
||||
return false;
|
||||
}
|
||||
@ -55,48 +54,55 @@ bool ZoomWidget::mouseRelease(double x, double y, const osgWidget::WindowManager
|
||||
{
|
||||
_pZoomManager->state = ZoomManager::MOUSE_RELEASE;
|
||||
|
||||
if ("bar" == _order)
|
||||
{
|
||||
setOrigin(0, 67);
|
||||
getParent()->getByName("bar_")->setOrigin(0, 66);
|
||||
getParent()->resize();
|
||||
}
|
||||
//if ("bar" == _order)
|
||||
//{
|
||||
// setOrigin(0, 67);
|
||||
// getParent()->getByName("bar_")->setOrigin(0, 66);
|
||||
// getParent()->resize();
|
||||
//}
|
||||
_pZoomManager->zoom = 0.0;
|
||||
UpdateBarPosition(_pZoomManager->zoom);
|
||||
setColor(1, 1, 1, 0);
|
||||
return false;
|
||||
}
|
||||
//
|
||||
//bool ZoomWidget::mouseDrag(double x, double y, const osgWidget::WindowManager* wm)
|
||||
//{
|
||||
// if (_order == "bar")
|
||||
// {
|
||||
// _pointX += x;
|
||||
// _pointY += y;
|
||||
//
|
||||
// while (_pZoomManager->zoom > 43)
|
||||
// _pZoomManager->zoom = 43;
|
||||
// while (_pZoomManager->zoom < -43)
|
||||
// _pZoomManager->zoom = -43;
|
||||
//
|
||||
// if (y > 43 - _pZoomManager->zoom)
|
||||
// {
|
||||
// y = 43 - _pZoomManager->zoom;
|
||||
// }
|
||||
// if (y < -43 - _pZoomManager->zoom)
|
||||
// {
|
||||
// y = -43 - _pZoomManager->zoom;
|
||||
// }
|
||||
//
|
||||
// if (_pZoomManager->zoom >= -43 && _pZoomManager->zoom <= 43)
|
||||
// {
|
||||
// /*addOrigin(0, y);
|
||||
// getParent()->getByName("bar_")->addOrigin(0, y);*/
|
||||
// double y1 = _pZoomManager->GetBar()->getOrigin().y();
|
||||
// UpdateBarPosition(y + y1);
|
||||
// _pZoomManager->zoom += y;
|
||||
// }
|
||||
// else {
|
||||
// _pZoomManager->zoom += y;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
|
||||
bool ZoomWidget::mouseDrag(double x, double y, const osgWidget::WindowManager* wm)
|
||||
{
|
||||
if (_order == "bar")
|
||||
{
|
||||
_pointX += x;
|
||||
_pointY += y;
|
||||
|
||||
while (_pZoomManager->zoom > 43)
|
||||
_pZoomManager->zoom = 43;
|
||||
while (_pZoomManager->zoom < -43)
|
||||
_pZoomManager->zoom = -43;
|
||||
|
||||
if (y > 43 - _pZoomManager->zoom)
|
||||
{
|
||||
y = 43 - _pZoomManager->zoom;
|
||||
}
|
||||
if (y < -43 - _pZoomManager->zoom)
|
||||
{
|
||||
y = -43 - _pZoomManager->zoom;
|
||||
}
|
||||
|
||||
if (_pZoomManager->zoom >= -43 && _pZoomManager->zoom <= 43)
|
||||
{
|
||||
addOrigin(0, y);
|
||||
getParent()->getByName("bar_")->addOrigin(0, y);
|
||||
_pZoomManager->zoom += y;
|
||||
}
|
||||
else {
|
||||
_pZoomManager->zoom += y;
|
||||
}
|
||||
getParent()->resize();
|
||||
}
|
||||
return true;
|
||||
void ZoomWidget::UpdateBarPosition(double y) {
|
||||
_pZoomManager->GetBar()->setOrigin(0, 67 + y * 0.5);
|
||||
_pZoomManager->GetCanvasZoom()->update();
|
||||
}
|
@ -21,15 +21,16 @@ public:
|
||||
osgWidget::Widget::Layer layer,
|
||||
ZoomManager *pZoomManager);
|
||||
|
||||
~ZoomWidget(void);
|
||||
~ZoomWidget(void) override = default;
|
||||
|
||||
bool mousePush(double, double, const osgWidget::WindowManager*);
|
||||
bool mouseRelease(double, double, const osgWidget::WindowManager*);
|
||||
bool mouseDrag(double, double, const osgWidget::WindowManager*);
|
||||
//bool mouseDrag(double, double, const osgWidget::WindowManager*);
|
||||
|
||||
std::string GetOrder() { return _order; }
|
||||
double GetPointerX() { return _pointX; }
|
||||
double GetpointerY() { return _pointY; }
|
||||
void UpdateBarPosition(double y);
|
||||
|
||||
private:
|
||||
double _pointX;
|
||||
|
@ -267,6 +267,22 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Dialog</name>
|
||||
<message>
|
||||
<location filename="../ui/Dialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DialogTitleBar</name>
|
||||
<message>
|
||||
<location filename="../ui/DialogTitleBar.ui" line="14"/>
|
||||
<source>DialogTitleBar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DockChildList</name>
|
||||
<message>
|
||||
@ -356,7 +372,7 @@
|
||||
<message>
|
||||
<location filename="../ui/Menu/FileManagerMenu.ui" line="20"/>
|
||||
<source>new workspace</source>
|
||||
<translation type="unfinished">新建空间</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/FileManagerMenu.ui" line="30"/>
|
||||
@ -386,7 +402,7 @@
|
||||
<message>
|
||||
<location filename="../ui/Menu/FileManagerMenu.cpp" line="65"/>
|
||||
<source>warning</source>
|
||||
<translation type="unfinished">警告</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/FileManagerMenu.cpp" line="65"/>
|
||||
@ -428,17 +444,17 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="114"/>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="136"/>
|
||||
<source>default</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="114"/>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="136"/>
|
||||
<source>silver</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="114"/>
|
||||
<location filename="../ui/FrameTitleBar.cpp" line="136"/>
|
||||
<source>blue</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -454,33 +470,29 @@
|
||||
<context>
|
||||
<name>MainFrame</name>
|
||||
<message>
|
||||
<location filename="../ui/MainFrame.cpp" line="42"/>
|
||||
<location filename="../ui/MainFrame.cpp" line="43"/>
|
||||
<source>Dyt</source>
|
||||
<translation>Dyt</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainFrame.cpp" line="101"/>
|
||||
<location filename="../ui/MainFrame.cpp" line="102"/>
|
||||
<source>file manager</source>
|
||||
<translation>文件管理</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainFrame.cpp" line="107"/>
|
||||
<location filename="../ui/MainFrame.cpp" line="108"/>
|
||||
<source>simu manager</source>
|
||||
<translation>仿真管理</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainFrame.cpp" line="110"/>
|
||||
<location filename="../ui/MainFrame.cpp" line="111"/>
|
||||
<source>play manager</source>
|
||||
<translation>回放管理</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>window manager</source>
|
||||
<translation type="vanished">窗口管理</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainFrame.cpp" line="113"/>
|
||||
<location filename="../ui/MainFrame.cpp" line="114"/>
|
||||
<source>system manager</source>
|
||||
<translation>系统管理</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -491,132 +503,132 @@
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="71"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="65"/>
|
||||
<source>model elements</source>
|
||||
<translation>实体</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="77"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="71"/>
|
||||
<source>attribte</source>
|
||||
<translation type="unfinished">属性</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="114"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="108"/>
|
||||
<source>Wave Curve</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="120"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="114"/>
|
||||
<source>Speed Curve</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="129"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="123"/>
|
||||
<source>3D Curve</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="141"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="135"/>
|
||||
<source>Target number</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="141"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="135"/>
|
||||
<source>Signal-to-noise ratio</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="142"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="136"/>
|
||||
<source>Azimuth line of sight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="142"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="136"/>
|
||||
<source>Pitch gaze angle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="143"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="137"/>
|
||||
<source>azimuth</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="143"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="137"/>
|
||||
<source>Pitch angle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="144"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="138"/>
|
||||
<source>attribute</source>
|
||||
<translation type="unfinished">属性</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="144"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="138"/>
|
||||
<source>Doppler</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="145"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="139"/>
|
||||
<source>course</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="145"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="139"/>
|
||||
<source>Speed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="146"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="140"/>
|
||||
<source>longitude</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="146"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="140"/>
|
||||
<source>latitude</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="147"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="141"/>
|
||||
<source>distance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="147"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="141"/>
|
||||
<source>velocity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="148"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="142"/>
|
||||
<source>Radial dimensions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="148"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="142"/>
|
||||
<source>Target RCS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="154"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="148"/>
|
||||
<source>Report Table</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="163"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="157"/>
|
||||
<source>Signal Indicator Lamp</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="170"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="164"/>
|
||||
<source>ParamSetting</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="175"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="169"/>
|
||||
<source>Matlab File</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/MainWindow.cpp" line="180"/>
|
||||
<location filename="../ui/MainWindow.cpp" line="174"/>
|
||||
<source>name: 5year 0412</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -626,57 +638,70 @@
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="96"/>
|
||||
<source>Release Track</source>
|
||||
<translation>取消关注</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="113"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="112"/>
|
||||
<source>Add boke Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="120"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="119"/>
|
||||
<source>Add lsjhqt Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="127"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="126"/>
|
||||
<source>Add nimizi Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="134"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="133"/>
|
||||
<source>Add tkdlj Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="141"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="140"/>
|
||||
<source>Add jiaofan Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="148"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="147"/>
|
||||
<source>Add satellite Entity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="250"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="249"/>
|
||||
<source>Track</source>
|
||||
<translation>关注</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="258"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="256"/>
|
||||
<source>Add Mesh Component</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="262"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="259"/>
|
||||
<source>Add Path Component</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="269"/>
|
||||
<location filename="../ui/ModelBrowser/ModelTreeWidget.cpp" line="266"/>
|
||||
<source>Delete</source>
|
||||
<translation>删除</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OsgWidget</name>
|
||||
<message>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="81"/>
|
||||
<source>warning</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="82"/>
|
||||
<source>open dyt file failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -692,7 +717,7 @@
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="14"/>
|
||||
<source>PlayManagerMenu</source>
|
||||
<translation>播放管理菜单</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="20"/>
|
||||
@ -700,12 +725,12 @@
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="150"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="157"/>
|
||||
<source>play</source>
|
||||
<translation>播放</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="27"/>
|
||||
<source>stop</source>
|
||||
<translation>停止</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="55"/>
|
||||
@ -725,28 +750,12 @@
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="105"/>
|
||||
<source>up</source>
|
||||
<translation>加速</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.ui" line="112"/>
|
||||
<source>down</source>
|
||||
<translation>减速</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>question</source>
|
||||
<translation type="obsolete">警告</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="34"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="41"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="63"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="70"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="81"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="88"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="99"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="106"/>
|
||||
<source>has not workspace</source>
|
||||
<translation>空间不存在</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="34"/>
|
||||
@ -758,14 +767,26 @@
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="99"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="106"/>
|
||||
<source>warning</source>
|
||||
<translation>警告</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="34"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="41"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="63"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="70"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="81"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="88"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="99"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="106"/>
|
||||
<source>has not workspace</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="48"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="52"/>
|
||||
<location filename="../ui/Menu/PlayManagerMenu.cpp" line="147"/>
|
||||
<source>pause</source>
|
||||
<translation>暂停</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -773,7 +794,7 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser.cpp" line="40"/>
|
||||
<source>attribute</source>
|
||||
<translation>属性</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser.cpp" line="55"/>
|
||||
@ -827,12 +848,12 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../common/CrashHandler.cpp" line="69"/>
|
||||
<location filename="../common/CrashHandler.cpp" line="70"/>
|
||||
<source>error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../common/CrashHandler.cpp" line="70"/>
|
||||
<location filename="../common/CrashHandler.cpp" line="71"/>
|
||||
<source>the appliaction is crash</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1104,7 +1125,7 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8328"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">名称</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8335"/>
|
||||
@ -1205,7 +1226,7 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="7792"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">名称</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="7799"/>
|
||||
@ -1226,18 +1247,12 @@
|
||||
<context>
|
||||
<name>QtOsgViewWidget</name>
|
||||
<message>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="131"/>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="139"/>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="136"/>
|
||||
<source>warning</source>
|
||||
<translation type="unfinished">警告</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="131"/>
|
||||
<source>default workspace failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="139"/>
|
||||
<location filename="../viewer/QtOsgViewWidget.cpp" line="136"/>
|
||||
<source>open dyt file failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
@ -1253,7 +1268,7 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8683"/>
|
||||
<source>Path</source>
|
||||
<translation type="unfinished">路径</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -1472,12 +1487,12 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qttreepropertybrowser.cpp" line="454"/>
|
||||
<source>Property</source>
|
||||
<translation>属性</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qttreepropertybrowser.cpp" line="455"/>
|
||||
<source>Value</source>
|
||||
<translation>值</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -1503,7 +1518,7 @@
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8059"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished">名称</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/PropertyBrowser/qtpropertymanager.cpp" line="8066"/>
|
||||
@ -1585,28 +1600,28 @@
|
||||
<message>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.ui" line="14"/>
|
||||
<source>SystemManagerMenu</source>
|
||||
<translation>系统管理菜单</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.ui" line="20"/>
|
||||
<source>exit</source>
|
||||
<translation>退出</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.ui" line="40"/>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.ui" line="50"/>
|
||||
<source>ui setting</source>
|
||||
<translation>ui设置</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.cpp" line="57"/>
|
||||
<source>question</source>
|
||||
<translation>询问</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/Menu/SystemManagerMenu.cpp" line="57"/>
|
||||
<source>are you sure to exit</source>
|
||||
<translation>确定退出</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@ -1673,101 +1688,97 @@
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="14"/>
|
||||
<source>New WorkSpace</source>
|
||||
<translation>新建空间</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="22"/>
|
||||
<source>Name</source>
|
||||
<translation>名称</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="32"/>
|
||||
<source>input workspace name</source>
|
||||
<translation>空间名称</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="43"/>
|
||||
<source>Path</source>
|
||||
<translation>路径</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="56"/>
|
||||
<source>select workspace save path</source>
|
||||
<translation>选择路径</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="63"/>
|
||||
<source>...</source>
|
||||
<translation></translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="74"/>
|
||||
<source>describe</source>
|
||||
<translation>描述</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="101"/>
|
||||
<source>Sure</source>
|
||||
<translation>确认</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.ui" line="108"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="27"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="21"/>
|
||||
<source>new workspace</source>
|
||||
<translation>新建空间</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="51"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="57"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="63"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="73"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="80"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="67"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="74"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="83"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="89"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="95"/>
|
||||
<source>warning</source>
|
||||
<translation>警告</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="51"/>
|
||||
<source>name or save path is empty, please check it</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="57"/>
|
||||
<source>name or save path is empty, please check it</source>
|
||||
<translation>名称或者路径为空</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="63"/>
|
||||
<source>save current workspace?</source>
|
||||
<translation>保存当前空间?</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="73"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="67"/>
|
||||
<source>current path is contains current folder, do you want to overwrite it?</source>
|
||||
<translation>当前空间已存在,是否替换?</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="80"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="74"/>
|
||||
<source>removeRecursively failed</source>
|
||||
<translation>删除失败</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="83"/>
|
||||
<source>mkpath failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="89"/>
|
||||
<source>mkpath failed</source>
|
||||
<translation>创建路径失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="95"/>
|
||||
<source>name is exits</source>
|
||||
<translation>名称已存在</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>create workSpace failed</source>
|
||||
<translation type="vanished">创建空间失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="110"/>
|
||||
<location filename="../ui/WorkSpace/WorkSpaceDlg.cpp" line="104"/>
|
||||
<source>save spaceWork directory</source>
|
||||
<translation>保存空间目录</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -9,30 +9,35 @@
|
||||
|
||||
Dialog::Dialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, delegate_(FramelessDelegate::Create(this)) {
|
||||
, ui_(new Ui::Dialog)
|
||||
/*, delegate_(FramelessDelegate::Create(this)) */{
|
||||
setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
ui_->setupUi(this);
|
||||
|
||||
ui_->titleBar->SetMainWidget(this);
|
||||
InitFrame();
|
||||
}
|
||||
|
||||
Dialog::~Dialog() {
|
||||
delete ui_;
|
||||
//delete delegate_;
|
||||
//delegate_ = nullptr;
|
||||
}
|
||||
|
||||
void Dialog::DeleteThisOnClose() {
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
|
||||
void Dialog::SetTitleBar(FrameTitleBar* titleBar) {
|
||||
delegate_->SetTitleBar(titleBar);
|
||||
/* delegate_->SetTitleBar(titleBar);
|
||||
|
||||
QVBoxLayout* layout = reinterpret_cast<QVBoxLayout*>(this->layout());
|
||||
layout->insertWidget(0, titleBar, 0);
|
||||
layout->insertWidget(0, titleBar, 0);*/
|
||||
}
|
||||
|
||||
void Dialog::SetTitle(const QString& title) {
|
||||
if (!delegate_) {
|
||||
return;
|
||||
}
|
||||
|
||||
delegate_->SetTitle(title);
|
||||
ui_->titleBar->SetTitle(title);
|
||||
}
|
||||
|
||||
void Dialog::hideEvent(QHideEvent*) {
|
||||
@ -47,9 +52,10 @@ bool Dialog::nativeEvent(const QByteArray& eventType, void* message, long* resul
|
||||
#else
|
||||
bool Dialog::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) {
|
||||
#endif
|
||||
if (!delegate_->nativeEvent(eventType, message, result)) {
|
||||
return QDialog::nativeEvent(eventType, message, result);
|
||||
/*if (!delegate_->nativeEvent(eventType, message, result)) {
|
||||
return QDialog::nativeEvent(eventType, message, result);
|
||||
}
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -62,6 +68,7 @@ void Dialog::paintEvent(QPaintEvent* event) {
|
||||
}
|
||||
|
||||
void Dialog::InitFrame() {
|
||||
/* ui->
|
||||
FrameTitleBar* titleBar = new FrameTitleBar(this);
|
||||
titleBar->SetMainWidget(this);
|
||||
|
||||
@ -77,5 +84,5 @@ void Dialog::InitFrame() {
|
||||
SetTitleBar(titleBar);
|
||||
|
||||
mainDilag_ = new QWidget(this);
|
||||
layout->addWidget(mainDilag_, 1);
|
||||
layout->addWidget(mainDilag_, 1);*/
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui_Dialog.h"
|
||||
|
||||
class FrameTitleBar;
|
||||
class FramelessDelegate;
|
||||
|
||||
@ -10,7 +12,7 @@ class Dialog : public QDialog {
|
||||
|
||||
public:
|
||||
Dialog(QWidget* parent);
|
||||
~Dialog() override = default;
|
||||
~Dialog() override;
|
||||
|
||||
void DeleteThisOnClose();
|
||||
void SetTitleBar(FrameTitleBar* titleBar);
|
||||
@ -27,16 +29,18 @@ protected:
|
||||
#endif
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
|
||||
protected:
|
||||
template<typename UI>
|
||||
void SetupUI(UI* ui) {
|
||||
ui->setupUi(mainDilag_);
|
||||
//ui->setupUi(mainDilag_);
|
||||
ui->setupUi(ui_->mianWidget);
|
||||
}
|
||||
|
||||
private:
|
||||
void InitFrame();
|
||||
|
||||
private:
|
||||
Ui::Dialog* ui_;
|
||||
FramelessDelegate* delegate_;
|
||||
QWidget* mainDilag_{ nullptr };
|
||||
};
|
65
src/ui/Dialog.ui
Normal file
65
src/ui/Dialog.ui
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>654</width>
|
||||
<height>509</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="DialogTitleBar" name="titleBar" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="mianWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DialogTitleBar</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>DialogTitleBar.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../Hydro.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
74
src/ui/DialogTitleBar.cpp
Normal file
74
src/ui/DialogTitleBar.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "DialogTitleBar.h"
|
||||
|
||||
#include <QStyleOption>
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QButtonGroup>
|
||||
|
||||
#include "common/RecourceHelper.h"
|
||||
#include "ui/Dialog.h"
|
||||
|
||||
#include "ui_DialogTitleBar.h"
|
||||
|
||||
DialogTitleBar::DialogTitleBar(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::DialogTitleBar) {
|
||||
ui->setupUi(this);
|
||||
connect(ui->sys_close, &QPushButton::clicked, this, &DialogTitleBar::closeDialog);
|
||||
}
|
||||
|
||||
DialogTitleBar::~DialogTitleBar() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
//QSize DockTitleBar::minimumSizeHint() const {
|
||||
// QSize s = size();
|
||||
// return s;
|
||||
//}
|
||||
|
||||
void DialogTitleBar::SetTitle(const QString& title) {
|
||||
ui->sys_title->setText(title);
|
||||
}
|
||||
|
||||
void DialogTitleBar::paintEvent(QPaintEvent* event) {
|
||||
QStyleOption opt;
|
||||
opt.initFrom(this);
|
||||
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
void DialogTitleBar::mouseReleaseEvent(QMouseEvent* event) {
|
||||
if (pressed_) {
|
||||
pressed_ = false;
|
||||
point_ = event->pos();
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void DialogTitleBar::mousePressEvent(QMouseEvent* event) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
pressed_ = true;
|
||||
point_ = event->pos();
|
||||
}
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void DialogTitleBar::mouseMoveEvent(QMouseEvent* event) {
|
||||
if (pressed_) {
|
||||
QPoint movePoint = event->globalPos() - point_;
|
||||
if (nullptr != mainDialog_) {
|
||||
mainDialog_->move(movePoint);
|
||||
}
|
||||
}
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void DialogTitleBar::closeDialog() {
|
||||
if (nullptr != mainDialog_) {
|
||||
mainDialog_->reject();
|
||||
return;
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
36
src/ui/DialogTitleBar.h
Normal file
36
src/ui/DialogTitleBar.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class DialogTitleBar;
|
||||
}
|
||||
|
||||
class DialogTitleBar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DialogTitleBar(QWidget* parent = 0);
|
||||
~DialogTitleBar() override;
|
||||
|
||||
//QSize minimumSizeHint() const override;
|
||||
|
||||
void SetMainWidget(class Dialog* dialog) { mainDialog_ = dialog; }
|
||||
void SetTitle(const QString& title);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
|
||||
protected:
|
||||
void closeDialog();
|
||||
|
||||
private:
|
||||
Ui::DialogTitleBar* ui;
|
||||
class Dialog* mainDialog_{ nullptr };
|
||||
|
||||
bool pressed_{ false };
|
||||
QPoint point_;
|
||||
};
|
71
src/ui/DialogTitleBar.ui
Normal file
71
src/ui/DialogTitleBar.ui
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogTitleBar</class>
|
||||
<widget class="QWidget" name="DialogTitleBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>451</width>
|
||||
<height>42</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>DialogTitleBar</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="sys_title">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>612</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sys_close">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../Hydro.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
@ -4,6 +4,7 @@
|
||||
#include <QPainter>
|
||||
#include <QAction>
|
||||
#include <QButtonGroup>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <qDebug>
|
||||
|
||||
@ -20,11 +21,12 @@ FrameTitleBar::FrameTitleBar(QWidget* parent)
|
||||
connect(ui->sys_close, &QPushButton::clicked, this, &FrameTitleBar::OnCloseBtnClicked);
|
||||
connect(ui->sys_min, &QPushButton::clicked, this, &FrameTitleBar::OnMinBtnClicked);
|
||||
connect(ui->sys_max, &QPushButton::clicked, this, &FrameTitleBar::OnMaxBtnClicked);
|
||||
connect(ui->sys_restore, &QPushButton::clicked, this, &FrameTitleBar::OnRestorClicked);
|
||||
//connect(ui->sys_restore, &QPushButton::clicked, this, &FrameTitleBar::OnRestorClicked);
|
||||
//connect(this, &FrameTitleBar::doubleClick, this, &FrameTitleBar::OnDoubleClicked);
|
||||
|
||||
ui->sys_restore->hide();
|
||||
ui->sys_max->hide();
|
||||
/*ui->sys_close->setIcon(style()->standardPixmap(QStyle::SP_TitleBarCloseButton));
|
||||
ui->sys_min->setIcon(style()->standardPixmap(QStyle::SP_TitleBarMinButton));
|
||||
ui->sys_max->setIcon(style()->standardPixmap(QStyle::SP_TitleBarMaxButton));*/
|
||||
|
||||
SetSysButton(0);
|
||||
|
||||
@ -44,10 +46,12 @@ void FrameTitleBar::SetTitle(const QString& title) {
|
||||
|
||||
void FrameTitleBar::SetMainWidget(QWidget* widget) {
|
||||
mainWidget_ = widget;
|
||||
|
||||
if (nullptr == mainWidget_) {
|
||||
qDebug() << __FUNCTION__ << "mainWidget is nullptr";
|
||||
return;
|
||||
}
|
||||
}
|
||||
void FrameTitleBar::OnMaximized(bool maximized) {
|
||||
ui->sys_restore->setVisible(maximized);
|
||||
ui->sys_max->setVisible(!maximized);
|
||||
}
|
||||
|
||||
@ -72,6 +76,28 @@ void FrameTitleBar::paintEvent(QPaintEvent* event) {
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
void FrameTitleBar::mouseReleaseEvent(QMouseEvent* event) {
|
||||
Q_UNUSED(event);
|
||||
pressed_ = false;
|
||||
}
|
||||
|
||||
void FrameTitleBar::mousePressEvent(QMouseEvent* event) {
|
||||
if (nullptr == mainWidget_ || mainWidget_->isMaximized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
pressed_ = true;
|
||||
point_ = event->pos();
|
||||
}
|
||||
}
|
||||
|
||||
void FrameTitleBar::mouseMoveEvent(QMouseEvent* event) {
|
||||
if (pressed_ && nullptr != mainWidget_) {
|
||||
mainWidget_->move(event->pos() - point_ + mainWidget_->pos());
|
||||
}
|
||||
}
|
||||
|
||||
void FrameTitleBar::OnMinBtnClicked() {
|
||||
if (nullptr == mainWidget_) {
|
||||
qDebug() << __FUNCTION__ << "mainWidget is nullptr";
|
||||
@ -82,22 +108,18 @@ void FrameTitleBar::OnMinBtnClicked() {
|
||||
}
|
||||
|
||||
void FrameTitleBar::OnMaxBtnClicked() {
|
||||
|
||||
if (nullptr == mainWidget_) {
|
||||
qDebug() << __FUNCTION__ << "mainWidget is nullptr";
|
||||
return;
|
||||
}
|
||||
|
||||
mainWidget_->showMaximized();
|
||||
}
|
||||
|
||||
void FrameTitleBar::OnRestorClicked() {
|
||||
if (nullptr == mainWidget_) {
|
||||
qDebug() << __FUNCTION__ << "mainWidget is nullptr";
|
||||
return;
|
||||
if (mainWidget_->isMaximized()) {
|
||||
mainWidget_->showNormal();
|
||||
ui->sys_max->setIcon(QPixmap(":/res/sys_max.png"));
|
||||
} else {
|
||||
mainWidget_->showMaximized();
|
||||
ui->sys_max->setIcon(QPixmap(":/res/sys_restore.png"));
|
||||
}
|
||||
|
||||
mainWidget_->showNormal();
|
||||
}
|
||||
|
||||
void FrameTitleBar::OnCloseBtnClicked() {
|
||||
|
@ -41,11 +41,13 @@ public:
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
|
||||
protected:
|
||||
void OnMinBtnClicked();
|
||||
void OnMaxBtnClicked();
|
||||
void OnRestorClicked();
|
||||
void OnCloseBtnClicked();
|
||||
|
||||
private:
|
||||
@ -55,4 +57,7 @@ private:
|
||||
class QBoxLayout* menuLayout_{ nullptr };
|
||||
class QButtonGroup* buttonCourp_{ nullptr };
|
||||
unsigned int ftbButton_{ 0 };
|
||||
|
||||
bool pressed_{ false };
|
||||
QPoint point_;
|
||||
};
|
@ -89,19 +89,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sys_restore">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sys_close">
|
||||
<property name="maximumSize">
|
||||
|
@ -32,7 +32,7 @@ bool FramelessDelegate::nativeEvent(const QByteArray & eventType, void* message,
|
||||
}
|
||||
|
||||
void FramelessDelegate::SetTitleBar(FrameTitleBar* titleBar) {
|
||||
if (nullptr == titleBar || titleBar_ == titleBar) {
|
||||
/* if (nullptr == titleBar || titleBar_ == titleBar) {
|
||||
return;
|
||||
}
|
||||
if (nullptr != titleBar_) {
|
||||
@ -43,7 +43,7 @@ void FramelessDelegate::SetTitleBar(FrameTitleBar* titleBar) {
|
||||
|
||||
if (nullptr != titleBar_) {
|
||||
titleBar_->installEventFilter(this);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void FramelessDelegate::SetTitle(const QString& title) {
|
||||
|
@ -96,7 +96,8 @@ bool FramelessDelegateWin::nativeEvent(const QByteArray & eventType, void* messa
|
||||
auto rc = workRect_;
|
||||
if (!rc)
|
||||
return false;
|
||||
if (auto ret = DefWindowProcW(msg->hwnd, WM_NCCALCSIZE, msg->wParam, msg->lParam); ret) {
|
||||
auto ret = DefWindowProcW(msg->hwnd, WM_NCCALCSIZE, msg->wParam, msg->lParam);
|
||||
if ( ret) {
|
||||
*result = ret;
|
||||
return true;
|
||||
}
|
||||
@ -108,7 +109,8 @@ bool FramelessDelegateWin::nativeEvent(const QByteArray & eventType, void* messa
|
||||
} else {
|
||||
const auto clientRect = reinterpret_cast<LPRECT>(msg->lParam);
|
||||
const auto before = *clientRect;
|
||||
if (auto ret = DefWindowProcW(msg->hwnd, WM_NCCALCSIZE, msg->wParam, msg->lParam); ret) {
|
||||
auto ret = DefWindowProcW(msg->hwnd, WM_NCCALCSIZE, msg->wParam, msg->lParam);
|
||||
if ( ret) {
|
||||
*result = ret;
|
||||
return true;
|
||||
}
|
||||
@ -276,7 +278,7 @@ void FramelessDelegateWin::CheckMonitorChanged() {
|
||||
auto newMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
|
||||
if (newMonitor != monitor_) {
|
||||
monitor_ = newMonitor;
|
||||
auto ret = GetScreenNativeWorkRect(hwnd);
|
||||
std::optional<QRect> ret = GetScreenNativeWorkRect(hwnd);
|
||||
if ( !!ret)
|
||||
workRect_ = ret;
|
||||
}
|
||||
|
@ -12,72 +12,209 @@ namespace std {
|
||||
};
|
||||
constexpr explicit nullopt_t(_Tag) {}
|
||||
};
|
||||
inline constexpr nullopt_t nullopt{ nullopt_t::_Tag{} };
|
||||
constexpr nullopt_t nullopt{ nullopt_t::_Tag{} };
|
||||
|
||||
class bad_optional_access : public std::exception
|
||||
{
|
||||
public:
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "bad optional access";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <class T>
|
||||
class optional {
|
||||
public:
|
||||
optional() : has_value_(false) {}
|
||||
optional(const T& value) : has_value_(true), value_(value) {}
|
||||
optional(T&& value) : has_value_(true), value_(std::move(value)) {}
|
||||
optional(nullopt_t) : has_value_(false) {}
|
||||
constexpr optional() noexcept : _engaged(false) {}
|
||||
constexpr optional(nullopt_t) noexcept : _engaged(false) {}
|
||||
|
||||
bool has_value() const {
|
||||
return has_value_;
|
||||
}
|
||||
|
||||
T& value() {
|
||||
if (!has_value_) {
|
||||
throw std::runtime_error("optional has no value");
|
||||
optional(const optional& other) : _engaged(other._engaged) {
|
||||
if (other._engaged) {
|
||||
new (_storage) T(*other);
|
||||
}
|
||||
return value_;
|
||||
}
|
||||
|
||||
const T& value() const {
|
||||
if (!has_value_) {
|
||||
throw std::runtime_error("optional has no value");
|
||||
optional(optional&& other) noexcept : _engaged(other._engaged) {
|
||||
if (other._engaged) {
|
||||
new (_storage) T(std::move(*other));
|
||||
other._engaged = false;
|
||||
}
|
||||
return value_;
|
||||
}
|
||||
|
||||
// 重载运算符 * 和 -> 使得使用更加方便
|
||||
T& operator*() {
|
||||
return value();
|
||||
}
|
||||
|
||||
const T& operator*() const {
|
||||
return value();
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &value();
|
||||
}
|
||||
|
||||
const T* operator->() const {
|
||||
return &value();
|
||||
}
|
||||
|
||||
bool operator==(const optional& other) const {
|
||||
if (has_value_ && other.has_value_) {
|
||||
return value_ == other.value_;
|
||||
optional& operator=(const optional& other)
|
||||
{
|
||||
if(this == &other)
|
||||
return *this;
|
||||
if(_engaged && other._engaged)
|
||||
{
|
||||
**this = *other;
|
||||
}
|
||||
else if(other._engaged)
|
||||
{
|
||||
new (_storage) T(*other);
|
||||
_engaged = true;
|
||||
} else if(_engaged)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
return has_value_ == other.has_value_;
|
||||
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
bool operator!=(const optional& other) const {
|
||||
return !(*this == other);
|
||||
optional& operator=(optional&& other) noexcept
|
||||
{
|
||||
if(this == &other)
|
||||
return *this;
|
||||
if(_engaged && other._engaged)
|
||||
{
|
||||
**this = std::move(*other);
|
||||
|
||||
} else if (other._engaged)
|
||||
{
|
||||
new(_storage) T(std::move(*other));
|
||||
_engaged = true;
|
||||
|
||||
} else if(_engaged)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
other._engaged = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator!() const {
|
||||
return !has_value();
|
||||
optional(const T& value) : _engaged(true) {
|
||||
new (_storage) T(value);
|
||||
}
|
||||
|
||||
optional(T&& value) : _engaged(true) {
|
||||
new (_storage) T(std::move(value));
|
||||
}
|
||||
|
||||
~optional() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() noexcept {
|
||||
if (_engaged) {
|
||||
reinterpret_cast<T*>(_storage)->~T();
|
||||
_engaged = false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool has_value() const noexcept
|
||||
{
|
||||
return _engaged;
|
||||
}
|
||||
|
||||
T& operator*() &
|
||||
{
|
||||
if(!_engaged)
|
||||
throw std::bad_optional_access();
|
||||
return *reinterpret_cast<T*>(_storage);
|
||||
}
|
||||
const T& operator*() const&
|
||||
{
|
||||
if(!_engaged)
|
||||
throw std::bad_optional_access();
|
||||
return *reinterpret_cast<const T*>(_storage);
|
||||
}
|
||||
|
||||
T&& operator*() &&
|
||||
{
|
||||
if(!_engaged)
|
||||
throw std::bad_optional_access();
|
||||
return std::move(*reinterpret_cast<T*>(_storage));
|
||||
}
|
||||
|
||||
const T&& operator*() const&&
|
||||
{
|
||||
if(!_engaged)
|
||||
throw std::bad_optional_access();
|
||||
return std::move(*reinterpret_cast<T*>(_storage));
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return reinterpret_cast<T*>(_storage);
|
||||
}
|
||||
const T* operator->() const {
|
||||
return reinterpret_cast<const T*>(_storage);
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return _engaged;
|
||||
}
|
||||
|
||||
private:
|
||||
bool has_value_;
|
||||
T value_;
|
||||
bool _engaged;
|
||||
char _storage[sizeof(T)];
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// template<typename T>
|
||||
// class optional {
|
||||
// public:
|
||||
// optional() : has_value_(false) {}
|
||||
// optional(const T& value) : has_value_(true), value_(value) {}
|
||||
// optional(T&& value) : has_value_(true), value_(std::move(value)) {}
|
||||
// optional(nullopt_t) : has_value_(false) {}
|
||||
//
|
||||
// bool has_value() const {
|
||||
// return has_value_;
|
||||
// }
|
||||
//
|
||||
// T& value() {
|
||||
// if (!has_value_) {
|
||||
// throw std::runtime_error("optional has no value");
|
||||
// }
|
||||
// return value_;
|
||||
// }
|
||||
//
|
||||
// const T& value() const {
|
||||
// if (!has_value_) {
|
||||
// throw std::runtime_error("optional has no value");
|
||||
// }
|
||||
// return value_;
|
||||
// }
|
||||
//
|
||||
// T& operator*() {
|
||||
// return value();
|
||||
// }
|
||||
//
|
||||
// const T& operator*() const {
|
||||
// return value();
|
||||
// }
|
||||
//
|
||||
// T* operator->() {
|
||||
// return &value();
|
||||
// }
|
||||
//
|
||||
// const T* operator->() const {
|
||||
// return &value();
|
||||
// }
|
||||
//
|
||||
// bool operator==(const optional& other) const {
|
||||
// if (has_value_ && other.has_value_) {
|
||||
// return value_ == other.value_;
|
||||
// }
|
||||
// return has_value_ == other.has_value_;
|
||||
// }
|
||||
//
|
||||
// bool operator!=(const optional& other) const {
|
||||
// return !(*this == other);
|
||||
// }
|
||||
//
|
||||
// bool operator!() const {
|
||||
// return !has_value();
|
||||
// }
|
||||
//
|
||||
// private:
|
||||
// bool has_value_;
|
||||
// T value_;
|
||||
// };
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
FramelessWindow::FramelessWindow(QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, delegate_(FramelessDelegate::Create(this)) {
|
||||
//setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
/* , delegate_(FramelessDelegate::Create(this))*/ {
|
||||
setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
|
||||
}
|
||||
|
||||
@ -15,7 +15,8 @@ FramelessWindow::~FramelessWindow() {
|
||||
}
|
||||
|
||||
void FramelessWindow::SetTitleBar(FrameTitleBar* titleBar) {
|
||||
delegate_->SetTitleBar(titleBar);
|
||||
/*delegate_->SetTitleBar(titleBar);*/
|
||||
titleBar->SetMainWidget(this);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -23,8 +24,9 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qi
|
||||
#else
|
||||
bool FramelessWindow::nativeEvent(const QByteArray & eventType, void* message, long* result) {
|
||||
#endif
|
||||
if (!delegate_->nativeEvent(eventType, message, result)) {
|
||||
/* if (!delegate_->nativeEvent(eventType, message, result)) {
|
||||
return QFrame::nativeEvent(eventType, message, result);
|
||||
}
|
||||
}*/
|
||||
return QFrame::nativeEvent(eventType, message, result);
|
||||
return true;
|
||||
}
|
||||
|
@ -22,5 +22,5 @@ protected:
|
||||
#endif
|
||||
|
||||
private:
|
||||
FramelessDelegate* delegate_;
|
||||
FramelessDelegate* delegate_{ nullptr };
|
||||
};
|
@ -26,6 +26,7 @@
|
||||
#include "common/SpdLogger.h"
|
||||
|
||||
#include "ui_MainFrame.h"
|
||||
#include "viewer/OsgWidget.h"
|
||||
|
||||
MainFrame* s_instance { nullptr };
|
||||
|
||||
@ -115,9 +116,9 @@ void MainFrame::InitUI() {
|
||||
MainWindow* mainWindow = new MainWindow(this);
|
||||
layout->addWidget(mainWindow);
|
||||
|
||||
QtOsgViewWidget* viewWidget = mainWindow->GetViewWidget();
|
||||
connect(fileMenu, &FileManagerMenu::LoadDyt, viewWidget, &QtOsgViewWidget::OnLoadDyt);
|
||||
connect(viewWidget, &QtOsgViewWidget::signalResetWorkSpace, mainWindow, &MainWindow::slotResetWorkSpace);
|
||||
OsgWidget* viewWidget = mainWindow->GetViewWidget();
|
||||
connect(fileMenu, &FileManagerMenu::LoadDyt, viewWidget, &OsgWidget::OnLoadDyt);
|
||||
connect(viewWidget, &OsgWidget::signalResetWorkSpace, mainWindow, &MainWindow::slotResetWorkSpace);
|
||||
|
||||
connect(system_, &SystemManagerMenu::signalShowUISetting, mainWindow, &MainWindow::slotShowUISetting);
|
||||
|
||||
|
@ -1,12 +1,5 @@
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QUrl>
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QMimeDatabase>
|
||||
#include <QDir>
|
||||
#include <qtabwidget.h>
|
||||
|
||||
#include "PropertyBrowser.h"
|
||||
@ -34,6 +27,7 @@
|
||||
#include "Matlab/MatlabObject.h"
|
||||
|
||||
#include "ui_MainWindow.h"
|
||||
#include "viewer/OsgWidget.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent)
|
||||
: QMainWindow(parent)
|
||||
@ -44,7 +38,7 @@ MainWindow::MainWindow(QWidget* parent)
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
OsgViewer::Get().Uninitialize();
|
||||
//OsgViewer::Get().Uninitialize();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@ -83,7 +77,7 @@ void MainWindow::InitUI() {
|
||||
connect(modelBrowser_, &ModelBrowser::WorkSpaceChange, propertyBrowser_, &PropertyBrowser::OnWorkSpaceChange);
|
||||
connect(modelBrowser_, &ModelBrowser::EntityChange, propertyBrowser_, &PropertyBrowser::OnEntityChange);
|
||||
|
||||
qtOsgViewWidget_ = new QtOsgViewWidget;
|
||||
qtOsgViewWidget_ = new OsgWidget;
|
||||
qtOsgViewWidget_->Initialize();
|
||||
m_mapDockWidget.insert("PropertyBrowser", attribte);
|
||||
|
||||
@ -138,14 +132,14 @@ void MainWindow::InitUI() {
|
||||
targetUITable_ = new TargetListWgt;
|
||||
|
||||
QStringList headerLabels;
|
||||
headerLabels << tr("Target number") << tr("Signal-to-noise ratio") //QString::fromLocal8Bit("目标编号") << QString::fromLocal8Bit("信噪比")
|
||||
<< tr("Azimuth line of sight") << tr("Pitch gaze angle") // QString::fromLocal8Bit("方位视线角") << QString::fromLocal8Bit("俯仰视线角")
|
||||
<< tr("azimuth") << tr("Pitch angle") // QString::fromLocal8Bit("方位角") << QString::fromLocal8Bit("俯仰角")
|
||||
<< tr("attribute") << tr("Doppler") // QString::fromLocal8Bit("属性") << QString::fromLocal8Bit("多普勒")
|
||||
<< tr("course") << tr("Speed") // QString::fromLocal8Bit("航向") << QString::fromLocal8Bit("航速")
|
||||
<< tr("longitude") << tr("latitude") // QString::fromLocal8Bit("经度") << QString::fromLocal8Bit("纬度")
|
||||
<< tr("distance") << tr("velocity") // QString::fromLocal8Bit("距离") << QString::fromLocal8Bit("速度")
|
||||
<< tr("Radial dimensions") << tr("Target RCS"); // QString::fromLocal8Bit("径向尺寸") << QString::fromLocal8Bit("目标RCS");
|
||||
headerLabels << tr("Target number") << tr("Signal-to-noise ratio")
|
||||
<< tr("Azimuth line of sight") << tr("Pitch gaze angle")
|
||||
<< tr("azimuth") << tr("Pitch angle")
|
||||
<< tr("attribute") << tr("Doppler")
|
||||
<< tr("course") << tr("Speed")
|
||||
<< tr("longitude") << tr("latitude")
|
||||
<< tr("distance") << tr("velocity")
|
||||
<< tr("Radial dimensions") << tr("Target RCS");
|
||||
|
||||
targetUITable_->SetHeader(headerLabels);
|
||||
//const QString reportPath = RecourceHelper::Get().GetBasePath() + "/workspace/Report.txt";
|
||||
@ -184,8 +178,8 @@ void MainWindow::InitUI() {
|
||||
|
||||
//ui->viewWidget->layout()->addWidget(qtOsgViewWidget_);
|
||||
qtOsgViewWidget_->LoadDefaultScene();
|
||||
OsgViewer::Get().Initialize();
|
||||
OsgViewer::Get().OnFrame();
|
||||
/*OsgViewer::Get().Initialize();
|
||||
OsgViewer::Get().OnFrame();*/
|
||||
|
||||
#if 1
|
||||
// MatlabObject* mtlb = new MatlabObject;
|
||||
@ -211,8 +205,8 @@ void MainWindow::InitDockLayout() {
|
||||
tabWidget_->insertTab(i, mainWindow_, strTabName);
|
||||
if (listDocArea[0].toList().size() > 0) {
|
||||
mainWindow_->setCentralWidget(qtOsgViewWidget_);
|
||||
OsgViewer::Get().Initialize();
|
||||
OsgViewer::Get().OnFrame();
|
||||
//OsgViewer::Get().Initialize();
|
||||
//OsgViewer::Get().OnFrame();
|
||||
} else {
|
||||
mainWindow_->takeCentralWidget();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
class ModelBrowser* GetModelBrowser() const {
|
||||
return modelBrowser_;
|
||||
}
|
||||
class QtOsgViewWidget* GetViewWidget() const {
|
||||
class OsgWidget* GetViewWidget() const {
|
||||
return qtOsgViewWidget_;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ private:
|
||||
class ModelBrowser* modelBrowser_{ nullptr };
|
||||
class PropertyBrowser* propertyBrowser_{ nullptr };
|
||||
class QWebEngineView* webEngineView_{ nullptr };
|
||||
class QtOsgViewWidget* qtOsgViewWidget_{ nullptr };
|
||||
class OsgWidget* qtOsgViewWidget_{ nullptr };
|
||||
|
||||
class FitCurveDialog* fitCurveDlg_{ nullptr };
|
||||
class FitCurveDialog* fitYLgCurveDlg_{ nullptr };
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <QVariant>
|
||||
#include <QMenu>
|
||||
|
||||
#include <osgEarth/EarthManipulator>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
|
||||
#include "common/RecourceHelper.h"
|
||||
#include "common/SpdLogger.h"
|
||||
@ -109,7 +109,6 @@ void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
||||
} else {
|
||||
QMenu menu(this);
|
||||
|
||||
// 警속꽉데淃
|
||||
QAction* addEntiy = new QAction(tr("Add boke Entity"), this);
|
||||
connect(addEntiy, &QAction::triggered, [this]() {
|
||||
OnAddMeshEntity("boke/boke.ive", "boke");
|
||||
@ -152,7 +151,7 @@ void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
||||
);
|
||||
menu.addAction(addEntiy);
|
||||
|
||||
// 鞫刻꽉데
|
||||
// <EFBFBD><EFBFBD>ʾ<EFBFBD>˵<EFBFBD>
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
@ -254,11 +253,9 @@ void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity)
|
||||
}
|
||||
);
|
||||
|
||||
// 警속꽉데淃
|
||||
addEntiy = new QAction(tr("Add Mesh Component"), this);
|
||||
menu.addAction(addEntiy);
|
||||
|
||||
// 쉥꽉데淃警속돕꽉데櫓
|
||||
addEntiy = new QAction(tr("Add Path Component"), this);
|
||||
menu.addAction(addEntiy);
|
||||
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
||||
@ -273,7 +270,6 @@ void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity)
|
||||
}
|
||||
);
|
||||
|
||||
// 鞫刻꽉데
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
@ -324,35 +320,35 @@ void ModelTreeWidget::OnAddSatelliteEntity() {
|
||||
}
|
||||
|
||||
void ModelTreeWidget::OnTrackEntity(Entity* entity) {
|
||||
OsgCameraManipulator* manipulator = OsgViewer::Get().GetView()->GetCameraManipulator();
|
||||
if (nullptr == manipulator) {
|
||||
LOG_WARN("manipulator is nullptr");
|
||||
return;
|
||||
}
|
||||
//OsgCameraManipulator* manipulator = OsgViewer::Get().GetView()->GetCameraManipulator();
|
||||
//if (nullptr == manipulator) {
|
||||
// LOG_WARN("manipulator is nullptr");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//
|
||||
//osgGA::CameraManipulator* gaManipulator = manipulator->GetManipulator();
|
||||
//osgEarth::Util::EarthManipulator* ccm = dynamic_cast<osgEarth::Util::EarthManipulator*>(gaManipulator);
|
||||
//if (nullptr != ccm) {
|
||||
// if (nullptr != entity) {
|
||||
// osg::MatrixTransform* mt = entity->GetRootComponent()->GetMatrixTransform();
|
||||
// ccm->setNode(mt);
|
||||
// ccm->getSettings()->setTetherMode(osgEarth::Util::EarthManipulator::TETHER_CENTER);
|
||||
// osgEarth::Util::Viewpoint newVP;
|
||||
// newVP.setNode(mt);
|
||||
// double range = mt->getBound().radius() * 10.0;
|
||||
// newVP.range()->set(range, osgEarth::Units::METERS);
|
||||
|
||||
osgGA::CameraManipulator* gaManipulator = manipulator->GetManipulator();
|
||||
osgEarth::Util::EarthManipulator* ccm = dynamic_cast<osgEarth::Util::EarthManipulator*>(gaManipulator);
|
||||
if (nullptr != ccm) {
|
||||
if (nullptr != entity) {
|
||||
osg::MatrixTransform* mt = entity->GetRootComponent()->GetMatrixTransform();
|
||||
ccm->setNode(mt);
|
||||
ccm->getSettings()->setTetherMode(osgEarth::Util::EarthManipulator::TETHER_CENTER);
|
||||
osgEarth::Util::Viewpoint newVP;
|
||||
newVP.setNode(mt);
|
||||
double range = mt->getBound().radius() * 10.0;
|
||||
newVP.range()->set(range, osgEarth::Units::METERS);
|
||||
|
||||
const osg::Vec3 rotation = entity->GetRootComponent()->GetTransform()->GetRotation();
|
||||
newVP.heading()->set(rotation.x(), osgEarth::Units::DEGREES);
|
||||
newVP.pitch()->set(rotation.y() - 15.0, osgEarth::Units::DEGREES);
|
||||
//newVP.roll()->set(rotation.z(), osgEarth::Units::DEGREES);
|
||||
ccm->setViewpoint(newVP, 1.5);
|
||||
//ccm->setTetherMode(osgGA::CameraManipulator::TETHER_CENTER_AND_ROTATION);
|
||||
} else {
|
||||
ccm->clearViewpoint();
|
||||
}
|
||||
}
|
||||
// const osg::Vec3 rotation = entity->GetRootComponent()->GetTransform()->GetRotation();
|
||||
// newVP.heading()->set(rotation.x(), osgEarth::Units::DEGREES);
|
||||
// newVP.pitch()->set(rotation.y() - 15.0, osgEarth::Units::DEGREES);
|
||||
// //newVP.roll()->set(rotation.z(), osgEarth::Units::DEGREES);
|
||||
// ccm->setViewpoint(newVP, 1.5);
|
||||
// //ccm->setTetherMode(osgGA::CameraManipulator::TETHER_CENTER_AND_ROTATION);
|
||||
// } else {
|
||||
// ccm->clearViewpoint();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
void ModelTreeWidget::AddEntity(class QTreeWidgetItem* parent, Entity* entity) {
|
||||
|
@ -15,12 +15,6 @@
|
||||
WorkSpaceDlg::WorkSpaceDlg(QWidget* parent)
|
||||
: Dialog(parent)
|
||||
, ui(new Ui::WorkSpaceDlg) {
|
||||
/* setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);*/
|
||||
|
||||
|
||||
//QWidget* mainDilag_ = new QWidget(this);
|
||||
//layout->addWidget(mainDilag_, 1);
|
||||
SetupUI(ui);
|
||||
InitConnect();
|
||||
|
||||
@ -116,23 +110,23 @@ void WorkSpaceDlg::OnSelectSavePath() {
|
||||
ui->lePath->setText(QString("%1/%2").arg(path_).arg(ui->leName->text()));
|
||||
LOG_INFO("save path: {}", path_.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
void WorkSpaceDlg::InitFrame() {
|
||||
FrameTitleBar* titleBar = new FrameTitleBar(this);
|
||||
titleBar->SetMainWidget(this);
|
||||
|
||||
titleBar->SetSysButton(FrameTitleBar::FTB_ICON | FrameTitleBar::FTB_CLOSE);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
layout->setStretch(0, 0);
|
||||
layout->setStretch(1, 1);
|
||||
layout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
SetTitleBar(titleBar);
|
||||
|
||||
QWidget* mainDilag_ = new QWidget(this);
|
||||
layout->addWidget(mainDilag_, 1);
|
||||
ui->setupUi(mainDilag_);
|
||||
}
|
||||
//
|
||||
//void WorkSpaceDlg::InitFrame() {
|
||||
// FrameTitleBar* titleBar = new FrameTitleBar(this);
|
||||
// titleBar->SetMainWidget(this);
|
||||
//
|
||||
// titleBar->SetSysButton(FrameTitleBar::FTB_ICON | FrameTitleBar::FTB_CLOSE);
|
||||
//
|
||||
// QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
// layout->setContentsMargins(0, 0, 0, 0);
|
||||
// layout->setSpacing(0);
|
||||
//
|
||||
// layout->setStretch(0, 0);
|
||||
// layout->setStretch(1, 1);
|
||||
// layout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
// SetTitleBar(titleBar);
|
||||
//
|
||||
// QWidget* mainDilag_ = new QWidget(this);
|
||||
// layout->addWidget(mainDilag_, 1);
|
||||
// ui->setupUi(mainDilag_);
|
||||
//}
|
||||
|
@ -19,7 +19,7 @@ protected:
|
||||
void OnSure();
|
||||
void OnSelectSavePath();
|
||||
|
||||
void InitFrame();
|
||||
//void InitFrame();
|
||||
|
||||
private:
|
||||
Ui::WorkSpaceDlg* ui;
|
||||
|
@ -68,9 +68,9 @@ std::string StringUtils::ViewpointToString(const osgEarth::Viewpoint& value) {
|
||||
double latitude = location->y();
|
||||
double altitude = location->z();
|
||||
|
||||
double heading = value.heading().get();
|
||||
double pitch = value.pitch().get();
|
||||
double range = value.range().get();
|
||||
double heading = value.heading().get().getValue();
|
||||
double pitch = value.pitch().get().getValue();
|
||||
double range = value.range().get().getValue();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(6);
|
||||
|
@ -143,11 +143,7 @@ void CameraControlManipulator::setByMatrix(const osg::Matrixd& matrix) {
|
||||
fixVerticalAxis(_center, _rotation, true);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Get the position of the manipulator as 4x4 Matrix.*/
|
||||
@ -196,9 +192,6 @@ osg::Matrixd CameraControlManipulator::getMatrix() const {
|
||||
osg::Matrixd::translate(_center);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return matrix;
|
||||
@ -347,8 +340,6 @@ void CameraControlManipulator::rotateYawPitch(osg::Quat& rotation, const double
|
||||
} while (true);
|
||||
}
|
||||
bool CameraControlManipulator::calcMovement() {
|
||||
|
||||
// return if less then two events have been added.
|
||||
if (_ga_t0.get() == NULL || _ga_t1.get() == NULL)
|
||||
return false;
|
||||
|
||||
@ -361,7 +352,7 @@ bool CameraControlManipulator::calcMovement() {
|
||||
// get delta time
|
||||
double eventTimeDelta = _ga_t0->getTime() - _ga_t1->getTime();
|
||||
if (eventTimeDelta < 0.) {
|
||||
OSG_WARN << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl;
|
||||
OSG_WARN << "Manipulator warning: eventTimeDelta = " << eventTimeDelta;
|
||||
eventTimeDelta = 0.;
|
||||
}
|
||||
|
||||
@ -1184,7 +1175,7 @@ bool CameraControlManipulator::handleMouseWheel(const osgGA::GUIEventAdapter& ea
|
||||
|
||||
view->getCamera()->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar);
|
||||
|
||||
float scale = 1.0f + dy;
|
||||
float scale = 1.0f + static_cast<float>(dy);
|
||||
|
||||
_distance *= scale;
|
||||
|
||||
|
@ -19,17 +19,6 @@
|
||||
#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));
|
||||
@ -39,51 +28,11 @@ 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_) {
|
||||
if (nullptr == pView) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -91,68 +40,6 @@ 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;
|
||||
@ -185,9 +72,6 @@ void OsgView::Uninitialize(void) {
|
||||
}
|
||||
|
||||
initialized_ = false;
|
||||
if (nullptr != graphiceWindow_) {
|
||||
graphiceWindow_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool OsgView::SetCameraManipulator(OsgCameraManipulator* cameraManipulator) {
|
||||
@ -204,8 +88,3 @@ bool OsgView::SetCameraManipulator(OsgCameraManipulator* cameraManipulator) {
|
||||
view_->setCameraManipulator(cameraMainp);
|
||||
return true;
|
||||
}
|
||||
|
||||
osgGA::EventQueue* OsgView::GetEventQueue() const {
|
||||
assert(nullptr != view_);
|
||||
return view_->getEventQueue();
|
||||
}
|
||||
|
@ -13,19 +13,8 @@ public:
|
||||
OsgView(QObject* parent = nullptr) noexcept;
|
||||
~OsgView();
|
||||
|
||||
void InitGraphiceWindow(int x, int y, int width, int height,
|
||||
WId windowHandle, const char* name = "",
|
||||
bool windowDecoration = false);
|
||||
void InitView(osgViewer::View* pView);
|
||||
osgViewer::View* GetView(void) const;
|
||||
void Resize(int x, int y, int width, int height);
|
||||
void MouseMotion(int x, int y);
|
||||
void MousePress(int x, int y, unsigned int button);
|
||||
void MouseRelease(int x, int y, unsigned int button);
|
||||
void MouseWheel(int wheel);
|
||||
void KeyPress(QKeyEvent* keyInput);
|
||||
void KeyRelease(QKeyEvent* keyInput);
|
||||
void SetKeyModifiers(int mask);
|
||||
|
||||
void Initialize(OsgCameraManipulator* cameraManipulator);
|
||||
void Uninitialize(void);
|
||||
@ -37,11 +26,8 @@ public:
|
||||
return cameraManipulator_;
|
||||
}
|
||||
|
||||
protected:
|
||||
osgGA::EventQueue* GetEventQueue() const;
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::GraphicsContext> graphiceWindow_;
|
||||
osg::ref_ptr<osgViewer::View> view_;
|
||||
osg::ref_ptr<OsgViewUI> viewUI_;
|
||||
OsgCameraManipulator* cameraManipulator_{ nullptr };
|
||||
|
@ -4,167 +4,136 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osgEarth/GLUtils>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include "common/SpdLogger.h"
|
||||
#include "viewer/OsgView.h"
|
||||
#include "viewer/IUpdateRender.h"
|
||||
#include "workspace/WorkSpaceManager.h"
|
||||
|
||||
template<> OsgViewer* Singleton<OsgViewer>::instance_ = nullptr;
|
||||
|
||||
constexpr QEvent::Type sOsgViewUpdateEvent{ QEvent::Type(QEvent::User + 1) };
|
||||
|
||||
OsgViewer::OsgViewer(QObject* parent) noexcept
|
||||
: QObject(parent) {
|
||||
LOG_INFO("actor, self={}", fmt::ptr(this));
|
||||
|
||||
//compositeViewer_->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false);
|
||||
osgEarth::initialize();
|
||||
compositeViewer_ = new osgViewer::CompositeViewer;
|
||||
compositeViewer_->setReleaseContextAtEndOfFrameHint(false);
|
||||
compositeViewer_->setKeyEventSetsDone(0);
|
||||
osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper("osg::Image");
|
||||
// compositeViewer_->getDatabasePager()->setUnrefImageDataAfterApplyPolicy( true, false );
|
||||
compositeViewer_->setThreadingModel(osgViewer::ViewerBase::ThreadingModel::SingleThreaded);
|
||||
|
||||
}
|
||||
|
||||
OsgViewer::~OsgViewer() {
|
||||
compositeViewer_ = nullptr;
|
||||
LOG_INFO("dctor, self={}", fmt::ptr(this));
|
||||
}
|
||||
|
||||
void OsgViewer::OnDestory() {
|
||||
|
||||
}
|
||||
|
||||
void OsgViewer::OnFrame(void) {
|
||||
assert(nullptr != compositeViewer_);
|
||||
|
||||
WorkSpaceManager::Get().OnFrame();
|
||||
|
||||
if (IsDone()) {
|
||||
RenderUpdate();
|
||||
|
||||
compositeViewer_->frame();
|
||||
}
|
||||
|
||||
qApp->postEvent(this, new QEvent(sOsgViewUpdateEvent));
|
||||
}
|
||||
|
||||
OsgView* OsgViewer::CreateView(int x, int y, int width, int height, void* winHandle) {
|
||||
OsgView* view = new OsgView(this);
|
||||
if (nullptr == view) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
view->InitGraphiceWindow(x, y, width, height, reinterpret_cast<WId>(winHandle), "dytView");
|
||||
|
||||
OnAddView(view, x, y, width, height);
|
||||
//compositeViewer_->setRealizeOperation(new osgEarth::GL3RealizeOperation());
|
||||
return view;
|
||||
}
|
||||
|
||||
void OsgViewer::DestroyView(OsgView* osgView) {
|
||||
if (nullptr == osgView) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnRemoveView(osgView);
|
||||
}
|
||||
|
||||
bool OsgViewer::IsDone() const {
|
||||
assert(nullptr != compositeViewer_);
|
||||
bool done = compositeViewer_->done();
|
||||
return !done && initalized_;
|
||||
}
|
||||
|
||||
OsgView* OsgViewer::GetView() const {
|
||||
if (osgViews_.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *(osgViews_.begin());
|
||||
}
|
||||
|
||||
bool OsgViewer::Initialize(void) {
|
||||
if (initalized_) {
|
||||
return initalized_;
|
||||
}
|
||||
initalized_ = true;
|
||||
compositeViewer_->setRealizeOperation(new osgEarth::GL3RealizeOperation());
|
||||
return initalized_;
|
||||
}
|
||||
|
||||
void OsgViewer::Uninitialize(void) {
|
||||
initalized_ = false;
|
||||
}
|
||||
|
||||
void OsgViewer::RegistRender(IUpdateRender* render) {
|
||||
if (nullptr == render) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto itor = std::find_if(updateRenderList_.begin(), updateRenderList_.end(), [render](auto& item) {
|
||||
return render == item;
|
||||
}
|
||||
);
|
||||
|
||||
if (itor != updateRenderList_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateRenderList_.push_back(render);
|
||||
}
|
||||
|
||||
void OsgViewer::UnRegistRender(IUpdateRender* render) {
|
||||
if (nullptr == render) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto itor = std::find_if(updateRenderList_.begin(), updateRenderList_.end(), [render](auto& item) {
|
||||
return render == item;
|
||||
}
|
||||
);
|
||||
if (itor != updateRenderList_.end()) {
|
||||
updateRenderList_.erase(itor);
|
||||
}
|
||||
}
|
||||
|
||||
void OsgViewer::customEvent(QEvent* event) {
|
||||
if (sOsgViewUpdateEvent == event->type()) {
|
||||
OnFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void OsgViewer::OnStartPlay() {
|
||||
compositeViewer_->setStartTick(0);
|
||||
}
|
||||
|
||||
void OsgViewer::OnAddView(OsgView* osgView, int x, int y, int width, int height) {
|
||||
osgViewer::View* view = new osgViewer::View;
|
||||
osgView->InitView(view);
|
||||
|
||||
compositeViewer_->addView(view);
|
||||
osgViews_.insert(osgView);
|
||||
}
|
||||
|
||||
void OsgViewer::OnRemoveView(OsgView* osgView) {
|
||||
if (nullptr == osgView || nullptr == osgView->GetView()) {
|
||||
LOG_WARN("osgview is nullptr or getview is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
osgViews_.erase(osgView);
|
||||
compositeViewer_->removeView(osgView->GetView());
|
||||
}
|
||||
|
||||
void OsgViewer::RenderUpdate() {
|
||||
osg::FrameStamp* frameStamp = compositeViewer_->getFrameStamp();
|
||||
double dt = frameStamp->getSimulationTime();
|
||||
for (auto render : updateRenderList_) {
|
||||
render->Render(dt);
|
||||
}
|
||||
}
|
||||
//
|
||||
//template<> OsgViewer* Singleton<OsgViewer>::instance_ = nullptr;
|
||||
//
|
||||
//constexpr QEvent::Type sOsgViewUpdateEvent{ QEvent::Type(QEvent::User + 1) };
|
||||
//
|
||||
//OsgViewer::OsgViewer(QObject* parent) noexcept
|
||||
// : QObject(parent) {
|
||||
// LOG_INFO("actor, self={}", fmt::ptr(this));
|
||||
//
|
||||
// //compositeViewer_->getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false);
|
||||
//}
|
||||
//
|
||||
//OsgViewer::~OsgViewer() {
|
||||
// compositeViewer_ = nullptr;
|
||||
// LOG_INFO("dctor, self={}", fmt::ptr(this));
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::OnDestory() {
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::OnFrame(void) {
|
||||
// assert(nullptr != compositeViewer_);
|
||||
//
|
||||
// WorkSpaceManager::Get().OnFrame();
|
||||
//
|
||||
// if (IsDone()) {
|
||||
// RenderUpdate();
|
||||
//
|
||||
// compositeViewer_->frame();
|
||||
// }
|
||||
//
|
||||
// qApp->postEvent(this, new QEvent(sOsgViewUpdateEvent));
|
||||
//}
|
||||
//
|
||||
//bool OsgViewer::IsDone() const {
|
||||
// assert(nullptr != compositeViewer_);
|
||||
// bool done = compositeViewer_->done();
|
||||
// return !done && initalized_;
|
||||
//}
|
||||
//
|
||||
//OsgView* OsgViewer::GetView() const {
|
||||
// if (osgViews_.empty()) {
|
||||
// return nullptr;
|
||||
// }
|
||||
//
|
||||
// return *(osgViews_.begin());
|
||||
//}
|
||||
//
|
||||
//bool OsgViewer::Initialize(void) {
|
||||
// if (initalized_) {
|
||||
// return initalized_;
|
||||
// }
|
||||
// initalized_ = true;
|
||||
// return initalized_;
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::Uninitialize(void) {
|
||||
// initalized_ = false;
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::RegistRender(IUpdateRender* render) {
|
||||
// if (nullptr == render) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto itor = std::find_if(updateRenderList_.begin(), updateRenderList_.end(), [render](auto& item) {
|
||||
// return render == item;
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// if (itor != updateRenderList_.end()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// updateRenderList_.push_back(render);
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::UnRegistRender(IUpdateRender* render) {
|
||||
// if (nullptr == render) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto itor = std::find_if(updateRenderList_.begin(), updateRenderList_.end(), [render](auto& item) {
|
||||
// return render == item;
|
||||
// }
|
||||
// );
|
||||
// if (itor != updateRenderList_.end()) {
|
||||
// updateRenderList_.erase(itor);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::customEvent(QEvent* event) {
|
||||
// if (sOsgViewUpdateEvent == event->type()) {
|
||||
// OnFrame();
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::OnStartPlay() {
|
||||
// compositeViewer_->setStartTick(0);
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::OnAddView(OsgView* osgView, int x, int y, int width, int height) {
|
||||
// osgViewer::View* view = new osgViewer::View;
|
||||
// osgView->InitView(view);
|
||||
//
|
||||
// compositeViewer_->addView(view);
|
||||
// osgViews_.insert(osgView);
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::OnRemoveView(OsgView* osgView) {
|
||||
// if (nullptr == osgView || nullptr == osgView->GetView()) {
|
||||
// LOG_WARN("osgview is nullptr or getview is nullptr");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// osgViews_.erase(osgView);
|
||||
// compositeViewer_->removeView(osgView->GetView());
|
||||
//}
|
||||
//
|
||||
//void OsgViewer::RenderUpdate() {
|
||||
// osg::FrameStamp* frameStamp = compositeViewer_->getFrameStamp();
|
||||
// double dt = frameStamp->getSimulationTime();
|
||||
// for (auto render : updateRenderList_) {
|
||||
// render->Render(dt);
|
||||
// }
|
||||
//}
|
||||
|
@ -11,44 +11,47 @@
|
||||
|
||||
class OsgView;
|
||||
class IUpdateRender;
|
||||
|
||||
class OsgViewer : public QObject, public Singleton<OsgViewer> {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OsgViewer(QObject* parent = nullptr) noexcept;
|
||||
~OsgViewer() override;
|
||||
void OnDestory();
|
||||
|
||||
void OnFrame(void);
|
||||
class OsgView* CreateView(int x, int y, int width, int height, void* winHandle);
|
||||
void DestroyView(OsgView* view);
|
||||
bool IsDone(void) const;
|
||||
|
||||
OsgView* GetView() const;
|
||||
|
||||
bool Initialize(void);
|
||||
void Uninitialize(void);
|
||||
|
||||
void RegistRender(IUpdateRender* render);
|
||||
void UnRegistRender(IUpdateRender* render);
|
||||
|
||||
protected:
|
||||
void customEvent(QEvent* event) override;
|
||||
|
||||
void OnStartPlay();
|
||||
|
||||
void OnAddView(OsgView* view, int x, int y, int width, int height);
|
||||
void OnRemoveView(OsgView* view);
|
||||
void RenderUpdate();
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osgViewer::CompositeViewer> compositeViewer_;
|
||||
bool initalized_{ false };
|
||||
|
||||
using OsgViewSet = std::set<OsgView*>;
|
||||
OsgViewSet osgViews_;
|
||||
|
||||
using UpdateRenderList = std::vector<IUpdateRender*>;
|
||||
UpdateRenderList updateRenderList_;
|
||||
};
|
||||
//
|
||||
//class OsgViewer : public QObject, public Singleton<OsgViewer> {
|
||||
// Q_OBJECT
|
||||
//
|
||||
//public:
|
||||
// explicit OsgViewer(QObject* parent = nullptr) noexcept;
|
||||
// ~OsgViewer() override;
|
||||
//
|
||||
// void SetViewer(osgViewer::CompositeViewer* viewer) {
|
||||
// compositeViewer_ = viewer;
|
||||
// }
|
||||
// void OnDestory();
|
||||
//
|
||||
// void OnFrame(void);
|
||||
//
|
||||
// bool IsDone(void) const;
|
||||
//
|
||||
// OsgView* GetView() const;
|
||||
//
|
||||
// bool Initialize(void);
|
||||
// void Uninitialize(void);
|
||||
//
|
||||
// void RegistRender(IUpdateRender* render);
|
||||
// void UnRegistRender(IUpdateRender* render);
|
||||
//
|
||||
//protected:
|
||||
// void customEvent(QEvent* event) override;
|
||||
//
|
||||
// void OnStartPlay();
|
||||
//
|
||||
// void OnAddView(OsgView* view, int x, int y, int width, int height);
|
||||
// void OnRemoveView(OsgView* view);
|
||||
// void RenderUpdate();
|
||||
//
|
||||
//private:
|
||||
// osgViewer::CompositeViewer* compositeViewer_;
|
||||
// bool initalized_{ false };
|
||||
//
|
||||
// using OsgViewSet = std::set<OsgView*>;
|
||||
// OsgViewSet osgViews_;
|
||||
//
|
||||
// using UpdateRenderList = std::vector<IUpdateRender*>;
|
||||
// UpdateRenderList updateRenderList_;
|
||||
//};
|
||||
|
@ -1,71 +1,151 @@
|
||||
#include "viewer/OsgWidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include <QWindow>
|
||||
#include <QGridLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QScreen>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
|
||||
#include "viewer/OSGRendererImpl.h"
|
||||
#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"
|
||||
|
||||
OsgWidget::OsgWidget(QWidget* parent)
|
||||
: QOpenGLWidget(parent)
|
||||
, renderer_(nullptr)
|
||||
{
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void OsgWidget::initializeGL()
|
||||
|
||||
OsgWidget::OsgWidget(QWidget* parent, Qt::WindowFlags f)
|
||||
: QWidget(parent, f)
|
||||
{
|
||||
renderer_ = new OSGRendererImpl(this);
|
||||
renderer_->setup(this);
|
||||
QScreen *screen = windowHandle() && windowHandle()->screen() ? windowHandle()->screen() : qApp->screens().front();
|
||||
renderer_->setupOSG(width(), height(), screen->devicePixelRatio());
|
||||
emit initialized();
|
||||
// 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);
|
||||
|
||||
connect( &timer_, SIGNAL(timeout()), this, SLOT(update()) );
|
||||
timer_.start( 10 );
|
||||
}
|
||||
|
||||
void OsgWidget::resizeGL(int w, int h)
|
||||
{
|
||||
QScreen *screen = windowHandle() && windowHandle()->screen() ? windowHandle()->screen() : qApp->screens().front();
|
||||
renderer_->resize(w, h, screen->devicePixelRatio());
|
||||
void 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());
|
||||
}
|
||||
|
||||
void OsgWidget::paintGL()
|
||||
{
|
||||
renderer_->render();
|
||||
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::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
renderer_->keyPressEvent(event);
|
||||
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();
|
||||
}
|
||||
|
||||
void OsgWidget::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
renderer_->keyReleaseEvent(event);
|
||||
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());
|
||||
}
|
||||
|
||||
void OsgWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
renderer_->mousePressEvent(event);
|
||||
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::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
renderer_->mouseReleaseEvent(event);
|
||||
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::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
renderer_->mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
void OsgWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
renderer_->mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void OsgWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
renderer_->wheelEvent(event);
|
||||
void OsgWidget::paintEvent(QPaintEvent*) {
|
||||
frame();
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QTimer>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
#include "osgqt/GraphicsWindowQt.h"
|
||||
|
||||
class OSGRendererImpl;
|
||||
class OEScene;
|
||||
|
||||
class OsgWidget : public QOpenGLWidget {
|
||||
class OsgWidget : public QWidget, public osgViewer::CompositeViewer {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OsgWidget(QWidget *parent = nullptr);
|
||||
OsgWidget(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr);
|
||||
|
||||
void Initialize(void);
|
||||
void LoadDefaultScene(void);
|
||||
void OnLoadDyt(const QString& path);
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
void signalResetWorkSpace();
|
||||
void signalScaleInfo(const QString&);
|
||||
|
||||
protected:
|
||||
void initializeGL() override;
|
||||
void resizeGL(int w, int h) override;
|
||||
void paintGL() override;
|
||||
osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h,
|
||||
const std::string& name="", bool windowDecoration=false );
|
||||
QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw);
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
void paintEvent( QPaintEvent* /*event*/ ) override;
|
||||
|
||||
void keyPressEvent( QKeyEvent* event ) override;
|
||||
void keyReleaseEvent( QKeyEvent* event ) override;
|
||||
void mousePressEvent( QMouseEvent* event ) override;
|
||||
void mouseReleaseEvent( QMouseEvent* event ) override;
|
||||
void mouseDoubleClickEvent( QMouseEvent* event ) override;
|
||||
void mouseMoveEvent( QMouseEvent* event ) override;
|
||||
void wheelEvent( QWheelEvent* event ) override;
|
||||
|
||||
private:
|
||||
OSGRendererImpl *renderer_;
|
||||
QTimer timer_;
|
||||
|
||||
osg::ref_ptr<OEScene> activeScene_;
|
||||
osg::ref_ptr<class OsgViewUI> viewUI_;
|
||||
class WorkSpace* workspace_{ nullptr };
|
||||
osg::ref_ptr<osgViewer::View> view_;
|
||||
// class OsgView* view_{nullptr};
|
||||
};
|
||||
|
||||
|
@ -13,12 +13,10 @@
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
#include <osgEarth/EarthManipulator>
|
||||
#include <osgEarth/Viewpoint>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
#include <osgEarth/GeoMath>
|
||||
|
||||
#include "config.h"
|
||||
#include "app/Application.h"
|
||||
#include "common/SpdLogger.h"
|
||||
#include "viewer/OsgView.h"
|
||||
#include "viewer/OsgViewer.h"
|
||||
@ -52,12 +50,12 @@ QtOsgViewWidget::~QtOsgViewWidget() {
|
||||
|
||||
void QtOsgViewWidget::keyPressEvent(QKeyEvent* event) {
|
||||
assert(nullptr != view_);
|
||||
view_->KeyPress(event);
|
||||
// view_->KeyPress(event);
|
||||
}
|
||||
|
||||
void QtOsgViewWidget::keyReleaseEvent(QKeyEvent* event) {
|
||||
assert(nullptr != view_);
|
||||
view_->KeyRelease(event);
|
||||
// view_->KeyRelease(event);
|
||||
}
|
||||
|
||||
void QtOsgViewWidget::Initialize(void) {
|
||||
@ -68,26 +66,26 @@ void QtOsgViewWidget::Initialize(void) {
|
||||
WId handle= winId();
|
||||
|
||||
double pixelRatio = screen()->devicePixelRatio();
|
||||
view_ = OsgViewer::Get().CreateView(x(), y(), width() * pixelRatio, height() * pixelRatio, reinterpret_cast<void*>(handle));
|
||||
if (nullptr == view_) {
|
||||
LOG_ERROR("view is nullptr");
|
||||
return;
|
||||
}
|
||||
// view_ = OsgViewer::Get().CreateView(x(), y(), width() * pixelRatio, height() * pixelRatio, reinterpret_cast<void*>(handle));
|
||||
// if (nullptr == view_) {
|
||||
// LOG_ERROR("view is nullptr");
|
||||
// return;
|
||||
// }
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
activeScene_ = new OEScene;
|
||||
activeScene_->AttachView(view_);
|
||||
activeScene_->InitEventHandle(view_);
|
||||
// activeScene_->AttachView(view_);
|
||||
// activeScene_->InitEventHandle(view_);
|
||||
|
||||
|
||||
osgEarth::Util::EarthManipulator* manipulator = new osgEarth::Util::EarthManipulator;
|
||||
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged, [](WorkSpace* workspace) {
|
||||
connect(&WorkSpaceManager::Get(), &WorkSpaceManager::WorkSpaceChanged, [this](WorkSpace* workspace) {
|
||||
LOG_INFO("WorkSpaceChanged");
|
||||
if (nullptr == workspace) {
|
||||
return;
|
||||
}
|
||||
OsgCameraManipulator* manipulator = OsgViewer::Get().GetView()->GetCameraManipulator();
|
||||
OsgCameraManipulator* manipulator = view_->GetCameraManipulator();
|
||||
if (nullptr == manipulator) {
|
||||
LOG_WARN("manipulator is nullptr");
|
||||
return;
|
||||
@ -118,17 +116,16 @@ void QtOsgViewWidget::Uninitialize(void) {
|
||||
scene_ = nullptr;
|
||||
}*/
|
||||
|
||||
if (nullptr != view_) {
|
||||
view_->Uninitialize();
|
||||
OsgViewer::Get().DestroyView(view_);
|
||||
}
|
||||
// if (nullptr != view_) {
|
||||
// view_->Uninitialize();
|
||||
// OsgViewer::Get().DestroyView(view_);
|
||||
// }
|
||||
}
|
||||
|
||||
void QtOsgViewWidget::LoadDefaultScene(void) {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +158,6 @@ void QtOsgViewWidget::resizeEvent(QResizeEvent* event) {
|
||||
|
||||
devicePixelRatio_ = screen()->devicePixelRatio();
|
||||
const QSize& size = event->size();
|
||||
view_->Resize(0, 0, size.width() * devicePixelRatio_, size.height() * devicePixelRatio_);
|
||||
// view_->Resize(0, 0, size.width() * devicePixelRatio_, size.height() * devicePixelRatio_);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "viewer/OsgViewer.h"
|
||||
|
||||
UpdateRenderStd::UpdateRenderStd() {
|
||||
OsgViewer::Get().RegistRender(this);
|
||||
//OsgViewer::Get().RegistRender(this);
|
||||
}
|
||||
|
||||
UpdateRenderStd::~UpdateRenderStd() {
|
||||
@ -11,5 +11,5 @@ UpdateRenderStd::~UpdateRenderStd() {
|
||||
}
|
||||
|
||||
void UpdateRenderStd::OnDestroy() {
|
||||
OsgViewer::Get().UnRegistRender(this);
|
||||
//OsgViewer::Get().UnRegistRender(this);
|
||||
}
|
||||
|
@ -59,6 +59,18 @@ void WorkSpace::RemoveEntity(Entity* entity) {
|
||||
}
|
||||
}
|
||||
|
||||
void WorkSpace::SetActiveScene(OEScene* scene) {
|
||||
dyt_check(nullptr != scene);
|
||||
scene_ = scene;
|
||||
|
||||
osgEarth::Viewpoint vp;
|
||||
vp.name() = "home";
|
||||
vp.focalPoint()->set(scene->GetSrs(), -121.488, 46.2054, 0, osgEarth::AltitudeMode::ALTMODE_ABSOLUTE);
|
||||
vp.pitch() = -50.0;
|
||||
vp.range() = 100000;
|
||||
homeViewpoint_ = vp;
|
||||
}
|
||||
|
||||
bool WorkSpace::SetTimestep(Timestep* timestep) {
|
||||
if (!timestep) {
|
||||
return false;
|
||||
|
@ -95,10 +95,7 @@ public:
|
||||
return entities_;
|
||||
}
|
||||
|
||||
void SetActiveScene(OEScene* scene) {
|
||||
dyt_check(nullptr != scene);
|
||||
scene_ = scene;
|
||||
}
|
||||
void SetActiveScene(OEScene* scene);
|
||||
|
||||
OEScene* GetActiveScene() const {
|
||||
dyt_check(nullptr != scene_);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include<time.h>
|
||||
#include <QSettings>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
#include "app/Application.h"
|
||||
#include "workspace/WorkSpace.h"
|
||||
@ -64,8 +65,12 @@ WorkSpace* WorkSpaceManager::LoadDefaultWorkspace(class OEScene* secen) {
|
||||
void WorkSpaceManager::SaveDefaultWorkspace() {
|
||||
const QString iniFile = GetDefaultWorkSpaceName();
|
||||
if (!QFile::exists(iniFile)) {
|
||||
LOG_ERROR("default workspace file not exist:{}", iniFile.toStdString());
|
||||
return;
|
||||
QFileInfo fileInfo(iniFile);
|
||||
QDir dir;
|
||||
if (!dir.mkdir(fileInfo.absolutePath())) {
|
||||
LOG_ERROR("default workspace file not exist:{}", iniFile.toStdString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorkSpace* current = GetCurrent();
|
||||
@ -116,6 +121,7 @@ bool WorkSpaceManager::Remove(WorkSpace* workspace) {
|
||||
return true;
|
||||
}
|
||||
workSpaces_.erase(itor);
|
||||
return true;
|
||||
}
|
||||
|
||||
WorkSpace* WorkSpaceManager::LoadDyt(const QString& dyt) {
|
||||
|
Loading…
Reference in New Issue
Block a user