Skip to content

Commit

Permalink
Move Pivot calculation routine to ManipulationPivot class
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Dec 19, 2016
1 parent 489f407 commit 8030516
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 65 deletions.
77 changes: 77 additions & 0 deletions radiant/selection/ManipulationPivot.cpp
@@ -1,8 +1,29 @@
#include "ManipulationPivot.h"

#include "algorithm/General.h"
#include "selectionlib.h"

namespace selection
{

namespace
{
const std::string RKEY_ENTITY_PIVOT_IS_ORIGIN = "user/ui/rotationPivotIsOrigin";
}

ManipulationPivot::ManipulationPivot() :
_entityPivotIsOrigin(false)
{}

void ManipulationPivot::initialise()
{
_entityPivotIsOrigin = registry::getValue<bool>(RKEY_ENTITY_PIVOT_IS_ORIGIN);

GlobalRegistry().signalForKey(RKEY_ENTITY_PIVOT_IS_ORIGIN).connect(
sigc::mem_fun(this, &ManipulationPivot::onRegistryKeyChanged)
);
}

// Returns the pivot-to-world transform
const Matrix4& ManipulationPivot::getMatrix4() const
{
Expand Down Expand Up @@ -46,4 +67,60 @@ void ManipulationPivot::applyTranslation(const Vector3& translation)
_pivot2World.translateBy(translation);
}

void ManipulationPivot::updateFromSelection()
{
Vector3 objectPivot;

const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

if (info.entityCount == 1 && info.totalCount == 1 &&
Node_getLightNode(GlobalSelectionSystem().ultimateSelected()))
{
// When a single light is selected, use the origin for rotation
objectPivot = Node_getLightNode(GlobalSelectionSystem().ultimateSelected())->getSelectAABB().origin;
}
else if (info.entityCount == 1 && info.totalCount == 1 && _entityPivotIsOrigin)
{
// Test if a single entity is selected
scene::INodePtr node = GlobalSelectionSystem().ultimateSelected();
Entity* entity = Node_getEntity(node);

if (entity != nullptr)
{
objectPivot = string::convert<Vector3>(entity->getKeyValue("origin"));
}
}
else
{
// Create a local variable where the aabb information is stored
AABB bounds;

// Traverse through the selection and update the <bounds> variable
if (GlobalSelectionSystem().Mode() == SelectionSystem::eComponent)
{
bounds = algorithm::getCurrentComponentSelectionBounds();
}
else
{
bounds = algorithm::getCurrentSelectionBounds();
}

// the <bounds> variable now contains the AABB of the selection, retrieve the origin
objectPivot = bounds.origin;
}

// Snap the pivot point to the grid (greebo: disabled this (issue #231))
//vector3_snap(objectPivot, GlobalGrid().getGridSize());

// The pivot2world matrix is just a translation from the world origin (0,0,0) to the object pivot
setFromMatrix(Matrix4::getTranslation(objectPivot));
}

void ManipulationPivot::onRegistryKeyChanged()
{
_entityPivotIsOrigin = registry::getValue<bool>(RKEY_ENTITY_PIVOT_IS_ORIGIN);

GlobalSelectionSystem().pivotChanged();
}

}
14 changes: 14 additions & 0 deletions radiant/selection/ManipulationPivot.h
Expand Up @@ -24,7 +24,14 @@ class ManipulationPivot
// operation, they are applied on top of the pivot2WorldStart.
Matrix4 _pivot2WorldStart;

// Use a single Entity's "origin" keyvalue as pivot
bool _entityPivotIsOrigin;

public:
ManipulationPivot();

void initialise();

// Returns the pivot-to-world transform
const Matrix4& getMatrix4() const;

Expand All @@ -43,6 +50,13 @@ class ManipulationPivot
void endOperation();

void applyTranslation(const Vector3& translation);

// Rescans the selection and calculates the pivot afresh,
// respecting the currently active settings
void updateFromSelection();

private:
void onRegistryKeyChanged();
};

}
66 changes: 3 additions & 63 deletions radiant/selection/RadiantSelectionSystem.cpp
Expand Up @@ -34,11 +34,6 @@ namespace selection
// Initialise the shader pointer
ShaderPtr RadiantSelectionSystem::_state;

namespace
{
const std::string RKEY_ROTATION_PIVOT = "user/ui/rotationPivotIsOrigin";
}

// --------- RadiantSelectionSystem Implementation ------------------------------------------

RadiantSelectionSystem::RadiantSelectionSystem() :
Expand Down Expand Up @@ -873,14 +868,6 @@ const WorkZone& RadiantSelectionSystem::getWorkZone()
return _workZone;
}

void RadiantSelectionSystem::keyChanged()
{
if (!nothingSelected()) {
pivotChanged();
recalculatePivot2World();
}
}

/* greebo: This calculates and constructs the pivot point of the selection.
* It cycles through all selected objects and creates its AABB. The origin point of the AABB
* is basically the pivot point. Pivot2World is therefore a translation from (0,0,0) to the calculated origin.
Expand All @@ -892,54 +879,9 @@ void RadiantSelectionSystem::recalculatePivot2World()

_pivotChanged = false;

Vector3 objectPivot;

if (!nothingSelected())
{
if (_selectionInfo.entityCount == 1 && _selectionInfo.totalCount == 1 &&
Node_getLightNode(ultimateSelected()))
{
// When a single light is selected, use the origin for rotation
objectPivot = Node_getLightNode(ultimateSelected())->getSelectAABB().origin;
}
else if (_selectionInfo.entityCount == 1 && _selectionInfo.totalCount == 1 &&
registry::getValue<bool>(RKEY_ROTATION_PIVOT))
{
// Test, if a single entity is selected
scene::INodePtr node = ultimateSelected();
Entity* entity = Node_getEntity(node);

if (entity != NULL)
{
objectPivot = string::convert<Vector3>(
entity->getKeyValue("origin")
);
}
}
else {
// Create a local variable where the aabb information is stored
AABB bounds;

// Traverse through the selection and update the <bounds> variable
if (Mode() == eComponent)
{
bounds = algorithm::getCurrentComponentSelectionBounds();
}
else
{
bounds = algorithm::getCurrentSelectionBounds();
}

// the <bounds> variable now contains the AABB of the selection, retrieve the origin
objectPivot = bounds.origin;
}

// Snap the pivot point to the grid (greebo: disabled this (issue #231))
//vector3_snap(objectPivot, GlobalGrid().getGridSize());

// The pivot2world matrix is just a translation from the world origin (0,0,0) to the object pivot
// Save this to our ManipulationPivot class
_pivot.setFromMatrix(Matrix4::getTranslation(objectPivot));
_pivot.updateFromSelection();
}
}
/* greebo: Renders the currently active manipulator by setting the render state and
Expand Down Expand Up @@ -997,6 +939,8 @@ void RadiantSelectionSystem::initialiseModule(const ApplicationContext& ctx)

constructStatic();

_pivot.initialise();

// Add manipulators
registerManipulator(std::make_shared<DragManipulator>(_pivot));
registerManipulator(std::make_shared<ClipManipulator>());
Expand All @@ -1020,10 +964,6 @@ void RadiantSelectionSystem::initialiseModule(const ApplicationContext& ctx)
sigc::mem_fun(this, &RadiantSelectionSystem::pivotChanged)
);

GlobalRegistry().signalForKey(RKEY_ROTATION_PIVOT).connect(
sigc::mem_fun(this, &RadiantSelectionSystem::keyChanged)
);

GlobalEventManager().addToggle("ToggleClipper", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Clip, std::placeholders::_1));
GlobalEventManager().addToggle("MouseTranslate", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Translate, std::placeholders::_1));
GlobalEventManager().addToggle("MouseRotate", std::bind(&RadiantSelectionSystem::toggleManipulatorMode, this, Manipulator::Rotate, std::placeholders::_1));
Expand Down
2 changes: 0 additions & 2 deletions radiant/selection/RadiantSelectionSystem.h
Expand Up @@ -76,8 +76,6 @@ class RadiantSelectionSystem :

bool nothingSelected() const;

void keyChanged();

public:

RadiantSelectionSystem();
Expand Down

0 comments on commit 8030516

Please sign in to comment.