diff --git a/src/modules/character/actor.rs b/src/modules/character/actor.rs index e066c2cc..248a1fd4 100644 --- a/src/modules/character/actor.rs +++ b/src/modules/character/actor.rs @@ -1,15 +1,21 @@ use std::f32::consts::{FRAC_2_PI, PI}; -use cgmath::{InnerSpace, Matrix3, Matrix4, Rad, Transform, Vector3}; +use cgmath::{Angle, InnerSpace, Matrix3, Matrix4, Quaternion, Rad, Rotation3, Transform, Vector3, VectorSpace}; use winit::{event::ElementState, keyboard::KeyCode}; -use crate::modules::{camera::{camera::Camera, orbit_controller::OrbitController}, core::scene::Scene}; +use crate::modules::{camera::{camera::Camera, orbit_controller::OrbitController}, core::scene::Scene, utils::functions::{denormalize_f32x3, lerp_angle}}; use super::character::{Character, CharacterState}; +const ROTATION_SPEED: f32 = PI / (200.0 / 1000.0); +// ^^^^^ duration in ms to make a a 360 pub struct Actor { pub character: String, pub orbit_controller: OrbitController, controller: Controller, + // current_rotation: Quaternion, + // target_rotation: Quaternion, + direction: Vector3, + rotation_speed: f32, } impl Actor { @@ -19,10 +25,14 @@ impl Actor { character, controller: Default::default(), orbit_controller: OrbitController::new(), + // current_rotation: Quaternion::from_angle_y(Rad(0.0)), + // target_rotation: Quaternion::from_angle_y(Rad(0.0)), + direction: Vector3::new(0.0, 0.0, 0.0), + rotation_speed: ROTATION_SPEED, } } - pub fn apply_controls(&self, character: &mut Character, scene: &mut Scene, camera: &Camera, delta_ms: f32) { + pub fn apply_controls(&mut self, character: &mut Character, scene: &mut Scene, camera: &Camera, delta_ms: f32) { let mut movement_direction = Vector3::new(0.0, 0.0, 0.0); if self.controller.forward { movement_direction.z -= 1.0; @@ -31,10 +41,10 @@ impl Actor { movement_direction.z += 1.0; } if self.controller.left { - movement_direction.x -= 1.0; + movement_direction.x -= 0.9; } if self.controller.right { - movement_direction.x += 1.0; + movement_direction.x += 0.9; } if self.controller.attack == true { @@ -47,8 +57,13 @@ impl Actor { { let rotation = Matrix4::from_angle_y(-camera.yaw - Rad(PI / 2.0)); let camera_space_movement = rotation.transform_vector(movement_direction); - let movement = Vector3::new(camera_space_movement.x, 0.0, camera_space_movement.z).normalize(); - character.move_in_direction(movement, scene, delta_ms); + let desired_direction = Vector3::new(camera_space_movement.x, 0.0, camera_space_movement.z).normalize(); + let delta_seconds = delta_ms / 1000.0; + let current_angle = Rad::atan2(self.direction.z, self.direction.x); + let desired_angle = Rad::atan2(desired_direction.z, desired_direction.x); + let new_angle = lerp_angle(current_angle, desired_angle, self.rotation_speed * delta_seconds); + self.direction = Vector3::new(new_angle.cos(), 0.0, new_angle.sin()).normalize(); + character.move_in_direction(self.direction, scene, delta_ms); character.set_state(CharacterState::Run, scene); } else { character.set_state(CharacterState::Wait, scene); diff --git a/src/modules/utils/functions.rs b/src/modules/utils/functions.rs index f9187602..cf0e7f06 100644 --- a/src/modules/utils/functions.rs +++ b/src/modules/utils/functions.rs @@ -1,4 +1,6 @@ -use cgmath::Vector3; +use std::f32::consts::PI; + +use cgmath::{Rad, Vector3}; use super::time_factory::TimeFactory; pub fn debug_using_trash_file( @@ -137,10 +139,20 @@ pub fn srgb_to_linear(color: [f32; 3]) -> [f32; 3] { ((color[2] + 0.055) / 1.055).powf(2.4) }; - [r, g, b] // Retourne la couleur convertie en espace linéaire + [r, g, b] } pub fn correct_color(colors: [f32; 4]) -> [f32; 4] { let rgb = srgb_to_linear([colors[0], colors[1], colors[2]]); [rgb[0], rgb[1], rgb[2], colors[3]] } + +pub fn lerp_angle(start: Rad, end: Rad, t: f32) -> Rad { + let mut delta = (end - start).0; + if delta > PI { + delta -= 2.0 * PI; + } else if delta < -PI { + delta += 2.0 * PI; + } + Rad(start.0 + delta * t.clamp(0.0, 1.0)) +}