Skip to content

Commit

Permalink
Add Measurement Mouse Tool to orthoviews (#2303)
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Dec 26, 2016
1 parent e1b95d2 commit 4811361
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 1 deletion.
1 change: 1 addition & 0 deletions install/input.xml
Expand Up @@ -12,6 +12,7 @@
<tool name="ClipperTool" button="LMB" modifiers="" />
<tool name="MoveViewTool" button="RMB" modifiers="" />
<tool name="ZoomTool" button="RMB" modifiers="SHIFT" />
<tool name="MeasurementTool" button="MMB" modifiers="CONTROL+ALT" />
</mouseToolMapping>
<!-- ID 1 = camera -->
<mouseToolMapping name="CameraView" id="1">
Expand Down
1 change: 1 addition & 0 deletions radiant/Makefile.am
Expand Up @@ -147,6 +147,7 @@ darkradiant_SOURCES = main.cpp \
ui/aas/AasControlDialog.cpp \
xyview/tools/BrushCreatorTool.cpp \
xyview/tools/ClipperTool.cpp \
xyview/tools/MeasurementTool.cpp \
xyview/XYWnd.cpp \
xyview/FloatingOrthoView.cpp \
xyview/GlobalXYWnd.cpp \
Expand Down
2 changes: 2 additions & 0 deletions radiant/xyview/GlobalXYWnd.cpp
Expand Up @@ -20,6 +20,7 @@
#include "tools/CameraAngleTool.h"
#include "tools/CameraMoveTool.h"
#include "tools/MoveViewTool.h"
#include "tools/MeasurementTool.h"

#include <functional>

Expand Down Expand Up @@ -676,6 +677,7 @@ void XYWndManager::initialiseModule(const ApplicationContext& ctx)
toolGroup.registerMouseTool(std::make_shared<CameraAngleTool>());
toolGroup.registerMouseTool(std::make_shared<CameraMoveTool>());
toolGroup.registerMouseTool(std::make_shared<MoveViewTool>());
toolGroup.registerMouseTool(std::make_shared<MeasurementTool>());
}

void XYWndManager::shutdownModule()
Expand Down
2 changes: 1 addition & 1 deletion radiant/xyview/XYWnd.cpp
Expand Up @@ -122,7 +122,7 @@ XYWnd::XYWnd(int id, wxWindow* parent) :
_wxGLWidget->Connect(wxEVT_IDLE, wxIdleEventHandler(XYWnd::onIdle), NULL, this);

_freezePointer.connectMouseEvents(
wxutil::FreezePointer::MouseEventFunction(),
std::bind(&XYWnd::onGLMouseButtonPress, this, std::placeholders::_1),
std::bind(&XYWnd::onGLMouseButtonRelease, this, std::placeholders::_1));

updateProjection();
Expand Down
187 changes: 187 additions & 0 deletions radiant/xyview/tools/MeasurementTool.cpp
@@ -0,0 +1,187 @@
#include "MeasurementTool.h"

#include "iclipper.h"
#include "iuimanager.h"
#include "XYMouseToolEvent.h"
#include "selectionlib.h"
#include "string/convert.h"
#include <boost/format.hpp>

namespace ui
{

MeasurementTool::MeasurementTool() :
_points(GL_POINTS),
_lines(GL_LINE_STRIP)
{}

const std::string& MeasurementTool::getName()
{
static std::string name("MeasurementTool");
return name;
}

const std::string& MeasurementTool::getDisplayName()
{
static std::string displayName(_("Measure"));
return displayName;
}

MouseTool::Result MeasurementTool::onMouseDown(Event& ev)
{
try
{
if (GlobalClipper().clipMode())
{
return Result::Ignored; // no measurement in clip mode
}

// We only operate on XY view events, so attempt to cast
XYMouseToolEvent& xyEvent = dynamic_cast<XYMouseToolEvent&>(ev);

Vector3 clickPos = xyEvent.getWorldPos();
xyEvent.getView().snapToGrid(clickPos);

assert(_lines.size() == _points.size());

VertexCb clickVertex(clickPos, Colour4b());

if (_points.empty())
{
// If we just started, allocate two points
_points.push_back(clickVertex);
_points.push_back(clickVertex);

// Copy the vertices to the lines vector
_lines.push_back(clickVertex);
_lines.push_back(clickVertex);
}
else
{
// Store the click position and add a new vertex
_points[_points.size() - 1].vertex = clickVertex.vertex;
_lines[_lines.size() - 1].vertex = clickVertex.vertex;

// Add one additional point to the chain
_points.push_back(clickVertex);
_lines.push_back(clickVertex);
}

return Result::Activated;
}
catch (std::bad_cast&)
{
}

return Result::Ignored; // not handled
}

MouseTool::Result MeasurementTool::onMouseMove(Event& ev)
{
try
{
// We only operate on XY view events, so attempt to cast
XYMouseToolEvent& xyEvent = dynamic_cast<XYMouseToolEvent&>(ev);

Vector3 endPos = xyEvent.getWorldPos();
xyEvent.getView().snapToGrid(endPos);

assert(!_points.empty());

_points[_points.size() - 1].vertex = endPos;
_points.setColour(Colour4b(0, 0, 0, 0));

_lines[_lines.size() -1] = _points[_points.size() - 1];
}
catch (std::bad_cast&)
{
return Result::Ignored;
}

return Result::Continued;
}

MouseTool::Result MeasurementTool::onMouseUp(Event& ev)
{
try
{
// We only operate on XY view events, so attempt to cast
dynamic_cast<XYMouseToolEvent&>(ev);

// We continue until the user hits ESC
return Result::Continued;
}
catch (std::bad_cast&)
{
return Result::Ignored;
}
}

MeasurementTool::Result MeasurementTool::onCancel(IInteractiveView& view)
{
_points.clear();
_lines.clear();

return Result::Finished;
}

void MeasurementTool::onMouseCaptureLost(IInteractiveView& view)
{
onCancel(view);
}

unsigned int MeasurementTool::getPointerMode()
{
return PointerMode::Normal;
}

unsigned int MeasurementTool::getRefreshMode()
{
return RefreshMode::Force | RefreshMode::ActiveView;
}

void MeasurementTool::ensureShaders(RenderSystem& renderSystem)
{
if (!_wireShader)
{
Vector3 colour = ColourSchemes().getColour("drag_selection");

_colour.x() = colour.x();
_colour.y() = colour.y();
_colour.z() = colour.z();
_colour.w() = 1;

_wireShader = renderSystem.capture((boost::format("<%f %f %f>") % _colour[0] % _colour[1] % _colour[2]).str());
}

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

void MeasurementTool::render(RenderSystem& renderSystem, RenderableCollector& collector, const VolumeTest& volume)
{
ensureShaders(renderSystem);

// Render lines
collector.SetState(_wireShader, RenderableCollector::eWireframeOnly);
collector.addRenderable(_lines, Matrix4::getIdentity());

// Render points
collector.SetState(_pointShader, RenderableCollector::eWireframeOnly);
collector.addRenderable(_points, Matrix4::getIdentity());

// Render distance string
for (std::size_t i = 1; i < _points.size(); ++i)
{
const Vector3& a = _points[i-1].vertex;
const Vector3& b = _points[i].vertex;

glColor4dv(_colour);
glRasterPos3dv((a+b)*0.5);
GlobalOpenGL().drawString(string::to_string((a-b).getLength()));
}
}

} // namespace
49 changes: 49 additions & 0 deletions radiant/xyview/tools/MeasurementTool.h
@@ -0,0 +1,49 @@
#pragma once

#include "imousetool.h"
#include "iorthoview.h"
#include "math/Vector3.h"
#include "render.h"
#include "render/Colour4.h"

namespace ui
{

/**
* This tool can be used to measure distances.
* It is working on the orthoviews only.
*/
class MeasurementTool :
public MouseTool
{
private:
RenderablePointVector _points;
RenderablePointVector _lines;

ShaderPtr _pointShader;
ShaderPtr _wireShader;

Colour4 _colour;

public:
MeasurementTool();

const std::string& getName() override;
const std::string& getDisplayName() override;

Result onMouseDown(Event& ev) override;
Result onMouseMove(Event& ev) override;
Result onMouseUp(Event& ev) override;

unsigned int getPointerMode() override;
unsigned int getRefreshMode() override;
Result onCancel(IInteractiveView& view) override;
void onMouseCaptureLost(IInteractiveView& view) override;

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

private:
void ensureShaders(RenderSystem& renderSystem);
};

} // namespace
2 changes: 2 additions & 0 deletions tools/msvc2015/DarkRadiant.vcxproj
Expand Up @@ -555,6 +555,7 @@
<ClCompile Include="..\..\radiant\xyview\GlobalXYWnd.cpp" />
<ClCompile Include="..\..\radiant\xyview\tools\BrushCreatorTool.cpp" />
<ClCompile Include="..\..\radiant\xyview\tools\ClipperTool.cpp" />
<ClCompile Include="..\..\radiant\xyview\tools\MeasurementTool.cpp" />
<ClCompile Include="..\..\radiant\xyview\XYWnd.cpp" />
<ClCompile Include="..\..\radiant\referencecache\ModelCache.cpp" />
<ClCompile Include="..\..\radiant\referencecache\NullModel.cpp" />
Expand Down Expand Up @@ -848,6 +849,7 @@
<ClInclude Include="..\..\radiant\xyview\tools\CameraAngleTool.h" />
<ClInclude Include="..\..\radiant\xyview\tools\CameraMoveTool.h" />
<ClInclude Include="..\..\radiant\xyview\tools\ClipperTool.h" />
<ClInclude Include="..\..\radiant\xyview\tools\MeasurementTool.h" />
<ClInclude Include="..\..\radiant\xyview\tools\MoveViewTool.h" />
<ClInclude Include="..\..\radiant\xyview\tools\XYMouseToolEvent.h" />
<ClInclude Include="..\..\radiant\xyview\tools\ZoomTool.h" />
Expand Down
6 changes: 6 additions & 0 deletions tools/msvc2015/DarkRadiant.vcxproj.filters
Expand Up @@ -883,6 +883,9 @@
<ClCompile Include="..\..\radiant\selection\ManipulationPivot.cpp">
<Filter>src\selection</Filter>
</ClCompile>
<ClCompile Include="..\..\radiant\xyview\tools\MeasurementTool.cpp">
<Filter>src\xyview\tools</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\radiant\RadiantModule.h">
Expand Down Expand Up @@ -1797,6 +1800,9 @@
<ClInclude Include="..\..\radiant\selection\ManipulationPivot.h">
<Filter>src\selection</Filter>
</ClInclude>
<ClInclude Include="..\..\radiant\xyview\tools\MeasurementTool.h">
<Filter>src\xyview\tools</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\radiant\darkradiant.rc" />
Expand Down

0 comments on commit 4811361

Please sign in to comment.