add scene world postion get geo
This commit is contained in:
parent
9df23631c8
commit
743565fd75
@ -103,6 +103,64 @@ osg::Viewport* OEScene::GetViewport() const {
|
||||
return curentView_->getCamera()->getViewport();
|
||||
}
|
||||
|
||||
bool OEScene::ScreenToWorldCoordinate(int x, int y, osg::Vec3d* output) const {
|
||||
if (nullptr == output) {
|
||||
LOG_WARN("OEScene::ScreenToWorldCoordinate - worldPoint is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::Camera* camera = curentView_->getCamera();
|
||||
if (!camera) {
|
||||
LOG_WARN("OEScene::ScreenToWorldCoordinate - camera is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector =
|
||||
new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y);
|
||||
|
||||
osgUtil::IntersectionVisitor iv(intersector.get());
|
||||
camera->accept(iv);
|
||||
|
||||
if (intersector->containsIntersections()) {
|
||||
osgUtil::LineSegmentIntersector::Intersections& intersections = intersector->getIntersections();
|
||||
osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
|
||||
|
||||
osg::Vec3d worldPoint = intersection.getWorldIntersectPoint();
|
||||
|
||||
Vec3ToLocation(worldPoint, output);
|
||||
|
||||
LOG_INFO("OsgWidget::ScreenToWorldCoordinate - Screen({}, {}) -> World({:.6f}, {:.6f}, {:.2f})",
|
||||
x, y, output->x(), output->y(), output->z());
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_WARN("OsgWidget::ScreenToWorldCoordinate - No intersection found for screen coordinates ({}, {})", x, y);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OEScene::Vec3ToLocation(const osg::Vec3& input, osg::Vec3d* output) const {
|
||||
if (nullptr == output) {
|
||||
LOG_WARN("OEScene::vec3ToLocation - output is null");
|
||||
return false;
|
||||
}
|
||||
const osgEarth::SpatialReference* srs = OEScene::GetSrs();
|
||||
if (!srs) {
|
||||
LOG_WARN("OEScene::vec3ToLocation - spatial reference system is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
osgEarth::GeoPoint geoPoint;
|
||||
geoPoint.fromWorld(srs, input);
|
||||
|
||||
const osgEarth::SpatialReference* wgs84 = osgEarth::SpatialReference::get("wgs84");
|
||||
if (wgs84) {
|
||||
geoPoint = geoPoint.transform(wgs84);
|
||||
}
|
||||
|
||||
output->set(geoPoint.x(), geoPoint.y(),geoPoint.z());
|
||||
return true;
|
||||
}
|
||||
|
||||
const osgEarth::SpatialReference* OEScene::GetSrs() {
|
||||
dyt_check(nullptr != g_srs_);
|
||||
return g_srs_;
|
||||
|
||||
@ -35,6 +35,8 @@ public:
|
||||
}
|
||||
|
||||
osg::Viewport* GetViewport() const;
|
||||
bool ScreenToWorldCoordinate(int x, int y, osg::Vec3d* output) const;
|
||||
bool Vec3ToLocation(const osg::Vec3& input, osg::Vec3d* output) const;
|
||||
|
||||
static const osgEarth::SpatialReference* GetSrs();
|
||||
|
||||
|
||||
@ -2082,12 +2082,12 @@
|
||||
<context>
|
||||
<name>OsgWidget</name>
|
||||
<message>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="122"/>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="129"/>
|
||||
<source>warning</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="123"/>
|
||||
<location filename="../viewer/OsgWidget.cpp" line="130"/>
|
||||
<source>open dyt file failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
||||
@ -57,7 +57,7 @@ void PresetModelListWidget::startDrag(Qt::DropActions supportedActions) {
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// Draw semi-transparent background
|
||||
painter.setBrush(QColor(255, 255, 255, 80)); // White with 70% opacity
|
||||
painter.setBrush(QColor(255, 255, 255, 50)); // White with 70% opacity
|
||||
painter.setPen(QPen(QColor(200, 200, 200, 200), 1)); // Light gray border
|
||||
painter.drawRoundedRect(2, 2, totalWidth - 4, totalHeight - 4, 4, 4);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
<item>
|
||||
<widget class="QToolBox" name="PresetModelToolBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="shipPage">
|
||||
<property name="geometry">
|
||||
@ -119,8 +119,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>290</width>
|
||||
<height>470</height>
|
||||
<width>98</width>
|
||||
<height>73</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@ -159,8 +159,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>290</width>
|
||||
<height>470</height>
|
||||
<width>98</width>
|
||||
<height>73</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#include <QDebug>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgEarthUtil/EarthManipulator>
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
#include <osgEarth/SpatialReference>
|
||||
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
@ -24,6 +26,11 @@
|
||||
#include "workspace/WorkSpace.h"
|
||||
#include "scutcheon/osgScutcheon.h"
|
||||
|
||||
#include "entities/EntitiesManager.h"
|
||||
#include "entities/ComponentFactory.h"
|
||||
#include "entities/Entity.h"
|
||||
#include "entities/Component.h"
|
||||
|
||||
static void ConfigureView( osgViewer::View* view ) {
|
||||
view->addEventHandler(new osgViewer::StatsHandler());
|
||||
view->addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
@ -245,13 +252,102 @@ void OsgWidget::dropEvent(QDropEvent* event) {
|
||||
}
|
||||
|
||||
void OsgWidget::OnPresetModelDropped(const QString& modelType, const QString& modelName, const QPointF& position) {
|
||||
// TODO: 实现预制模型拖拽处理逻辑
|
||||
// 1. 将屏幕坐标转换为世界坐标
|
||||
// 2. 创建对应的Entity和MeshComponent
|
||||
// 3. 添加到场景中
|
||||
|
||||
LOG_INFO("OsgWidget::OnPresetModelDropped - Dropped model type:{} name:{} position:({}, {})", modelType.toStdString(), modelName.toStdString(), position.x(), position.y());
|
||||
|
||||
// 这里暂时只是输出调试信息,后续需要集成实体系统
|
||||
WorkSpace* currentWorkSpace = WorkSpaceManager::Get().GetCurrent();
|
||||
if (nullptr == currentWorkSpace) {
|
||||
LOG_WARN("OsgWidget::OnPresetModelDropped - Current workspace is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
// 将屏幕坐标转换为世界坐标
|
||||
double longitude, latitude, height;
|
||||
if (!ScreenToWorldCoordinate(static_cast<int>(position.x()), static_cast<int>(position.y()), longitude, latitude, height)) {
|
||||
LOG_WARN("OsgWidget::OnPresetModelDropped - Failed to convert screen coordinates to world coordinates");
|
||||
// 使用默认位置
|
||||
longitude = 0.0;
|
||||
latitude = 0.0;
|
||||
height = 0.0;
|
||||
}
|
||||
|
||||
QString meshPath;
|
||||
if (modelType == "boke") {
|
||||
meshPath = "boke/boke.ive";
|
||||
} else if (modelType == "lsjhqt") {
|
||||
meshPath = "lsjhqt/lsjhqt.flt";
|
||||
} else if (modelType == "nimizi") {
|
||||
meshPath = "nimizi/nimizi.ive";
|
||||
} else if (modelType == "tkdlj") {
|
||||
meshPath = "tkdlj/tkdlj.ive";
|
||||
} else if (modelType == "jiaofan") {
|
||||
meshPath = "jf/decorative-shape-008.obj";
|
||||
} else if (modelType == "satellite") {
|
||||
meshPath = "satellite/satellite.ive";
|
||||
} else {
|
||||
LOG_WARN("OsgWidget::OnPresetModelDropped - Unknown model type: {}", modelType.toStdString());
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建实体
|
||||
Entity* entity = EntitiesManager::Get().CreateMesh(meshPath);
|
||||
if (nullptr == entity) {
|
||||
LOG_ERROR("OsgWidget::OnPresetModelDropped - Failed to create entity for mesh: {}", meshPath.toStdString());
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置实体名称(添加序号避免重名)
|
||||
int count = currentWorkSpace->GetEntities().size();
|
||||
entity->SetName(QString("%1_%2").arg(modelName).arg(count));
|
||||
|
||||
// 设置实体位置
|
||||
SceneComponent* rootComponent = entity->GetRootComponent();
|
||||
if (rootComponent) {
|
||||
// 将经纬高坐标转换为OSG世界坐标
|
||||
osg::Vec3 worldPos(longitude, latitude, height);
|
||||
rootComponent->SetLocation(worldPos);
|
||||
LOG_INFO("OsgWidget::OnPresetModelDropped - Set entity position to ({:.6f}, {:.6f}, {:.2f})", longitude, latitude, height);
|
||||
}
|
||||
|
||||
// 添加到工作空间
|
||||
currentWorkSpace->AddEntity(entity);
|
||||
|
||||
// 添加标签组件
|
||||
if (rootComponent) {
|
||||
SceneComponent* labelComponent = ComponentFactory::Create("LabelComponent", rootComponent);
|
||||
if (labelComponent) {
|
||||
labelComponent->AttachTo(rootComponent);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是卫星类型,添加锥波组件
|
||||
if (modelType == "satellite") {
|
||||
if (rootComponent) {
|
||||
SceneComponent* coneWaveComponent = ComponentFactory::Create("ConeWaveComponent", rootComponent);
|
||||
if (coneWaveComponent) {
|
||||
coneWaveComponent->AttachTo(rootComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO("OsgWidget::OnPresetModelDropped - Successfully created entity: {} with mesh: {} at position ({:.6f}, {:.6f}, {:.2f})",
|
||||
entity->GetName().toStdString(), meshPath.toStdString(), longitude, latitude, height);
|
||||
}
|
||||
|
||||
bool OsgWidget::ScreenToWorldCoordinate(int x, int y, double& longitude, double& latitude, double& height) {
|
||||
if (!activeScene_.valid()) {
|
||||
LOG_WARN("OsgWidget::ScreenToWorldCoordinate - active scene is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::Vec3d output;
|
||||
if (!activeScene_->ScreenToWorldCoordinate(x, y, &output)) {
|
||||
LOG_WARN("OsgWidget::ScreenToWorldCoordinate - Failed to convert screen coordinates to world coordinates");
|
||||
return false;
|
||||
}
|
||||
|
||||
longitude = output.x();
|
||||
latitude = output.y();
|
||||
height = output.z();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <QTimer>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
@ -43,6 +43,8 @@ public slots:
|
||||
*/
|
||||
void OnPresetModelDropped(const QString& modelType, const QString& modelName, const QPointF& position = QPointF());
|
||||
|
||||
bool ScreenToWorldCoordinate(int x, int y, double& longitude, double& latitude, double& altitude);
|
||||
|
||||
|
||||
private:
|
||||
QTimer timer_;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user