Browse Source

Make orbit cam spring oscillation frequencie tunable, add hz<->rads conversion functions, and fix relative mouse movement cursor visibility bug

master
C. J. Howard 3 years ago
parent
commit
f95819628d
11 changed files with 117 additions and 30 deletions
  1. +41
    -16
      src/animation/orbit-cam.cpp
  2. +5
    -0
      src/animation/orbit-cam.hpp
  3. +30
    -0
      src/animation/spring.hpp
  4. +8
    -4
      src/application.cpp
  5. +1
    -0
      src/application.hpp
  6. +6
    -5
      src/game/bootloader.cpp
  7. +8
    -1
      src/game/systems/camera-system.cpp
  8. +5
    -0
      src/game/systems/tool-system.cpp
  9. +4
    -2
      src/game/systems/tool-system.hpp
  10. +5
    -0
      src/game/systems/ui-system.cpp
  11. +4
    -2
      src/game/systems/ui-system.hpp

+ 41
- 16
src/animation/orbit-cam.cpp View File

@ -33,25 +33,24 @@ orbit_cam::orbit_cam():
clip_near_limits({-std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()}),
clip_far_limits({-std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()})
{
// Init focal point spring
focal_point_spring.v = {0.0f, 0.0f, 0.0f};
// Make all springs critically-damped
focal_point_spring.z = 1.0f;
focal_point_spring.w = 2.0f * math::two_pi<float>;
// Init azimuth spring
azimuth_spring.v = 0.0f;
azimuth_spring.z = 1.0f;
azimuth_spring.w = 2.0f * math::two_pi<float>;
// Init elevation spring
elevation_spring.v = 0.0f;
elevation_spring.z = 1.0f;
elevation_spring.w = 2.0f * math::two_pi<float>;
// Init zoom spring
zoom_spring.v = 0.0f;
zoom_spring.z = 1.0f;
zoom_spring.w = 5.0f * math::two_pi<float>;
// Init spring oscillation frequencies to 1 rad/s
focal_point_spring.w = math::two_pi<float>;
azimuth_spring.w = math::two_pi<float>;
elevation_spring.w = math::two_pi<float>;
zoom_spring.w = math::two_pi<float>;
// Zero spring values and velocities
focal_point_spring.x1 = {0.0f, 0.0f, 0.0f};
azimuth_spring.x1 = 0.0f;
elevation_spring.x1 = 0.0f;
zoom_spring.x1 = 0.0f;
reset_springs();
}
orbit_cam::~orbit_cam()
@ -91,7 +90,6 @@ void orbit_cam::update(float dt)
update_transform(transform);
// Update camera projection
float zoom_factor = 0.0f;
update_projection(fov, aspect_ratio, clip_near, clip_far);
}
@ -117,10 +115,17 @@ void orbit_cam::zoom(float factor)
void orbit_cam::reset_springs()
{
// Reset values
focal_point_spring.x0 = focal_point_spring.x1;
azimuth_spring.x0 = azimuth_spring.x1;
elevation_spring.x0 = elevation_spring.x1;
zoom_spring.x0 = zoom_spring.x1;
// Reset velocities
focal_point_spring.v = {0.0f, 0.0f, 0.0f};
azimuth_spring.v = 0.0f;
elevation_spring.v = 0.0f;
zoom_spring.v = 0.0f;
}
void orbit_cam::set_aspect_ratio(float ratio)
@ -197,3 +202,23 @@ void orbit_cam::set_clip_far_limits(const std::array& limits)
{
clip_far_limits = limits;
}
void orbit_cam::set_focal_point_oscillation(float frequency)
{
focal_point_spring.w = frequency;
}
void orbit_cam::set_azimuth_oscillation(float frequency)
{
azimuth_spring.w = frequency;
}
void orbit_cam::set_elevation_oscillation(float frequency)
{
elevation_spring.w = frequency;
}
void orbit_cam::set_zoom_oscillation(float frequency)
{
zoom_spring.w = frequency;
}

+ 5
- 0
src/animation/orbit-cam.hpp View File

@ -61,6 +61,11 @@ public:
void set_clip_near_limits(const std::array<float, 2>& limits);
void set_clip_far_limits(const std::array<float, 2>& limits);
void set_focal_point_oscillation(float frequency);
void set_azimuth_oscillation(float frequency);
void set_elevation_oscillation(float frequency);
void set_zoom_oscillation(float frequency);
const float3& get_focal_point() const;
float get_azimuth() const;
float get_elevation() const;

+ 30
- 0
src/animation/spring.hpp View File

@ -66,6 +66,24 @@ void spring(T& x0, T& v, const T& x1, S z, S w, S dt);
template <typename T, typename S>
void solve_numeric_spring(numeric_spring<T, S>& ns, S dt);
/**
* Converts a frequency from hertz to radians per second.
*
* @param hz Frequency in hertz.
* @return Frequency in radians per second.
*/
template <typename T>
T hz_to_rads(T hz);
/**
* Converts a frequency from radians per second to hertz.
*
* @param rads Frequency in radians per second.
* @return Frequency in hertz.
*/
template <typename T>
T rads_to_hz(T rads);
template <typename T, typename S>
void spring(T& x0, T& v, const T& x1, S z, S w, S dt)
{
@ -86,4 +104,16 @@ void solve_numeric_spring(numeric_spring& ns, S dt)
spring(ns.x0, ns.v, ns.x1, ns.z, ns.w, dt);
}
template <typename T>
inline T hz_to_rads(T hz)
{
return hz * math::two_pi<T>;
}
template <typename T>
inline T rads_to_hz(T rads)
{
return rads / math::two_pi<T>;
}
#endif // ANTKEEPER_SPRING_HPP

+ 8
- 4
src/application.cpp View File

@ -47,6 +47,7 @@ application::application():
render_callback(nullptr),
fullscreen(true),
vsync(true),
cursor_visible(true),
display_dimensions({0, 0}),
window_dimensions({0, 0}),
viewport_dimensions({0, 0}),
@ -358,6 +359,7 @@ void application::set_title(const std::string& title)
void application::set_cursor_visible(bool visible)
{
SDL_ShowCursor((visible) ? SDL_ENABLE : SDL_DISABLE);
cursor_visible = visible;
}
void application::set_relative_mouse_mode(bool enabled)
@ -365,13 +367,15 @@ void application::set_relative_mouse_mode(bool enabled)
if (enabled)
{
SDL_GetMouseState(&mouse_position[0], &mouse_position[1]);
SDL_ShowCursor(SDL_DISABLE);
SDL_SetRelativeMouseMode(SDL_TRUE);
}
SDL_SetRelativeMouseMode((enabled) ? SDL_TRUE : SDL_FALSE);
if (!enabled)
else
{
SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_WarpMouseInWindow(sdl_window, mouse_position[0], mouse_position[1]);
if (cursor_visible)
SDL_ShowCursor(SDL_ENABLE);
}
}

+ 1
- 0
src/application.hpp View File

@ -205,6 +205,7 @@ private:
render_callback_type render_callback;
bool fullscreen;
bool vsync;
bool cursor_visible;
std::array<int, 2> display_dimensions;
std::array<int, 2> window_dimensions;
std::array<int, 2> viewport_dimensions;

+ 6
- 5
src/game/bootloader.cpp View File

@ -838,9 +838,6 @@ void setup_systems(game_context* ctx)
ctx->ui_system->set_scene(ctx->ui_scene);
ctx->ui_system->set_viewport(viewport);
ctx->ui_system->set_tool_menu_control(ctx->control_system->get_tool_menu_control());
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->ui_system);
}
void setup_controls(game_context* ctx)
@ -999,10 +996,14 @@ void setup_controls(game_context* ctx)
ctx->input_event_router->add_mapping(game_controller_axis_mapping(ctx->control_system->get_zoom_in_control(), nullptr, game_controller_axis::trigger_right, false));
event_dispatcher->subscribe<mouse_moved_event>(ctx->control_system);
event_dispatcher->subscribe<window_resized_event>(ctx->control_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->camera_system);
event_dispatcher->subscribe<window_resized_event>(ctx->camera_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->tool_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->ui_system);
event_dispatcher->subscribe<window_resized_event>(ctx->control_system);
event_dispatcher->subscribe<window_resized_event>(ctx->camera_system);
event_dispatcher->subscribe<window_resized_event>(ctx->tool_system);
event_dispatcher->subscribe<window_resized_event>(ctx->ui_system);
}
void setup_cli(game_context* ctx)

+ 8
- 1
src/game/systems/camera-system.cpp View File

@ -45,8 +45,12 @@ camera_system::camera_system(entt::registry& registry):
orbit_cam.set_target_elevation(math::radians(45.0f));
orbit_cam.set_target_zoom(0.0f);
orbit_cam.set_focal_point_oscillation(hz_to_rads(8.0f));
orbit_cam.set_azimuth_oscillation(hz_to_rads(2.0f));
orbit_cam.set_elevation_oscillation(hz_to_rads(2.0f));
orbit_cam.set_zoom_oscillation(hz_to_rads(5.0f));
orbit_cam.reset_springs();
}
void camera_system::update(double t, double dt)
@ -66,8 +70,11 @@ void camera_system::update(double t, double dt)
if (subject_count > 1)
target_focal_point /= static_cast<float>(subject_count);
// Focus at ant's head height off the ground.
target_focal_point.y += 0.2f;
// Check for collision with environment
//...
orbit_cam.set_target_focal_point(target_focal_point);
orbit_cam.update(static_cast<float>(dt));

+ 5
- 0
src/game/systems/tool-system.cpp View File

@ -145,3 +145,8 @@ void tool_system::handle_event(const mouse_moved_event& event)
mouse_position[1] = event.y;
}
}
void tool_system::handle_event(const window_resized_event& event)
{
set_viewport({0.0f, 0.0f, static_cast<float>(event.w), static_cast<float>(event.h)});
}

+ 4
- 2
src/game/systems/tool-system.hpp View File

@ -23,6 +23,7 @@
#include "entity-system.hpp"
#include "event/event-handler.hpp"
#include "event/input-events.hpp"
#include "event/window-events.hpp"
#include "utility/fundamental-types.hpp"
class camera;
@ -30,7 +31,8 @@ class orbit_cam;
class tool_system:
public entity_system,
public event_handler<mouse_moved_event>
public event_handler<mouse_moved_event>,
public event_handler<window_resized_event>
{
public:
tool_system(entt::registry& registry);
@ -43,6 +45,7 @@ public:
private:
virtual void handle_event(const mouse_moved_event& event);
virtual void handle_event(const window_resized_event& event);
const camera* camera;
const orbit_cam* orbit_cam;
@ -53,4 +56,3 @@ private:
};
#endif // ANTKEEPER_TOOL_SYSTEM_HPP

+ 5
- 0
src/game/systems/ui-system.cpp View File

@ -153,6 +153,11 @@ void ui_system::handle_event(const mouse_moved_event& event)
mouse_position[1] = event.y;
}
void ui_system::handle_event(const window_resized_event& event)
{
set_viewport({0.0f, 0.0f, static_cast<float>(event.w), static_cast<float>(event.h)});
}
void ui_system::update_projection()
{
if (camera)

+ 4
- 2
src/game/systems/ui-system.hpp View File

@ -22,6 +22,7 @@
#include "event/event-handler.hpp"
#include "event/input-events.hpp"
#include "event/window-events.hpp"
#include "scene/scene.hpp"
#include "scene/camera.hpp"
#include "scene/directional-light.hpp"
@ -36,7 +37,8 @@ class scene;
class resource_manager;
class ui_system:
public event_handler<mouse_moved_event>
public event_handler<mouse_moved_event>,
public event_handler<window_resized_event>
{
public:
ui_system(::resource_manager* resource_manager);
@ -51,6 +53,7 @@ public:
private:
virtual void handle_event(const mouse_moved_event& event);
virtual void handle_event(const window_resized_event& event);
void update_projection();
@ -82,4 +85,3 @@ private:
};
#endif // ANTKEEPER_UI_SYSTEM_HPP

Loading…
Cancel
Save