2025-01-04 04:12:51 +00:00
|
|
|
|
#include "ui/ModelBrowser/ModelTreeWidget.h"
|
|
|
|
|
|
|
|
|
|
#include <QResizeEvent>
|
|
|
|
|
#include <QUuid>
|
|
|
|
|
#include <QVariant>
|
|
|
|
|
#include <QMenu>
|
|
|
|
|
|
|
|
|
|
#include "common/RecourceHelper.h"
|
|
|
|
|
#include "common/SpdLogger.h"
|
|
|
|
|
#include "entities/EntitiesManager.h"
|
|
|
|
|
#include "entities/ComponentFactory.h"
|
|
|
|
|
#include "viewer/OsgViewer.h"
|
|
|
|
|
#include "viewer/OsgView.h"
|
|
|
|
|
#include "viewer/OsgCameraManipulator.h"
|
|
|
|
|
#include "viewer/CameraControlManipulator.h"
|
|
|
|
|
#include "ui/ModelBrowser/EntityConstent.h"
|
|
|
|
|
|
|
|
|
|
#include "ui_ModelBrowserPannal.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ModelTreeWidget::ModelTreeWidget(QWidget* parent)
|
|
|
|
|
: QTreeWidget(parent){
|
|
|
|
|
setColumnCount(1);
|
|
|
|
|
connect(this, &QTreeWidget::itemClicked, this, &ModelTreeWidget::OnWorkItemCliecked);
|
|
|
|
|
connect(this, &QTreeWidget::itemDoubleClicked, this, &ModelTreeWidget::OnItemDoubleClicked);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ModelTreeWidget::~ModelTreeWidget() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnWorkspaceChange(WorkSpace* workSpace) {
|
|
|
|
|
LOG_INFO("WorkSpace change");
|
|
|
|
|
|
|
|
|
|
clear();
|
|
|
|
|
|
|
|
|
|
currentWorkSpace_ = workSpace;
|
|
|
|
|
if (nullptr == currentWorkSpace_) {
|
|
|
|
|
LOG_WARN("workspace is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connect(workSpace, &WorkSpace::EntityAdded, this, &ModelTreeWidget::OnEntityAdded);
|
|
|
|
|
connect(workSpace, &WorkSpace::EntityRemoved, this, &ModelTreeWidget::OnEntityRemoved);
|
|
|
|
|
|
|
|
|
|
const QString& name = currentWorkSpace_->GetName();
|
|
|
|
|
root_ = new QTreeWidgetItem(this);
|
|
|
|
|
root_->setText(0, name);
|
|
|
|
|
QVariant root;
|
|
|
|
|
root.setValue(currentWorkSpace_);
|
|
|
|
|
root_->setData(0, E_Workspace, root);
|
|
|
|
|
root_->setData(0, E_UUid, currentWorkSpace_->GetUUid());
|
|
|
|
|
addTopLevelItem(root_);
|
|
|
|
|
|
|
|
|
|
const std::vector<Entity*>& entities = currentWorkSpace_->GetEntities();
|
|
|
|
|
for (const auto& entity : entities) {
|
|
|
|
|
AddEntity(root_, entity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnEntityAdded(Entity* entity) {
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("entity is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString& entityName = entity->GetName();
|
|
|
|
|
|
|
|
|
|
QTreeWidgetItem* item = new QTreeWidgetItem;
|
|
|
|
|
connect(entity, &Entity::NameChanged, [item](const QString& name) {
|
|
|
|
|
LOG_WARN("entity name changed: {}", name.toStdString());
|
|
|
|
|
item->setText(0, name);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
item->setText(0, entityName);
|
|
|
|
|
QVariant root;
|
|
|
|
|
root.setValue(entity);
|
|
|
|
|
item->setData(0, E_Entity, root);
|
|
|
|
|
item->setData(0, E_UUid, entity->GetUUid());
|
|
|
|
|
root_->addChild(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnEntityRemoved(Entity* entity) {
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("entity is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString& uuid = entity->GetUUid();
|
|
|
|
|
FindAndRemoveItem(uuid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
|
|
|
|
QTreeWidgetItem* item = itemAt(event->pos());
|
|
|
|
|
if (nullptr == item) {
|
|
|
|
|
QMenu menu(this);
|
|
|
|
|
QAction* addEntiy = new QAction(tr("Release Track"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnTrackEntity(nullptr);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
menu.exec(event->globalPos());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
QVariant value = item->data(0, E_Entity);
|
|
|
|
|
if (nullptr != item && value.isValid()) {
|
|
|
|
|
Entity* entity = value.value<Entity*>();
|
|
|
|
|
PopupEntityMenu(event, entity);
|
|
|
|
|
} else {
|
|
|
|
|
QMenu menu(this);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ӳ˵<D3B2><CBB5><EFBFBD>
|
|
|
|
|
QAction* addEntiy = new QAction(tr("Add boke Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddMeshEntity("boke/boke.ive", "boke");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Add lsjhqt Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddMeshEntity("lsjhqt/lsjhqt.flt", "lsjhqt");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Add nimizi Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddMeshEntity("nimizi/nimizi.ive", "nimizi");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Add tkdlj Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddMeshEntity("tkdlj/tkdlj.ive", "tkdlj");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Add jiaofan Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddMeshEntity("jf/decorative-shape-008.obj", "jiaofan");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Add satellite Entity"), this);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this]() {
|
|
|
|
|
OnAddSatelliteEntity();
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
// <20><>ʾ<EFBFBD>˵<EFBFBD>
|
|
|
|
|
menu.exec(event->globalPos());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnWorkItemChanged(WorkSpaceItem* item) {
|
|
|
|
|
LOG_INFO("WorkItemChanged");
|
|
|
|
|
if (nullptr == item) {
|
|
|
|
|
LOG_WARN("item is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnWorkItemCliecked(QTreeWidgetItem* item, int column) {
|
|
|
|
|
QVariant value = item->data(column, E_Entity);
|
|
|
|
|
bool isEntity = true;
|
|
|
|
|
if (!value.isValid()) {
|
|
|
|
|
value = item->data(column, E_Workspace);
|
|
|
|
|
isEntity = false;
|
|
|
|
|
}
|
|
|
|
|
if (!value.isValid()) {
|
|
|
|
|
LOG_WARN("unknown data rol");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isEntity) {
|
|
|
|
|
emit EntityChange(value);
|
|
|
|
|
} else {
|
|
|
|
|
emit WorkSpaceChange(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnItemDoubleClicked(QTreeWidgetItem* item, int column) {
|
|
|
|
|
QVariant value = item->data(column, E_Entity);
|
|
|
|
|
bool isEntity = true;
|
|
|
|
|
if (!value.isValid()) {
|
|
|
|
|
LOG_WARN("unknown data E_Entity");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entity* entity = value.value<Entity*>();
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("entity is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OnTrackEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnAddMeshEntity(const QString& mesh, const QString& name) {
|
|
|
|
|
if (nullptr == currentWorkSpace_) {
|
|
|
|
|
LOG_WARN("currentWorkSpace_ is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entity* entity = EntitiesManager::Get().CreateMesh(mesh);
|
|
|
|
|
|
|
|
|
|
int count = currentWorkSpace_->GetEntities().size();
|
|
|
|
|
entity->SetName(QString("%1_%2").arg(name).arg(count));
|
|
|
|
|
currentWorkSpace_->AddEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SceneComponent* ModelTreeWidget::OnAddComponent(const QString& typeName, Entity* entity) {
|
|
|
|
|
LOG_INFO("enter, typename:{}", typeName.toStdString().c_str());
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("entity is nullptr");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SceneComponent* rootComponent = entity->GetRootComponent();
|
|
|
|
|
SceneComponent* conponent = ComponentFactory::Create(typeName, rootComponent);
|
|
|
|
|
conponent->AttachTo(rootComponent);
|
|
|
|
|
//conponent->AttachEntity(entity);
|
|
|
|
|
|
|
|
|
|
QVariant value;
|
|
|
|
|
value.setValue(entity);
|
|
|
|
|
emit EntityChange(value);
|
|
|
|
|
return conponent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnDeleteEntity(Entity* entity) {
|
|
|
|
|
LOG_INFO("enter");
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("entity is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entity->Destory();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity) {
|
|
|
|
|
QMenu menu(this);
|
|
|
|
|
|
|
|
|
|
QAction* addEntiy = new QAction(tr("Track"), this);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
|
|
|
|
OnTrackEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ӳ˵<D3B2><CBB5><EFBFBD>
|
|
|
|
|
addEntiy = new QAction(tr("Add Mesh Component"), this);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5>˵<EFBFBD><CBB5><EFBFBD>
|
|
|
|
|
addEntiy = new QAction(tr("Add Path Component"), this);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
|
|
|
|
OnAddComponent("PathComponent", entity);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
addEntiy = new QAction(tr("Delete"), this);
|
|
|
|
|
menu.addAction(addEntiy);
|
|
|
|
|
connect(addEntiy, &QAction::triggered, [this, entity]() {
|
|
|
|
|
OnDeleteEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// <20><>ʾ<EFBFBD>˵<EFBFBD>
|
|
|
|
|
menu.exec(event->globalPos());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::FindAndRemoveItem(const QString& itemToRemove) {
|
|
|
|
|
for (int i = 0; i < topLevelItemCount(); ++i) {
|
|
|
|
|
QTreeWidgetItem* topItem = topLevelItem(i);
|
|
|
|
|
if (RemoveItemFromParent(topItem, itemToRemove)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ModelTreeWidget::RemoveItemFromParent(QTreeWidgetItem* parentItem, const QString& itemToRemove) {
|
|
|
|
|
for (int i = 0; i < parentItem->childCount(); ++i) {
|
|
|
|
|
QTreeWidgetItem* childItem = parentItem->child(i);
|
|
|
|
|
const QString uuid = childItem->data(0, E_UUid).toString();
|
|
|
|
|
if (uuid == itemToRemove) {
|
|
|
|
|
while (childItem->childCount() > 0) {
|
|
|
|
|
QTreeWidgetItem* grandChildItem = childItem->child(0);
|
2025-01-05 03:33:33 +00:00
|
|
|
|
childItem->removeChild(grandChildItem);
|
2025-01-04 04:12:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
parentItem->removeChild(childItem);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (RemoveItemFromParent(childItem, itemToRemove)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnAddSatelliteEntity() {
|
|
|
|
|
if (nullptr == currentWorkSpace_) {
|
|
|
|
|
LOG_WARN("currentWorkSpace_ is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//const QString mesh("sat/sat.ive");
|
|
|
|
|
const QString mesh("satellite/satellite.ive");
|
|
|
|
|
Entity* entity = EntitiesManager::Get().CreateMesh(mesh);
|
|
|
|
|
int count = currentWorkSpace_->GetEntities().size();
|
|
|
|
|
entity->SetName(QString("%1_%2").arg("satellite").arg(count));
|
|
|
|
|
OnAddComponent("ConeWaveComponent", entity);
|
|
|
|
|
currentWorkSpace_->AddEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::OnTrackEntity(Entity* entity) {
|
|
|
|
|
OsgCameraManipulator* manipulator = OsgViewer::Get().GetView()->GetCameraManipulator();
|
|
|
|
|
if (nullptr == manipulator) {
|
|
|
|
|
LOG_WARN("manipulator is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osgGA::CameraManipulator* gaManipulator = manipulator->GetManipulator();
|
|
|
|
|
CameraControlManipulator* ccm = dynamic_cast<CameraControlManipulator*>(gaManipulator);
|
|
|
|
|
if (nullptr != ccm) {
|
|
|
|
|
if (nullptr != entity) {
|
|
|
|
|
osg::MatrixTransform* mt = entity->GetRootComponent()->GetMatrixTransform();
|
|
|
|
|
ccm->setManipulatorMode(CameraControlManipulator::Tracker_ManipulatorMode);
|
|
|
|
|
ccm->setTrackNode(mt);
|
|
|
|
|
} else {
|
|
|
|
|
ccm->setManipulatorMode(CameraControlManipulator::Roam_ManipulatorMode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ModelTreeWidget::AddEntity(class QTreeWidgetItem* parent, Entity* entity) {
|
|
|
|
|
const QString& entityName = entity->GetName();
|
|
|
|
|
|
|
|
|
|
QTreeWidgetItem* item = new QTreeWidgetItem;
|
|
|
|
|
connect(entity, &Entity::NameChanged, [item](const QString& name) {
|
|
|
|
|
LOG_WARN("entity name changed: {}", name.toStdString());
|
|
|
|
|
item->setText(0, name);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
item->setText(0, entityName);
|
|
|
|
|
QVariant root;
|
|
|
|
|
root.setValue(entity);
|
|
|
|
|
item->setData(0, E_Entity, root);
|
|
|
|
|
item->setData(0, E_UUid, entity->GetUUid());
|
|
|
|
|
parent->addChild(item);
|
|
|
|
|
|
|
|
|
|
const std::vector<Entity*>& childer = entity->GetChilder();
|
|
|
|
|
for (const auto& child : childer) {
|
|
|
|
|
AddEntity(item, child);
|
|
|
|
|
}
|
|
|
|
|
}
|