Merge branch 'dev-kinematic' of ssh://git@129.151.217.187:23/MikolajG/ttt-ce.git into dev-kinematic

# Conflicts:
#    .vscode/settings.json
#    src/player_utils/character_controller.rs
This commit is contained in:
Mikolaj Wojciech Gorski 2024-07-11 14:12:11 +02:00
commit 24bf13666f
5 changed files with 252 additions and 29 deletions

View file

@ -1,29 +0,0 @@
# The run config is used for both run mode and debug mode
[[configs]]
# the name of this task
name = "[Dev] Build and run"
# the type of the debugger. If not set, it can't be debugged but can still be run
# type = "lldb"
# the program to run
program = "nix-shell"
# the program arguments, e.g. args = ["arg1", "arg2"], optional
args = ["--run"]
# current working directory, optional
# cwd = "${workspace}"
# enviroment variables, optional
# [configs.env]
# VAR1 = "VAL1"
# VAR2 = "VAL2"
# task to run before the run/debug session is started, optional
# [configs.prelaunch]
# program = "cargo"
# args = [
# "build",
# ]

6
.vscode/launch.json vendored
View file

@ -17,6 +17,12 @@
"request": "launch",
"type": "node-terminal"
},
{
"command": "nix-shell --run 'cargo check'",
"name": "Check for errors",
"request": "launch",
"type": "node-terminal"
},
{
"type": "lldb",
"request": "launch",

View file

@ -5,5 +5,9 @@
"Substep",
"xpbd"
],
<<<<<<< HEAD
"rust-analyzer.checkOnSave": false
=======
"rust-analyzer.checkOnSave": false,
>>>>>>> branch 'dev-kinematic' of ssh://git@129.151.217.187:23/MikolajG/ttt-ce.git
}

View file

@ -31,6 +31,11 @@ lto = true
codegen-units = 1
strip = true
[build]
rustflags = ["-Z", "threads=7"]
[features]
dev = [
"bevy/dynamic_linking",

View file

@ -175,6 +175,7 @@ fn new_fall_velocity(initial_velocity: LinearVelocity, gravity: Vec3, delta_time
return result;
}
<<<<<<< HEAD
// fn move_character(
// time: Res<Time>,
// mut movement_event_reader: EventReader<MovementAction>,
@ -394,6 +395,242 @@ fn move_character(
velocity.y = character_controller.jump_impulse;
}
}
=======
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.0, 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 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 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);
>>>>>>> branch 'dev-kinematic' of ssh://git@129.151.217.187:23/MikolajG/ttt-ce.git
}
}
}