36 m_fixed_update_time =
static_cast<double>(t);
37 m_fixed_timestep =
static_cast<double>(dt);
42 const double variable_update_time = m_fixed_update_time + m_fixed_timestep *
static_cast<double>(alpha);
43 const double variable_timestep =
std::max(0.0, variable_update_time - m_variable_update_time);
44 m_variable_update_time = variable_update_time;
82 spring_arm_group.begin(),
83 spring_arm_group.end(),
86 auto& spring_arm = spring_arm_group.get<spring_arm_component>(entity_id);
87 auto& camera = static_cast<scene::camera&>(*spring_arm_group.get<scene_component>(entity_id).object);
89 math::transform<double> parent_transform = math::transform<double>::identity();
90 if (spring_arm.parent_eid != entt::null)
92 const auto parent_scene = registry.try_get<scene_component>(spring_arm.parent_eid);
95 parent_transform.translation = math::dvec3(parent_scene->object->get_translation());
96 parent_transform.rotation = math::dquat(parent_scene->object->get_rotation());
101 spring_arm.focal_point_spring.set_target_value(parent_transform * spring_arm.focal_point_offset);
104 spring_arm.angles_spring.set_target_value(spring_arm.angles_spring.get_target_value() + spring_arm.angular_velocities * variable_timestep);
107 spring_arm.angles_spring.set_target_value(
math::clamp(spring_arm.angles_spring.get_target_value(), spring_arm.min_angles, spring_arm.max_angles));
110 spring_arm.focal_point_spring.solve(variable_timestep);
111 spring_arm.angles_spring.solve(variable_timestep);
116 spring_arm.zoom = ease<double, double>::in_sine(1.0, 0.0, spring_arm.angles_spring.get_value().x() / -math::half_pi<double>);
120 spring_arm.zoom = std::min<double>(std::max<double>(spring_arm.zoom, 0.0), 1.0);
124 spring_arm.vfov =
math::vertical_fov(spring_arm.hfov,
static_cast<double>(camera.get_aspect_ratio()));
127 spring_arm.focal_plane_height =
ease<double, double>::out_sine(spring_arm.far_focal_plane_height, spring_arm.near_focal_plane_height, spring_arm.zoom);
128 spring_arm.focal_plane_width = spring_arm.focal_plane_height *
static_cast<double>(camera.get_aspect_ratio());
131 spring_arm.focal_distance = spring_arm.focal_plane_height * 0.5 / std::tan(spring_arm.vfov * 0.5);
133 const auto camera_up = spring_arm.up_rotation *
math::dvec3{0, 1, 0};
134 const auto parent_up = parent_transform.rotation *
math::dvec3{0, 1, 0};
141 const auto camera_translation = spring_arm.focal_point_spring.get_value() + spring_arm.camera_rotation *
math::dvec3{0.0f, 0.0f, spring_arm.focal_distance};
145 camera_transform.rotation =
math::fquat(spring_arm.camera_rotation);
146 camera_transform.scale = {1, 1, 1};
149 double center_offset = (1.0 -
std::abs(spring_arm.angles_spring.get_value().x()) / math::half_pi<double>) * (spring_arm.focal_plane_height / 3.0 * 0.5);
150 camera_transform.translation +=
math::fvec3(spring_arm.camera_rotation *
math::dvec3{0, center_offset, 0});
152 camera.set_transform(camera_transform);
153 camera.set_vertical_fov(
static_cast<float>(spring_arm.vfov));
161 m_aspect_ratio = m_viewport[2] / m_viewport[3];
void interpolate(float alpha)
void set_viewport(const math::fvec4 &viewport)
camera_system(entity::registry ®istry)
void update(float t, float dt) override
Perform's a system's update() function.
Abstract base class for updatable systems.
entity::registry & registry
Registry on which the system operate.
entt::registry registry
Component registry type.
dvec< 4 > dvec4
n-dimensional vector of double-precision floating-point numbers.
T vertical_fov(T h, T r)
Calculates a vertical FoV given a horizontal FoV and aspect ratio.
quat< T > euler_xyz_to_quat(const vec3< T > &angles)
Constructs a quaternion from Euler angles.
constexpr vector< T, N > max(const vector< T, N > &x, const vector< T, N > &y)
Returns a vector containing the maximum elements of two vectors.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
constexpr vector< T, N > abs(const vector< T, N > &x)
Returns the absolute values of each element.
quaternion< T > rotation(const vec3< T > &from, const vec3< T > &to, T tolerance=T{1e-6})
Constructs a quaternion representing the minimum rotation from one direction to another direction.
constexpr vector< T, N > clamp(const vector< T, N > &x, const vector< T, N > &min, const vector< T, N > &max)
Clamps the values of a vector's elements.
Container for templated easing functions.
Quaternion composed of a real scalar part and imaginary vector part.
Attaches a camera to an entity using springs.