diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 1adb4a48..887fe11d 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -3,8 +3,10 @@ #include "common/RecourceHelper.h" #include "workspace/WorkSpaceManager.h" #include "entities/EntitiesManager.h" +#include "entities/EntityFactory.h" #include "viewer/OsgViewer.h" #include "scene/MeshManager.h" +#include "workspace/PresetModelConfigParser.h" #include "network/NetDriver.h" #include "python/PythonModule.h" @@ -30,9 +32,11 @@ QString Application::GetBinPath() { void Application::Init() { Singleton::Create(this); Singleton::Create(this); + Singleton::Create(this); Singleton::Create(this); Singleton::Create(this); Singleton::Create(this); + Singleton::Create(this); //Singleton::Create(this); connect(&timer_, &QTimer::timeout, this, &Application::OnTimeout); @@ -46,8 +50,10 @@ void Application::OnTimeout() { void Application::Uninit() { //Singleton::Destory(); Singleton::Destory(); + Singleton::Destory(); Singleton::Destory(); Singleton::Destory(); + Singleton::Destory(); Singleton::Destory(); Singleton::Destory(); } diff --git a/src/entities/EntitiesManager.cpp b/src/entities/EntitiesManager.cpp index a2c47199..e8271843 100644 --- a/src/entities/EntitiesManager.cpp +++ b/src/entities/EntitiesManager.cpp @@ -7,6 +7,8 @@ #include "common/SpdLogger.h" #include "entities/Entity.h" #include "entities/ComponentFactory.h" +#include "entities/EntityFactory.h" +#include "entities/EntityRegistration.h" #include "xml/tinyxml2.h" @@ -14,6 +16,7 @@ template<> EntitiesManager* Singleton::instance_ = nullptr; EntitiesManager::EntitiesManager(QObject* parent) : QObject(parent) { + Initialize(); } EntitiesManager::~EntitiesManager() { @@ -106,9 +109,6 @@ Entity* EntitiesManager::CreateMesh(const QString& mesh) { SceneComponent* conponent = ComponentFactory::Create("MeshComponent", nullptr); conponent->SetAttribute("mesh", mesh.toStdString().c_str()); conponent->AttachEntity(entity); - - //conponent = ComponentFactory::Create("PathComponent", conponent); - //conponent->AttachEntity(entity); return entity; } @@ -148,3 +148,78 @@ void EntitiesManager::RemoveEntity(Entity* entity) { entities_.erase(entity->GetUUid()); } + +void EntitiesManager::Initialize() { + if (!initialized_) { + EntityRegistration::RegisterAllEntities(); + initialized_ = true; + LOG_INFO("EntitiesManager::Initialize - Entity factory initialized"); + } +} + +Entity* EntitiesManager::CreateEntity(const QString& type, WorkSpace* workspace) { + if (!initialized_) { + Initialize(); + } + + if (!workspace) { + workspace = WorkSpaceManager::Get().GetCurrent(); + } + + Entity* entity = EntityFactory::Get().CreateEntity(type, workspace); + if (entity) { + AddEntity(entity); + if (workspace) { + workspace->AddEntity(entity); + } + LOG_INFO("EntitiesManager::CreateEntity - Created entity of type: {}", type.toStdString()); + } else { + LOG_ERROR("EntitiesManager::CreateEntity - Failed to create entity of type: {}", type.toStdString()); + } + + return entity; +} + +Entity* EntitiesManager::CreateEntityWithComponents(const QString& type, WorkSpace* workspace) { + if (!initialized_) { + Initialize(); + } + + if (!workspace) { + workspace = WorkSpaceManager::Get().GetCurrent(); + } + + Entity* entity = EntityFactory::Get().CreateEntityWithComponents(type, workspace); + if (entity) { + AddEntity(entity); + if (workspace) { + workspace->AddEntity(entity); + } + LOG_INFO("EntitiesManager::CreateEntityWithComponents - Created entity with components of type: {}", type.toStdString()); + } else { + LOG_ERROR("EntitiesManager::CreateEntityWithComponents - Failed to create entity of type: {}", type.toStdString()); + } + + return entity; +} + +QStringList EntitiesManager::GetSupportedEntityTypes() const { + if (!initialized_) { + return QStringList(); + } + return EntityFactory::Get().GetRegisteredTypes(); +} + +QString EntitiesManager::GetEntityDisplayName(const QString& type) const { + if (!initialized_) { + return type; + } + return EntityFactory::Get().GetDisplayName(type); +} + +QString EntitiesManager::GetEntityDescription(const QString& type) const { + if (!initialized_) { + return QString(); + } + return EntityFactory::Get().GetDescription(type); +} diff --git a/src/entities/EntitiesManager.h b/src/entities/EntitiesManager.h index 80bdd69a..ad2b43d5 100644 --- a/src/entities/EntitiesManager.h +++ b/src/entities/EntitiesManager.h @@ -9,6 +9,7 @@ #include "xml/tinyxml2.h" class Entity; +class WorkSpace; class EntitiesManager : public QObject, public Singleton { Q_OBJECT @@ -18,12 +19,26 @@ public: ~EntitiesManager(); void OnDestory(); + // Initialize entity factory + void Initialize(); + bool Contains(const QString& name) const; bool Parse(const tinyxml2::XMLElement* element, class WorkSpace* workspce); + // Legacy methods (for backward compatibility) Entity* Create(const QString& name); Entity* CreateMesh(const QString& mesh); + + // New factory methods + Entity* CreateEntity(const QString& type, WorkSpace* workspace = nullptr); + Entity* CreateEntityWithComponents(const QString& type, WorkSpace* workspace = nullptr); + + // Get supported entity types + QStringList GetSupportedEntityTypes() const; + QString GetEntityDisplayName(const QString& type) const; + QString GetEntityDescription(const QString& type) const; + bool DeleteEntity(Entity* entity); Entity* GetEntity(const QString& uuid); @@ -36,5 +51,5 @@ protected: private: std::unordered_map entities_; - + bool initialized_{false}; }; \ No newline at end of file diff --git a/src/entities/EntityFactory.cpp b/src/entities/EntityFactory.cpp new file mode 100644 index 00000000..3107dfd4 --- /dev/null +++ b/src/entities/EntityFactory.cpp @@ -0,0 +1,108 @@ +#include "entities/EntityFactory.h" +#include "entities/ComponentFactory.h" +#include "common/SpdLogger.h" +#include "workspace/WorkSpace.h" +#include + +template<> EntityFactory* Singleton::instance_ = nullptr; + +Entity* EntityFactory::CreateEntity(const QString& type, WorkSpace* workspace) { + auto it = creators_.find(type); + if (it == creators_.end()) { + LOG_WARN("EntityFactory::CreateEntity - Unknown entity type: {}", type.toStdString()); + return nullptr; + } + + Entity* entity = it->second->CreateEntity(workspace); + if (!entity) { + LOG_ERROR("EntityFactory::CreateEntity - Failed to create entity of type: {}", type.toStdString()); + return nullptr; + } + + LOG_INFO("EntityFactory::CreateEntity - Successfully created entity of type: {}", type.toStdString()); + return entity; +} + +Entity* EntityFactory::CreateEntityWithComponents(const QString& type, WorkSpace* workspace) { + Entity* entity = CreateEntity(type, workspace); + if (!entity) { + return nullptr; + } + + auto it = creators_.find(type); + if (it == creators_.end()) { + return entity; + } + + // Get default mesh + QString defaultMesh = it->second->GetDefaultMesh(); + if (!defaultMesh.isEmpty()) { + SceneComponent* meshComponent = ComponentFactory::Create("MeshComponent", nullptr); + if (meshComponent) { + meshComponent->SetAttribute("mesh", defaultMesh.toStdString().c_str()); + meshComponent->AttachEntity(entity); + LOG_INFO("EntityFactory::CreateEntityWithComponents - Added MeshComponent with mesh: {}", defaultMesh.toStdString()); + } + } + + // Add required components + QStringList requiredComponents = it->second->GetRequiredComponents(); + SceneComponent* rootComponent = entity->GetRootComponent(); + + for (int i = 0; i < requiredComponents.size(); ++i) { + QString componentType = requiredComponents.at(i); + SceneComponent* component = ComponentFactory::Create(componentType, rootComponent); + if (component && rootComponent) { + component->AttachTo(rootComponent); + LOG_INFO("EntityFactory::CreateEntityWithComponents - Added component: {}", componentType.toStdString()); + } else { + LOG_WARN("EntityFactory::CreateEntityWithComponents - Failed to create component: {}", componentType.toStdString()); + } + } + + return entity; +} + +QStringList EntityFactory::GetRegisteredTypes() const { + QStringList types; + for (auto it = creators_.begin(); it != creators_.end(); ++it) { + types.append(it->first); + } + return types; +} + +QString EntityFactory::GetDisplayName(const QString& type) const { + auto it = creators_.find(type); + if (it != creators_.end()) { + return it->second->GetDisplayName(); + } + return type; // 返回类型名作为默认显示名 +} + +QString EntityFactory::GetDescription(const QString& type) const { + auto it = creators_.find(type); + if (it != creators_.end()) { + return it->second->GetDescription(); + } + return QString(); +} + +QString EntityFactory::GetDefaultMesh(const QString& type) const { + auto it = creators_.find(type); + if (it != creators_.end()) { + return it->second->GetDefaultMesh(); + } + return QString(); +} + +QStringList EntityFactory::GetRequiredComponents(const QString& type) const { + auto it = creators_.find(type); + if (it != creators_.end()) { + return it->second->GetRequiredComponents(); + } + return QStringList(); +} + +bool EntityFactory::IsTypeSupported(const QString& type) const { + return creators_.find(type) != creators_.end(); +} \ No newline at end of file diff --git a/src/entities/EntityFactory.h b/src/entities/EntityFactory.h new file mode 100644 index 00000000..7a40e94f --- /dev/null +++ b/src/entities/EntityFactory.h @@ -0,0 +1,86 @@ +#pragma once + +#include +#include +#include +#include + +#include "app/Singleton.h" +#include "entities/Entity.h" + +class WorkSpace; + +class IEntityCreator { +public: + virtual ~IEntityCreator() = default; + virtual Entity* CreateEntity(WorkSpace* workspace) = 0; + virtual QString GetEntityType() const = 0; + virtual QString GetDisplayName() const = 0; + virtual QString GetDescription() const = 0; + virtual QString GetDefaultMesh() const = 0; + virtual QStringList GetRequiredComponents() const = 0; +}; + +template +class EntityCreator : public IEntityCreator { +public: + EntityCreator(const QString& type, const QString& displayName, + const QString& description, const QString& defaultMesh, + const QStringList& requiredComponents = QStringList()) + : entityType_(type), displayName_(displayName), description_(description), + defaultMesh_(defaultMesh), requiredComponents_(requiredComponents) {} + + Entity* CreateEntity(WorkSpace* workspace) override { + return new T(workspace); + } + + QString GetEntityType() const override { return entityType_; } + QString GetDisplayName() const override { return displayName_; } + QString GetDescription() const override { return description_; } + QString GetDefaultMesh() const override { return defaultMesh_; } + QStringList GetRequiredComponents() const override { return requiredComponents_; } + +private: + QString entityType_; + QString displayName_; + QString description_; + QString defaultMesh_; + QStringList requiredComponents_; +}; + +class EntityFactory : public Singleton { +public: + EntityFactory() = default; + explicit EntityFactory(class Application* app) : app_(app) {} + ~EntityFactory() = default; + + void OnDestory() { } + + template + void RegisterEntity(const QString& type, const QString& displayName, + const QString& description, const QString& defaultMesh, + const QStringList& requiredComponents = QStringList()) { + auto creator = std::make_unique>(type, displayName, description, defaultMesh, requiredComponents); + creators_[type] = std::move(creator); + } + + Entity* CreateEntity(const QString& type, WorkSpace* workspace); + + Entity* CreateEntityWithComponents(const QString& type, WorkSpace* workspace); + + QStringList GetRegisteredTypes() const; + + QString GetDisplayName(const QString& type) const; + QString GetDescription(const QString& type) const; + QString GetDefaultMesh(const QString& type) const; + QStringList GetRequiredComponents(const QString& type) const; + + bool IsTypeSupported(const QString& type) const; + +private: + std::unordered_map> creators_; + class Application* app_ = nullptr; +}; + +#define REGISTER_ENTITY(EntityClass, Type, DisplayName, Description, DefaultMesh, ...) \ + EntityFactory::Get().RegisterEntity(Type, DisplayName, Description, DefaultMesh, QStringList{__VA_ARGS__}) \ No newline at end of file diff --git a/src/entities/EntityRegistration.cpp b/src/entities/EntityRegistration.cpp new file mode 100644 index 00000000..ae6a086e --- /dev/null +++ b/src/entities/EntityRegistration.cpp @@ -0,0 +1,88 @@ +#include "entities/EntityRegistration.h" +#include "common/SpdLogger.h" + +void EntityRegistration::RegisterAllEntities() { + EntityFactory& factory = EntityFactory::Get(); + + // Register missile entity + factory.RegisterEntity("Missile", + "Missile", + "Military missile entity with target tracking and flight capabilities", + "models/missile.osg", + QStringList() << "LabelComponent" << "TrajectoryComponent" + ); + + // Register satellite entity + factory.RegisterEntity("Satellite", + "Satellite", + "Artificial satellite entity with orbital motion and communication capabilities", + "models/satellite.osg", + QStringList() << "LabelComponent" << "ConeWaveComponent" << "OrbitComponent" + ); + + // Register ship entity + factory.RegisterEntity("Ship", + "Ship", + "Naval vessel entity with maritime navigation and combat capabilities", + "models/ship.osg", + QStringList() << "LabelComponent" << "NavigationComponent" + ); + + // Register radar entity + factory.RegisterEntity("Radar", + "Radar", + "Radar system entity with target detection and tracking capabilities", + "models/radar.osg", + QStringList() << "LabelComponent" << "RadarComponent" << "ScanComponent" + ); + + // Register vehicle entity + factory.RegisterEntity("Vehicle", + "Vehicle", + "Generic vehicle entity configurable for different types of transportation", + "models/vehicle.osg", + QStringList() << "LabelComponent" << "MovementComponent" + ); + + // Register aircraft entity + factory.RegisterEntity("Aircraft", + "Aircraft", + "Aviation entity with flight and aerial combat capabilities", + "models/aircraft.osg", + QStringList() << "LabelComponent" << "FlightComponent" << "NavigationComponent" + ); + + // Register tank entity + factory.RegisterEntity("Tank", + "Tank", + "Armored vehicle entity with ground combat capabilities", + "models/tank.osg", + QStringList() << "LabelComponent" << "ArmorComponent" << "WeaponComponent" + ); + + // Register submarine entity + factory.RegisterEntity("Submarine", + "Submarine", + "Submarine entity with underwater combat capabilities", + "models/submarine.osg", + QStringList() << "LabelComponent" << "SonarComponent" << "TorpedoComponent" + ); + + // Register base entity + factory.RegisterEntity("Base", + "Base", + "Military base entity serving as command and logistics center", + "models/base.osg", + QStringList() << "LabelComponent" << "CommandComponent" << "DefenseComponent" + ); + + // Register generic entity (for backward compatibility) + factory.RegisterEntity("Entity", + "Entity", + "Basic entity type extensible through component system", + "models/default.osg", + QStringList() << "LabelComponent" + ); + + LOG_INFO("EntityRegistration::RegisterAllEntities - All entity types registered successfully"); +} \ No newline at end of file diff --git a/src/entities/EntityRegistration.h b/src/entities/EntityRegistration.h new file mode 100644 index 00000000..832cd7bf --- /dev/null +++ b/src/entities/EntityRegistration.h @@ -0,0 +1,11 @@ +#pragma once + +#include "entities/EntityFactory.h" +#include "entities/SpecializedEntities.h" + +// Entity registration class +class EntityRegistration { +public: + // Register all entity types + static void RegisterAllEntities(); +}; \ No newline at end of file diff --git a/src/entities/SpecializedEntities.cpp b/src/entities/SpecializedEntities.cpp new file mode 100644 index 00000000..58288a1e --- /dev/null +++ b/src/entities/SpecializedEntities.cpp @@ -0,0 +1,60 @@ +#include "entities/SpecializedEntities.h" + +#include + +#include "common/SpdLogger.h" + +MissileEntity::MissileEntity(WorkSpace* workspace) + : Entity(workspace) { + SetName("Missile"); + LOG_INFO("MissileEntity created"); +} + +MissileEntity::MissileEntity(const QString& name, QObject* parent) + : Entity(name, parent) { + LOG_INFO("MissileEntity created with name: {}", name.toStdString()); +} + +SatelliteEntity::SatelliteEntity(WorkSpace* workspace) + : Entity(workspace) { + SetName("Satellite"); + LOG_INFO("SatelliteEntity created"); +} + +SatelliteEntity::SatelliteEntity(const QString& name, QObject* parent) + : Entity(name, parent) { + LOG_INFO("SatelliteEntity created with name: {}", name.toStdString()); +} + +ShipEntity::ShipEntity(WorkSpace* workspace) + : Entity(workspace) { + SetName("Ship"); + LOG_INFO("ShipEntity created"); +} + +ShipEntity::ShipEntity(const QString& name, QObject* parent) + : Entity(name, parent) { + LOG_INFO("ShipEntity created with name: {}", name.toStdString()); +} + +RadarEntity::RadarEntity(WorkSpace* workspace) + : Entity(workspace) { + SetName("Radar"); + LOG_INFO("RadarEntity created"); +} + +RadarEntity::RadarEntity(const QString& name, QObject* parent) + : Entity(name, parent) { + LOG_INFO("RadarEntity created with name: {}", name.toStdString()); +} + +VehicleEntity::VehicleEntity(WorkSpace* workspace) + : Entity(workspace) { + SetName("Vehicle"); + LOG_INFO("VehicleEntity created"); +} + +VehicleEntity::VehicleEntity(const QString& name, QObject* parent) + : Entity(name, parent) { + LOG_INFO("VehicleEntity created with name: {}", name.toStdString()); +} diff --git a/src/entities/SpecializedEntities.h b/src/entities/SpecializedEntities.h new file mode 100644 index 00000000..44c16011 --- /dev/null +++ b/src/entities/SpecializedEntities.h @@ -0,0 +1,58 @@ +#pragma once + +#include "entities/Entity.h" + +// 导弹实体 +class MissileEntity : public Entity { + Q_OBJECT + +public: + explicit MissileEntity(WorkSpace* workspace); + explicit MissileEntity(const QString& name, QObject* parent = nullptr); + ~MissileEntity() override = default; + +}; + +// 卫星实体 +class SatelliteEntity : public Entity { + Q_OBJECT + +public: + explicit SatelliteEntity(WorkSpace* workspace); + explicit SatelliteEntity(const QString& name, QObject* parent = nullptr); + ~SatelliteEntity() override = default; + +}; + +// 舰船实体 +class ShipEntity : public Entity { + Q_OBJECT + +public: + explicit ShipEntity(WorkSpace* workspace); + explicit ShipEntity(const QString& name, QObject* parent = nullptr); + ~ShipEntity() override = default; + +}; + +// 雷达实体 +class RadarEntity : public Entity { + Q_OBJECT + +public: + explicit RadarEntity(WorkSpace* workspace); + explicit RadarEntity(const QString& name, QObject* parent = nullptr); + ~RadarEntity() override = default; + +}; + +// 通用载具实体 +class VehicleEntity : public Entity { + Q_OBJECT + +public: + explicit VehicleEntity(WorkSpace* workspace); + explicit VehicleEntity(const QString& name, QObject* parent = nullptr); + ~VehicleEntity() override = default; + +}; \ No newline at end of file diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 49825d5e..9a5fbf47 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -2082,12 +2082,12 @@ OsgWidget - + warning - + open dyt file failed diff --git a/src/ui/ModelBrowser/PresetModelListWidget.h b/src/ui/ModelBrowser/PresetModelListWidget.h index 408fec71..65c46e78 100644 --- a/src/ui/ModelBrowser/PresetModelListWidget.h +++ b/src/ui/ModelBrowser/PresetModelListWidget.h @@ -1,6 +1,7 @@ #include #include -#include "ui/ModelBrowser/ModelInfo.h" + +#include "workspace/ModelInfo.h" class PresetModelListWidget : public QListWidget { diff --git a/src/ui/ModelBrowser/PresetModelPanel.cpp b/src/ui/ModelBrowser/PresetModelPanel.cpp index dcafb751..c9f7cccf 100644 --- a/src/ui/ModelBrowser/PresetModelPanel.cpp +++ b/src/ui/ModelBrowser/PresetModelPanel.cpp @@ -55,50 +55,48 @@ void PresetModelPanel::InitUI() { // Try to load model data from configuration files QString presetsPath = QString("%1/presets").arg(RecourceHelper::Get().GetResourcesPath()); - if (configParser_.LoadAllConfigs(presetsPath)) { + if (PresetModelConfigParser::Get().LoadAllConfigs(presetsPath)) { // Successfully loaded from configuration files LoadModelsFromConfig(); } else { // Failed to load configuration files, use hardcoded defaults as fallback LOG_WARN("Failed to load preset models from config files, using hardcoded defaults. Error: {}", - configParser_.GetLastError().toStdString()); + PresetModelConfigParser::Get().GetLastError().toStdString()); LoadDefaultModels(); } } -void PresetModelPanel::LoadModelsFromConfig() -{ +void PresetModelPanel::LoadModelsFromConfig() { // Load ship models - ModelCategory shipCategory = configParser_.GetCategory("Ship"); + ModelCategory shipCategory = PresetModelConfigParser::Get().GetCategory("Ship"); if (!shipCategory.models.isEmpty()) { ui->shipList->setModelType("Ship"); ui->shipList->setModelList(shipCategory.models); } // Load satellite models - ModelCategory satelliteCategory = configParser_.GetCategory("Satellite"); + ModelCategory satelliteCategory = PresetModelConfigParser::Get().GetCategory("Satellite"); if (!satelliteCategory.models.isEmpty()) { ui->satelliteList->setModelType("Satellite"); ui->satelliteList->setModelList(satelliteCategory.models); } // Load missile models - ModelCategory missileCategory = configParser_.GetCategory("Missile"); + ModelCategory missileCategory = PresetModelConfigParser::Get().GetCategory("Missile"); if (!missileCategory.models.isEmpty()) { ui->missileList->setModelType("Missile"); ui->missileList->setModelList(missileCategory.models); } // Load jammer models - ModelCategory jammerCategory = configParser_.GetCategory("Jammer"); + ModelCategory jammerCategory = PresetModelConfigParser::Get().GetCategory("Jammer"); if (!jammerCategory.models.isEmpty()) { ui->jammerList->setModelType("Jammer"); ui->jammerList->setModelList(jammerCategory.models); } } -void PresetModelPanel::LoadDefaultModels() -{ +void PresetModelPanel::LoadDefaultModels() { // Use hardcoded default models as fallback mechanism QVector shipModels = { {"destroyer", "Destroyer", "Naval destroyer vessel", "", ":/icons/ship.png", true}, @@ -136,108 +134,3 @@ void PresetModelPanel::LoadDefaultModels() ui->jammerList->setModelType("Jammer"); ui->jammerList->setModelList(jammerModels); } - -// void PresetModelPanel::OnModelItemDoubleClicked(QListWidgetItem* item) -// { -// if (!item) return; - -// // Get the list widget that contains this item -// QListWidget* listWidget = item->listWidget(); -// if (!listWidget) return; - -// QString modelType = listWidget->property("modelType").toString(); - -// // Get model name from stored data -// QString modelName = item->data(Qt::UserRole).toString(); -// if (modelName.isEmpty()) { -// modelName = item->text(); // Fallback to display text -// } - -// LOG_INFO("Model double-clicked: {} of type {}", qPrintable(modelName), qPrintable(modelType)); - -// // Emit signal for model selection -// emit ModelDropped(modelType, modelName); -// } - -// bool PresetModelPanel::eventFilter(QObject* obj, QEvent* event) -// { -// QListWidget* listWidget = qobject_cast(obj); -// if (!listWidget) { -// return QWidget::eventFilter(obj, event); -// } - -// if (event->type() == QEvent::MouseButtonPress) { -// QMouseEvent* mouseEvent = static_cast(event); -// if (mouseEvent->button() == Qt::LeftButton) { -// dragStartPosition_ = mouseEvent->pos(); -// dragSourceWidget_ = listWidget; -// } -// } else if (event->type() == QEvent::MouseMove) { -// QMouseEvent* mouseEvent = static_cast(event); -// if (!(mouseEvent->buttons() & Qt::LeftButton)) { -// return QWidget::eventFilter(obj, event); -// } - -// if ((mouseEvent->pos() - dragStartPosition_).manhattanLength() < QApplication::startDragDistance()) { -// return QWidget::eventFilter(obj, event); -// } - -// QListWidgetItem* item = listWidget->itemAt(dragStartPosition_); -// if (!item) { -// return QWidget::eventFilter(obj, event); -// } - -// QString modelType = listWidget->property("modelType").toString(); - -// // Get model name from stored data -// QString modelName = item->data(Qt::UserRole).toString(); -// if (modelName.isEmpty()) { -// modelName = item->text(); // Fallback to item text -// } - -// // Create mime data -// QMimeData* mimeData = new QMimeData; -// QString dragData = QString("%1|%2").arg(modelType, modelName); -// mimeData->setData("application/x-preset-model", dragData.toUtf8()); - -// // Create drag object -// QDrag* drag = new QDrag(this); -// drag->setMimeData(mimeData); - -// // Set drag pixmap (icon or text) -// QPixmap pixmap(item->icon().pixmap(32, 32)); -// if (pixmap.isNull()) { -// pixmap = QPixmap(100, 30); -// pixmap.fill(Qt::transparent); -// QPainter painter(&pixmap); -// painter.setPen(Qt::black); -// painter.drawText(pixmap.rect(), Qt::AlignCenter, item->text()); -// } -// drag->setPixmap(pixmap); - -// // Execute drag -// Qt::DropAction dropAction = drag->exec(Qt::CopyAction); -// Q_UNUSED(dropAction); - -// return true; -// } - -// return QWidget::eventFilter(obj, event); -// } - -// // DraggableListWidget implementation -// DraggableListWidget::DraggableListWidget(const QString& modelType, QWidget* parent) -// : QListWidget(parent), modelType_(modelType) -// { -// setProperty("modelType", modelType); -// } - -// void DraggableListWidget::mousePressEvent(QMouseEvent* event) -// { -// QListWidget::mousePressEvent(event); -// } - -// void DraggableListWidget::mouseMoveEvent(QMouseEvent* event) -// { -// QListWidget::mouseMoveEvent(event); -// } \ No newline at end of file diff --git a/src/ui/ModelBrowser/PresetModelPanel.h b/src/ui/ModelBrowser/PresetModelPanel.h index 1fe4aa62..6d220217 100644 --- a/src/ui/ModelBrowser/PresetModelPanel.h +++ b/src/ui/ModelBrowser/PresetModelPanel.h @@ -14,8 +14,9 @@ #include #include #include -#include "ModelInfo.h" -#include "PresetModelConfigParser.h" + +#include "workspace/ModelInfo.h" +#include "workspace/PresetModelConfigParser.h" namespace Ui { class PresetModelPanel; } @@ -62,7 +63,6 @@ private: private: Ui::PresetModelPanel *ui; - PresetModelConfigParser configParser_; // Drag and drop support QPoint dragStartPosition_; diff --git a/src/viewer/OsgWidget.cpp b/src/viewer/OsgWidget.cpp index 5280a035..0a28707a 100644 --- a/src/viewer/OsgWidget.cpp +++ b/src/viewer/OsgWidget.cpp @@ -25,6 +25,7 @@ #include "workspace/WorkSpaceManager.h" #include "workspace/WorkSpace.h" #include "scutcheon/osgScutcheon.h" +#include "workspace/PresetModelConfigParser.h" #include "entities/EntitiesManager.h" #include "entities/ComponentFactory.h" @@ -269,68 +270,25 @@ void OsgWidget::OnPresetModelDropped(const QString& modelType, const QString& mo 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); + + Entity* entity = EntitiesManager::Get().CreateEntityWithComponents(modelType, currentWorkSpace); if (nullptr == entity) { - LOG_ERROR("OsgWidget::OnPresetModelDropped - Failed to create entity for mesh: {}", meshPath.toStdString()); + LOG_ERROR("OsgWidget::OnPresetModelDropped - Failed to create entity of type: {}", modelType.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); + + LOG_INFO("OsgWidget::OnPresetModelDropped - Successfully created {} entity: {} at position ({:.6f}, {:.6f}, {:.2f})", + modelType.toStdString(), entity->GetName().toStdString(), longitude, latitude, height); } bool OsgWidget::ScreenToWorldCoordinate(int x, int y, double& longitude, double& latitude, double& height) { diff --git a/src/ui/ModelBrowser/ModelInfo.h b/src/workspace/ModelInfo.h similarity index 100% rename from src/ui/ModelBrowser/ModelInfo.h rename to src/workspace/ModelInfo.h diff --git a/src/ui/ModelBrowser/PresetModelConfigParser.cpp b/src/workspace/PresetModelConfigParser.cpp similarity index 91% rename from src/ui/ModelBrowser/PresetModelConfigParser.cpp rename to src/workspace/PresetModelConfigParser.cpp index ffecfe72..c0fd4428 100644 --- a/src/ui/ModelBrowser/PresetModelConfigParser.cpp +++ b/src/workspace/PresetModelConfigParser.cpp @@ -1,19 +1,21 @@ -#include "PresetModelConfigParser.h" -#include "../../xml/tinyxml2.h" -#include "../../common/SpdLogger.h" +#include "workspace/PresetModelConfigParser.h" + #include #include -PresetModelConfigParser::PresetModelConfigParser() -{ +#include "xml/tinyxml2.h" +#include "common/SpdLogger.h" + +template<> PresetModelConfigParser* Singleton::instance_ = nullptr; + +PresetModelConfigParser::PresetModelConfigParser(QObject* parent) + : QObject(parent) { } -PresetModelConfigParser::~PresetModelConfigParser() -{ +PresetModelConfigParser::~PresetModelConfigParser() { } -bool PresetModelConfigParser::LoadAllConfigs(const QString& configDir) -{ +bool PresetModelConfigParser::LoadAllConfigs(const QString& configDir) { Clear(); QDir dir(configDir); @@ -158,16 +160,18 @@ ModelCategory PresetModelConfigParser::GetCategory(const QString& categoryName) return ModelCategory(); } -ModelInfo PresetModelConfigParser::GetModelInfo(const QString& categoryName, const QString& modelName) const -{ +ModelInfo PresetModelConfigParser::GetModelInfo(const QString& categoryName, const QString& modelName, bool* success) const { if (m_categories.contains(categoryName)) { const ModelCategory& category = m_categories[categoryName]; for (const ModelInfo& model : category.models) { if (model.name == modelName) { + if (success) *success = true; return model; } } } + + if (success) *success = false; return ModelInfo(); } diff --git a/src/ui/ModelBrowser/PresetModelConfigParser.h b/src/workspace/PresetModelConfigParser.h similarity index 80% rename from src/ui/ModelBrowser/PresetModelConfigParser.h rename to src/workspace/PresetModelConfigParser.h index a61f1d27..cb785a38 100644 --- a/src/ui/ModelBrowser/PresetModelConfigParser.h +++ b/src/workspace/PresetModelConfigParser.h @@ -1,16 +1,22 @@ #pragma once +#include #include #include #include + +#include "app/Singleton.h" + #include "ModelInfo.h" -class PresetModelConfigParser -{ +class PresetModelConfigParser : public QObject, public Singleton { + Q_OBJECT public: - PresetModelConfigParser(); + explicit PresetModelConfigParser(QObject* parent = nullptr); ~PresetModelConfigParser(); + void OnDestory() { } + // Load all preset model configurations bool LoadAllConfigs(const QString& configDir = "workspace/presets"); @@ -27,7 +33,7 @@ public: ModelCategory GetCategory(const QString& categoryName) const; // Get model information - ModelInfo GetModelInfo(const QString& categoryName, const QString& modelName) const; + ModelInfo GetModelInfo(const QString& categoryName, const QString& modelName, bool* success) const; // Check if configuration data exists bool HasData() const;