Skip to content

Commit

Permalink
#5128: Working on the rotate manipulator
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Sep 12, 2021
1 parent 7057b97 commit 3836a9e
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 46 deletions.
16 changes: 16 additions & 0 deletions include/imanipulator.h
Expand Up @@ -123,6 +123,22 @@ class ISceneManipulator :
virtual bool supportsComponentManipulation() const = 0;
};

/**
* A Texture Tool Manipulator is a 2D-renderable object that does the rendering itself
* without taking the path of a RenderableCollector.
*/
class ITextureToolManipulator :
public IManipulator
{
public:
using Ptr = std::shared_ptr<ITextureToolManipulator>;

virtual ~ITextureToolManipulator() {}

// Renders the manipulator's visual representation to the scene (absolute UV coordinates)
virtual void renderComponents(const Matrix4& pivot2World) = 0;
};

// Factory interface instantiating new IManipulator instances for a given purpose
class IManipulatorManager :
public RegisterableModule
Expand Down
51 changes: 41 additions & 10 deletions radiant/textool/TexTool.cpp
Expand Up @@ -58,7 +58,8 @@ TexTool::TexTool() :
_grid(GRID_DEFAULT),
_gridActive(registry::getValue<bool>(RKEY_GRID_STATE)),
_updateNeeded(false),
_selectionRescanNeeded(false)
_selectionRescanNeeded(false),
_pivot2World(Matrix4::getIdentity())
{
Bind(wxEVT_IDLE, &TexTool::onIdle, this);
Bind(wxEVT_KEY_DOWN, &TexTool::onKeyPress, this);
Expand All @@ -77,8 +78,9 @@ TexTool::TexTool() :
std::bind(&TexTool::onMouseDown, this, std::placeholders::_1),
std::bind(&TexTool::onMouseUp, this, std::placeholders::_1));

registerManipulator(GlobalManipulatorManager().createManipulator(
selection::IManipulator::Context::TextureTool, selection::IManipulator::Rotate));
registerManipulator(std::static_pointer_cast<selection::ITextureToolManipulator>(
GlobalManipulatorManager().createManipulator(
selection::IManipulator::Context::TextureTool, selection::IManipulator::Rotate)));

_defaultManipulatorType = selection::IManipulator::Rotate;
setActiveManipulator(_defaultManipulatorType);
Expand Down Expand Up @@ -363,7 +365,7 @@ void TexTool::testSelect(SelectionTest& test)
selection::SelectionPool selectionPool;

// Cycle through all the toplevel items and test them for selectability
for (const auto& item : _items)
for (const auto& item : _items)
{
item->testSelect(selectionPool, test);
}
Expand All @@ -385,6 +387,30 @@ void TexTool::testSelect(SelectionTest& test)

auto bestSelectable = *selectionPool.begin();
bestSelectable.second->setSelected(true);

// Check the centerpoint of all selected items
Vector2 sum;
std::size_t count = 0;

for (const auto& item : _items)
{
if (item->isSelected())
{
auto bounds = item->getSelectedExtents();
sum += Vector2(bounds.origin.x(), bounds.origin.y());
count++;
}
}

if (count > 0)
{
sum /= count;
_pivot2World = Matrix4::getTranslation(Vector3(sum.x(), sum.y(), 0));
}
else
{
_pivot2World = Matrix4::getIdentity();
}
}

void TexTool::flipSelected(int axis) {
Expand Down Expand Up @@ -965,6 +991,11 @@ bool TexTool::onGLDraw()
// Draw the u/v coordinates
drawUVCoords();

if (_activeManipulator)
{
_activeManipulator->renderComponents(_pivot2World);
}

if (!_activeMouseTools.empty())
{
glMatrixMode(GL_PROJECTION);
Expand All @@ -974,7 +1005,7 @@ bool TexTool::onGLDraw()
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

for (const ActiveMouseTools::value_type& i : _activeMouseTools)
for (const auto& i : _activeMouseTools)
{
i.second->renderOverlay();
}
Expand Down Expand Up @@ -1217,7 +1248,7 @@ TextureToolMouseEvent TexTool::createMouseEvent(const Vector2& point, const Vect
return TextureToolMouseEvent(*this, normalisedDeviceCoords, delta);
}

std::size_t TexTool::registerManipulator(const selection::IManipulator::Ptr& manipulator)
std::size_t TexTool::registerManipulator(const selection::ITextureToolManipulator::Ptr& manipulator)
{
std::size_t newId = 1;

Expand All @@ -1243,9 +1274,9 @@ std::size_t TexTool::registerManipulator(const selection::IManipulator::Ptr& man
return newId;
}

void TexTool::unregisterManipulator(const selection::IManipulator::Ptr& manipulator)
void TexTool::unregisterManipulator(const selection::ITextureToolManipulator::Ptr& manipulator)
{
for (Manipulators::const_iterator i = _manipulators.begin(); i != _manipulators.end(); ++i)
for (auto i = _manipulators.begin(); i != _manipulators.end(); ++i)
{
if (i->second == manipulator)
{
Expand All @@ -1261,7 +1292,7 @@ selection::IManipulator::Type TexTool::getActiveManipulatorType()
return _activeManipulator->getType();
}

const selection::IManipulator::Ptr& TexTool::getActiveManipulator()
const selection::ITextureToolManipulator::Ptr& TexTool::getActiveManipulator()
{
return _activeManipulator;
}
Expand Down Expand Up @@ -1312,7 +1343,7 @@ sigc::signal<void, selection::IManipulator::Type>& TexTool::signal_activeManipul

Matrix4 TexTool::getPivot2World()
{
return Matrix4::getTranslation(Vector3(0,0,0));
return _pivot2World;
}

void TexTool::onManipulationStart()
Expand Down
12 changes: 7 additions & 5 deletions radiant/textool/TexTool.h
Expand Up @@ -90,15 +90,17 @@ class TexTool :
sigc::connection _undoHandler;
sigc::connection _redoHandler;

typedef std::map<std::size_t, selection::IManipulator::Ptr> Manipulators;
typedef std::map<std::size_t, selection::ITextureToolManipulator::Ptr> Manipulators;
Manipulators _manipulators;

// The currently active manipulator
selection::IManipulator::Ptr _activeManipulator;
selection::ITextureToolManipulator::Ptr _activeManipulator;
selection::IManipulator::Type _defaultManipulatorType;

sigc::signal<void, selection::IManipulator::Type> _sigActiveManipulatorChanged;

Matrix4 _pivot2World;

private:
// This is where the static shared_ptr of the singleton instance is held.
static TexToolPtr& InstancePtr();
Expand Down Expand Up @@ -281,11 +283,11 @@ class TexTool :
static void registerCommands();

// Returns the ID of the registered manipulator
std::size_t registerManipulator(const selection::IManipulator::Ptr& manipulator);
void unregisterManipulator(const selection::IManipulator::Ptr& manipulator);
std::size_t registerManipulator(const selection::ITextureToolManipulator::Ptr& manipulator);
void unregisterManipulator(const selection::ITextureToolManipulator::Ptr& manipulator);

selection::IManipulator::Type getActiveManipulatorType();
const selection::IManipulator::Ptr& getActiveManipulator();
const selection::ITextureToolManipulator::Ptr& getActiveManipulator();
void setActiveManipulator(std::size_t manipulatorId);
void setActiveManipulator(selection::IManipulator::Type manipulatorType);
sigc::signal<void, selection::IManipulator::Type>& signal_activeManipulatorChanged();
Expand Down
2 changes: 2 additions & 0 deletions radiant/textool/item/FaceItem.cpp
Expand Up @@ -68,6 +68,8 @@ void FaceItem::render()

glEnd();

glDisable(GL_BLEND);

// Now invoke the default render method (calls render() on all children)
TexToolItem::render();
}
Expand Down
24 changes: 0 additions & 24 deletions radiant/textool/tools/TextureToolManipulateMouseTool.cpp
Expand Up @@ -261,28 +261,4 @@ void TextureToolManipulateMouseTool::renderOverlay()
#endif
}

void TextureToolManipulateMouseTool::render(RenderSystem& renderSystem, RenderableCollector& collector, const VolumeTest& volume)
{
#if 0
if (nothingSelected()) return;

const selection::ManipulatorPtr& activeManipulator = _selectionSystem.getActiveManipulator();

if (!activeManipulator) return;

if (!_pointShader)
{
_pointShader = renderSystem.capture("$POINT");
}

collector.setHighlightFlag(RenderableCollector::Highlight::Faces, false);
collector.setHighlightFlag(RenderableCollector::Highlight::Primitives, false);

collector.SetState(_pointShader, RenderableCollector::eWireframeOnly);
collector.SetState(_pointShader, RenderableCollector::eFullMaterials);

activeManipulator->render(collector, volume);
#endif
}

}
1 change: 0 additions & 1 deletion radiant/textool/tools/TextureToolManipulateMouseTool.h
Expand Up @@ -51,7 +51,6 @@ class TextureToolManipulateMouseTool :
virtual unsigned int getRefreshMode() override;

void renderOverlay() override;
void render(RenderSystem& renderSystem, RenderableCollector& collector, const VolumeTest& volume) override;

private:
bool selectManipulator(const render::View& view, const Vector2& devicePoint, const Vector2& deviceEpsilon);
Expand Down
@@ -1,8 +1,39 @@
#include "TextureToolRotateManipulator.h"

#include "iselectiontest.h"
#include "selection/BestPoint.h"
#include "selection/SelectionPool.h"

namespace selection
{

void TextureRotator::beginTransformation(const Matrix4& pivot2world, const VolumeTest& view, const Vector2& devicePoint)
{

}

void TextureRotator::transform(const Matrix4& pivot2world, const VolumeTest& view, const Vector2& devicePoint, unsigned int constraints)
{

}

void TextureRotator::resetCurAngle()
{
_curAngle = 0;
}

Vector3::ElementType TextureRotator::getCurAngle() const
{
return _curAngle;
}

TextureToolRotateManipulator::TextureToolRotateManipulator() :
_renderableCircle(8 << 3)
{
draw_circle(8, 1.0f, &_renderableCircle.front(), RemapXYZ());
_renderableCircle.setColour(Colour4b(255, 0, 0, 255));
}

std::size_t TextureToolRotateManipulator::getId() const
{
return _id;
Expand All @@ -20,22 +51,69 @@ IManipulator::Type TextureToolRotateManipulator::getType() const

IManipulator::Component* TextureToolRotateManipulator::getActiveComponent()
{
return nullptr;
return &_rotator;
}

void TextureToolRotateManipulator::setSelected(bool select)
{
_isSelected = select;
_selectableZ.setSelected(select);
}

bool TextureToolRotateManipulator::isSelected() const
{
return _isSelected;
return _selectableZ.isSelected();
}

void TextureToolRotateManipulator::testSelect(SelectionTest& test, const Matrix4& pivot2world)
{
// TODO
SelectionPool selector;

test.BeginMesh(pivot2world, false);

SelectionIntersection best;
test.TestLineStrip(VertexPointer(&_renderableCircle.front().vertex, sizeof(VertexCb)), _renderableCircle.size(), best);

if (best.isValid())
{
Selector_add(selector, _selectableZ);
}

if (!selector.empty())
{
//rMessage() << "Got the circle!" << std::endl;

selector.begin()->second->setSelected(true);
}
else
{
//rMessage() << "MISSED" << std::endl;
}
}

void TextureToolRotateManipulator::renderComponents(const Matrix4& pivot2World)
{
if (!_shader)
{
_shader = GlobalRenderSystem().capture("$WIRE_OVERLAY");
}

if (_renderableCircle.empty()) return;

const auto& translation = pivot2World.tCol().getVector3();

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslated(translation.x(), translation.y(), 0);

// Enable point colours if required
glEnableClientState(GL_COLOR_ARRAY);

pointvertex_gl_array(&_renderableCircle.front());
glDrawArrays(GL_LINE_LOOP, 0, static_cast<GLsizei>(_renderableCircle.size()));

glDisableClientState(GL_COLOR_ARRAY);

glPopMatrix();
}

}

0 comments on commit 3836a9e

Please sign in to comment.