rework vehicle driving model
parent
3cda4cc334
commit
936658056a
|
@ -66,8 +66,8 @@ void platform_input() {
|
||||||
uint8_t use, sprint;
|
uint8_t use, sprint;
|
||||||
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f;
|
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f;
|
||||||
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f;
|
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f;
|
||||||
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y -= 1.0f;
|
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y += 1.0f;
|
||||||
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y += 1.0f;
|
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y -= 1.0f;
|
||||||
|
|
||||||
use = IsKeyPressed(KEY_SPACE);
|
use = IsKeyPressed(KEY_SPACE);
|
||||||
sprint = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
|
sprint = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
|
||||||
|
|
|
@ -11,6 +11,9 @@ uint64_t vehicle_spawn(void) {
|
||||||
Vehicle *veh = ecs_get_mut(world_ecs(), e, Vehicle, NULL);
|
Vehicle *veh = ecs_get_mut(world_ecs(), e, Vehicle, NULL);
|
||||||
zpl_zero_item(veh);
|
zpl_zero_item(veh);
|
||||||
veh->wheel_base = 50.0f;
|
veh->wheel_base = 50.0f;
|
||||||
|
veh->speed = 50.0f;
|
||||||
|
veh->reverse_speed = -20.0f;
|
||||||
|
veh->force = 0.0f;
|
||||||
return (uint64_t)e;
|
return (uint64_t)e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,9 @@ ECS_STRUCT(Vehicle, {
|
||||||
float heading;
|
float heading;
|
||||||
float steer;
|
float steer;
|
||||||
float wheel_base;
|
float wheel_base;
|
||||||
|
|
||||||
|
float speed;
|
||||||
|
float reverse_speed;
|
||||||
});
|
});
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -136,9 +136,6 @@ void SystemsImport(ecs_world_t *ecs) {
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.EcsDemoNPC);
|
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.EcsDemoNPC);
|
||||||
ECS_SYSTEM(ecs, EnterVehicle, EcsOnLoad, components.Input, components.Position, !components.IsInVehicle);
|
|
||||||
ECS_SYSTEM(ecs, LeaveVehicle, EcsOnLoad, components.Input, components.IsInVehicle);
|
|
||||||
ECS_SYSTEM(ecs, DemoPlaceIceBlock, EcsOnLoad, components.Input, components.Position, !components.IsInVehicle);
|
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity);
|
||||||
ECS_SYSTEM(ecs, HurtOnHazardBlock, EcsOnUpdate, components.Position, components.Health);
|
ECS_SYSTEM(ecs, HurtOnHazardBlock, EcsOnUpdate, components.Position, components.Health);
|
||||||
|
@ -147,6 +144,10 @@ void SystemsImport(ecs_world_t *ecs) {
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
||||||
|
|
||||||
|
ECS_SYSTEM(ecs, EnterVehicle, EcsPostUpdate, components.Input, components.Position, !components.IsInVehicle);
|
||||||
|
ECS_SYSTEM(ecs, LeaveVehicle, EcsPostUpdate, components.Input, components.IsInVehicle, components.Velocity);
|
||||||
|
ECS_SYSTEM(ecs, DemoPlaceIceBlock, EcsPostUpdate, components.Input, components.Position, !components.IsInVehicle);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, components.Position, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
||||||
|
|
|
@ -11,6 +11,6 @@ void MovementImpulse(ecs_iter_t *it) {
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
||||||
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
||||||
v[i].x += in[i].x*speed*drag;
|
v[i].x += in[i].x*speed*drag;
|
||||||
v[i].y += in[i].y*speed*drag;
|
v[i].y -= in[i].y*speed*drag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
void LeaveVehicle(ecs_iter_t *it) {
|
void LeaveVehicle(ecs_iter_t *it) {
|
||||||
Input *in = ecs_column(it, Input, 1);
|
Input *in = ecs_column(it, Input, 1);
|
||||||
IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2);
|
IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2);
|
||||||
|
Velocity *v = ecs_column(it, Velocity, 3);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (!in[i].use) continue;
|
if (!in[i].use) continue;
|
||||||
|
@ -20,6 +21,14 @@ void LeaveVehicle(ecs_iter_t *it) {
|
||||||
|
|
||||||
in[i].use = false;
|
in[i].use = false;
|
||||||
ecs_remove(it->world, it->entities[i], IsInVehicle);
|
ecs_remove(it->world, it->entities[i], IsInVehicle);
|
||||||
|
|
||||||
|
// NOTE(zaklaus): push passenger out
|
||||||
|
{
|
||||||
|
float px = zpl_sin(veh->heading)*400.0f;
|
||||||
|
float py = zpl_cos(veh->heading)*400.0f;
|
||||||
|
v->x += px;
|
||||||
|
v->y += py;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ZPL_PANIC("unreachable code");
|
ZPL_PANIC("unreachable code");
|
||||||
}
|
}
|
||||||
|
@ -64,10 +73,10 @@ void EnterVehicle(ecs_iter_t *it) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VEHICLE_FORCE 34.8f
|
#define VEHICLE_FORCE 34.8f
|
||||||
#define VEHICLE_ACCEL 0.27f
|
#define VEHICLE_ACCEL 0.02f
|
||||||
#define VEHICLE_DECEL 0.28f
|
#define VEHICLE_DECEL 0.28f
|
||||||
#define VEHICLE_STEER 0.11f
|
#define VEHICLE_STEER 0.09f
|
||||||
#define VEHICLE_STEER_MUL 0.087f
|
#define VEHICLE_BRAKE_FORCE 0.04f
|
||||||
|
|
||||||
void VehicleHandling(ecs_iter_t *it) {
|
void VehicleHandling(ecs_iter_t *it) {
|
||||||
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
||||||
|
@ -78,7 +87,6 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
Vehicle *car = &veh[i];
|
Vehicle *car = &veh[i];
|
||||||
|
|
||||||
// NOTE(zaklaus): Apply friction
|
// NOTE(zaklaus): Apply friction
|
||||||
car->force = zpl_lerp(car->force, 0.0f, VEHICLE_DECEL);
|
|
||||||
car->steer *= 0.97f;
|
car->steer *= 0.97f;
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
|
@ -90,26 +98,24 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
|
|
||||||
ecs_entity_t pe = veh[i].seats[j];
|
ecs_entity_t pe = veh[i].seats[j];
|
||||||
|
|
||||||
// NOTE(zaklaus): Update passenger position
|
|
||||||
{
|
|
||||||
Position *p2 = ecs_get_mut(it->world, pe, Position, NULL);
|
|
||||||
Velocity *v2 = ecs_get_mut(it->world, pe, Velocity, NULL);
|
|
||||||
*p2 = p[i];
|
|
||||||
*v2 = v[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(zaklaus): Handle driver input
|
// NOTE(zaklaus): Handle driver input
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
Input const* in = ecs_get(it->world, pe, Input);
|
Input const* in = ecs_get(it->world, pe, Input);
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
|
||||||
|
|
||||||
car->force += zpl_lerp(0.0f, in->y * VEHICLE_FORCE, VEHICLE_ACCEL) * drag;
|
car->force += zpl_lerp(0.0f, in->y * VEHICLE_FORCE, VEHICLE_ACCEL);
|
||||||
car->steer += in->x * -VEHICLE_STEER;
|
if (in->sprint) {
|
||||||
|
car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE);
|
||||||
|
|
||||||
|
if (zpl_abs(car->force) < 5.5f)
|
||||||
|
car->force = 0.0f;
|
||||||
|
}
|
||||||
|
car->steer += in->x * VEHICLE_STEER;
|
||||||
car->steer = zpl_clamp(car->steer, -40.0f, 40.0f);
|
car->steer = zpl_clamp(car->steer, -40.0f, 40.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
car->force = zpl_clamp(car->force, car->reverse_speed, car->speed);
|
||||||
|
|
||||||
// NOTE(zaklaus): Vehicle physics
|
// NOTE(zaklaus): Vehicle physics
|
||||||
float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
||||||
float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
||||||
|
@ -117,15 +123,31 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
||||||
float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
||||||
|
|
||||||
bk_x += car->force * zpl_cos(car->heading);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||||
bk_y += car->force * zpl_sin(car->heading);
|
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
||||||
fr_x += car->force * zpl_cos(car->heading + zpl_to_radians(car->steer));
|
|
||||||
fr_y += car->force * zpl_sin(car->heading + zpl_to_radians(car->steer));
|
bk_x += car->force * drag * zpl_cos(car->heading);
|
||||||
|
bk_y += car->force * drag * zpl_sin(car->heading);
|
||||||
|
fr_x += car->force * drag * zpl_cos(car->heading + zpl_to_radians(car->steer));
|
||||||
|
fr_y += car->force * drag * zpl_sin(car->heading + zpl_to_radians(car->steer));
|
||||||
|
|
||||||
v[i].x += (fr_x + bk_x) / 2.0f - p[i].x;
|
v[i].x += (fr_x + bk_x) / 2.0f - p[i].x;
|
||||||
v[i].y += (fr_y + bk_y) / 2.0f - p[i].y;
|
v[i].y += (fr_y + bk_y) / 2.0f - p[i].y;
|
||||||
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (!world_entity_valid(veh[i].seats[j])) continue;
|
||||||
|
ecs_entity_t pe = veh[i].seats[j];
|
||||||
|
|
||||||
|
// NOTE(zaklaus): Update passenger position
|
||||||
|
{
|
||||||
|
Position *p2 = ecs_get_mut(it->world, pe, Position, NULL);
|
||||||
|
Velocity *v2 = ecs_get_mut(it->world, pe, Velocity, NULL);
|
||||||
|
*p2 = p[i];
|
||||||
|
*v2 = v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
|
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
|
||||||
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
|
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
|
||||||
|
|
Loading…
Reference in New Issue