From 37f95a087d936ab1149bd8d5ab53739121e907ca Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Wed, 19 Aug 2020 23:24:16 -0700 Subject: [PATCH] Improve orbit cam springing --- CMakeLists.txt | 1 + src/{ => animation}/camera-rig.cpp | 41 ++++-- src/{ => animation}/camera-rig.hpp | 36 ++--- src/animation/orbit-cam.cpp | 199 ++++++++++++++++++++++++++++ src/{ => animation}/orbit-cam.hpp | 106 +++++++-------- src/animation/spring.hpp | 15 ++- src/game/bootloader.cpp | 33 +++-- src/game/game-context.hpp | 3 +- src/game/states/play-state.cpp | 16 +-- src/game/systems/camera-system.cpp | 153 ++++----------------- src/game/systems/camera-system.hpp | 50 ++----- src/game/systems/control-system.cpp | 159 +++------------------- src/game/systems/control-system.hpp | 3 - src/game/systems/render-system.cpp | 7 + src/game/systems/render-system.hpp | 2 + src/game/systems/tool-system.cpp | 11 +- src/game/systems/tool-system.hpp | 1 + src/math/angles.hpp | 4 +- src/orbit-cam.cpp | 154 --------------------- src/renderer/material-flags.hpp | 1 + 20 files changed, 400 insertions(+), 595 deletions(-) rename src/{ => animation}/camera-rig.cpp (58%) rename src/{ => animation}/camera-rig.hpp (83%) create mode 100644 src/animation/orbit-cam.cpp rename src/{ => animation}/orbit-cam.hpp (54%) delete mode 100644 src/orbit-cam.cpp 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