203 lines
6.0 KiB
Rust
203 lines
6.0 KiB
Rust
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|