add Physics_Body and basic move_body
This commit is contained in:
parent
75b1752dba
commit
58cd083c2d
@ -1,4 +1,4 @@
|
||||
master_volume 0.15
|
||||
master_volume 0
|
||||
music_volume 1
|
||||
sfx_volume 1
|
||||
fullscreen 0
|
||||
|
||||
@ -1,2 +1,86 @@
|
||||
#load "colliders.jai";
|
||||
#load "worldphysics.jai";
|
||||
|
||||
Physics_Body :: struct {
|
||||
half_extents : Vector3;
|
||||
velocity : Vector3;
|
||||
position : Vector3;
|
||||
|
||||
// Status, don't write to these outside of the engine physics code:
|
||||
on_ground : bool;
|
||||
hit_x : bool;
|
||||
hit_y : bool;
|
||||
hit_z : bool;
|
||||
|
||||
// Config:
|
||||
prevent_falling : bool = true;
|
||||
max_step_height : float = 0.0;
|
||||
gravity : float = 20;
|
||||
downward_probe_dist : float = 0.01;
|
||||
}
|
||||
|
||||
move_body :: (body : *Physics_Body, dt: float) {
|
||||
// reset status
|
||||
body.on_ground = false;
|
||||
body.hit_x = false;
|
||||
body.hit_y = false;
|
||||
body.hit_z = false;
|
||||
|
||||
|
||||
// apply velocity XZ
|
||||
body.position.x += body.velocity.x * dt;
|
||||
if body_overlaps_solid(body) {
|
||||
body.hit_x = true;
|
||||
if body.velocity.x < 0 {
|
||||
hit_cell := floor(body.position.x - body.half_extents.x);
|
||||
body.position.x = hit_cell + 1.0 + body.half_extents.x;
|
||||
} else {
|
||||
hit_cell := floor(body.position.x + body.half_extents.x);
|
||||
body.position.x = hit_cell - body.half_extents.x;
|
||||
}
|
||||
body.velocity.x = 0;
|
||||
}
|
||||
|
||||
body.position.z+= body.velocity.z * dt;
|
||||
if body_overlaps_solid(body) {
|
||||
body.hit_z = true;
|
||||
if body.velocity.z < 0 {
|
||||
hit_cell := floor(body.position.z - body.half_extents.z);
|
||||
body.position.z = hit_cell + 1.0 + body.half_extents.z;
|
||||
} else {
|
||||
hit_cell := floor(body.position.z + body.half_extents.z);
|
||||
body.position.z = hit_cell - body.half_extents.z;
|
||||
}
|
||||
body.velocity.z = 0;
|
||||
}
|
||||
|
||||
// gravity
|
||||
probe_body := body.*;
|
||||
probe_body.position.y -= body.downward_probe_dist;
|
||||
if body.velocity.y <= 0 && body_overlaps_solid(*probe_body) {
|
||||
// Do this so we don't stutter on the ground
|
||||
body.hit_y = true;
|
||||
body.on_ground = true;
|
||||
body.velocity.y = 0;
|
||||
hit_cell := floor(probe_body.position.y - body.half_extents.y);
|
||||
body.position.y = hit_cell + 1.0 + body.half_extents.y;
|
||||
} else {
|
||||
body.velocity.y -= body.gravity * dt;
|
||||
}
|
||||
|
||||
// apply velocity Y
|
||||
body.position.y += body.velocity.y * dt;
|
||||
if body_overlaps_solid(body) {
|
||||
body.hit_y = true;
|
||||
if body.velocity.y < 0 {
|
||||
body.on_ground = true;
|
||||
hit_cell := floor(body.position.y - body.half_extents.y);
|
||||
body.position.y = hit_cell + 1.0 + body.half_extents.y;
|
||||
} else {
|
||||
hit_cell := floor(body.position.y + body.half_extents.y);
|
||||
body.position.y = hit_cell - body.half_extents.y;
|
||||
}
|
||||
body.velocity.y = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
is_trile_collision :: (fx: float, fy: float, fz: float) -> bool {
|
||||
x := cast(s32)floor(fx);
|
||||
y := cast(s32)floor(fy);
|
||||
z := cast(s32)floor(fz);
|
||||
is_cell_solid :: (x : s32, y : s32, z : s32) -> bool {
|
||||
world := get_current_world();
|
||||
if !world.valid then return false;
|
||||
|
||||
@ -12,3 +9,36 @@ is_trile_collision :: (fx: float, fy: float, fz: float) -> bool {
|
||||
lx, ly, lz := world_to_local(x, y, z);
|
||||
return chunk_get_occupancy_mask_at(chunk, lx, ly, lz) != .FREE;
|
||||
}
|
||||
|
||||
is_trile_collision :: (fx: float, fy: float, fz: float) -> bool {
|
||||
x := cast(s32)floor(fx);
|
||||
y := cast(s32)floor(fy);
|
||||
z := cast(s32)floor(fz);
|
||||
return is_cell_solid(x, y, z);
|
||||
}
|
||||
|
||||
// A little bit of leeway into collisions so we aren't jittering
|
||||
SKIN :: 0.001;
|
||||
|
||||
body_overlaps_solid :: (body : *Physics_Body) -> bool {
|
||||
max := body.position + body.half_extents;
|
||||
min := body.position - body.half_extents;
|
||||
|
||||
min_x := cast(s32)floor(min.x + SKIN);
|
||||
min_y := cast(s32)floor(min.y + SKIN);
|
||||
min_z := cast(s32)floor(min.z + SKIN);
|
||||
max_x := cast(s32)floor(max.x - SKIN);
|
||||
max_y := cast(s32)floor(max.y - SKIN);
|
||||
max_z := cast(s32)floor(max.z - SKIN);
|
||||
|
||||
for x : min_x..max_x {
|
||||
for y : min_y..max_y {
|
||||
for z : min_z..max_z {
|
||||
if is_cell_solid(x,y,z) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user