summaryrefslogtreecommitdiff
path: root/tangle/util/camera.h
blob: 0a793d323afbe71524612e5fb393f738722659d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <cuda-samples/Common/helper_math.h>
#include "SFML/Window/Event.hpp"

class Camera {
private:
  float _distance;
  float _phi;
  float _psi;
  float3 _target;
  float3 _eye;
  float3 _direction;
  bool _dragging;
  bool _moving;
  float2 _lastMouse;

public:
  Camera(float3 target, float distance, float phi, float psi):
    _distance(distance),
    _phi(phi),
    _psi(psi),
    _target(target),
    _dragging(false),
    _moving(false) {
    update();
  }

  void update() {
    _eye = _target + make_float3(_distance*sin(_psi)*cos(_phi), _distance*sin(_psi)*sin(_phi), _distance*cos(_psi));
    _direction = normalize(_target - _eye);
  }

  void handle(sf::Event& event) {
    switch (event.type) {
    case sf::Event::MouseWheelMoved:
      _distance -= event.mouseWheel.delta * 10;
      break;
    case sf::Event::MouseButtonPressed:
      if (event.mouseButton.button == sf::Mouse::Left) {
        _dragging = true;
        _lastMouse = make_float2(event.mouseButton.x, event.mouseButton.y);
      } else if (event.mouseButton.button == sf::Mouse::Right) {
        _moving = true;
        _lastMouse = make_float2(event.mouseButton.x, event.mouseButton.y);
      }
      break;
    case sf::Event::MouseButtonReleased:
      if (event.mouseButton.button == sf::Mouse::Left) {
        _dragging = false;
      } else if (event.mouseButton.button == sf::Mouse::Right) {
        _moving = false;
      }
      break;
    case sf::Event::MouseMoved:
      if (_dragging) {
        float2 mouse = make_float2(event.mouseMove.x, event.mouseMove.y);
        float2 delta = mouse - _lastMouse;
        _lastMouse = mouse;
        _phi += 0.4*delta.x * 2*M_PI/360;
        if (delta.y > 0 && _psi <= M_PI-2*M_PI/60) {
          _psi += 0.4*delta.y * M_PI/180;
        } else if (delta.y < 0 && _psi >= 2*M_PI/60) {
          _psi += 0.4*delta.y * M_PI/180;
        }
      }
      if (_moving) {
        float2 mouse = make_float2(event.mouseMove.x, event.mouseMove.y);
        float2 delta = mouse - _lastMouse;
        _lastMouse = mouse;
        float3 forward = normalize(_target - _eye);
    	   float3 right   = normalize(cross(make_float3(0.f, 0.f, -1.f), forward));
        float3 up      = cross(right, forward);
        _target += 0.4*right*delta.x - 0.4*up*delta.y;
      }
      break;
    }
    update();
  }

  float3 getDirection() const {
    return _direction;
  }

  float3 getEyePosition() const {
    return _eye;
  }
};