diff --git a/radiant/selection/ManipulationPivot.cpp b/radiant/selection/ManipulationPivot.cpp index d2d192f3b0..e80861b907 100644 --- a/radiant/selection/ManipulationPivot.cpp +++ b/radiant/selection/ManipulationPivot.cpp @@ -12,7 +12,9 @@ namespace } ManipulationPivot::ManipulationPivot() : - _entityPivotIsOrigin(false) + _entityPivotIsOrigin(false), + _needsRecalculation(true), + _operationActive(false) {} void ManipulationPivot::initialise() @@ -25,14 +27,24 @@ void ManipulationPivot::initialise() } // Returns the pivot-to-world transform -const Matrix4& ManipulationPivot::getMatrix4() const +const Matrix4& ManipulationPivot::getMatrix4() { + if (_needsRecalculation && !_operationActive) + { + updateFromSelection(); + } + return _pivot2World; } // Returns the position of the pivot point relative to origin -const Vector3& ManipulationPivot::getVector3() const +const Vector3& ManipulationPivot::getVector3() { + if (_needsRecalculation && !_operationActive) + { + updateFromSelection(); + } + return _pivot2World.t().getVector3(); } @@ -41,11 +53,17 @@ void ManipulationPivot::setFromMatrix(const Matrix4& newPivot2World) _pivot2World = newPivot2World; } +void ManipulationPivot::setNeedsRecalculation(bool needsRecalculation) +{ + _needsRecalculation = needsRecalculation; +} + // Call this before an operation is started, such that later // transformations can be applied on top of the correct starting point void ManipulationPivot::beginOperation() { _pivot2WorldStart = _pivot2World; + _operationActive = true; } // Reverts the matrix to the state it had at the beginning of the operation @@ -57,6 +75,7 @@ void ManipulationPivot::revertToStart() void ManipulationPivot::endOperation() { _pivot2WorldStart = _pivot2World; + _operationActive = false; } void ManipulationPivot::applyTranslation(const Vector3& translation) @@ -69,6 +88,8 @@ void ManipulationPivot::applyTranslation(const Vector3& translation) void ManipulationPivot::updateFromSelection() { + _needsRecalculation = false; + Vector3 objectPivot; const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo(); diff --git a/radiant/selection/ManipulationPivot.h b/radiant/selection/ManipulationPivot.h index 0679fafa2e..219718dee1 100644 --- a/radiant/selection/ManipulationPivot.h +++ b/radiant/selection/ManipulationPivot.h @@ -27,19 +27,29 @@ class ManipulationPivot // Use a single Entity's "origin" keyvalue as pivot bool _entityPivotIsOrigin; + // "dirty" flag + bool _needsRecalculation; + + // During operations, we want to block pivot recalculations + bool _operationActive; + public: ManipulationPivot(); void initialise(); // Returns the pivot-to-world transform - const Matrix4& getMatrix4() const; + const Matrix4& getMatrix4(); // Returns the position of the pivot point relative to origin - const Vector3& getVector3() const; + const Vector3& getVector3(); void setFromMatrix(const Matrix4& newPivot2World); + // Set the dirty flag of the matrix, this will trigger + // an updateFromSelection() next time getMatrix4() is called + void setNeedsRecalculation(bool needsRecalculation); + // Call this before an operation is started, such that later // transformations can be applied on top of the correct starting point void beginOperation(); diff --git a/radiant/selection/RadiantSelectionSystem.cpp b/radiant/selection/RadiantSelectionSystem.cpp index 08364b4db7..038eb45282 100644 --- a/radiant/selection/RadiantSelectionSystem.cpp +++ b/radiant/selection/RadiantSelectionSystem.cpp @@ -188,6 +188,7 @@ bool RadiantSelectionSystem::nothingSelected() const void RadiantSelectionSystem::pivotChanged() const { _pivotChanged = true; + const_cast(*this)._pivot.setNeedsRecalculation(true); SceneChangeNotify(); } @@ -831,7 +832,7 @@ const Matrix4& RadiantSelectionSystem::getPivot2World() const // Questionable const design - almost everything needs to be declared const here... const_cast(this)->recalculatePivot2World(); - return _pivot.getMatrix4(); + return const_cast(this)->_pivot.getMatrix4(); } void RadiantSelectionSystem::constructStatic()