better impulse & force application
This commit is contained in:
parent
0ed2a403dc
commit
10c9c833ba
@ -111,6 +111,7 @@ INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
|
|||||||
|
|
||||||
struct entity *entity_alloc(struct entity *parent)
|
struct entity *entity_alloc(struct entity *parent)
|
||||||
{
|
{
|
||||||
|
ASSERT(parent->valid);
|
||||||
struct entity_store *store = entity_get_store(parent);
|
struct entity_store *store = entity_get_store(parent);
|
||||||
struct entity *e = entity_alloc_internal(store);
|
struct entity *e = entity_alloc_internal(store);
|
||||||
entity_link_parent(e, parent);
|
entity_link_parent(e, parent);
|
||||||
@ -137,7 +138,9 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
|
|||||||
|
|
||||||
void entity_release(struct entity_store *store, struct entity *ent)
|
void entity_release(struct entity_store *store, struct entity *ent)
|
||||||
{
|
{
|
||||||
entity_unlink_parent(ent);
|
if (ent->parent.gen) {
|
||||||
|
entity_unlink_parent(ent);
|
||||||
|
}
|
||||||
entity_release_internal(store, ent);
|
entity_release_internal(store, ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
src/entity.h
13
src/entity.h
@ -90,32 +90,23 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Control */
|
/* Control */
|
||||||
|
|
||||||
|
f32 control_move_force; /* How much force is applied to achieve desired control movement */
|
||||||
struct {
|
struct {
|
||||||
struct v2 move;
|
struct v2 move;
|
||||||
struct v2 focus;
|
struct v2 focus;
|
||||||
} control;
|
} control;
|
||||||
|
|
||||||
/* ====================================================================== */
|
|
||||||
/* Player control */
|
|
||||||
|
|
||||||
/* ENTITY_PROP_PLAYER_CONTROLLED */
|
|
||||||
f32 player_max_speed;
|
|
||||||
f32 player_acceleration;
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Physics */
|
/* Physics */
|
||||||
|
|
||||||
/* ENTITY_PROP_PHYSICAL */
|
/* ENTITY_PROP_PHYSICAL */
|
||||||
|
|
||||||
f32 density;
|
f32 density;
|
||||||
|
f32 ground_friction;
|
||||||
|
|
||||||
/* Xform of the entity from the previous frame (used to calculate velocity) */
|
/* Xform of the entity from the previous frame (used to calculate velocity) */
|
||||||
struct xform verlet_xform;
|
struct xform verlet_xform;
|
||||||
|
|
||||||
/* Calculated */
|
|
||||||
struct v2 final_velocity;
|
|
||||||
struct v2 final_acceleration;
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Impulse */
|
/* Impulse */
|
||||||
|
|
||||||
|
|||||||
196
src/game.c
196
src/game.c
@ -124,9 +124,10 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->sprite_span_name = STR("idle.two_handed");
|
e->sprite_span_name = STR("idle.two_handed");
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
e->player_max_speed = 4.f;
|
e->control_move_force = 50;
|
||||||
e->player_acceleration = 20;
|
|
||||||
e->control.focus = V2(0, -1);
|
e->control.focus = V2(0, -1);
|
||||||
|
e->ground_friction = 12;
|
||||||
|
e->density = 1.0;
|
||||||
|
|
||||||
player_ent = e;
|
player_ent = e;
|
||||||
|
|
||||||
@ -477,7 +478,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -528,120 +528,101 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
struct v2 move = ent->control.move;
|
struct v2 move = ent->control.move;
|
||||||
if (!v2_eq(move, V2(0, 0))) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
struct xform xf = entity_get_xform(ent);
|
|
||||||
|
|
||||||
struct v2 tick_velocity = v2_sub(xf.og, ent->verlet_xform.og);
|
|
||||||
|
|
||||||
/* Player movement */
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
|
||||||
f32 max_speed = ent->player_max_speed;
|
|
||||||
f32 acceleration_rate = ent->player_acceleration;
|
|
||||||
acceleration_rate = clamp_f32(acceleration_rate, 0, GAME_FPS); /* Can't integrate acceleration rate higher than FPS */
|
|
||||||
struct v2 target_velocity = v2_mul(ent->control.move, max_speed);
|
|
||||||
struct v2 target_acceleration = v2_sub(target_velocity, v2_div(tick_velocity, dt));
|
|
||||||
struct v2 acceleration = v2_mul(target_acceleration, acceleration_rate);
|
|
||||||
|
|
||||||
/* Create force */
|
|
||||||
struct entity *f = entity_alloc(ent);
|
|
||||||
entity_enable_prop(f, ENTITY_PROP_FORCE);
|
|
||||||
f->force = acceleration;
|
|
||||||
activate_now(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Create constant forces
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
/* TODO: Just do this in simulation processing */
|
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
|
||||||
struct entity *ent = &store->entities[entity_index];
|
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
|
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
|
||||||
struct v2 velocity = v2_div(v2_sub(xf.og, ent->verlet_xform.og), dt);
|
|
||||||
|
|
||||||
/* Ground friction */
|
|
||||||
{
|
|
||||||
struct entity *f = entity_alloc(ent);
|
struct entity *f = entity_alloc(ent);
|
||||||
|
|
||||||
f32 force_len = -v2_len(velocity) * 8;
|
|
||||||
|
|
||||||
entity_enable_prop(f, ENTITY_PROP_FORCE);
|
entity_enable_prop(f, ENTITY_PROP_FORCE);
|
||||||
f->force = v2_mul(v2_norm(velocity), force_len);
|
f->force = v2_mul(move, ent->control_move_force);
|
||||||
|
|
||||||
activate_now(f);
|
activate_now(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Apply impulses to verlet xform
|
* Create ground friction force
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
/* TODO: Do this globally rather than creating entities for constant forces */
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
|
||||||
|
if (ent->ground_friction != 0) {
|
||||||
|
struct xform verlet_xform = ent->verlet_xform;
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
struct v2 velocity = v2_div(v2_sub(xf.og, verlet_xform.og), dt);
|
||||||
|
|
||||||
/* FIXME: Why does marking all ents with ENTITY_PROP_RELEASE here raise exception */
|
/* Ground friction */
|
||||||
|
if (!v2_eq(velocity, V2(0, 0))) {
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_IMPULSE)) {
|
/* FIXME: Incorrect behavior at low FPS & low entity density */
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
const f32 clamp_epsilon = 0.025;
|
||||||
if (entity_has_prop(parent, ENTITY_PROP_ACTIVE)) {
|
f32 velocity_len = v2_len(velocity);
|
||||||
struct v2 tick_velocity = v2_mul(ent->impulse, dt);
|
if (velocity_len >= clamp_epsilon) {
|
||||||
parent->verlet_xform.og = v2_sub(parent->verlet_xform.og, tick_velocity);
|
f32 force_len = -velocity_len * ent->ground_friction;
|
||||||
entity_enable_prop(ent, ENTITY_PROP_RELEASE);
|
struct entity *force = entity_alloc(ent);
|
||||||
|
entity_enable_prop(force, ENTITY_PROP_FORCE);
|
||||||
|
force->force = v2_mul(v2_norm(velocity), force_len);
|
||||||
|
activate_now(force);
|
||||||
|
} else {
|
||||||
|
/* If velocity is below clamp_epsilon, stop entity movement. */
|
||||||
|
struct entity *impulse = entity_alloc(ent);
|
||||||
|
entity_enable_prop(impulse, ENTITY_PROP_IMPULSE);
|
||||||
|
impulse->impulse = v2_neg(velocity);
|
||||||
|
activate_now(impulse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Apply forces to verlet xform
|
* Simulate physics
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
|
||||||
struct entity *ent = &store->entities[entity_index];
|
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
|
||||||
|
|
||||||
f32 density = ent->density;
|
|
||||||
f32 mass = density; /* TODO: Real mass calculation */
|
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_FORCE)) {
|
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
|
||||||
if (entity_has_prop(parent, ENTITY_PROP_ACTIVE)) {
|
|
||||||
struct v2 acceleration = v2_div(ent->force, mass);
|
|
||||||
struct v2 tick_acceleration = v2_mul(acceleration, dt * dt);
|
|
||||||
parent->verlet_xform.og = v2_sub(parent->verlet_xform.og, tick_acceleration);
|
|
||||||
entity_enable_prop(ent, ENTITY_PROP_RELEASE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Simulate entity physics
|
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* TODO: Run physics on top-level entities, and then calculate child xforms as part of physics step (rather than caching at each xform_get). */
|
/* TODO: Run physics on top-level entities, and then calculate child xforms as part of physics step (rather than caching at each xform_get). */
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
|
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
||||||
|
f32 density = ent->density;
|
||||||
|
f32 mass = density; /* TODO: Real mass calculation */
|
||||||
|
|
||||||
|
struct v2 acceleration = V2(0, 0);
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
/* Apply impulses */
|
||||||
|
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
|
||||||
|
if (entity_has_prop(child, ENTITY_PROP_IMPULSE)) {
|
||||||
|
acceleration = v2_add(acceleration, child->impulse);
|
||||||
|
entity_enable_prop(child, ENTITY_PROP_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate velocity from old position */
|
/* Apply forces */
|
||||||
struct v2 tick_velocity = V2(0, 0);
|
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
|
||||||
{
|
if (entity_has_prop(child, ENTITY_PROP_FORCE)) {
|
||||||
tick_velocity = v2_sub(xf.og, ent->verlet_xform.og);
|
struct v2 force_acceleration = v2_mul(v2_div(child->force, mass), dt);
|
||||||
|
acceleration = v2_add(acceleration, force_acceleration);
|
||||||
|
entity_enable_prop(child, ENTITY_PROP_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verlet integration */
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
struct v2 tick_velocity = v2_sub(xf.og, ent->verlet_xform.og);
|
||||||
ent->verlet_xform = xf;
|
ent->verlet_xform = xf;
|
||||||
|
xf.og = v2_add(xf.og, v2_add(tick_velocity, v2_mul(acceleration, dt)));
|
||||||
|
entity_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Player aim
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
|
struct entity *ent = &store->entities[entity_index];
|
||||||
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
/* Player angle */
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|
||||||
/* Solve for final angle using law of sines */
|
/* Solve for final angle using law of sines */
|
||||||
f32 final_xf_angle;
|
f32 final_xf_angle;
|
||||||
{
|
{
|
||||||
@ -693,52 +674,22 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
xf = xform_with_rotation(xf, final_xf_angle);
|
xf = xform_with_rotation(xf, final_xf_angle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply velocity */
|
|
||||||
xf.og = v2_add(xf.og, tick_velocity);
|
|
||||||
|
|
||||||
ent->final_velocity = v2_div(tick_velocity, dt);
|
|
||||||
ent->final_acceleration = v2_div(v2_sub(v2_sub(xf.og, ent->verlet_xform.og), tick_velocity), dt);
|
|
||||||
entity_set_xform(ent, xf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Initialize bullet kinematics from sources
|
* Initialize bullet kinematics from sources
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
|
||||||
struct entity *ent = &store->entities[entity_index];
|
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
|
||||||
|
|
||||||
/* FIXME: Apply src entity velocity to bullet velocity */
|
|
||||||
/* TODO: Use impulse */
|
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_BULLET) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
|
||||||
struct entity *src = entity_from_handle(store, ent->bullet_src);
|
|
||||||
struct xform src_xf = entity_get_xform(src);
|
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(src_xf, ent->bullet_src_pos);
|
|
||||||
struct v2 vec = xform_basis_mul_v2(src_xf, ent->bullet_src_dir);
|
|
||||||
vec = v2_mul(v2_norm(vec), ent->bullet_impulse);
|
|
||||||
|
|
||||||
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(vec) + PI / 2);
|
|
||||||
entity_set_xform(ent, xf);
|
|
||||||
|
|
||||||
ent->verlet_xform = XFORM_POS(v2_sub(pos, v2_mul(vec, dt)));
|
|
||||||
|
|
||||||
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
|
|
||||||
/* FIXME: Apply src entity velocity to bullet velocity */
|
/* FIXME: Apply src entity velocity to bullet velocity */
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_BULLET) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
if (entity_has_prop(ent, ENTITY_PROP_BULLET) && ent->activation_tick == G.tick.tick_id) {
|
||||||
struct entity *src = entity_from_handle(store, ent->bullet_src);
|
struct entity *src = entity_from_handle(store, ent->bullet_src);
|
||||||
struct xform src_xf = entity_get_xform(src);
|
struct xform src_xf = entity_get_xform(src);
|
||||||
|
|
||||||
@ -749,7 +700,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(velocity) + PI / 2);
|
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(velocity) + PI / 2);
|
||||||
entity_set_xform(ent, xf);
|
entity_set_xform(ent, xf);
|
||||||
ent->verlet_xform = xf;
|
ent->verlet_xform = xf;
|
||||||
|
|
||||||
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL);
|
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL);
|
||||||
|
|
||||||
/* Create impulse */
|
/* Create impulse */
|
||||||
@ -758,7 +708,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
entity_enable_prop(impulse, ENTITY_PROP_IMPULSE);
|
entity_enable_prop(impulse, ENTITY_PROP_IMPULSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update camera position
|
* Update camera position
|
||||||
@ -857,7 +806,10 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (u64 i = 0; i < ents_to_release_count; ++i) {
|
for (u64 i = 0; i < ents_to_release_count; ++i) {
|
||||||
entity_release(store, ents_to_release[i]);
|
struct entity *ent = ents_to_release[i];
|
||||||
|
if (ent->valid) {
|
||||||
|
entity_release(store, ent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arena_temp_end(temp);
|
arena_temp_end(temp);
|
||||||
|
|||||||
15
src/user.c
15
src/user.c
@ -381,16 +381,14 @@ INTERNAL void debug_draw_movement(struct entity *ent)
|
|||||||
f32 arrow_len = 15.f;
|
f32 arrow_len = 15.f;
|
||||||
|
|
||||||
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
||||||
u32 color_acc = RGBA_32_F(1, 1, 0.5, 1);
|
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
struct v2 velocity = v2_div(v2_sub(xf.og, ent->verlet_xform.og), G.world.dt);
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(G.world_view, xf.og);
|
struct v2 pos = xform_mul_v2(G.world_view, xf.og);
|
||||||
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, ent->final_velocity);
|
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, velocity);
|
||||||
struct v2 acc_ray = xform_basis_mul_v2(G.world_view, ent->final_acceleration);
|
|
||||||
|
|
||||||
draw_solid_arrow_ray(G.viewport_canvas, pos, vel_ray, thickness, arrow_len, color_vel);
|
draw_solid_arrow_ray(G.viewport_canvas, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||||
draw_solid_arrow_ray(G.viewport_canvas, pos, acc_ray, thickness, arrow_len, color_acc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void user_update(void)
|
INTERNAL void user_update(void)
|
||||||
@ -443,6 +441,7 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Blend world globals */
|
/* Blend world globals */
|
||||||
G.world.time = math_lerp64(t0->time, t1->time, (f64)tick_blend);
|
G.world.time = math_lerp64(t0->time, t1->time, (f64)tick_blend);
|
||||||
|
G.world.dt = math_lerp64(t0->dt, t1->dt, (f64)tick_blend);
|
||||||
|
|
||||||
/* Blend entities */
|
/* Blend entities */
|
||||||
u64 num_entities = min_u64(t0->entity_store->reserved, t1->entity_store->reserved);
|
u64 num_entities = min_u64(t0->entity_store->reserved, t1->entity_store->reserved);
|
||||||
@ -466,10 +465,8 @@ INTERNAL void user_update(void)
|
|||||||
e->cached_global_xform = xform_lerp(e0->cached_global_xform, e1->cached_global_xform, tick_blend);
|
e->cached_global_xform = xform_lerp(e0->cached_global_xform, e1->cached_global_xform, tick_blend);
|
||||||
|
|
||||||
e->verlet_xform = xform_lerp(e0->verlet_xform, e1->verlet_xform, tick_blend);
|
e->verlet_xform = xform_lerp(e0->verlet_xform, e1->verlet_xform, tick_blend);
|
||||||
e->final_acceleration = v2_lerp(e0->final_acceleration, e1->final_acceleration, tick_blend);
|
|
||||||
e->final_velocity = v2_lerp(e0->final_velocity, e1->final_velocity, tick_blend);
|
|
||||||
|
|
||||||
e->player_acceleration = math_lerp(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
e->control_move_force = math_lerp(e0->control_move_force, e1->control_move_force, tick_blend);
|
||||||
|
|
||||||
e->control.move = v2_lerp(e0->control.move, e1->control.move, tick_blend);
|
e->control.move = v2_lerp(e0->control.move, e1->control.move, tick_blend);
|
||||||
e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, tick_blend);
|
e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, tick_blend);
|
||||||
@ -896,7 +893,9 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug_draw_movement(ent);
|
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) {
|
||||||
|
debug_draw_movement(ent);
|
||||||
|
}
|
||||||
|
|
||||||
if (!skip_debug_draw_transform) {
|
if (!skip_debug_draw_transform) {
|
||||||
debug_draw_xform(xf);
|
debug_draw_xform(xf);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user