Revert "stuff I did while I was away"

This reverts commit 0fee74976c.
This commit is contained in:
Mikolaj Wojciech Gorski 2024-07-11 14:10:54 +02:00
parent 0fee74976c
commit c9159e1ebf
12 changed files with 239 additions and 298 deletions

3
.cargo/config Normal file
View file

@ -0,0 +1,3 @@
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-Clink-arg=-fuse-ld=mold"]

View file

@ -1,9 +1,9 @@
{
"rust-analyzer.debug.engine": "vadimcn.vscode-lldb",
"cSpell.words": [
"Gamepad",
"qeury",
"Substep",
"xpbd"
],
"rust-analyzer.checkOnSave": false
}

9
.vscode/tasks.json vendored
View file

@ -48,15 +48,6 @@
"--run",
"steam-run cargo fmt --all"
]
},
{
"label": "generate docs",
"type": "shell",
"command": "nix-shell",
"args": [
"--run",
"cargo doc"
]
}
]
}

12
Cargo.lock generated
View file

@ -1209,8 +1209,7 @@ dependencies = [
[[package]]
name = "bevy_xpbd_3d"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0425ea7361b9b27c2a382e0663deb42f41147eee60fb2b3d5fa7e42d363ea848"
source = "git+https://git.opencodebox.com/MikolajG/bevy_xpbd?branch=reflect-serialize#489e53505abda9649a9ee6e9de6e03a7d5801e28"
dependencies = [
"bevy",
"bevy_math",
@ -1227,9 +1226,9 @@ dependencies = [
[[package]]
name = "bevy_xpbd_derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e1ef1d5e328abe1b76df974245f78e17fd17867583883d5e77444c6a8223a64"
source = "git+https://git.opencodebox.com/MikolajG/bevy_xpbd?branch=reflect-serialize#489e53505abda9649a9ee6e9de6e03a7d5801e28"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.55",
]
@ -3707,9 +3706,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.117"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
@ -4186,7 +4185,6 @@ dependencies = [
"embed-resource",
"image",
"rand",
"serde_json",
"webbrowser",
"winit",
]

View file

@ -68,12 +68,11 @@ bevy_asset_loader = { version = "0.20" }
rand = { version = "0.8.3" }
webbrowser = { version = "0.8", features = ["hardened"] }
bevy_editor_pls = "0.8.1"
bevy_xpbd_3d = "0.4.2"
bevy_xpbd_3d = {git = "https://git.opencodebox.com/MikolajG/bevy_xpbd", branch = "reflect-serialize"}
# keep the following in sync with Bevy's dependencies
winit = { version = "0.29", default-features = false }
image = { version = "0.24", default-features = false }
serde_json = "1.0.117"
[build-dependencies]

View file

@ -1,36 +0,0 @@
/*
Trouble in Terror Town: Community Edition
Copyright (C) 2024 Mikolaj Wojciech Gorski
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License 3.0 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License 3.0 for more details.
You should have received a copy of the GNU General Public License 3.0
along with this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
*/
use bevy::prelude::*;
use serde::Deserialize;
use std::fs::*;
use std::time::{Duration, SystemTime};
#[derive(Deserialize, Clone, Debug)]
struct CharacterControllerConfig {
movement_acceleration: f32,
air_control_factor: f32,
movement_dampening_factor: f32,
jump_impulse: f32,
gravity: [f32; 3],
max_slope_angle: f32,
axis_speed_limit: f32,
max_acceleration: f32,
friction: f32,
}

View file

@ -79,7 +79,7 @@ fn setup(
commands,
meshes,
materials,
0.7,
0.5,
CharacterControllerBundle::new(Collider::capsule(1.0, 0.5), CharacterController::default()),
);
}
@ -105,9 +105,7 @@ fn spawn_map(
RigidBody::Static,
));
is_map_spawned.0 = true;
println!("map spawned!");
is_map_spawned.0 = true
}

View file

@ -34,7 +34,7 @@ fn main() {
.insert_resource(ClearColor(Color::rgb(0.4, 0.4, 0.4)))
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
title: "Trouble in Terror Town: Community Edition".to_string(), // ToDo
title: "Trouble in Terror Town: Source Crossed".to_string(), // ToDo
// Bind to canvas included in `index.html`
canvas: Some("#bevy".to_owned()),
// Tells wasm not to override default event handling, like F5 and Ctrl+R

View file

@ -37,8 +37,8 @@ pub struct CharacterControllerPlugin;
impl Plugin for CharacterControllerPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, move_character);
app.add_systems(FixedUpdate, (apply_gravity, update_grounded, dampen_movement));
app.add_systems(SubstepSchedule, collide_and_slide.in_set(SubstepSet::SolveUserConstraints));
app.add_systems(FixedUpdate, (apply_gravity, update_grounded, dampen_movement,));
app.add_systems(SubstepSchedule, kinematic_controller_collisions.in_set(SubstepSet::SolveUserConstraints));
}
}
@ -52,12 +52,10 @@ pub struct CharacterController {
pub air_control_factor: Scalar,
pub movement_dampening_factor: Scalar,
pub jump_impulse: Scalar,
/// direction in which gravity pulls the character look at [`new_fall_velocity`]
pub gravity: Vector,
pub max_slope_angle: Scalar,
pub axis_speed_limit: f32,
pub max_acceleration: f32,
/// value used for holding current calculated friction, do not change on spawn
pub friction: f32,
}
@ -67,7 +65,7 @@ impl Default for CharacterController {
movement_acceleration: 20.0,
air_control_factor: 0.5,
movement_dampening_factor: 0.95,
jump_impulse: 6.0,
jump_impulse: 4.0,
gravity: Vector::NEG_Y * 9.81 * 2.0,
max_slope_angle: (45.0 as Scalar).to_radians(),
axis_speed_limit: 6668.5,
@ -143,38 +141,212 @@ fn get_lateral_acceleration(
}
/// project a point on a plane
// function "borrowed" from UE
fn point_plane_project(point: Vec3, plane_base: Vec3, plane_normal: Vec3) -> Vec3 {
point - plane_normal * plane_normal.dot(point - plane_base)
let projection = point - plane_normal * plane_normal.dot(point - plane_base);
projection
}
/// calculating gravity, later you'll have to pass custom terminal velocity
// function "borrowed" from UE
fn new_fall_velocity(initial_velocity: LinearVelocity, gravity: Vec3, delta_time: f32, speed_limit: f32)
-> Vec3 {
let mut result: Vec3 = Vec3 { x: initial_velocity.x, y: initial_velocity.y, z: initial_velocity.z };
let terminal_velocity: f32 = 50.0;
// Apply gravity.
result += gravity * delta_time;
if delta_time > 0.0
{
// Don't exceed terminal velocity.
let terminal_limit: f32 = f32::abs(terminal_velocity); //FMath::Abs(GetPhysicsVolume()->TerminalVelocity);
if result.length_squared() > (terminal_limit * terminal_limit)
{
let gravity_dir: Vec3 = gravity.normalize();
// Apply gravity.
result += gravity * delta_time;
if result.y > terminal_limit || gravity_dir.y > terminal_limit
// Don't exceed terminal velocity.
let terminal_limit: f32 = f32::abs(terminal_velocity); //FMath::Abs(GetPhysicsVolume()->TerminalVelocity);
if result.length_squared() > (terminal_limit * terminal_limit)
{
result = point_plane_project(result, Vec3::ZERO, gravity_dir) + gravity_dir * terminal_limit;
}
}
let gravity_dir: Vec3 = gravity.normalize();
if result.y > terminal_limit || gravity_dir.y > terminal_limit
{
result = point_plane_project(result, Vec3::ZERO, gravity_dir) + gravity_dir * terminal_limit;
}
}
}
result.z = f32::clamp(result.z, -speed_limit, speed_limit);
return result;
}
fn apply_gravity(
time: Res<Time>,
mut controllers: Query<(&CharacterController, &mut LinearVelocity)>,
) {
// Precision is adjusted so that the example works with
// both the `f32` and `f64` features. Otherwise you don't need this.
let delta_time = time.delta_seconds_f64().adjust_precision();
for (character_controller, mut linear_velocity) in &mut controllers {
let mut fall_acceleration: Vec3 = get_lateral_acceleration(character_controller, delta_time, linear_velocity.0);
fall_acceleration.y = 0.0;
let has_limited_air_control: bool = false;
// Ugly fix for mismatch types, find a proper solution later
let new_velocity: Vec3 = new_fall_velocity(linear_velocity.clone(), character_controller.gravity, delta_time, character_controller.axis_speed_limit);
linear_velocity.x = new_velocity.x;
linear_velocity.y = new_velocity.y;
linear_velocity.z = new_velocity.z;
}
}
fn move_character(
time: Res<Time>,
mut movement_event_reader: EventReader<MovementAction>,
mut query: Query<(
&mut LinearVelocity,
&CharacterController,
Has<Grounded>,
&Rotation,
&ShapeHits,
&Transform,
)>,
) {
let delta_time = time.delta_seconds_f64().adjust_precision();
for event in movement_event_reader.read() {
for (
mut velocity,
character_controller,
is_grounded,
rotation,
shape_hits,
character_transform,
) in &mut query
{
character_controller.friction = f32::max(0.0f, character_controller.friction);
let forward = character_transform.forward().xyz().normalize();
match event {
MovementAction::Move(direction) => {
if is_grounded {
velocity.x = f32::clamp(velocity.x, -character_controller.axis_speed_limit, character_controller.axis_speed_limit);
velocity.y = f32::clamp(velocity.y, -character_controller.axis_speed_limit, character_controller.axis_speed_limit);
} else {
}
}
MovementAction::Jump => {
if is_grounded {
}
}
}
}
}
}
fn update_grounded(
mut commands: Commands,
mut query: Query<(Entity, &CharacterController, &Rotation, &ShapeHits)>,
) {
for (entity, character_controller, rotation, hits) in &mut query {
let is_grounded = hits.iter().any(|hit| {
let angle = rotation.rotate(-hit.normal2).angle_between(Vector::Y).abs();
println!(
"slope angle: {} / {}",
angle, character_controller.max_slope_angle
);
angle <= character_controller.max_slope_angle
});
//println!("is grounded: {}", is_grounded);
if is_grounded {
commands.entity(entity).insert(Grounded);
} else {
commands.entity(entity).remove::<Grounded>();
}
}
}
#[allow(clippy::type_complexity)]
fn kinematic_controller_collisions(
collisions: Res<Collisions>,
collider_parents: Query<&ColliderParent, Without<Sensor>>,
mut character_controllers: Query<
(
&RigidBody,
&mut Position,
&Rotation,
&mut LinearVelocity,
&CharacterController,
)
>,
) {
// Iterate through collisions and move the kinematic body to resolve penetration
for contacts in collisions.iter() {
// If the collision didn't happen during this substep, skip the collision
if !contacts.during_current_substep {
continue;
}
// Get the rigid body entities of the colliders (colliders could be children)
let Ok([collider_parent1, collider_parent2]) =
collider_parents.get_many([contacts.entity1, contacts.entity2])
else {
continue;
};
// Get the body of the character controller and whether it is the first
// or second entity in the collision.
let is_first: bool;
let (rb, mut position, rotation, mut linear_velocity, character_controller) =
if let Ok(character) = character_controllers.get_mut(collider_parent1.get()) {
is_first = true;
character
} else if let Ok(character) = character_controllers.get_mut(collider_parent2.get()) {
is_first = false;
character
} else {
continue;
};
// This system only handles collision response for kinematic character controllers
if !rb.is_kinematic() {
continue;
}
// Iterate through contact manifolds and their contacts.
// Each contact in a single manifold shares the same contact normal.
for manifold in contacts.manifolds.iter() {
let normal = if is_first {
-manifold.global_normal1(rotation)
} else {
-manifold.global_normal2(rotation)
};
// Solve each penetrating contact in the manifold
for contact in manifold.contacts.iter().filter(|c| c.penetration > 0.0) {
position.0 += normal * contact.penetration;
}
// If the slope isn't too steep to walk on but the character
// is falling, reset vertical velocity.
if normal.angle_between(Vector::Y).abs() <= character_controller.max_slope_angle
&& linear_velocity.y < 0.0
{
linear_velocity.y = linear_velocity.y.max(0.0);
}
}
}
}
// fn move_character(
// time: Res<Time>,
// mut movement_event_reader: EventReader<MovementAction>,
@ -199,21 +371,47 @@ fn new_fall_velocity(initial_velocity: LinearVelocity, gravity: Vec3, delta_time
// character_transform,
// ) in &mut query
// {
// character_controller.friction = f32::max(0.0f, character_controller.friction);
// let forward = character_transform.forward().xyz().normalize();
// match event {
// MovementAction::Move(direction) => {
// if is_grounded {
// velocity.x = f32::clamp(velocity.x, -character_controller.axis_speed_limit, character_controller.axis_speed_limit);
// velocity.y = f32::clamp(velocity.y, -character_controller.axis_speed_limit, character_controller.axis_speed_limit);
// } else {
// // Get the forward direction of the character in the local coordinate system
// let forward = character_transform.forward().xyz().normalize();
// // Calculate the movement in the local coordinate system
// let local_movement = forward
// * direction.y
// * character_controller.movement_acceleration
// * delta_time
// + character_transform
// .rotation
// .mul_vec3(Vec3::new(direction.x, 0.0, 0.0))
// * character_controller.movement_acceleration
// * delta_time;
// if is_grounded {
// let mut slope_factor = 1.0;
// for hit in shape_hits.iter() {
// let angle =
// rotation.rotate(-hit.normal2).angle_between(Vector::Y).abs();
// if angle <= character_controller.max_slope_angle {
// slope_factor *=
// (angle / character_controller.max_slope_angle).cos();
// // Update linear velocity
// velocity.x += local_movement.x * slope_factor;
// velocity.z += local_movement.z * slope_factor;
// } else {
// velocity.x = 0.0;
// velocity.z = 0.0;
// }
// }
// } else {
// velocity.x += local_movement.x * character_controller.air_control_factor;
// velocity.z += local_movement.z * character_controller.air_control_factor;
// }
// }
// MovementAction::Jump => {
// if is_grounded {
// velocity.y = character_controller.jump_impulse;
// }
// }
// }
@ -221,184 +419,6 @@ fn new_fall_velocity(initial_velocity: LinearVelocity, gravity: Vec3, delta_time
// }
// }
fn apply_gravity(
time: Res<Time>,
mut controllers: Query<(&CharacterController, &mut LinearVelocity)>,
) {
let delta_time = time.delta_seconds_f64().adjust_precision();
for (character_controller, mut linear_velocity) in &mut controllers {
let new_velocity = new_fall_velocity(
*linear_velocity,
character_controller.gravity,
delta_time,
character_controller.axis_speed_limit,
);
linear_velocity.0 = new_velocity;
}
}
fn update_grounded(
mut commands: Commands,
mut query: Query<(Entity, &CharacterController, &Rotation, &ShapeHits)>,
) {
for (entity, character_controller, rotation, hits) in &mut query {
let is_grounded = hits.iter().any(|hit| {
let angle = rotation.rotate(-hit.normal2).angle_between(Vector::Y).abs();
angle <= character_controller.max_slope_angle
});
if is_grounded {
commands.entity(entity).insert(Grounded);
} else {
commands.entity(entity).remove::<Grounded>();
}
}
}
#[allow(clippy::type_complexity)]
fn collide_and_slide(
collisions: Res<Collisions>,
collider_parents: Query<&ColliderParent, Without<Sensor>>,
mut character_controllers: Query<
(
&RigidBody,
&mut Position,
&Rotation,
&mut LinearVelocity,
&CharacterController,
)
>,
) {
for contacts in collisions.iter() {
if !contacts.during_current_substep {
continue;
}
let Ok([collider_parent1, collider_parent2]) =
collider_parents.get_many([contacts.entity1, contacts.entity2])
else {
continue;
};
let is_first: bool;
let (rb, mut position, rotation, mut linear_velocity, character_controller) =
if let Ok(character) = character_controllers.get_mut(collider_parent1.get()) {
is_first = true;
character
} else if let Ok(character) = character_controllers.get_mut(collider_parent2.get()) {
is_first = false;
character
} else {
continue;
};
// This system only handles collision response for kinematic character controllers
if !rb.is_kinematic() {
continue;
}
// Iterate through contact manifolds and their contacts.
// Each contact in a single manifold shares the same contact normal.
for manifold in contacts.manifolds.iter() {
// Determine the normal of the collision based on which entity the character is
let normal = if is_first {
-manifold.global_normal1(rotation)
} else {
-manifold.global_normal2(rotation)
};
// Resolve penetration by moving the position out of the collision
for contact in manifold.contacts.iter().filter(|c| c.penetration > 0.0) {
position.0 += normal * contact.penetration;
}
// If the slope isn't too steep to walk on but the character is falling, reset vertical velocity.
if normal.angle_between(Vector::Y).abs() <= character_controller.max_slope_angle
&& linear_velocity.y < 0.0
{
// Stop downward velocity to prevent sliding down walkable slopes
linear_velocity.y = linear_velocity.y.max(0.0);
}
}
}
}
fn move_character(
time: Res<Time>,
mut movement_event_reader: EventReader<MovementAction>,
mut query: Query<(
&mut LinearVelocity,
&CharacterController,
Has<Grounded>,
&Rotation,
&ShapeHits,
&Transform,
)>,
) {
let delta_time = time.delta_seconds_f64().adjust_precision();
for event in movement_event_reader.read() {
for (
mut velocity,
character_controller,
is_grounded,
rotation,
shape_hits,
character_transform,
) in &mut query
{
match event {
MovementAction::Move(direction) => {
// Get the forward direction of the character in the local coordinate system
let forward = character_transform.forward().xyz().normalize();
// Calculate the movement in the local coordinate system
let local_movement = forward
* direction.y
* character_controller.movement_acceleration
* delta_time
+ character_transform
.rotation
.mul_vec3(Vec3::new(direction.x, 0.0, 0.0))
* character_controller.movement_acceleration
* delta_time;
if is_grounded {
let mut slope_factor = 1.0;
for hit in shape_hits.iter() {
let angle =
rotation.rotate(-hit.normal2).angle_between(Vector::Y).abs();
if angle <= character_controller.max_slope_angle {
slope_factor *=
(angle / character_controller.max_slope_angle).cos();
// Update linear velocity
velocity.x += local_movement.x * slope_factor;
velocity.z += local_movement.z * slope_factor;
} else {
velocity.x = 0.0;
velocity.z = 0.0;
}
}
} else {
velocity.x += local_movement.x * character_controller.air_control_factor;
velocity.z += local_movement.z * character_controller.air_control_factor;
}
}
MovementAction::Jump => {
if is_grounded {
velocity.y = character_controller.jump_impulse;
}
}
}
}
}
}
fn dampen_movement(mut qeury: Query<(&mut LinearVelocity, &CharacterController)>) {
for (mut velocity, character_controller) in &mut qeury {
// We could use `LinearDamping`, but we don't want to dampen movement along the Y axis
@ -428,12 +448,6 @@ pub fn spawn_player(
parent.spawn((
PlayerCamera::default(),
Camera3dBundle {
projection: PerspectiveProjection {
// We must specify the FOV in radians.
// Rust can convert degrees to radians for us.
fov: 90.0_f32.to_radians(),
..default()
}.into(),
transform: Transform::from_xyz(0., camera_hight, 0.),
..default()
},

View file

@ -82,13 +82,13 @@ fn rotate_camera(
camera.rotation_limit_top,
);
let x_rotation = Quat::from_axis_angle(Vec3::X, camera.rotation.x);
//info!("{}", x_rotation);
info!("{}", x_rotation);
transform.rotation = x_rotation;
camera.rotation.y -= event.delta.x * camera.mouse_gain;
let y_rotation = Quat::from_axis_angle(Vec3::Y, camera.rotation.y);
//info!("{}", y_rotation);
info!("{}", y_rotation);
rotatable.rotation = y_rotation;
}

View file

@ -1 +0,0 @@
mod gun_framework;

View file

@ -1,25 +0,0 @@
use bevy::prelude::*;
enum GunType {
MachineGun,
SMG,
Pistol,
Rifle,
}
#[derive(Component)]
struct GunStats {
gun_type: GunType,
}
pub trait GunUtils {
fn shoot(&mut self);
fn reload(&mut self);
fn get_ammo_count(&self) -> u32;
}
pub struct GunBase {
gun_stats: GunStats,
gun_utils: dyn GunUtils,
}