From f7790a65fbf64314580e29958514f02dffd6de14 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 11 Oct 2020 07:23:50 +0200 Subject: [PATCH] #5263: Apply the same modified scale to the new model after being cloned --- radiantcore/entity/EntityNode.cpp | 30 +++++++++++++++++++ radiantcore/entity/EntityNode.h | 4 +++ .../entity/doom3group/Doom3GroupNode.cpp | 1 + .../entity/eclassmodel/EclassModelNode.cpp | 1 + .../entity/generic/GenericEntityNode.cpp | 1 + radiantcore/entity/light/LightNode.cpp | 1 + radiantcore/entity/speaker/SpeakerNode.cpp | 1 + 7 files changed, 39 insertions(+) diff --git a/radiantcore/entity/EntityNode.cpp b/radiantcore/entity/EntityNode.cpp index 32e800e8d0..0dec225a99 100644 --- a/radiantcore/entity/EntityNode.cpp +++ b/radiantcore/entity/EntityNode.cpp @@ -69,6 +69,31 @@ void EntityNode::construct() _shaderParms.addKeyObservers(); } +void EntityNode::constructClone(const EntityNode& original) +{ + // We just got cloned, it's possible that this node is the parent of a scaled model node + auto originalChildModel = original.getModelKey().getNode(); + + if (originalChildModel) + { + model::ModelNodePtr originalModel = Node_getModel(originalChildModel); + + // Check if the original model node is scaled + if (originalModel && originalModel->hasModifiedScale()) + { + assert(getModelKey().getNode()); // clone should have a child model like the original + auto transformable = Node_getTransformable(getModelKey().getNode()); + + if (transformable) + { + transformable->setType(TRANSFORM_PRIMITIVE); + transformable->setScale(originalModel->getModelScale()); + transformable->freezeTransform(); + } + } + } +} + void EntityNode::destruct() { _shaderParms.removeKeyObservers(); @@ -283,6 +308,11 @@ ModelKey& EntityNode::getModelKey() return _modelKey; } +const ModelKey& EntityNode::getModelKey() const +{ + return _modelKey; +} + void EntityNode::onModelKeyChanged(const std::string& value) { // Default implementation suitable for Light, Generic and EClassModel diff --git a/radiantcore/entity/EntityNode.h b/radiantcore/entity/EntityNode.h index 4c33858051..13c66a27f8 100644 --- a/radiantcore/entity/EntityNode.h +++ b/radiantcore/entity/EntityNode.h @@ -135,6 +135,7 @@ class EntityNode : const ShaderPtr& getColourShader() const; ModelKey& getModelKey(); // needed by the Doom3Group class, could be a fixme + const ModelKey& getModelKey() const; const ShaderPtr& getWireShader() const override; const ShaderPtr& getFillShader() const; @@ -154,6 +155,9 @@ class EntityNode : */ virtual void construct(); + // Called after cloning and construct to perform additional setup + virtual void constructClone(const EntityNode& original); + // Signal method to be overridden by subclasses. // Don't forget to call the base class implementation as this will // reload the entity key values and notify observers diff --git a/radiantcore/entity/doom3group/Doom3GroupNode.cpp b/radiantcore/entity/doom3group/Doom3GroupNode.cpp index 86caf970ea..230718e17f 100644 --- a/radiantcore/entity/doom3group/Doom3GroupNode.cpp +++ b/radiantcore/entity/doom3group/Doom3GroupNode.cpp @@ -222,6 +222,7 @@ scene::INodePtr Doom3GroupNode::clone() const { Doom3GroupNodePtr clone(new Doom3GroupNode(*this)); clone->construct(); + clone->constructClone(*this); return clone; } diff --git a/radiantcore/entity/eclassmodel/EclassModelNode.cpp b/radiantcore/entity/eclassmodel/EclassModelNode.cpp index 01f26a6270..1867fcbc43 100644 --- a/radiantcore/entity/eclassmodel/EclassModelNode.cpp +++ b/radiantcore/entity/eclassmodel/EclassModelNode.cpp @@ -99,6 +99,7 @@ scene::INodePtr EclassModelNode::clone() const { EclassModelNodePtr node(new EclassModelNode(*this)); node->construct(); + node->constructClone(*this); return node; } diff --git a/radiantcore/entity/generic/GenericEntityNode.cpp b/radiantcore/entity/generic/GenericEntityNode.cpp index d0317db6ad..de39a2eb24 100644 --- a/radiantcore/entity/generic/GenericEntityNode.cpp +++ b/radiantcore/entity/generic/GenericEntityNode.cpp @@ -53,6 +53,7 @@ scene::INodePtr GenericEntityNode::clone() const { GenericEntityNodePtr node(new GenericEntityNode(*this)); node->construct(); + node->constructClone(*this); return node; } diff --git a/radiantcore/entity/light/LightNode.cpp b/radiantcore/entity/light/LightNode.cpp index e2213e5d68..9ca3cf964e 100644 --- a/radiantcore/entity/light/LightNode.cpp +++ b/radiantcore/entity/light/LightNode.cpp @@ -253,6 +253,7 @@ scene::INodePtr LightNode::clone() const { LightNodePtr node(new LightNode(*this)); node->construct(); + node->constructClone(*this); return node; } diff --git a/radiantcore/entity/speaker/SpeakerNode.cpp b/radiantcore/entity/speaker/SpeakerNode.cpp index 769de21957..f2ac48d7c1 100644 --- a/radiantcore/entity/speaker/SpeakerNode.cpp +++ b/radiantcore/entity/speaker/SpeakerNode.cpp @@ -232,6 +232,7 @@ scene::INodePtr SpeakerNode::clone() const { SpeakerNodePtr node(new SpeakerNode(*this)); node->construct(); + node->constructClone(*this); return node; }