Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tgeometry.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Zoom Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class ZoomTool : public TTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int m_oldY;
Toshihiro Shimizu 890ddd
	TPointD m_center;
Toshihiro Shimizu 890ddd
	bool m_dragging;
Toshihiro Shimizu 890ddd
	double m_factor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ZoomTool()
Toshihiro Shimizu 890ddd
		: TTool("T_Zoom"), m_dragging(false), m_oldY(0), m_factor(1)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bind(TTool::AllTargets);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolType getToolType() const { return TTool::GenericTool; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateMatrix() { return setMatrix(TAffine()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_dragging = true;
Toshihiro Shimizu 890ddd
		int v = 1;
Toshihiro Shimizu 890ddd
		if (e.isAltPressed())
Toshihiro Shimizu 890ddd
			v = -1;
Toshihiro Shimizu 890ddd
		m_oldY = e.m_pos.y;
Toshihiro Shimizu 890ddd
		// m_center = getViewer()->winToWorld(e.m_pos);
Toshihiro Shimizu 890ddd
		m_center = TPointD(e.m_pos.x, e.m_pos.y);
Toshihiro Shimizu 890ddd
		m_factor = 1;
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int d = m_oldY - e.m_pos.y;
Toshihiro Shimizu 890ddd
		m_oldY = e.m_pos.y;
Toshihiro Shimizu 890ddd
		double f = exp(-d * 0.01);
Toshihiro Shimizu 890ddd
		m_factor = f;
Toshihiro Shimizu 890ddd
		m_viewer->zoom(m_center, f);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_dragging = false;
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void rightButtonDown(const TPointD &, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_dragging)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD center = m_viewer->winToWorld(TPoint(m_center.x, m_center.y));
Toshihiro Shimizu 890ddd
		double pixelSize = getPixelSize();
Toshihiro Shimizu 890ddd
		double unit = pixelSize;
Toshihiro Shimizu 890ddd
		glPushMatrix();
Toshihiro Shimizu 890ddd
		glTranslated(center.x, center.y, 0);
Toshihiro Shimizu 890ddd
		glScaled(unit, unit, unit);
Toshihiro Shimizu 890ddd
		glColor3f(1, 0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double u = 4;
Toshihiro Shimizu 890ddd
		glBegin(GL_LINES);
Toshihiro Shimizu 890ddd
		glVertex2d(0, -10);
Toshihiro Shimizu 890ddd
		glVertex2d(0, 10);
Toshihiro Shimizu 890ddd
		glVertex2d(-10, 0);
Toshihiro Shimizu 890ddd
		glVertex2d(10, 0);
Toshihiro Shimizu 890ddd
		glEnd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		glPopMatrix();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getCursorId() const { return ToolCursor::ZoomCursor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} zoomTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Hand Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class HandTool : public TTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStopWatch m_sw;
Toshihiro Shimizu 890ddd
	TPoint m_oldPos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	HandTool()
Toshihiro Shimizu 890ddd
		: TTool("T_Hand")
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bind(TTool::AllTargets);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolType getToolType() const { return TTool::GenericTool; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateMatrix() { return setMatrix(TAffine()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_oldPos = e.m_pos;
Toshihiro Shimizu 890ddd
		m_sw.start(true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (m_sw.getTotalTime() < 10)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_sw.stop();
Toshihiro Shimizu 890ddd
		m_sw.start(true);
Toshihiro Shimizu 890ddd
		TPoint delta = e.m_pos - m_oldPos;
Toshihiro Shimizu 890ddd
		delta.y = -delta.y;
Toshihiro Shimizu 890ddd
		m_viewer->pan(delta);
Toshihiro Shimizu 890ddd
		m_oldPos = e.m_pos;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_sw.stop();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getCursorId() const { return ToolCursor::PanCursor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} handTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rotate Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RotateTool : public TTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStopWatch m_sw;
Toshihiro Shimizu 890ddd
	TPointD m_oldPos;
Toshihiro Shimizu 890ddd
	TPointD m_center;
Toshihiro Shimizu 890ddd
	bool m_dragging;
Toshihiro Shimizu 890ddd
	double m_angle;
Toshihiro Shimizu 890ddd
	TPoint m_oldMousePos;
Toshihiro Shimizu 890ddd
	TBoolProperty m_cameraCentered;
Toshihiro Shimizu 890ddd
	TPropertyGroup m_prop;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RotateTool()
Toshihiro Shimizu 890ddd
		: TTool("T_Rotate"), m_dragging(false), m_cameraCentered("Rotate On Camera Center", false), m_angle(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bind(TTool::AllTargets);
Toshihiro Shimizu 890ddd
		m_prop.bind(m_cameraCentered);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolType getToolType() const { return TTool::GenericTool; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateMatrix() { return setMatrix(TAffine()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPropertyGroup *getProperties(int targetType) { return &m_prop; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_angle = 0.0;
Toshihiro Shimizu 890ddd
		m_dragging = true;
Toshihiro Shimizu 890ddd
		m_oldPos = pos;
Toshihiro Shimizu 890ddd
		m_oldMousePos = e.m_pos;
Toshihiro Shimizu 890ddd
		//m_center = TPointD(0,0);
Toshihiro Shimizu 890ddd
		m_sw.start(true);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//m_center = viewAffine.inv()*TPointD(0,0);//m_viewer->winToWorld(m_viewer);
Toshihiro Shimizu 890ddd
		//virtual TPointD winToWorld(const TPoint &winPos) const = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_viewer)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (m_sw.getTotalTime() < 50)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_sw.stop();
Toshihiro Shimizu 890ddd
		m_sw.start(true);
Toshihiro Shimizu 890ddd
		TPointD p = pos;
Toshihiro Shimizu 890ddd
		if (m_viewer->is3DView()) {
Toshihiro Shimizu 890ddd
			TPoint d = e.m_pos - m_oldMousePos;
Toshihiro Shimizu 890ddd
			m_oldMousePos = e.m_pos;
Toshihiro Shimizu 890ddd
			double factor = 0.5;
Toshihiro Shimizu 890ddd
			m_viewer->rotate3D(factor * d.x, -factor * d.y);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			TPointD a = p - m_center;
Toshihiro Shimizu 890ddd
			TPointD b = m_oldPos - m_center;
Toshihiro Shimizu 890ddd
			if (norm2(a) > 0 && norm2(b) > 0) {
Toshihiro Shimizu 890ddd
				double ang = 180 * asin(cross(b, a) / (norm(a) * norm(b))) / TConsts::pi;
Toshihiro Shimizu 890ddd
				m_angle = m_angle + ang;
Toshihiro Shimizu 890ddd
				m_viewer->rotate(m_center, m_angle);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_oldPos = p;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_dragging = false;
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
		m_sw.stop();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		glColor3f(1, 0, 0);
Toshihiro Shimizu 890ddd
		double u = 50;
Toshihiro Shimizu 890ddd
		if (m_cameraCentered.getValue())
Toshihiro Shimizu 890ddd
			m_center = TPointD(0, 0);
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			TAffine aff = m_viewer->getViewMatrix().inv();
Toshihiro Shimizu 890ddd
			u = u * sqrt(aff.det());
Toshihiro Shimizu 890ddd
			m_center = aff * TPointD(0, 0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		tglDrawSegment(TPointD(-u + m_center.x, m_center.y), TPointD(u + m_center.x, m_center.y));
Toshihiro Shimizu 890ddd
		tglDrawSegment(TPointD(m_center.x, -u + m_center.y), TPointD(m_center.x, u + m_center.y));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getCursorId() const { return ToolCursor::RotateCursor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} rotateTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace