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