rendering, physics, player and camera WIP
This commit is contained in:
202
src/systems/camera.rs
Normal file
202
src/systems/camera.rs
Normal file
@@ -0,0 +1,202 @@
|
||||
use glam::Vec3;
|
||||
|
||||
use crate::utility::input::InputState;
|
||||
use crate::world::World;
|
||||
|
||||
pub fn camera_input_system(world: &mut World, input_state: &InputState)
|
||||
{
|
||||
let cameras: Vec<_> = world.cameras.all();
|
||||
|
||||
for camera_entity in cameras
|
||||
{
|
||||
if let Some(camera) = world.cameras.get_mut(camera_entity)
|
||||
{
|
||||
if !camera.is_active
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if input_state.mouse_delta.0.abs() > 0.0 || input_state.mouse_delta.1.abs() > 0.0
|
||||
{
|
||||
let is_following = world
|
||||
.camera_follows
|
||||
.get(camera_entity)
|
||||
.map(|f| f.is_following)
|
||||
.unwrap_or(false);
|
||||
|
||||
camera.yaw += input_state.mouse_delta.0 * 0.0008;
|
||||
|
||||
if is_following
|
||||
{
|
||||
camera.pitch += input_state.mouse_delta.1 * 0.0008;
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.pitch -= input_state.mouse_delta.1 * 0.0008;
|
||||
}
|
||||
|
||||
camera.pitch = camera
|
||||
.pitch
|
||||
.clamp(-89.0_f32.to_radians(), 89.0_f32.to_radians());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn camera_follow_system(world: &mut World)
|
||||
{
|
||||
let camera_entities: Vec<_> = world.camera_follows.all();
|
||||
|
||||
for camera_entity in camera_entities
|
||||
{
|
||||
if let Some(follow) = world.camera_follows.get(camera_entity)
|
||||
{
|
||||
if !follow.is_following
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let target_entity = follow.target_entity;
|
||||
let offset = follow.offset;
|
||||
|
||||
if let Some(target_transform) = world.transforms.get(target_entity)
|
||||
{
|
||||
let target_position = target_transform.position;
|
||||
|
||||
if let Some(camera) = world.cameras.get_mut(camera_entity)
|
||||
{
|
||||
let distance = offset.length();
|
||||
|
||||
let orbit_yaw = camera.yaw + std::f32::consts::PI;
|
||||
|
||||
let offset_x = distance * orbit_yaw.cos() * camera.pitch.cos();
|
||||
let offset_y = distance * camera.pitch.sin();
|
||||
let offset_z = distance * orbit_yaw.sin() * camera.pitch.cos();
|
||||
|
||||
let new_offset = Vec3::new(offset_x, offset_y, offset_z);
|
||||
|
||||
if let Some(camera_transform) = world.transforms.get_mut(camera_entity)
|
||||
{
|
||||
camera_transform.position = target_position + new_offset;
|
||||
}
|
||||
|
||||
if let Some(follow_mut) = world.camera_follows.get_mut(camera_entity)
|
||||
{
|
||||
follow_mut.offset = new_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn camera_noclip_system(world: &mut World, input_state: &InputState, delta: f32)
|
||||
{
|
||||
let cameras: Vec<_> = world.cameras.all();
|
||||
|
||||
for camera_entity in cameras
|
||||
{
|
||||
if let Some(camera) = world.cameras.get(camera_entity)
|
||||
{
|
||||
if !camera.is_active
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let forward = camera.get_forward();
|
||||
let right = camera.get_right();
|
||||
|
||||
let mut input_vec = Vec3::ZERO;
|
||||
|
||||
if input_state.w
|
||||
{
|
||||
input_vec.z += 1.0;
|
||||
}
|
||||
if input_state.s
|
||||
{
|
||||
input_vec.z -= 1.0;
|
||||
}
|
||||
if input_state.d
|
||||
{
|
||||
input_vec.x += 1.0;
|
||||
}
|
||||
if input_state.a
|
||||
{
|
||||
input_vec.x -= 1.0;
|
||||
}
|
||||
if input_state.space
|
||||
{
|
||||
input_vec.y += 1.0;
|
||||
}
|
||||
|
||||
if input_vec.length_squared() > 0.0
|
||||
{
|
||||
input_vec = input_vec.normalize();
|
||||
}
|
||||
|
||||
let mut speed = 10.0 * delta;
|
||||
if input_state.shift
|
||||
{
|
||||
speed *= 2.0;
|
||||
}
|
||||
|
||||
if let Some(camera_transform) = world.transforms.get_mut(camera_entity)
|
||||
{
|
||||
camera_transform.position += forward * input_vec.z * speed;
|
||||
camera_transform.position += right * input_vec.x * speed;
|
||||
camera_transform.position += Vec3::Y * input_vec.y * speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_camera_following(world: &mut World, camera_entity: crate::entity::EntityHandle)
|
||||
{
|
||||
if let Some(follow) = world.camera_follows.get_mut(camera_entity)
|
||||
{
|
||||
let target_entity = follow.target_entity;
|
||||
|
||||
if let Some(target_transform) = world.transforms.get(target_entity)
|
||||
{
|
||||
if let Some(camera_transform) = world.transforms.get(camera_entity)
|
||||
{
|
||||
let offset = camera_transform.position - target_transform.position;
|
||||
follow.offset = offset;
|
||||
follow.is_following = true;
|
||||
|
||||
let distance = offset.length();
|
||||
if distance > 0.0
|
||||
{
|
||||
if let Some(camera) = world.cameras.get_mut(camera_entity)
|
||||
{
|
||||
camera.pitch = (offset.y / distance).asin();
|
||||
camera.yaw = offset.z.atan2(offset.x) + std::f32::consts::PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop_camera_following(world: &mut World, camera_entity: crate::entity::EntityHandle)
|
||||
{
|
||||
if let Some(follow) = world.camera_follows.get_mut(camera_entity)
|
||||
{
|
||||
follow.is_following = false;
|
||||
|
||||
if let Some(camera_transform) = world.transforms.get(camera_entity)
|
||||
{
|
||||
if let Some(target_transform) = world.transforms.get(follow.target_entity)
|
||||
{
|
||||
let look_direction =
|
||||
(target_transform.position - camera_transform.position).normalize();
|
||||
|
||||
if let Some(camera) = world.cameras.get_mut(camera_entity)
|
||||
{
|
||||
camera.yaw = look_direction.z.atan2(look_direction.x);
|
||||
camera.pitch = look_direction.y.asin();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user