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
|
music_volume 1
|
||||||
sfx_volume 1
|
sfx_volume 1
|
||||||
fullscreen 0
|
fullscreen 0
|
||||||
|
|||||||
@ -1,2 +1,86 @@
|
|||||||
#load "colliders.jai";
|
#load "colliders.jai";
|
||||||
#load "worldphysics.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 {
|
is_cell_solid :: (x : s32, y : s32, z : s32) -> bool {
|
||||||
x := cast(s32)floor(fx);
|
|
||||||
y := cast(s32)floor(fy);
|
|
||||||
z := cast(s32)floor(fz);
|
|
||||||
world := get_current_world();
|
world := get_current_world();
|
||||||
if !world.valid then return false;
|
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);
|
lx, ly, lz := world_to_local(x, y, z);
|
||||||
return chunk_get_occupancy_mask_at(chunk, lx, ly, lz) != .FREE;
|
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