diff --git a/src/PrpShop/CMakeLists.txt b/src/PrpShop/CMakeLists.txt index 63e0961..71c4963 100644 --- a/src/PrpShop/CMakeLists.txt +++ b/src/PrpShop/CMakeLists.txt @@ -61,6 +61,7 @@ set(PrpShop_Headers PRP/Surface/QLayerSDLAnimation.h PRP/Surface/QMaterial.h PRP/Surface/QMipmap.h + PRP/Render/QSceneNode_Preview.h PRP/Render/QSceneObj_Preview.h PRP/Render/QPlasmaRender.h ) @@ -131,6 +132,7 @@ set(PrpShop_Sources PRP/Surface/QMaterial.cpp PRP/Surface/QMipmap.cpp PRP/Render/QPlasmaRender.cpp + PRP/Render/QSceneNode_Preview.cpp PRP/Render/QSceneObj_Preview.cpp PRP/Render/QTrackball.cpp ) diff --git a/src/PrpShop/PRP/QCreatable.cpp b/src/PrpShop/PRP/QCreatable.cpp index c4faef4..ac822f4 100644 --- a/src/PrpShop/PRP/QCreatable.cpp +++ b/src/PrpShop/PRP/QCreatable.cpp @@ -118,6 +118,7 @@ void QCreatable::closeEvent(QCloseEvent*) #include "PRP/Surface/QLayerSDLAnimation.h" #include "PRP/Surface/QMaterial.h" #include "PRP/Surface/QMipmap.h" +#include "PRP/Render/QSceneNode_Preview.h" #include "PRP/Render/QSceneObj_Preview.h" QCreatable* pqMakeCreatableForm(plCreatable* pCre, QWidget* parent, int forceType) @@ -285,6 +286,8 @@ QCreatable* pqMakeCreatableForm(plCreatable* pCre, QWidget* parent, int forceTyp // Preview meta-types case kPreviewMipmap: return new QMipmap_Preview(pCre, parent); + case kPreviewSceneNode: + return new QSceneNode_Preview(pCre, parent); case kPreviewSceneObject: return new QSceneObj_Preview(pCre, parent); diff --git a/src/PrpShop/PRP/Render/QPlasmaRender.cpp b/src/PrpShop/PRP/Render/QPlasmaRender.cpp index ad43646..f9eb263 100644 --- a/src/PrpShop/PRP/Render/QPlasmaRender.cpp +++ b/src/PrpShop/PRP/Render/QPlasmaRender.cpp @@ -227,6 +227,22 @@ void QPlasmaRender::mouseReleaseEvent(QMouseEvent* evt) } } +void QPlasmaRender::addObject(plKey obj) +{ + fObjects[obj] = ObjectInfo(); + + plSceneObject* sceneObj = GET_KEY_OBJECT(obj, plSceneObject); + plCoordinateInterface* coord = GET_KEY_OBJECT(sceneObj->getCoordInterface(), plCoordinateInterface); + if (coord == nullptr) { + return; + } + for (auto childKey : coord->getChildren()) { + if (childKey->getType() == kSceneObject) { + addObject(std::move(childKey)); + } + } +} + void QPlasmaRender::setView(const hsVector3& view, float angle) { fViewPos = view; diff --git a/src/PrpShop/PRP/Render/QPlasmaRender.h b/src/PrpShop/PRP/Render/QPlasmaRender.h index d067861..7186358 100644 --- a/src/PrpShop/PRP/Render/QPlasmaRender.h +++ b/src/PrpShop/PRP/Render/QPlasmaRender.h @@ -92,7 +92,7 @@ class QPlasmaRender : public QOpenGLWidget QSize minimumSizeHint() const override { return QSize(50, 50); } QSize sizeHint() const override { return QSize(400, 400); } - void addObject(plKey obj) { fObjects[obj] = ObjectInfo(); } + void addObject(plKey obj); void setView(const hsVector3& view, float angle = 0.0f); void center(plKey obj, bool world); void build(NavigationMode navMode, DrawMode drawMode); diff --git a/src/PrpShop/PRP/Render/QSceneNode_Preview.cpp b/src/PrpShop/PRP/Render/QSceneNode_Preview.cpp new file mode 100644 index 0000000..7523026 --- /dev/null +++ b/src/PrpShop/PRP/Render/QSceneNode_Preview.cpp @@ -0,0 +1,53 @@ +/* This file is part of PlasmaShop. + * + * PlasmaShop is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlasmaShop 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PlasmaShop. If not, see . + */ + +#include "QSceneNode_Preview.h" + +#include +#include +#include +#include + +QSceneNode_Preview::QSceneNode_Preview(plCreatable* pCre, QWidget* parent) + : QCreatable(pCre, kPreviewSceneNode, parent) +{ + plSceneNode* obj = plSceneNode::Convert(fCreatable); + fRender = new QPlasmaRender(this); + bool centered = false; + for (const auto& soKey : obj->getSceneObjects()) { + if (soKey->getType() == kSceneObject) { + fRender->addObject(soKey); + if (!centered) { + fRender->center(soKey, false); + centered = true; + } + } + } + fRender->build(QPlasmaRender::kNavModel, QPlasmaRender::kDrawTextured); + QSizePolicy renderPolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + fRender->setSizePolicy(renderPolicy); + + QToolBar* viewToolbar = new QToolBar(tr("View"), this); + viewToolbar->setFloatable(false); + QActionGroup* viewActions = fRender->createViewActions(); + viewToolbar->addActions(viewActions->actions()); + + QGridLayout* layout = new QGridLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setVerticalSpacing(0); + layout->addWidget(viewToolbar, 0, 0); + layout->addWidget(fRender, 1, 0); +} diff --git a/src/PrpShop/PRP/Render/QSceneNode_Preview.h b/src/PrpShop/PRP/Render/QSceneNode_Preview.h new file mode 100644 index 0000000..a6c4424 --- /dev/null +++ b/src/PrpShop/PRP/Render/QSceneNode_Preview.h @@ -0,0 +1,34 @@ +/* This file is part of PlasmaShop. + * + * PlasmaShop is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlasmaShop 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PlasmaShop. If not, see . + */ + +#ifndef _QSCENENODE_PREVIEW_H +#define _QSCENENODE_PREVIEW_H + +#include "PRP/QCreatable.h" +#include "QPlasmaRender.h" + +class QSceneNode_Preview : public QCreatable +{ + Q_OBJECT + +protected: + QPlasmaRender* fRender; + +public: + QSceneNode_Preview(plCreatable* pCre, QWidget* parent = nullptr); +}; + +#endif diff --git a/src/PrpShop/QPlasmaUtils.cpp b/src/PrpShop/QPlasmaUtils.cpp index 4835782..0f53a4d 100644 --- a/src/PrpShop/QPlasmaUtils.cpp +++ b/src/PrpShop/QPlasmaUtils.cpp @@ -17,6 +17,8 @@ #include #include "QPlasmaUtils.h" #include +#include +#include #include bool s_showTypeIDs = false; @@ -613,6 +615,25 @@ bool pqIsValidKOType(short objType) return std::find(valid_types.begin(), valid_types.end(), objType) != valid_types.end(); } +static bool pqCanPreviewSceneObject(plSceneObject* sceneObj) +{ + if (sceneObj->getDrawInterface().Exists()) { + return true; + } + + plCoordinateInterface* coord = GET_KEY_OBJECT(sceneObj->getCoordInterface(), plCoordinateInterface); + if (coord == nullptr) { + return false; + } + for (const auto& childKey : coord->getChildren()) { + plSceneObject* child = GET_KEY_OBJECT(childKey, plSceneObject); + if (child != nullptr && pqCanPreviewSceneObject(child)) { + return true; + } + } + return false; +} + bool pqCanPreviewType(plCreatable* pCre) { short type = pCre->ClassIndex(); @@ -622,9 +643,18 @@ bool pqCanPreviewType(plCreatable* pCre) }; static size_t s_numTypes = sizeof(s_typeList) / sizeof(s_typeList[0]); - if (type == kSceneObject) { + if (type == kSceneNode) { + plSceneNode* tmp = plSceneNode::Convert(pCre); + for (const auto& soKey : tmp->getSceneObjects()) { + plSceneObject* so = GET_KEY_OBJECT(soKey, plSceneObject); + if (so != nullptr && pqCanPreviewSceneObject(so)) { + return true; + } + } + return false; + } else if (type == kSceneObject) { plSceneObject* tmp = plSceneObject::Convert(pCre); - return tmp->getDrawInterface().Exists(); + return pqCanPreviewSceneObject(tmp); } for (size_t i=0; i