trenches/src/camera_effects.cpp

78 lines
2.8 KiB
C++

#include "camera_effects.hpp"
#include "utils/godot_macros.hpp"
#include "utils/util_functions.hpp"
#include <godot_cpp/variant/utility_functions.hpp>
void CameraEffects::_bind_methods() {
#define CLASSNAME CameraEffects
}
void CameraEffects::_ready() {
if(gd::Engine::get_singleton()->is_editor_hint())
return;
this->home = this->get_position();
this->target = this->home;
this->base_fov = this->target_fov = this->get_fov();
this->spring = gd::Object::cast_to<gd::SpringArm3D>(this->get_parent());
this->pivot = gd::Object::cast_to<gd::Node3D>(this->spring->get_parent());
this->target_rotation = this->spring->get_rotation().y;
this->rotation_range = gd::Math::abs(this->target_rotation);
}
void CameraEffects::_process(double delta [[maybe_unused]]) {
if(gd::Engine::get_singleton()->is_editor_hint())
return;
this->home = this->get_position();
if(utils::time_seconds() > this->end_time) {
intensity = 0.f;
this->set_position(this->home);
}
if(intensity != 0.f) {
gd::Vector3 pos{this->get_position()};
pos = this->target;
this->set_position(this->home + pos);
this->select_target();
}
float const current_y{this->spring->get_rotation().y};
float diff{gd::Math::wrapf(this->target_rotation - current_y, -M_2_PIf, M_2_PI)};
float const step(gd::Math::sign(diff) * delta * this->shoulder_switch_speed);
this->spring->rotate_y(gd::Math::abs(step) < gd::Math::abs(diff) ? step : diff);
this->set_fov(gd::Math::move_toward(this->get_fov(), this->target_fov, float(this->fov_speed * delta)));
gd::Vector3 const forward{this->get_global_position() - (this->pivot->get_global_position() + this->pivot->get_global_basis().get_column(2) * this->target_range)};
gd::Vector3 const left{gd::Vector3{0.f, 1.f, 0.f}.cross(forward)};
this->set_global_basis({left, forward.cross(left), forward});
}
void CameraEffects::push_shake_effect(float time, float intensity) {
if(intensity > this->intensity) {
this->intensity = intensity;
this->end_time = utils::time_seconds() + time;
}
}
void CameraEffects::push_zoom_effect(float factor, float speed) {
this->target_fov = factor * this->base_fov;
this->fov_speed = speed;
}
void CameraEffects::set_shoulder(bool weapon_shoulder) {
this->target_rotation = weapon_shoulder ? -this->rotation_range : this->rotation_range;
}
bool CameraEffects::is_weapon_shoulder() const {
return this->target_rotation < 0.f;
}
void CameraEffects::select_target() {
float const intensity_mod{this->intensity * 0.01f};
this->target = {
float(gd::UtilityFunctions::randf_range(0.f, 1.f) * -gd::Math::sign(this->target.x) * intensity_mod),
float(gd::UtilityFunctions::randf_range(-1.f, 1.f) * intensity_mod),
0.f
};
}