diff --git a/CMakeLists.txt b/CMakeLists.txt
index b80be9e..1405aa0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,7 @@ find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2-static SDL2::SDL2main CONFIG)
find_package(OpenAL REQUIRED CONFIG)
find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib")
+
# Determine dependencies
set(STATIC_LIBS
dr_wav
diff --git a/src/camera-rig.cpp b/src/animation/camera-rig.cpp
similarity index 58%
rename from src/camera-rig.cpp
rename to src/animation/camera-rig.cpp
index 5c3633d..e22cb8c 100644
--- a/src/camera-rig.cpp
+++ b/src/animation/camera-rig.cpp
@@ -17,7 +17,7 @@
* along with Antkeeper source code. If not, see .
*/
-#include "orbit-cam.hpp"
+#include "animation/camera-rig.hpp"
#include "scene/camera.hpp"
#include "math/constants.hpp"
#include "configuration.hpp"
@@ -26,8 +26,7 @@
camera_rig::camera_rig():
camera(nullptr),
- translation{0.0f, 0.0f, 0.0f},
- rotation(math::identity_quaternion),
+ transform(math::identity_transform),
forward(global_forward),
right(global_right),
up(global_up)
@@ -38,7 +37,7 @@ void camera_rig::attach(::camera* camera)
this->camera = camera;
if (camera != nullptr)
{
- camera->look_at(translation, translation + forward, up);
+ camera->set_transform(transform);
}
}
@@ -47,17 +46,33 @@ void camera_rig::detach()
camera = nullptr;
}
-void camera_rig::set_translation(const float3& translation)
+void camera_rig::update_transform(const transform_type& transform)
{
- this->translation = translation;
+ this->transform = transform;
+
+ // Calculate orthonormal basis
+ forward = transform.rotation * global_forward;
+ up = transform.rotation * global_up;
+ right = transform.rotation * global_right;
+
+ if (camera != nullptr)
+ {
+ camera->set_transform(transform);
+ }
}
-void camera_rig::set_rotation(const quaternion_type& rotation)
+void camera_rig::update_projection(float fov, float aspect_ratio, float clip_near, float clip_far)
{
- this->rotation = rotation;
-
- // Calculate orthonormal basis
- forward = rotation * global_forward;
- up = rotation * global_up;
- right = rotation * global_right;
+ if (camera != nullptr)
+ {
+ camera->set_perspective(fov, aspect_ratio, clip_near, clip_far);
+ }
+}
+
+void camera_rig::update_projection(float clip_left, float clip_right, float clip_bottom, float clip_top, float clip_near, float clip_far)
+{
+ if (camera != nullptr)
+ {
+ camera->set_orthographic(clip_left, clip_right, clip_bottom, clip_top, clip_near, clip_far);
+ }
}
diff --git a/src/camera-rig.hpp b/src/animation/camera-rig.hpp
similarity index 83%
rename from src/camera-rig.hpp
rename to src/animation/camera-rig.hpp
index 830bc6a..820e19d 100644
--- a/src/camera-rig.hpp
+++ b/src/animation/camera-rig.hpp
@@ -52,38 +52,35 @@ public:
void attach(::camera* camera);
/**
- * Detaches a camera from the rig.
+ * Detaches the camera from the rig.
*/
void detach();
- /**
- * Sets the translation of the camera rig.
- */
- void set_translation(const float3& translation);
-
- /**
- * Sets the rotation of the camera rig.
- */
- void set_rotation(const quaternion_type& rotation);
+
/**
* Returns the attached camera.
*/
const ::camera* get_camera() const;
- /// @copydoc camera_rig::get_camera() const
- ::camera* get_camera();
-
const float3& get_translation() const;
const quaternion_type& get_rotation() const;
const float3& get_forward() const;
const float3& get_right() const;
const float3& get_up() const;
+protected:
+ /**
+ * Updates the transform of the camera
+ */
+ void update_transform(const transform_type& transform);
+
+ void update_projection(float fov, float aspect_ratio, float clip_near, float clip_far);
+ void update_projection(float clip_left, float clip_right, float clip_bottom, float clip_top, float clip_near, float clip_far);
+
private:
camera* camera;
- float3 translation;
- quaternion_type rotation;
+ transform_type transform;
float3 forward;
float3 right;
float3 up;
@@ -94,19 +91,14 @@ inline const camera* camera_rig::get_camera() const
return camera;
}
-inline camera* camera_rig::get_camera()
-{
- return camera;
-}
-
inline const float3& camera_rig::get_translation() const
{
- return translation;
+ return transform.translation;
}
inline const typename camera_rig::quaternion_type& camera_rig::get_rotation() const
{
- return rotation;
+ return transform.rotation;
}
inline const float3& camera_rig::get_forward() const
diff --git a/src/animation/orbit-cam.cpp b/src/animation/orbit-cam.cpp
new file mode 100644
index 0000000..fd5c058
--- /dev/null
+++ b/src/animation/orbit-cam.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2020 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#include "animation/orbit-cam.hpp"
+#include "scene/camera.hpp"
+#include "math/math.hpp"
+#include
+#include
+#include
+#include
+
+orbit_cam::orbit_cam():
+ azimuth_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()}),
+ elevation_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()}),
+ focal_distance_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()}),
+ fov_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()}),
+ clip_near_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()}),
+ clip_far_limits({-std::numeric_limits::infinity(), std::numeric_limits::infinity()})
+{
+ // Init focal point spring
+ focal_point_spring.v = {0.0f, 0.0f, 0.0f};
+ focal_point_spring.z = 1.0f;
+ focal_point_spring.w = 2.0f * math::two_pi;
+
+ // Init azimuth spring
+ azimuth_spring.v = 0.0f;
+ azimuth_spring.z = 1.0f;
+ azimuth_spring.w = 2.0f * math::two_pi;
+
+ // Init elevation spring
+ elevation_spring.v = 0.0f;
+ elevation_spring.z = 1.0f;
+ elevation_spring.w = 2.0f * math::two_pi;
+
+ // Init zoom spring
+ zoom_spring.v = 0.0f;
+ zoom_spring.z = 1.0f;
+ zoom_spring.w = 5.0f * math::two_pi;
+}
+
+orbit_cam::~orbit_cam()
+{}
+
+void orbit_cam::update(float dt)
+{
+ if (!get_camera())
+ {
+ return;
+ }
+
+ // Solve springs
+ solve_numeric_spring(focal_point_spring, dt);
+ solve_numeric_spring(azimuth_spring, dt);
+ solve_numeric_spring(elevation_spring, dt);
+ solve_numeric_spring(zoom_spring, dt);
+
+ // Calculate zoom-dependent variables
+ float focal_distance = math::log_lerp(focal_distance_limits[1], focal_distance_limits[0], zoom_spring.x0);
+ float fov = math::log_lerp(fov_limits[1], fov_limits[0], zoom_spring.x0);
+ float clip_near = math::log_lerp(clip_near_limits[1], clip_near_limits[0], zoom_spring.x0);
+ float clip_far = math::log_lerp(clip_far_limits[1], clip_far_limits[0], zoom_spring.x0);
+
+ // Calculate camera transform
+ transform_type transform = math::identity_transform;
+
+ // Determine rotation
+ azimuth_rotation = math::angle_axis(azimuth_spring.x0, float3{0.0f, 1.0f, 0.0f});
+ elevation_rotation = math::angle_axis(elevation_spring.x0, float3{-1.0f, 0.0f, 0.0f});
+ transform.rotation = math::normalize(azimuth_rotation * elevation_rotation);
+
+ // Determine translation
+ transform.translation = focal_point_spring.x0 + transform.rotation * float3{0.0f, 0.0f, focal_distance};
+
+ // Update camera transform
+ update_transform(transform);
+
+ // Update camera projection
+ float zoom_factor = 0.0f;
+ update_projection(fov, aspect_ratio, clip_near, clip_far);
+}
+
+void orbit_cam::move(const float3& translation)
+{
+ set_target_focal_point(focal_point_spring.x1 + translation);
+}
+
+void orbit_cam::pan(float angle)
+{
+ set_target_azimuth(azimuth_spring.x1 + angle);
+}
+
+void orbit_cam::tilt(float angle)
+{
+ set_target_elevation(elevation_spring.x1 + angle);
+}
+
+void orbit_cam::zoom(float factor)
+{
+ set_target_zoom(zoom_spring.x1 + factor);
+}
+
+void orbit_cam::reset_springs()
+{
+ 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;
+}
+
+void orbit_cam::set_aspect_ratio(float ratio)
+{
+ aspect_ratio = ratio;
+}
+
+void orbit_cam::set_focal_point(const float3& point)
+{
+ focal_point_spring.x0 = point;
+}
+
+void orbit_cam::set_azimuth(float angle)
+{
+ azimuth_spring.x0 = std::max(azimuth_limits[0], std::min(azimuth_limits[1], angle));
+}
+
+void orbit_cam::set_elevation(float angle)
+{
+ elevation_spring.x0 = std::max(elevation_limits[0], std::min(elevation_limits[1], angle));
+}
+
+void orbit_cam::set_zoom(float factor)
+{
+ zoom_spring.x0 = std::max(0.0f, std::min(1.0f, factor));
+}
+
+void orbit_cam::set_target_focal_point(const float3& point)
+{
+ focal_point_spring.x1 = point;
+}
+
+void orbit_cam::set_target_azimuth(float angle)
+{
+ azimuth_spring.x1 = std::max(azimuth_limits[0], std::min(azimuth_limits[1], angle));
+}
+
+void orbit_cam::set_target_elevation(float angle)
+{
+ elevation_spring.x1 = std::max(elevation_limits[0], std::min(elevation_limits[1], angle));
+}
+
+void orbit_cam::set_target_zoom(float factor)
+{
+ zoom_spring.x1 = std::max(0.0f, std::min(1.0f, factor));
+}
+
+void orbit_cam::set_azimuth_limits(const std::array& limits)
+{
+ azimuth_limits = limits;
+}
+
+void orbit_cam::set_elevation_limits(const std::array& limits)
+{
+ elevation_limits = limits;
+}
+
+void orbit_cam::set_focal_distance_limits(const std::array& limits)
+{
+ focal_distance_limits = limits;
+}
+
+void orbit_cam::set_fov_limits(const std::array& limits)
+{
+ fov_limits = limits;
+}
+
+void orbit_cam::set_clip_near_limits(const std::array& limits)
+{
+ clip_near_limits = limits;
+}
+
+void orbit_cam::set_clip_far_limits(const std::array& limits)
+{
+ clip_far_limits = limits;
+}
diff --git a/src/orbit-cam.hpp b/src/animation/orbit-cam.hpp
similarity index 54%
rename from src/orbit-cam.hpp
rename to src/animation/orbit-cam.hpp
index f68d945..e53d74c 100644
--- a/src/orbit-cam.hpp
+++ b/src/animation/orbit-cam.hpp
@@ -21,6 +21,8 @@
#define ANTKEEPER_ORBIT_CAM_HPP
#include "camera-rig.hpp"
+#include "animation/spring.hpp"
+#include
/**
* Rig which orbits around a focal point.
@@ -33,98 +35,86 @@ public:
virtual void update(float dt);
/// @param direction Specifies the movement direction and speed scale on the XZ plane
- void move(const float2& direction);
- void rotate(float angle);
+ void move(const float3& translation);
+ void pan(float angle);
void tilt(float angle);
- void zoom(float distance);
+ void zoom(float factor);
+
+ void reset_springs();
+
+ void set_aspect_ratio(float ratio);
void set_focal_point(const float3& point);
- void set_focal_distance(float distance);
- void set_elevation(float angle);
void set_azimuth(float angle);
+ void set_elevation(float angle);
+ void set_zoom(float factor);
+
void set_target_focal_point(const float3& point);
- void set_target_focal_distance(float distance);
- void set_target_elevation(float angle);
void set_target_azimuth(float angle);
+ void set_target_elevation(float angle);
+ void set_target_zoom(float factor);
+
+ void set_azimuth_limits(const std::array& limits);
+ void set_elevation_limits(const std::array& limits);
+ void set_focal_distance_limits(const std::array& limits);
+ void set_fov_limits(const std::array& limits);
+ void set_clip_near_limits(const std::array& limits);
+ void set_clip_far_limits(const std::array& limits);
const float3& get_focal_point() const;
- float get_focal_distance() const;
- float get_elevation() const;
float get_azimuth() const;
- const float3& get_target_focal_point() const;
- float get_target_focal_distance() const;
- float get_target_elevation() const;
- float get_target_azimuth() const;
- const float3& get_target_translation() const;
- const quaternion_type& get_target_rotation() const;
+ float get_elevation() const;
+ float get_zoom() const;
+ const quaternion_type& get_azimuth_rotation() const;
+ const quaternion_type& get_elevation_rotation() const;
private:
- float3 focal_point;
- float focal_distance;
- float elevation;
- float azimuth;
+ float aspect_ratio;
+
+ numeric_spring focal_point_spring;
+ numeric_spring azimuth_spring;
+ numeric_spring elevation_spring;
+ numeric_spring zoom_spring;
- float3 target_focal_point;
- float target_focal_distance;
- float target_elevation;
- float target_azimuth;
+ std::array azimuth_limits;
+ std::array elevation_limits;
+ std::array focal_distance_limits;
+ std::array fov_limits;
+ std::array clip_near_limits;
+ std::array clip_far_limits;
- quaternion_type elevation_rotation;
quaternion_type azimuth_rotation;
- quaternion_type target_elevation_rotation;
- quaternion_type target_azimuth_rotation;
- quaternion_type target_rotation;
- float3 target_translation;
+ quaternion_type elevation_rotation;
};
inline const float3& orbit_cam::get_focal_point() const
{
- return focal_point;
-}
-
-inline float orbit_cam::get_focal_distance() const
-{
- return focal_distance;
-}
-
-inline float orbit_cam::get_elevation() const
-{
- return elevation;
+ return focal_point_spring.x0;
}
inline float orbit_cam::get_azimuth() const
{
- return azimuth;
+ return azimuth_spring.x0;
}
-inline const float3& orbit_cam::get_target_focal_point() const
-{
- return target_focal_point;
-}
-
-inline float orbit_cam::get_target_focal_distance() const
+inline float orbit_cam::get_elevation() const
{
- return target_focal_distance;
+ return elevation_spring.x0;
}
-inline float orbit_cam::get_target_elevation() const
+inline float orbit_cam::get_zoom() const
{
- return target_elevation;
+ return zoom_spring.x0;
}
-inline float orbit_cam::get_target_azimuth() const
-{
- return target_azimuth;
-}
-inline const float3& orbit_cam::get_target_translation() const
+inline const typename camera_rig::quaternion_type& orbit_cam::get_azimuth_rotation() const
{
- return target_translation;
+ return azimuth_rotation;
}
-inline const typename camera_rig::quaternion_type& orbit_cam::get_target_rotation() const
+inline const typename camera_rig::quaternion_type& orbit_cam::get_elevation_rotation() const
{
- return target_rotation;
+ return elevation_rotation;
}
-
#endif // ANTKEEPER_ORBIT_CAM_HPP
diff --git a/src/animation/spring.hpp b/src/animation/spring.hpp
index eb27649..53e9690 100644
--- a/src/animation/spring.hpp
+++ b/src/animation/spring.hpp
@@ -27,9 +27,10 @@
* @tparam S Scalar type.
*
* @see spring()
+ * @see solve_numeric_spring()
*/
template
-struct spring_constraint
+struct numeric_spring
{
T x0; ///< Start value
T x1; ///< End value
@@ -55,13 +56,15 @@ template
void spring(T& x0, T& v, const T& x1, S z, S w, S dt);
/**
- * Solves a spring constraint using the spring() function.
+ * Solves a numeric spring using the spring() function.
*
- * @param[in,out] constraint Spring constraint to be sovled.
+ * @param[in,out] ns Numeric spring to be sovled.
* @param dt Delta time, in seconds.
+ *
+ * @see spring()
*/
template
-void solve_spring_constraint(spring_constraint& constraint, S dt);
+void solve_numeric_spring(numeric_spring& ns, S dt);
template
void spring(T& x0, T& v, const T& x1, S z, S w, S dt)
@@ -78,9 +81,9 @@ void spring(T& x0, T& v, const T& x1, S z, S w, S dt)
}
template
-void solve_spring_constraint(spring_constraint& constraint, S dt)
+void solve_numeric_spring(numeric_spring& ns, S dt)
{
- spring(constraint.x0, constraint.v, constraint.x1, constraint.z, constraint.w, dt);
+ spring(ns.x0, ns.v, ns.x1, ns.z, ns.w, dt);
}
#endif // ANTKEEPER_SPRING_HPP
diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp
index a411532..722b526 100644
--- a/src/game/bootloader.cpp
+++ b/src/game/bootloader.cpp
@@ -81,7 +81,6 @@
#include "input/game-controller.hpp"
#include "input/mouse.hpp"
#include "input/keyboard.hpp"
-#include "orbit-cam.hpp"
#include "pheromone-matrix.hpp"
#include "configuration.hpp"
#include "input/scancode.hpp"
@@ -457,10 +456,10 @@ void setup_rendering(game_context* ctx)
ctx->shadow_map_framebuffer = new framebuffer(shadow_map_resolution, shadow_map_resolution);
ctx->shadow_map_framebuffer->attach(framebuffer_attachment_type::depth, ctx->shadow_map_depth_texture);
- // Create bloom pingpong framebuffers (32F color, no depth)
+ // Create bloom pingpong framebuffers (16F color, no depth)
int bloom_width = viewport_dimensions[0] >> 1;
int bloom_height = viewport_dimensions[1] >> 1;
- ctx->bloom_texture = new texture_2d(bloom_width, bloom_height, pixel_type::float_32, pixel_format::rgb);
+ ctx->bloom_texture = new texture_2d(bloom_width, bloom_height, pixel_type::float_16, pixel_format::rgb);
ctx->bloom_texture->set_wrapping(texture_wrapping::clamp, texture_wrapping::clamp);
ctx->bloom_texture->set_filters(texture_min_filter::linear, texture_mag_filter::linear);
ctx->bloom_texture->set_max_anisotropy(0.0f);
@@ -486,8 +485,8 @@ void setup_rendering(game_context* ctx)
ctx->overworld_bloom_pass = new bloom_pass(ctx->rasterizer, ctx->framebuffer_bloom, ctx->resource_manager);
ctx->overworld_bloom_pass->set_source_texture(ctx->framebuffer_hdr_color);
ctx->overworld_bloom_pass->set_brightness_threshold(1.0f);
- ctx->overworld_bloom_pass->set_blur_iterations(4);
- ctx->overworld_bloom_pass->set_enabled(false);
+ ctx->overworld_bloom_pass->set_blur_iterations(5);
+ ctx->overworld_bloom_pass->set_enabled(true);
ctx->overworld_final_pass = new ::final_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), ctx->resource_manager);
ctx->overworld_final_pass->set_color_texture(ctx->framebuffer_hdr_color);
ctx->overworld_final_pass->set_bloom_texture(ctx->bloom_texture);
@@ -563,6 +562,10 @@ void setup_scenes(game_context* ctx)
const auto& viewport_dimensions = ctx->rasterizer->get_default_framebuffer().get_dimensions();
float viewport_aspect_ratio = static_cast(viewport_dimensions[0]) / static_cast(viewport_dimensions[1]);
+ // Create infinite culling mask
+ float inf = std::numeric_limits::infinity();
+ ctx->no_cull = {{-inf, -inf, -inf}, {inf, inf, inf}};
+
// Setup overworld camera
ctx->overworld_camera = new camera();
ctx->overworld_camera->set_perspective(math::radians(45.0f), viewport_aspect_ratio, 0.1f, 1000.0f);
@@ -755,9 +758,6 @@ void setup_systems(game_context* ctx)
const auto& viewport_dimensions = ctx->app->get_viewport_dimensions();
float4 viewport = {0.0f, 0.0f, static_cast(viewport_dimensions[0]), static_cast(viewport_dimensions[1])};
- ctx->orbit_cam = new orbit_cam();
- ctx->orbit_cam->attach(ctx->overworld_camera);
-
// Setup terrain system
ctx->terrain_system = new ::terrain_system(*ctx->ecs_registry, ctx->resource_manager);
ctx->terrain_system->set_patch_size(TERRAIN_PATCH_SIZE);
@@ -770,16 +770,16 @@ void setup_systems(game_context* ctx)
ctx->vegetation_system->set_vegetation_model(ctx->resource_manager->load("grass-tuft.obj"));
ctx->vegetation_system->set_scene(ctx->overworld_scene);
+ // Setup camera system
+ ctx->camera_system = new camera_system(*ctx->ecs_registry);
+ ctx->camera_system->set_viewport(viewport);
+
// Setup tool system
ctx->tool_system = new tool_system(*ctx->ecs_registry);
ctx->tool_system->set_camera(ctx->overworld_camera);
- ctx->tool_system->set_orbit_cam(ctx->orbit_cam);
+ ctx->tool_system->set_orbit_cam(ctx->camera_system->get_orbit_cam());
ctx->tool_system->set_viewport(viewport);
- // Setup camera system
- ctx->camera_system = new camera_system(*ctx->ecs_registry);
- ctx->camera_system->set_viewport(viewport);
-
// Setup subterrain system
ctx->subterrain_system = new ::subterrain_system(*ctx->ecs_registry, ctx->resource_manager);
ctx->subterrain_system->set_scene(ctx->underworld_scene);
@@ -822,7 +822,6 @@ void setup_systems(game_context* ctx)
// Setup control system
ctx->control_system = new ::control_system(*ctx->ecs_registry);
- ctx->control_system->set_orbit_cam(ctx->orbit_cam);
ctx->control_system->set_viewport(viewport);
ctx->control_system->set_underworld_camera(ctx->underworld_camera);
ctx->control_system->set_tool(nullptr);
@@ -891,12 +890,12 @@ void setup_controls(game_context* ctx)
ctx->rotate_ccw_control = new control();
ctx->rotate_ccw_control->set_activated_callback
(
- std::bind(&camera_system::rotate, ctx->camera_system, math::radians(-90.0f))
+ std::bind(&camera_system::pan, ctx->camera_system, math::radians(-90.0f))
);
ctx->rotate_cw_control = new control();
ctx->rotate_cw_control->set_activated_callback
(
- std::bind(&camera_system::rotate, ctx->camera_system, math::radians(90.0f))
+ std::bind(&camera_system::pan, ctx->camera_system, math::radians(90.0f))
);
// Create menu back control
@@ -1050,7 +1049,7 @@ void setup_callbacks(game_context* ctx)
ctx->tool_system->update(t, dt);
ctx->constraint_system->update(t, dt);
- (*ctx->focal_point_tween)[1] = ctx->orbit_cam->get_focal_point();
+ //(*ctx->focal_point_tween)[1] = ctx->orbit_cam->get_focal_point();
ctx->ui_system->update(dt);
ctx->render_system->update(t, dt);
diff --git a/src/game/game-context.hpp b/src/game/game-context.hpp
index c68eef0..71ff31c 100644
--- a/src/game/game-context.hpp
+++ b/src/game/game-context.hpp
@@ -22,6 +22,7 @@
#include "utility/fundamental-types.hpp"
#include "resources/string-table.hpp"
+#include "geometry/aabb.hpp"
#include
#include
#include
@@ -173,6 +174,7 @@ struct game_context
ambient_light* underworld_ambient_light;
spotlight* spotlight;
billboard* splash_billboard;
+ aabb no_cull;
// Animation
timeline* timeline;
@@ -227,7 +229,6 @@ struct game_context
cli* cli;
// Misc
- orbit_cam* orbit_cam;
pheromone_matrix* pheromones;
};
diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp
index 0f61725..1e44e5a 100644
--- a/src/game/states/play-state.cpp
+++ b/src/game/states/play-state.cpp
@@ -46,6 +46,7 @@
#include "scene/camera.hpp"
#include "game/systems/control-system.hpp"
#include "game/systems/camera-system.hpp"
+#include "game/systems/render-system.hpp"
#include "utility/fundamental-types.hpp"
void play_state_enter(game_context* ctx)
@@ -64,7 +65,7 @@ void play_state_enter(game_context* ctx)
ecs::archetype* maple_tree_archetype = resource_manager->load("maple-tree.ent");
ecs::archetype* nest_archetype = resource_manager->load("harvester-nest.ent");
ecs::archetype* samara_archetype = resource_manager->load("samara.ent");
- ecs::archetype* forceps_archetype = resource_manager->load("forceps.ent");
+ ecs::archetype* forceps_archetype = resource_manager->load("lens.ent");
ecs::archetype* larva_archetype = resource_manager->load("larva.ent");
ecs::archetype* pebble_archetype = resource_manager->load("pebble.ent");
@@ -175,13 +176,7 @@ void play_state_enter(game_context* ctx)
// Setup camera
ctx->overworld_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0});
ctx->camera_system->set_camera(ctx->overworld_camera);
- ctx->camera_system->set_azimuth(0.0f);
- ctx->camera_system->set_elevation(math::radians(45.0f));
- ctx->camera_system->set_zoom(0.0f);
- ctx->camera_system->set_focal_distance(2.0f, 200.0f);
- ctx->camera_system->set_fov(math::radians(80.0f), math::radians(35.0f));
- ctx->camera_system->set_clip_near(1.0f, 5.0f);
- ctx->camera_system->set_clip_far(100.0f, 2000.0f);
+
// Create forceps tool
@@ -189,6 +184,11 @@ void play_state_enter(game_context* ctx)
ecs::tool_component forceps_tool_component;
forceps_tool_component.active = true;
ecs_registry.assign(forceps_entity, forceps_tool_component);
+ model_instance* forceps_model_instance = ctx->render_system->get_model_instance(forceps_entity);
+ if (forceps_model_instance)
+ {
+ forceps_model_instance->set_culling_mask(&ctx->no_cull);
+ }
ctx->overworld_scene->update_tweens();
diff --git a/src/game/systems/camera-system.cpp b/src/game/systems/camera-system.cpp
index 2daffa0..4f946c3 100644
--- a/src/game/systems/camera-system.cpp
+++ b/src/game/systems/camera-system.cpp
@@ -20,9 +20,9 @@
#include "camera-system.hpp"
#include "game/components/camera-subject-component.hpp"
#include "game/components/transform-component.hpp"
-#include "animation/spring.hpp"
#include "scene/camera.hpp"
#include "math/math.hpp"
+#include
#include
#include
@@ -34,25 +34,19 @@ camera_system::camera_system(entt::registry& registry):
viewport{0, 0, 0, 0},
mouse_position{0, 0}
{
- // Init azimuth spring constraint
- azimuth_spring.v = 0.0f;
- azimuth_spring.z = 1.0f;
- azimuth_spring.w = 2.0f * math::two_pi;
+ orbit_cam.set_elevation_limits({math::radians(5.0f), math::radians(89.0f)});
+ orbit_cam.set_focal_distance_limits({2.0f, 200.0f});
+ orbit_cam.set_fov_limits({math::radians(80.0f), math::radians(35.0f)});
+ orbit_cam.set_clip_near_limits({0.1f, 5.0f});
+ orbit_cam.set_clip_far_limits({100.0f, 2000.0f});
- // Init elevation spring constraint
- elevation_spring.v = 0.0f;
- elevation_spring.z = 1.0f;
- elevation_spring.w = 2.0f * math::two_pi;
+ orbit_cam.set_target_focal_point({0.0f, 0.0f, 0.0f});
+ orbit_cam.set_target_azimuth(0.0f);
+ orbit_cam.set_target_elevation(math::radians(45.0f));
+ orbit_cam.set_target_zoom(0.0f);
- // Init focal distance spring constraint
- focal_distance_spring.v = 0.0f;
- focal_distance_spring.z = 1.0f;
- focal_distance_spring.w = 5.0f * math::two_pi;
-
- // Init fov spring constraint
- fov_spring.v = 0.0f;
- fov_spring.z = 1.0f;
- fov_spring.w = 5.0f * math::two_pi;
+ orbit_cam.reset_springs();
+
}
void camera_system::update(double t, double dt)
@@ -72,124 +66,45 @@ void camera_system::update(double t, double dt)
if (subject_count > 1)
target_focal_point /= static_cast(subject_count);
- // Get source transform
- transform_type source_transform = camera->get_transform();
-
- // Solve azimuth spring
- float2 xz_direction = math::normalize(math::swizzle<0, 2>(target_focal_point) - math::swizzle<0, 2>(source_transform.translation));
- azimuth_spring.x0 = math::wrap_radians(std::atan2(-xz_direction.y, xz_direction.x) - math::half_pi);
- azimuth_spring.x1 = azimuth_spring.x0 + math::wrap_radians(azimuth_spring.x1 - azimuth_spring.x0);
- solve_spring_constraint(azimuth_spring, dt);
-
- // Sovle elevation spring
- elevation_spring.x0 = elevation;
- elevation_spring.x1 = elevation_spring.x0 + math::wrap_radians(elevation_spring.x1 - elevation_spring.x0);
- solve_spring_constraint(elevation_spring, dt);
-
- // Solve focal distance spring
- focal_distance_spring.x0 = math::length(source_transform.translation - target_focal_point);
- solve_spring_constraint(focal_distance_spring, dt);
-
- // Solve FOV spring
- fov_spring.x0 = camera->get_fov();
- solve_spring_constraint(fov_spring, dt);
-
- // Determine camera rotation
- quaternion_type smooth_azimuth_rotation = math::angle_axis(azimuth_spring.x0, float3{0.0f, 1.0f, 0.0f});
- quaternion_type smooth_elevation_rotation = math::angle_axis(elevation_spring.x0, float3{-1.0f, 0.0f, 0.0f});
- quaternion_type smooth_rotation = math::normalize(smooth_azimuth_rotation * smooth_elevation_rotation);
-
- // Determine camera view point
- float3 smooth_view_point = target_focal_point + smooth_rotation * float3{0.0f, 0.0f, focal_distance_spring.x0};
-
- // Update camera transform
- transform_type smooth_transform;
- smooth_transform.translation = smooth_view_point;
- smooth_transform.rotation = smooth_rotation;
- smooth_transform.scale = source_transform.scale;
- camera->set_transform(smooth_transform);
-
- // Determine aspect ratio
- float aspect_ratio = viewport[2] / viewport[3];
+ target_focal_point.y += 0.2f;
- // Determine clipping planes
- float clip_near = math::log_lerp(near_clip_far, near_clip_near, zoom_factor);
- float clip_far = math::log_lerp(far_clip_far, far_clip_near, zoom_factor);
- // Update camera projection
- camera->set_perspective(fov_spring.x0, aspect_ratio, clip_near, clip_far);
+ orbit_cam.set_target_focal_point(target_focal_point);
+ orbit_cam.update(static_cast(dt));
}
-void camera_system::rotate(float angle)
+void camera_system::pan(float angle)
{
- set_azimuth(azimuth + angle);
+ orbit_cam.pan(angle);
}
void camera_system::tilt(float angle)
{
- set_elevation(elevation + angle);
+ orbit_cam.tilt(angle);
}
void camera_system::zoom(float factor)
{
- set_zoom(zoom_factor + factor);
+ orbit_cam.zoom(factor);
}
void camera_system::set_camera(::camera* camera)
{
this->camera = camera;
+ if (camera)
+ {
+ orbit_cam.attach(camera);
+ }
+ else
+ {
+ orbit_cam.detach();
+ }
}
void camera_system::set_viewport(const float4& viewport)
{
this->viewport = viewport;
-}
-
-void camera_system::set_azimuth(float angle)
-{
- azimuth = math::wrap_radians(angle);
- azimuth_rotation = math::angle_axis(azimuth, float3{0.0f, 1.0f, 0.0f});
- azimuth_spring.x1 = azimuth;
-}
-
-void camera_system::set_elevation(float angle)
-{
- elevation = math::wrap_radians(angle);
- elevation_rotation = math::angle_axis(elevation, float3{-1.0f, 0.0f, 0.0f});
- elevation_spring.x1 = elevation;
-}
-
-void camera_system::set_zoom(float factor)
-{
- this->zoom_factor = std::max(0.0f, std::min(1.0f, factor));
- update_focal_distance();
- update_fov();
-}
-
-void camera_system::set_focal_distance(float distance_near, float distance_far)
-{
- focal_distance_near = distance_near;
- focal_distance_far = distance_far;
- update_focal_distance();
-}
-
-void camera_system::set_fov(float angle_near, float angle_far)
-{
- fov_near = angle_near;
- fov_far = angle_far;
- update_fov();
-}
-
-void camera_system::set_clip_near(float distance_near, float distance_far)
-{
- near_clip_near = distance_near;
- near_clip_far = distance_far;
-}
-
-void camera_system::set_clip_far(float distance_near, float distance_far)
-{
- far_clip_near = distance_near;
- far_clip_far = distance_far;
+ orbit_cam.set_aspect_ratio(viewport[2] / viewport[3]);
}
void camera_system::handle_event(const mouse_moved_event& event)
@@ -202,15 +117,3 @@ void camera_system::handle_event(const window_resized_event& event)
{
set_viewport({0.0f, 0.0f, static_cast(event.w), static_cast(event.h)});
}
-
-void camera_system::update_focal_distance()
-{
- focal_distance = math::log_lerp(focal_distance_far, focal_distance_near, zoom_factor);
- focal_distance_spring.x1 = focal_distance;
-}
-
-void camera_system::update_fov()
-{
- fov = math::log_lerp(fov_far, fov_near, zoom_factor);
- fov_spring.x1 = fov;
-}
diff --git a/src/game/systems/camera-system.hpp b/src/game/systems/camera-system.hpp
index ee297cc..0e8c075 100644
--- a/src/game/systems/camera-system.hpp
+++ b/src/game/systems/camera-system.hpp
@@ -27,7 +27,7 @@
#include "utility/fundamental-types.hpp"
#include "math/quaternion-type.hpp"
#include "math/transform-type.hpp"
-#include "animation/spring.hpp"
+#include "animation/orbit-cam.hpp"
class camera;
class orbit_cam;
@@ -44,61 +44,35 @@ public:
camera_system(entt::registry& registry);
virtual void update(double t, double dt);
- void rotate(float angle);
+ void pan(float angle);
void tilt(float angle);
void zoom(float factor);
void set_camera(::camera* camera);
void set_viewport(const float4& viewport);
- void set_azimuth(float angle);
- void set_elevation(float angle);
- void set_zoom(float factor);
- void set_focal_distance(float distance_near, float distance_far);
- void set_fov(float angle_near, float angle_far);
- void set_clip_near(float distance_near, float distance_far);
- void set_clip_far(float distance_near, float distance_far);
- const spring_constraint& get_azimuth_spring() const;
+ const orbit_cam* get_orbit_cam() const;
+ orbit_cam* get_orbit_cam();
private:
virtual void handle_event(const mouse_moved_event& event);
virtual void handle_event(const window_resized_event& event);
-
- void update_focal_distance();
- void update_fov();
camera* camera;
float4 viewport;
float2 mouse_position;
- spring_constraint azimuth_spring;
- spring_constraint elevation_spring;
- spring_constraint focal_distance_spring;
- spring_constraint fov_spring;
-
-
- float azimuth;
- float elevation;
- float focal_distance;
- float zoom_factor;
- float fov;
-
- float focal_distance_near;
- float focal_distance_far;
- float fov_near;
- float fov_far;
- float near_clip_near;
- float near_clip_far;
- float far_clip_near;
- float far_clip_far;
-
- quaternion_type elevation_rotation;
- quaternion_type azimuth_rotation;
+ orbit_cam orbit_cam;
};
-inline const spring_constraint& camera_system::get_azimuth_spring() const
+inline const orbit_cam* camera_system::get_orbit_cam() const
+{
+ return &orbit_cam;
+}
+
+inline orbit_cam* camera_system::get_orbit_cam()
{
- return azimuth_spring;
+ return &orbit_cam;
}
#endif // ANTKEEPER_CAMERA_SYSTEM_HPP
diff --git a/src/game/systems/control-system.cpp b/src/game/systems/control-system.cpp
index 2c9ddcd..c792eb5 100644
--- a/src/game/systems/control-system.cpp
+++ b/src/game/systems/control-system.cpp
@@ -19,7 +19,6 @@
#include "control-system.hpp"
#include "input/control.hpp"
-#include "orbit-cam.hpp"
#include "scene/camera.hpp"
#include "geometry/intersection.hpp"
#include "animation/ease.hpp"
@@ -27,6 +26,7 @@
#include "math/math.hpp"
#include "game/entity-commands.hpp"
#include "game/systems/camera-system.hpp"
+#include "animation/orbit-cam.hpp"
control_system::control_system(entt::registry& registry):
entity_system(registry),
@@ -74,7 +74,6 @@ control_system::control_system(entt::registry& registry):
far_clip_far = 2000.0f;
nest = nullptr;
- orbit_cam = nullptr;
mouse_angle = 0.0f;
old_mouse_angle = mouse_angle;
@@ -85,6 +84,8 @@ control_system::control_system(entt::registry& registry):
void control_system::update(double t, double dt)
{
+ timestep = dt;
+
// Zoom camera
if (zoom_in_control.is_active())
camera_system->zoom(zoom_speed * dt);
@@ -104,12 +105,15 @@ void control_system::update(double t, double dt)
if (math::length_squared(movement) != 0.0f)
{
- float max_speed = 100.0f * dt;
+ std::array speed_limits = {15.0f, 100.0f};
+
+ float zoom = camera_system->get_orbit_cam()->get_zoom();
+ float max_speed = math::log_lerp(speed_limits[1], speed_limits[0], zoom) * dt;
+
float speed = std::min(max_speed, math::length(movement * max_speed));
movement = math::normalize(movement) * speed;
- float azimuth = camera_system->get_azimuth_spring().x0;
- math::quaternion azimuth_rotation = math::angle_axis(azimuth, float3{0.0f, 1.0f, 0.0f});
+ const math::quaternion& azimuth_rotation = camera_system->get_orbit_cam()->get_azimuth_rotation();
movement = azimuth_rotation * movement;
ec::translate(registry, camera_subject_eid, movement);
@@ -150,139 +154,6 @@ void control_system::update(double t, double dt)
}
}
-/*
-void control_system::update(double t, double dt)
-{
- this->timestep = dt;
-
- if (adjust_camera_control.is_active() && !adjust_camera_control.was_active())
- {
- }
-
- // Determine zoom
- if (zoom_in_control.is_active())
- zoom += zoom_speed * dt * zoom_in_control.get_current_value();
- if (zoom_out_control.is_active())
- zoom -= zoom_speed * dt * zoom_out_control.get_current_value();
- zoom = std::max(0.0f, std::min(1.0f, zoom));
-
- float focal_distance = math::log_lerp(near_focal_distance, far_focal_distance, 1.0f - zoom);
-
- float fov = math::log_lerp(near_fov, far_fov, 1.0f - zoom);
-
- //float elevation_factor = (orbit_cam->get_target_elevation() - min_elevation) / max_elevation;
- //fov = math::log_lerp(near_fov, far_fov, elevation_factor);
- float clip_near = math::log_lerp(near_clip_near, far_clip_near, 1.0f - zoom);
- float clip_far = math::log_lerp(near_clip_far, far_clip_far, 1.0f - zoom);
- float movement_speed = math::log_lerp(near_movement_speed * dt, far_movement_speed * dt, 1.0f - zoom);
-
- orbit_cam->set_target_focal_distance(focal_distance);
- orbit_cam->get_camera()->set_perspective(fov, orbit_cam->get_camera()->get_aspect_ratio(), clip_near, clip_far);
-
- const float rotation_speed = 2.0f * dt;
- float rotation = 0.0f;
- if (rotate_ccw_control.is_active())
- rotation += rotate_ccw_control.get_current_value() * rotation_speed;
- if (rotate_cw_control.is_active())
- rotation -= rotate_cw_control.get_current_value() * rotation_speed;
- if (rotation)
- {
- orbit_cam->rotate(rotation);
- }
-
- const float tilt_speed = 2.0f * dt;
- float tilt = 0.0f;
- if (tilt_up_control.is_active())
- tilt -= tilt_up_control.get_current_value() * tilt_speed;
- if (tilt_down_control.is_active())
- tilt += tilt_down_control.get_current_value() * tilt_speed;
- if (tilt)
- {
- orbit_cam->tilt(tilt);
- float elevation = orbit_cam->get_target_elevation();
- elevation = std::min(max_elevation, std::max(min_elevation, elevation));
- orbit_cam->set_target_elevation(elevation);
- }
-
- float2 movement{0.0f, 0.0f};
- if (move_right_control.is_active())
- movement[0] += move_right_control.get_current_value();
- if (move_left_control.is_active())
- movement[0] -= move_left_control.get_current_value();
- if (move_forward_control.is_active())
- movement[1] -= move_forward_control.get_current_value();
- if (move_back_control.is_active())
- movement[1] += move_back_control.get_current_value();
-
- const float deadzone = 0.01f;
- float magnitude_squared = math::length_squared(movement);
-
- if (magnitude_squared > deadzone)
- {
- if (magnitude_squared > 1.0f)
- {
- movement = math::normalize(movement);
- }
-
- orbit_cam->move(movement * movement_speed);
- }
-
- float ascention = 0.0f;
- if (ascend_control.is_active())
- ascention += ascend_control.get_current_value();
- if (descend_control.is_active())
- ascention -= descend_control.get_current_value();
-
- if (ascention)
- {
- float old_depth = -orbit_cam->get_target_focal_point()[1];
-
- orbit_cam->set_target_focal_point(orbit_cam->get_target_focal_point() + float3{0.0f, ascention * movement_speed, 0.0f});
-
- if (nest)
- {
- float3 focal_point = orbit_cam->get_target_focal_point();
- float depth = -focal_point[1];
-
- float delta_shaft_angle = nest->get_shaft_angle(*nest->get_central_shaft(), depth) - nest->get_shaft_angle(*nest->get_central_shaft(), old_depth);
-
- //orbit_cam->set_target_azimuth(orbit_cam->get_target_azimuth() - delta_shaft_angle);
- orbit_cam->set_target_focal_point(nest->get_shaft_position(*nest->get_central_shaft(), depth));
- }
- }
-
- orbit_cam->update(dt);
-
- camera* camera = orbit_cam->get_camera();
-
- float3 pick_near = camera->unproject({mouse_position[0], viewport[3] - mouse_position[1], 0.0f}, viewport);
- float3 pick_far = camera->unproject({mouse_position[0], viewport[3] - mouse_position[1], 1.0f}, viewport);
- float3 pick_direction = math::normalize(pick_far - pick_near);
- ray picking_ray = {pick_near, pick_direction};
- plane ground_plane = {float3{0, 1, 0}, 0.0f};
-
- auto intersection_result = ray_plane_intersection(picking_ray, ground_plane);
- if (std::get<0>(intersection_result))
- {
- float3 pick = picking_ray.extrapolate(std::get<1>(intersection_result));
- if (tool)
- tool->set_translation(pick);
- }
-
- if (toggle_view_control.is_active() && !toggle_view_control.was_active())
- {
- }
-
-
-
-}
-*/
-
-void control_system::set_orbit_cam(::orbit_cam* orbit_cam)
-{
- this->orbit_cam = orbit_cam;
-}
-
void control_system::set_camera_system(::camera_system* camera_system)
{
this->camera_system = camera_system;
@@ -337,12 +208,12 @@ void control_system::handle_event(const mouse_moved_event& event)
elevation_factor *= -1.0f;
}
- float rotation = math::radians(22.5f) * rotation_factor * timestep;
- float elevation = orbit_cam->get_target_elevation() + elevation_factor * 0.25f * timestep;
- elevation = std::min(max_elevation, std::max(min_elevation, elevation));
-
- orbit_cam->rotate(rotation);
- orbit_cam->set_target_elevation(elevation);
+ float rotation = math::radians(15.0f) * rotation_factor * timestep;
+ float tilt = math::radians(15.0f) * elevation_factor * timestep;
+
+ camera_system->pan(rotation);
+ camera_system->tilt(tilt);
+
}
else if (!adjust_camera_control.was_active())
{
diff --git a/src/game/systems/control-system.hpp b/src/game/systems/control-system.hpp
index c2b617f..84d270c 100644
--- a/src/game/systems/control-system.hpp
+++ b/src/game/systems/control-system.hpp
@@ -29,7 +29,6 @@
#include "scene/model-instance.hpp"
#include "utility/fundamental-types.hpp"
-class orbit_cam;
class nest;
class camera;
class camera_system;
@@ -47,7 +46,6 @@ public:
void set_invert_mouse_x(bool invert);
void set_invert_mouse_y(bool invert);
- void set_orbit_cam(orbit_cam* orbit_cam);
void set_camera_system(camera_system* camera_system);
void set_nest(::nest* nest);
void set_tool(model_instance* tool);
@@ -111,7 +109,6 @@ private:
float timestep;
float zoom;
- orbit_cam* orbit_cam;
camera_system* camera_system;
::nest* nest;
model_instance* tool;
diff --git a/src/game/systems/render-system.cpp b/src/game/systems/render-system.cpp
index 655f03b..e871ea4 100644
--- a/src/game/systems/render-system.cpp
+++ b/src/game/systems/render-system.cpp
@@ -78,6 +78,13 @@ void render_system::set_renderer(::renderer* renderer)
this->renderer = renderer;
}
+model_instance* render_system::get_model_instance(entt::entity entity)
+{
+ if (auto it = model_instances.find(entity); it != model_instances.end())
+ return it->second;
+ return nullptr;
+}
+
void render_system::update_model_and_materials(entt::entity entity, model_component& model)
{
if (auto model_it = model_instances.find(entity); model_it != model_instances.end())
diff --git a/src/game/systems/render-system.hpp b/src/game/systems/render-system.hpp
index 8ed3e38..f237f3a 100644
--- a/src/game/systems/render-system.hpp
+++ b/src/game/systems/render-system.hpp
@@ -42,6 +42,8 @@ public:
void remove_layers();
void set_renderer(::renderer* renderer);
+
+ model_instance* get_model_instance(entt::entity entity);
private:
void update_model_and_materials(entt::entity entity, ecs::model_component& model);
diff --git a/src/game/systems/tool-system.cpp b/src/game/systems/tool-system.cpp
index 7bbf0b9..1794041 100644
--- a/src/game/systems/tool-system.cpp
+++ b/src/game/systems/tool-system.cpp
@@ -22,7 +22,7 @@
#include "game/components/tool-component.hpp"
#include "game/components/transform-component.hpp"
#include "scene/camera.hpp"
-#include "orbit-cam.hpp"
+#include "animation/orbit-cam.hpp"
#include "geometry/mesh.hpp"
#include "geometry/intersection.hpp"
#include "math/math.hpp"
@@ -35,7 +35,8 @@ tool_system::tool_system(entt::registry& registry):
orbit_cam(orbit_cam),
viewport{0, 0, 0, 0},
mouse_position{0, 0},
- pick_enabled(true)
+ pick_enabled(true),
+ was_pick_enabled(pick_enabled)
{}
void tool_system::update(double t, double dt)
@@ -106,12 +107,14 @@ void tool_system::update(double t, double dt)
if (intersection)
{
- transform.transform.translation = pick;
+ transform.transform.translation = pick + float3{0, 15, 0};
}
math::quaternion rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0});
transform.transform.rotation = rotation;
});
+
+ was_pick_enabled = pick_enabled;
}
void tool_system::set_camera(const ::camera* camera)
@@ -136,7 +139,7 @@ void tool_system::set_pick(bool enabled)
void tool_system::handle_event(const mouse_moved_event& event)
{
- if (pick_enabled)
+ if (pick_enabled && was_pick_enabled)
{
mouse_position[0] = event.x;
mouse_position[1] = event.y;
diff --git a/src/game/systems/tool-system.hpp b/src/game/systems/tool-system.hpp
index bc555a8..2b384b8 100644
--- a/src/game/systems/tool-system.hpp
+++ b/src/game/systems/tool-system.hpp
@@ -48,6 +48,7 @@ private:
const orbit_cam* orbit_cam;
float4 viewport;
float2 mouse_position;
+ bool was_pick_enabled;
bool pick_enabled;
};
diff --git a/src/math/angles.hpp b/src/math/angles.hpp
index 7825460..1aed27f 100644
--- a/src/math/angles.hpp
+++ b/src/math/angles.hpp
@@ -47,7 +47,7 @@ template
T radians(T degrees);
/**
- * Wraps an angle on [-180, 180].
+ * Wraps an angle to [-180, 180].
*
* @param degrees Angle in degrees.
* @return Wrapped angle.
@@ -56,7 +56,7 @@ template
T wrap_degrees(T degrees);
/**
- * Wraps an angle on [-pi, pi].
+ * Wraps an angle to [-pi, pi].
*
* @param radians Angle in radians.
* @return Wrapped angle.
diff --git a/src/orbit-cam.cpp b/src/orbit-cam.cpp
deleted file mode 100644
index 5666b81..0000000
--- a/src/orbit-cam.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2020 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see .
- */
-
-#include "orbit-cam.hpp"
-#include "scene/camera.hpp"
-#include "math/math.hpp"
-#include
-#include
-
-orbit_cam::orbit_cam():
- elevation_rotation(math::identity_quaternion),
- azimuth_rotation(math::identity_quaternion),
- target_elevation_rotation(math::identity_quaternion),
- target_azimuth_rotation(math::identity_quaternion),
- target_rotation(math::identity_quaternion)
-{}
-
-orbit_cam::~orbit_cam()
-{}
-
-void orbit_cam::update(float dt)
-{
- float interpolation_factor = 1.0f;
-
- // Calculate rotation and target rotation quaternions
- //rotation = azimuth_rotation * elevation_rotation;
- target_rotation = math::normalize(target_azimuth_rotation * target_elevation_rotation);
-
- // Calculate target translation
- target_translation = target_focal_point + target_rotation * float3{0.0f, 0.0f, target_focal_distance};
-
- // Interpolate rotation
- //rotation = glm::mix(rotation, target_rotation, interpolation_factor);
-
- // Interpolate angles
- set_elevation(math::lerp(elevation, target_elevation, interpolation_factor));
- set_azimuth(math::lerp(azimuth, target_azimuth, interpolation_factor));
-
- // Calculate rotation
- set_rotation(math::normalize(azimuth_rotation * elevation_rotation));
-
- // Interpolate focal point and focal distance
- focal_point = math::lerp(focal_point, target_focal_point, interpolation_factor);
- focal_distance = math::lerp(focal_distance, target_focal_distance, interpolation_factor);
-
- // Caluclate translation
- set_translation(focal_point + get_rotation() * float3{0.0f, 0.0f, focal_distance});
- /*
- // Recalculate azimuth
- azimuth_rotation = rotation;
- azimuth_rotation.x = 0.0f;
- azimuth_rotation.z = 0.0f;
- azimuth_rotation = glm::normalize(azimuth_rotation);
- azimuth = 2.0f * std::acos(azimuth_rotation.w);
-
- // Recalculate elevation
- elevation_rotation = rotation;
- elevation_rotation.y = 0.0f;
- elevation_rotation.z = 0.0f;
- elevation_rotation = glm::normalize(elevation_rotation);
- elevation = 2.0f * std::acos(elevation_rotation.w);
- */
-
- // Update camera
- if (get_camera() != nullptr)
- {
- transform_type transform = math::identity_transform;
- transform.translation = get_translation();
- transform.rotation = get_rotation();
- get_camera()->set_transform(transform);
- //get_camera()->look_at(get_translation(), get_translation() + get_forward(), get_up());
- }
-}
-
-void orbit_cam::move(const float2& direction)
-{
- target_focal_point += azimuth_rotation * float3{direction[0], 0.0f, direction[1]};
-}
-
-void orbit_cam::rotate(float angle)
-{
- set_target_azimuth(target_azimuth + angle);
-}
-
-void orbit_cam::tilt(float angle)
-{
- set_target_elevation(target_elevation + angle);
-}
-
-void orbit_cam::zoom(float distance)
-{
- set_target_focal_distance(target_focal_distance - distance);
-}
-
-void orbit_cam::set_focal_point(const float3& point)
-{
- focal_point = point;
-}
-
-void orbit_cam::set_focal_distance(float distance)
-{
- focal_distance = distance;
-}
-
-void orbit_cam::set_elevation(float angle)
-{
- elevation = angle;
- elevation_rotation = math::angle_axis(elevation, float3{-1.0f, 0.0f, 0.0f});
-}
-
-void orbit_cam::set_azimuth(float angle)
-{
- azimuth = angle;
- azimuth_rotation = math::angle_axis(azimuth, float3{0.0f, 1.0f, 0.0f});
-}
-
-void orbit_cam::set_target_focal_point(const float3& point)
-{
- target_focal_point = point;
-}
-
-void orbit_cam::set_target_focal_distance(float distance)
-{
- target_focal_distance = distance;
-}
-
-void orbit_cam::set_target_elevation(float angle)
-{
- target_elevation = angle;
- target_elevation_rotation = math::angle_axis(target_elevation, float3{-1.0f, 0.0f, 0.0f});
-}
-
-void orbit_cam::set_target_azimuth(float angle)
-{
- target_azimuth = angle;
- target_azimuth_rotation = math::angle_axis(target_azimuth, float3{0.0f, 1.0f, 0.0f});
-}
-
diff --git a/src/renderer/material-flags.hpp b/src/renderer/material-flags.hpp
index 7aa89c8..cd174a0 100644
--- a/src/renderer/material-flags.hpp
+++ b/src/renderer/material-flags.hpp
@@ -30,6 +30,7 @@
#define MATERIAL_FLAG_X_RAY 0x10
#define MATERIAL_FLAG_OUTLINE 0x20
#define MATERIAL_FLAG_VEGETATION 0x40
+#define MATERIAL_FLAG_REFRACTIVE 0x80
#define MATERIAL_FLAG_WIREFRAME 0x80000000
#endif // ANTKEEPER_MATERIAL_FLAGS_HPP