From 285c685ebf5513cb707fa37366012d51a053869e Mon Sep 17 00:00:00 2001 From: codereader Date: Sat, 12 Nov 2022 07:50:13 +0100 Subject: [PATCH] #6158: EntityClassPreview is inheriting from EntityPreview --- libs/wxutil/preview/EntityClassPreview.h | 22 +++++++++++---- libs/wxutil/preview/EntityPreview.cpp | 35 ++++++++++++++++++++---- libs/wxutil/preview/EntityPreview.h | 2 ++ libs/wxutil/preview/ModelPreview.cpp | 3 -- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/libs/wxutil/preview/EntityClassPreview.h b/libs/wxutil/preview/EntityClassPreview.h index 6fde8484b7..839a6bcb18 100644 --- a/libs/wxutil/preview/EntityClassPreview.h +++ b/libs/wxutil/preview/EntityClassPreview.h @@ -3,17 +3,18 @@ #include "ieclass.h" #include "ui/ideclpreview.h" #include "ModelPreview.h" +#include "../dialog/MessageBox.h" namespace wxutil { class EntityClassPreview : - public ModelPreview, + public EntityPreview, public ui::IDeclarationPreview { public: EntityClassPreview(wxWindow* parent) : - ModelPreview(parent) + EntityPreview(parent) {} // Returns the widget that can be packed into the selector container @@ -24,8 +25,7 @@ class EntityClassPreview : void ClearPreview() override { - setModel({}); - setSkin({}); + setEntity({}); } void SetPreviewDeclName(const std::string& declName) override @@ -38,8 +38,18 @@ class EntityClassPreview : return; } - setModel(eclass->getAttributeValue("model")); - setSkin(eclass->getAttributeValue("skin")); + try + { + // Create an entity of the selected type + auto entity = GlobalEntityModule().createEntity(eclass); + setEntity(entity); + } + catch (const std::runtime_error&) + { + Messagebox::ShowError(fmt::format( + _("Unable to setup the preview,\ncould not find the entity class '{0}'"), + declName)); + } } }; diff --git a/libs/wxutil/preview/EntityPreview.cpp b/libs/wxutil/preview/EntityPreview.cpp index dae41b2c99..c42daf8af1 100644 --- a/libs/wxutil/preview/EntityPreview.cpp +++ b/libs/wxutil/preview/EntityPreview.cpp @@ -2,6 +2,7 @@ #include "i18n.h" #include "ieclass.h" +#include "ifilter.h" #include "scene/BasicRootNode.h" #include "../dialog/MessageBox.h" @@ -40,7 +41,16 @@ void EntityPreview::setEntity(const IEntityNodePtr& entity) if (_entity) { _rootNode->addChildNode(_entity); + + // Remember the entity bounds including children + _untransformedEntityBounds = _entity->worldAABB(); + } + else + { + _untransformedEntityBounds = AABB({ 0,0,0 }, { 64,64,64 }); } + + queueSceneUpdate(); } void EntityPreview::setupSceneGraph() @@ -71,23 +81,36 @@ void EntityPreview::setupSceneGraph() AABB EntityPreview::getSceneBounds() { - if (!_entity) - { - return RenderPreview::getSceneBounds(); - } - - return _entity->localAABB(); + return _untransformedEntityBounds; } void EntityPreview::prepareScene() { + if (_sceneIsReady) return; + // Clear the flag _sceneIsReady = true; + + // Reset the model rotation + resetModelRotation(); + + if (_entity) + { + // Reset the default view, facing down to the model from diagonally above the bounding box + double distance = _entity->worldAABB().getRadius() * _defaultCamDistanceFactor; + + setViewOrigin(Vector3(1, 1, 1) * distance); + setViewAngles(Vector3(34, 135, 0)); + } + + // Trigger an initial update of the subgraph + GlobalFilterSystem().updateSubgraph(getScene()->root()); } void EntityPreview::queueSceneUpdate() { _sceneIsReady = false; + queueDraw(); } bool EntityPreview::onPreRender() diff --git a/libs/wxutil/preview/EntityPreview.h b/libs/wxutil/preview/EntityPreview.h index 0d6b1f628d..4da1562aae 100644 --- a/libs/wxutil/preview/EntityPreview.h +++ b/libs/wxutil/preview/EntityPreview.h @@ -25,6 +25,8 @@ class EntityPreview : // The previewed entity IEntityNodePtr _entity; + AABB _untransformedEntityBounds; + // The light scene::INodePtr _light; diff --git a/libs/wxutil/preview/ModelPreview.cpp b/libs/wxutil/preview/ModelPreview.cpp index 2bab58f4a6..e11f344613 100644 --- a/libs/wxutil/preview/ModelPreview.cpp +++ b/libs/wxutil/preview/ModelPreview.cpp @@ -140,9 +140,6 @@ void ModelPreview::prepareScene() scene::applyIdlePose(_modelNode, modelDef); } - // Trigger an initial update of the subgraph - GlobalFilterSystem().updateSubgraph(getScene()->root()); - if (_lastModel != _model) { // Reset the model rotation