From 6080bf163e75a9d05e4f322ee2162b1f4dbe2c23 Mon Sep 17 00:00:00 2001 From: codereader Date: Mon, 19 Dec 2016 14:00:46 +0100 Subject: [PATCH] SelectionSystem is not a Rotatable anymore --- radiant/selection/ManipulationPivot.h | 5 ++ radiant/selection/RadiantSelectionSystem.cpp | 46 +++++++---------- radiant/selection/RadiantSelectionSystem.h | 3 -- .../manipulators/RotateManipulator.cpp | 49 +++++++++++++------ .../manipulators/RotateManipulator.h | 22 ++++++--- 5 files changed, 70 insertions(+), 55 deletions(-) diff --git a/radiant/selection/ManipulationPivot.h b/radiant/selection/ManipulationPivot.h index 192e27d132..a89e097a78 100644 --- a/radiant/selection/ManipulationPivot.h +++ b/radiant/selection/ManipulationPivot.h @@ -27,6 +27,11 @@ class ManipulationPivot return _pivot2World; } + const Vector3& getVector3() const + { + return _pivot2World.t().getVector3(); + } + void setFromMatrix(const Matrix4& newPivot2World) { _pivot2World = newPivot2World; diff --git a/radiant/selection/RadiantSelectionSystem.cpp b/radiant/selection/RadiantSelectionSystem.cpp index 129a305c11..79dcae8bf2 100644 --- a/radiant/selection/RadiantSelectionSystem.cpp +++ b/radiant/selection/RadiantSelectionSystem.cpp @@ -742,30 +742,6 @@ void RadiantSelectionSystem::SelectArea(const render::View& view, } } -// Applies the rotation vector to the current selection -void RadiantSelectionSystem::rotate(const Quaternion& rotation) -{ - // Check if there is anything to do - if (nothingSelected()) return; - - // Store the quaternion internally - _rotation = rotation; - - // Perform the rotation according to the current mode - if (Mode() == eComponent) - { - Scene_Rotate_Component_Selected(GlobalSceneGraph(), _rotation, _pivot2world.t().getVector3()); - } - else - { - // Cycle through the selections and rotate them - foreachSelected(RotateSelected(rotation, _pivot2world.t().getVector3())); - } - - // Update the views - SceneChangeNotify(); -} - // Applies the scaling vector to the current selection, this is called by the according ManipulatorComponents void RadiantSelectionSystem::scale(const Vector3& scaling) { // Check if anything is selected @@ -818,10 +794,22 @@ void RadiantSelectionSystem::onManipulationEnd() } // Shortcut call for an instantly applied rotation of the current selection -void RadiantSelectionSystem::rotateSelected(const Quaternion& rotation) { - // Apply the transformation and freeze the changes - startMove(); - rotate(rotation); +void RadiantSelectionSystem::rotateSelected(const Quaternion& rotation) +{ + // Perform the rotation according to the current mode + if (Mode() == eComponent) + { + Scene_Rotate_Component_Selected(GlobalSceneGraph(), rotation, _pivot2world.t().getVector3()); + } + else + { + // Cycle through the selections and rotate them + foreachSelected(RotateSelected(rotation, _pivot2world.t().getVector3())); + } + + // Update the views + SceneChangeNotify(); + freezeTransforms(); } @@ -1031,7 +1019,7 @@ void RadiantSelectionSystem::initialiseModule(const ApplicationContext& ctx) registerManipulator(std::make_shared()); registerManipulator(std::make_shared(_pivot, 2, 64)); registerManipulator(std::make_shared(*this, 0, 64)); - registerManipulator(std::make_shared(*this, 8, 64)); + registerManipulator(std::make_shared(_pivot, 8, 64)); _defaultManipulatorType = Manipulator::Drag; setActiveManipulator(_defaultManipulatorType); diff --git a/radiant/selection/RadiantSelectionSystem.h b/radiant/selection/RadiantSelectionSystem.h index a5f00fa8ed..a764ebfef2 100644 --- a/radiant/selection/RadiantSelectionSystem.h +++ b/radiant/selection/RadiantSelectionSystem.h @@ -22,7 +22,6 @@ namespace selection class RadiantSelectionSystem : public SelectionSystem, - public Rotatable, public Scalable, public Renderable, protected wxutil::SingleIdleCallback @@ -36,7 +35,6 @@ class RadiantSelectionSystem : typedef std::list ObserverList; ObserverList _observers; - Quaternion _rotation; Vector3 _scale; // The 3D volume surrounding the most recent selection. @@ -159,7 +157,6 @@ class RadiantSelectionSystem : void SelectArea(const render::View& view, const Vector2& device_point, const Vector2& device_delta, EModifier modifier, bool face); // These are the "callbacks" that are used by the Manipulatables - void rotate(const Quaternion& rotation); void scale(const Vector3& scaling); void onManipulationStart() override; diff --git a/radiant/selection/manipulators/RotateManipulator.cpp b/radiant/selection/manipulators/RotateManipulator.cpp index f2a4149aa2..655a5a69de 100644 --- a/radiant/selection/manipulators/RotateManipulator.cpp +++ b/radiant/selection/manipulators/RotateManipulator.cpp @@ -55,9 +55,10 @@ inline void draw_semicircle(const std::size_t segments, const float radius, Vert } // Constructor -RotateManipulator::RotateManipulator(Rotatable& rotatable, std::size_t segments, float radius) : - _rotateFree(rotatable), - _rotateAxis(rotatable), +RotateManipulator::RotateManipulator(ManipulationPivot& pivot, std::size_t segments, float radius) : + _pivot(pivot), + _rotateFree(*this), + _rotateAxis(*this), _circleX((segments << 2) + 1), _circleY((segments << 2) + 1), _circleZ((segments << 2) + 1), @@ -84,7 +85,7 @@ void RotateManipulator::UpdateColours() void RotateManipulator::updateCircleTransforms() { Vector3 localViewpoint( - _pivot._worldSpace.getTransposed().transformDirection(_pivot._viewpointSpace.z().getVector3()) + _pivot2World._worldSpace.getTransposed().transformDirection(_pivot2World._viewpointSpace.z().getVector3()) ); _circleX_visible = !g_vector3_axis_x.isEqual(localViewpoint, 1e-6); @@ -94,7 +95,7 @@ void RotateManipulator::updateCircleTransforms() _local2worldX.y().getVector3() = g_vector3_axis_x.crossProduct(localViewpoint).getNormalised(); _local2worldX.z().getVector3() = _local2worldX.x().getVector3().crossProduct( _local2worldX.y().getVector3()).getNormalised(); - _local2worldX.premultiplyBy(_pivot._worldSpace); + _local2worldX.premultiplyBy(_pivot2World._worldSpace); } _circleY_visible = !g_vector3_axis_y.isEqual(localViewpoint, 1e-6); @@ -104,7 +105,7 @@ void RotateManipulator::updateCircleTransforms() _local2worldY.z().getVector3() = g_vector3_axis_y.crossProduct(localViewpoint).getNormalised(); _local2worldY.x().getVector3() = _local2worldY.y().getVector3().crossProduct( _local2worldY.z().getVector3()).getNormalised(); - _local2worldY.premultiplyBy(_pivot._worldSpace); + _local2worldY.premultiplyBy(_pivot2World._worldSpace); } _circleZ_visible = !g_vector3_axis_z.isEqual(localViewpoint, 1e-6); @@ -114,12 +115,13 @@ void RotateManipulator::updateCircleTransforms() _local2worldZ.x().getVector3() = g_vector3_axis_z.crossProduct(localViewpoint).getNormalised(); _local2worldZ.y().getVector3() = _local2worldZ.z().getVector3().crossProduct( _local2worldZ.x().getVector3()).getNormalised(); - _local2worldZ.premultiplyBy(_pivot._worldSpace); + _local2worldZ.premultiplyBy(_pivot2World._worldSpace); } } -void RotateManipulator::render(RenderableCollector& collector, const VolumeTest& volume, const Matrix4& pivot2world) { - _pivot.update(pivot2world, volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); +void RotateManipulator::render(RenderableCollector& collector, const VolumeTest& volume, const Matrix4& pivot2world) +{ + _pivot2World.update(_pivot.getMatrix4(), volume.GetModelview(), volume.GetProjection(), volume.GetViewport()); updateCircleTransforms(); // temp hack @@ -128,8 +130,8 @@ void RotateManipulator::render(RenderableCollector& collector, const VolumeTest& collector.SetState(_stateOuter, RenderableCollector::eWireframeOnly); collector.SetState(_stateOuter, RenderableCollector::eFullMaterials); - collector.addRenderable(_circleScreen, _pivot._viewpointSpace); - collector.addRenderable(_circleSphere, _pivot._viewpointSpace); + collector.addRenderable(_circleScreen, _pivot2World._viewpointSpace); + collector.addRenderable(_circleSphere, _pivot2World._viewpointSpace); if(_circleX_visible) { @@ -145,8 +147,9 @@ void RotateManipulator::render(RenderableCollector& collector, const VolumeTest& } } -void RotateManipulator::testSelect(const render::View& view, const Matrix4& pivot2world) { - _pivot.update(pivot2world, view.GetModelview(), view.GetProjection(), view.GetViewport()); +void RotateManipulator::testSelect(const render::View& view, const Matrix4& pivot2world) +{ + _pivot2World.update(_pivot.getMatrix4(), view.GetModelview(), view.GetProjection(), view.GetViewport()); updateCircleTransforms(); SelectionPool selector; @@ -178,7 +181,7 @@ void RotateManipulator::testSelect(const render::View& view, const Matrix4& pivo } { - Matrix4 local2view(view.GetViewMatrix().getMultipliedBy(_pivot._viewpointSpace)); + Matrix4 local2view(view.GetViewMatrix().getMultipliedBy(_pivot2World._viewpointSpace)); { SelectionIntersection best; @@ -193,7 +196,7 @@ void RotateManipulator::testSelect(const render::View& view, const Matrix4& pivo } } - _axisScreen = _pivot._axisScreen; + _axisScreen = _pivot2World._axisScreen; if(!selector.empty()) { @@ -237,6 +240,22 @@ bool RotateManipulator::isSelected() const { | _selectableSphere.isSelected(); } +void RotateManipulator::rotate(const Quaternion& rotation) +{ + // Perform the rotation according to the current mode + if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent) + { + Scene_Rotate_Component_Selected(GlobalSceneGraph(), rotation, _pivot.getVector3()); + } + else + { + // Cycle through the selections and rotate them + GlobalSelectionSystem().foreachSelected(RotateSelected(rotation, _pivot.getVector3())); + } + + SceneChangeNotify(); +} + // Initialise the shader of the RotateManipulator class ShaderPtr RotateManipulator::_stateOuter; diff --git a/radiant/selection/manipulators/RotateManipulator.h b/radiant/selection/manipulators/RotateManipulator.h index 5463a2e8ce..3f881b9561 100644 --- a/radiant/selection/manipulators/RotateManipulator.h +++ b/radiant/selection/manipulators/RotateManipulator.h @@ -5,6 +5,7 @@ #include "../Renderables.h" #include "../Pivot2World.h" #include "../BasicSelectable.h" +#include "selection/ManipulationPivot.h" namespace selection { @@ -16,9 +17,12 @@ namespace selection * rotation. */ class RotateManipulator : - public ManipulatorBase + public ManipulatorBase, + public Rotatable { private: + ManipulationPivot& _pivot; + RotateFree _rotateFree; RotateAxis _rotateAxis; Vector3 _axisScreen; @@ -27,12 +31,12 @@ class RotateManipulator : RenderableSemiCircle _circleZ; RenderableCircle _circleScreen; RenderableCircle _circleSphere; - selection::BasicSelectable _selectableX; - selection::BasicSelectable _selectableY; - selection::BasicSelectable _selectableZ; - selection::BasicSelectable _selectableScreen; - selection::BasicSelectable _selectableSphere; - Pivot2World _pivot; + BasicSelectable _selectableX; + BasicSelectable _selectableY; + BasicSelectable _selectableZ; + BasicSelectable _selectableScreen; + BasicSelectable _selectableSphere; + Pivot2World _pivot2World; Matrix4 _local2worldX; Matrix4 _local2worldY; Matrix4 _local2worldZ; @@ -44,7 +48,7 @@ class RotateManipulator : static ShaderPtr _stateOuter; // Constructor - RotateManipulator(Rotatable& rotatable, std::size_t segments, float radius); + RotateManipulator(ManipulationPivot& pivot, std::size_t segments, float radius); Type getType() const override { @@ -62,6 +66,8 @@ class RotateManipulator : void setSelected(bool select) override; bool isSelected() const override; + + void rotate(const Quaternion& rotation) override; }; }