add scene world postion get geo

This commit is contained in:
brige 2025-11-01 19:33:08 +08:00
parent 9df23631c8
commit 743565fd75
7 changed files with 173 additions and 15 deletions

View File

@ -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_;

View File

@ -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();

View File

@ -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>

View File

@ -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);

View File

@ -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">

View File

@ -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;
}

View File

@ -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_;