Symphony Of Empires
flat_camera.hpp
Go to the documentation of this file.
1 // Symphony of Empires
2 // Copyright (C) 2021, Symphony of Empires contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // client/flat_camera.hpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <glm/vec3.hpp>
28 #include <glm/glm.hpp>
29 #include <glm/gtc/matrix_transform.hpp>
30 #include <glm/gtc/type_ptr.hpp>
31 #include <glm/gtx/intersect.hpp>
32 
33 #include "eng3d/camera.hpp"
34 #include "eng3d/value_chase.hpp"
35 
36 namespace Eng3D {
37  class FlatCamera: public Camera {
38  public:
39  glm::vec3 target;
41 
42  FlatCamera(glm::vec2 _screen_size, glm::vec2 _map_size)
43  : Camera(_screen_size, _map_size)
44  {
45  world_position = glm::vec3(400.f, 200.f, 400.f);
48  }
49 
50  FlatCamera(const Camera& camera)
51  : Camera(camera)
52  {
55  }
56 
57  void move(float x_dir, float y_dir, float z_dir) override {
58  float scale = glm::abs(target.z * map_size.x / 1e5);
59  target.x += x_dir * scale;
60  target.y += y_dir * scale;
61  target.y = glm::clamp(target.y, 0.f, map_size.y);
62  target.z += z_dir * scale;
63  target.z = glm::clamp(target.z, 25.f, map_size.x / 2.f);
64  }
65 
66  void update() override {
68  map_position.y = glm::clamp(map_position.y, 0.f, map_size.y);
69  map_position.z = glm::clamp(map_position.z, 10.f, map_size.x / 2.f);
70 
72  world_position.x = glm::mod(world_position.x, map_size.x);
73  world_position.z *= -1;
74  }
75 
76  void set_pos(float x, float y) override {
77  map_position.x = glm::mod(x, map_size.x);
78  map_position.y = glm::clamp(y, 0.f, map_size.y);
80 
81  update();
82  }
83 
84  glm::vec3 get_map_pos() const override {
85  glm::vec3 out_pos = map_position;
86  out_pos.x = glm::mod(out_pos.x, map_size.x);
87  return out_pos;
88  }
89 
90  glm::mat4 get_view() const override {
91  glm::vec3 look_at = world_position;
92  look_at.z = 0;
93  look_at.y -= world_position.z > -300.f ? 0.08f * (300.f + world_position.z) : 0.f;
94  glm::vec3 up_vector = glm::vec3(0.f, -1.f, 0.f);
95  return glm::lookAt(world_position, look_at, up_vector);
96  }
97 
98  bool get_cursor_map_pos(glm::ivec2 mouse_pos, glm::ivec2& out_pos) const override {
99  const float mouse_x = mouse_pos.x;
100  const float mouse_y = screen_size.y - 1.f - mouse_pos.y;
101 
102  const glm::mat4 view = get_view();
103  const glm::mat4 projection = get_projection();
104  const glm::vec3 world_space_near = glm::unProject(
105  glm::vec3(mouse_x, mouse_y, 0.f),
106  view, projection,
107  glm::vec4(0.f, 0.f, screen_size)
108  );
109  const glm::vec3 world_space_far = glm::unProject(
110  glm::vec3(mouse_x, mouse_y, 1.f),
111  view, projection,
112  glm::vec4(0.f, 0.f, screen_size)
113  );
114 
115  glm::vec3 ray_direction = world_space_far - world_space_near;
116 
117  float distance = 0.f;
118  bool hit = glm::intersectRayPlane(world_space_near, ray_direction, glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), distance);
119 
120  glm::vec3 intersection_point = world_space_near + ray_direction * distance;
121  out_pos.x = intersection_point.x;
122  out_pos.x = glm::mod((float)out_pos.x, map_size.x);
123  out_pos.y = intersection_point.y;
124  if(intersection_point.y < 0 || intersection_point.y > map_size.y)
125  hit = false;
126  return hit;
127  }
128 
129  glm::vec3 get_tile_world_pos(glm::vec2 tile_pos) const override {
130  return glm::vec3(tile_pos.x, tile_pos.y, 0.f);
131  }
132  };
133 }
glm::vec2 screen_size
Definition: camera.hpp:38
virtual glm::mat4 get_projection() const
Get the projection matrix.
Definition: camera.hpp:91
glm::vec3 world_position
Definition: camera.hpp:37
glm::vec2 map_size
Definition: camera.hpp:39
glm::vec3 map_position
Definition: camera.hpp:36
void move(float x_dir, float y_dir, float z_dir) override
Move the camera in the specified direction. Uses the map coordinate system, where the Z-axis is the m...
Definition: flat_camera.hpp:57
FlatCamera(glm::vec2 _screen_size, glm::vec2 _map_size)
Definition: flat_camera.hpp:42
void update() override
Update the movement of the camera. Used for smooth camera movement.
Definition: flat_camera.hpp:66
ValueChase< glm::vec3 > chase
Definition: flat_camera.hpp:40
bool get_cursor_map_pos(glm::ivec2 mouse_pos, glm::ivec2 &out_pos) const override
Get the cursors position on the map.
Definition: flat_camera.hpp:98
glm::vec3 get_tile_world_pos(glm::vec2 tile_pos) const override
Get the tiles world position.
void set_pos(float x, float y) override
Set the map position of the camera.
Definition: flat_camera.hpp:76
FlatCamera(const Camera &camera)
Definition: flat_camera.hpp:50
glm::vec3 get_map_pos() const override
Get the map position of the camera.
Definition: flat_camera.hpp:84
glm::mat4 get_view() const override
Get the view matrix.
Definition: flat_camera.hpp:90
constexpr T move_towards(T current, T target)
Definition: value_chase.hpp:18