tracer beginnings
This commit is contained in:
parent
e70047f763
commit
a00798fc7a
16
src/entity.h
16
src/entity.h
@ -10,8 +10,8 @@ enum entity_prop {
|
|||||||
|
|
||||||
ENTITY_PROP_ACTIVE,
|
ENTITY_PROP_ACTIVE,
|
||||||
|
|
||||||
ENTITY_PROP_RELEASE_BEFORE_PUBLISH,
|
ENTITY_PROP_RELEASE_THIS_TICK,
|
||||||
ENTITY_PROP_RELEASE_AFTER_PUBLISH,
|
ENTITY_PROP_RELEASE_NEXT_TICK,
|
||||||
|
|
||||||
ENTITY_PROP_PHYSICAL_DYNAMIC,
|
ENTITY_PROP_PHYSICAL_DYNAMIC,
|
||||||
ENTITY_PROP_PHYSICAL_KINEMATIC,
|
ENTITY_PROP_PHYSICAL_KINEMATIC,
|
||||||
@ -32,6 +32,7 @@ enum entity_prop {
|
|||||||
ENTITY_PROP_TRIGGER_NEXT_TICK,
|
ENTITY_PROP_TRIGGER_NEXT_TICK,
|
||||||
|
|
||||||
ENTITY_PROP_BULLET,
|
ENTITY_PROP_BULLET,
|
||||||
|
ENTITY_PROP_TRACER,
|
||||||
|
|
||||||
ENTITY_PROP_ATTACHED,
|
ENTITY_PROP_ATTACHED,
|
||||||
|
|
||||||
@ -222,9 +223,20 @@ struct entity {
|
|||||||
/* Bullet */
|
/* Bullet */
|
||||||
|
|
||||||
struct entity_handle bullet_src;
|
struct entity_handle bullet_src;
|
||||||
|
struct entity_handle bullet_tracer;
|
||||||
struct v2 bullet_src_pos;
|
struct v2 bullet_src_pos;
|
||||||
struct v2 bullet_src_dir;
|
struct v2 bullet_src_dir;
|
||||||
f32 bullet_impulse;
|
f32 bullet_impulse;
|
||||||
|
b32 bullet_has_hit;
|
||||||
|
|
||||||
|
/* ====================================================================== */
|
||||||
|
/* Tracer */
|
||||||
|
|
||||||
|
f64 tracer_start_time;
|
||||||
|
struct v2 tracer_start;
|
||||||
|
f32 tracer_fade; /* How many seconds for tracer to fade to transparency */
|
||||||
|
|
||||||
|
struct v2 tracer_tail;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Testing */
|
/* Testing */
|
||||||
|
|||||||
109
src/game.c
109
src/game.c
@ -300,6 +300,9 @@ INTERNAL void release_entities_with_prop(enum entity_prop prop)
|
|||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
struct entity_store *store = G.tick.entity_store;
|
struct entity_store *store = G.tick.entity_store;
|
||||||
|
|
||||||
|
/* TODO: Breadth first iteration to only release parent entities (since
|
||||||
|
* child entities will be released along with parent anyway) */
|
||||||
|
|
||||||
struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *);
|
struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *);
|
||||||
u64 ents_to_release_count = 0;
|
u64 ents_to_release_count = 0;
|
||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
@ -349,32 +352,44 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
|
|||||||
(UNUSED)target;
|
(UNUSED)target;
|
||||||
(UNUSED)src;
|
(UNUSED)src;
|
||||||
|
|
||||||
if (entity_handle_eq(src->top, target->top)) {
|
if (bullet->bullet_has_hit || entity_handle_eq(src->top, target->top)) {
|
||||||
/* Ignore collision if weapon and target share same top level parent */
|
/* Ignore collision if bullet already spent or if weapon and
|
||||||
|
* target share same top level parent */
|
||||||
constraint->skip_solve = true;
|
constraint->skip_solve = true;
|
||||||
continue;
|
} else {
|
||||||
}
|
struct v2 point = data->point;
|
||||||
|
struct v2 normal = data->normal;
|
||||||
|
|
||||||
/* Disable bullet */
|
/* Update bullet */
|
||||||
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
bullet->bullet_has_hit = true;
|
||||||
entity_disable_prop(bullet, ENTITY_PROP_ACTIVE);
|
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
|
|
||||||
|
/* Update tracer */
|
||||||
|
struct entity *tracer = entity_from_handle(store, bullet->bullet_tracer);
|
||||||
|
if (entity_is_valid_and_active(tracer)) {
|
||||||
|
struct xform xf = entity_get_xform(tracer);
|
||||||
|
xf.og = point;
|
||||||
|
entity_set_xform(tracer, xf);
|
||||||
|
tracer->linear_velocity = V2(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create test blood */
|
/* Create test blood */
|
||||||
/* TODO: Remove this */
|
/* TODO: Remove this */
|
||||||
{
|
{
|
||||||
struct xform xf = XFORM_TRS(.t = data->point);
|
struct xform xf = XFORM_TRS(.t = point);
|
||||||
struct entity *decal = entity_alloc(root);
|
struct entity *decal = entity_alloc(root);
|
||||||
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
|
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
|
||||||
entity_set_xform(decal, xf);
|
entity_set_xform(decal, xf);
|
||||||
|
|
||||||
entity_enable_prop(decal, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
entity_enable_prop(decal, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
||||||
decal->linear_velocity = v2_mul(v2_norm(data->normal), 0.5f);
|
decal->linear_velocity = v2_mul(v2_norm(normal), 0.5f);
|
||||||
decal->angular_velocity = 1 - (((f32)sys_rand_u32() / (f32)U32_MAX) * 2);
|
decal->angular_velocity = 1 - (((f32)sys_rand_u32() / (f32)U32_MAX) * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update
|
* Update
|
||||||
@ -476,6 +491,12 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Release entities
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
release_entities_with_prop(ENTITY_PROP_RELEASE_NEXT_TICK);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Activate entities
|
* Activate entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -545,7 +566,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update sprite local xform */
|
/* Update sprite local xform */
|
||||||
|
|
||||||
{
|
{
|
||||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
|
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
|
||||||
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
||||||
@ -785,24 +805,36 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
|
struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center);
|
||||||
struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
|
struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir);
|
||||||
|
|
||||||
{
|
|
||||||
/* Spawn bullet */
|
/* Spawn bullet */
|
||||||
struct entity *bullet = entity_alloc(root);
|
struct entity *bullet;
|
||||||
bullet->sprite = sprite_tag_from_path(STR("res/graphics/bullet.ase"));
|
{
|
||||||
|
bullet = entity_alloc(root);
|
||||||
|
|
||||||
bullet->bullet_src = ent->handle;
|
bullet->bullet_src = ent->handle;
|
||||||
bullet->bullet_src_pos = rel_pos;
|
bullet->bullet_src_pos = rel_pos;
|
||||||
bullet->bullet_src_dir = rel_dir;
|
bullet->bullet_src_dir = rel_dir;
|
||||||
//bullet->bullet_impulse = 0.1f;
|
//bullet->bullet_impulse = 0.1f;
|
||||||
//bullet->bullet_impulse = 0.25f;
|
bullet->bullet_impulse = 0.25f;
|
||||||
bullet->bullet_impulse = 5.f;
|
//bullet->bullet_impulse = 5.f;
|
||||||
bullet->mass_unscaled = 0.04f;
|
bullet->mass_unscaled = 0.04f;
|
||||||
bullet->inertia_unscaled = 0.00001f;
|
bullet->inertia_unscaled = 0.00001f;
|
||||||
bullet->sprite_collider_slice = STR("shape");
|
|
||||||
|
/* Point collider */
|
||||||
|
bullet->local_collider.points[0] = V2(0, 0);
|
||||||
|
bullet->local_collider.count = 1;
|
||||||
|
|
||||||
entity_enable_prop(bullet, ENTITY_PROP_BULLET);
|
entity_enable_prop(bullet, ENTITY_PROP_BULLET);
|
||||||
entity_enable_prop(bullet, ENTITY_PROP_SENSOR);
|
entity_enable_prop(bullet, ENTITY_PROP_SENSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Spawn tracer */
|
||||||
|
{
|
||||||
|
struct entity *tracer = entity_alloc(root);
|
||||||
|
tracer->tracer_fade = 0.5f;
|
||||||
|
entity_enable_prop(tracer, ENTITY_PROP_TRACER);
|
||||||
|
|
||||||
|
bullet->bullet_tracer = tracer->handle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,10 +1038,11 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
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 (!entity_is_valid_and_active(ent)) continue;
|
if (!entity_is_valid_and_active(ent)) continue;
|
||||||
|
if (!entity_has_prop(ent, ENTITY_PROP_BULLET)) 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) && ent->activation_tick == G.tick.tick_id) {
|
if (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);
|
||||||
|
|
||||||
@ -1022,8 +1055,37 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
||||||
|
|
||||||
entity_apply_linear_impulse_to_center(ent, impulse);
|
entity_apply_linear_impulse_to_center(ent, impulse);
|
||||||
|
|
||||||
|
/* Initialize tracer */
|
||||||
|
struct entity *tracer = entity_from_handle(store, ent->bullet_tracer);
|
||||||
|
if (entity_is_valid_and_active(tracer)) {
|
||||||
|
entity_set_xform(tracer, xf);
|
||||||
|
entity_enable_prop(tracer, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
||||||
|
tracer->linear_velocity = ent->linear_velocity;
|
||||||
|
tracer->tracer_start_time = time;
|
||||||
|
tracer->tracer_start = pos;
|
||||||
|
tracer->tracer_tail = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update tracers
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
|
struct entity *ent = &store->entities[entity_index];
|
||||||
|
if (!entity_is_valid_and_active(ent)) continue;
|
||||||
|
if (!entity_has_prop(ent, ENTITY_PROP_TRACER)) continue;
|
||||||
|
|
||||||
|
struct v2 start = ent->tracer_start;
|
||||||
|
struct v2 tail = ent->tracer_tail;
|
||||||
|
struct v2 end = entity_get_xform(ent).og;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update camera position
|
* Update camera position
|
||||||
@ -1097,13 +1159,10 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Release entities pre-publish
|
* Release entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* TODO: Breadth first iteration to only release parent entities (since
|
release_entities_with_prop(ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
* child entities will be released along with parent anyway) */
|
|
||||||
|
|
||||||
release_entities_with_prop(ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Publish tick
|
* Publish tick
|
||||||
@ -1113,12 +1172,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
publish_game_tick();
|
publish_game_tick();
|
||||||
__profframe("Game");
|
__profframe("Game");
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Release entities post-publish
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
release_entities_with_prop(ENTITY_PROP_RELEASE_AFTER_PUBLISH);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* End frame cache scopes
|
* End frame cache scopes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -364,7 +364,7 @@ void phys_prepare_contacts(struct phys_ctx *ctx)
|
|||||||
} else {
|
} else {
|
||||||
/* Mark constraint for removal */
|
/* Mark constraint for removal */
|
||||||
entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
|
entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
|
||||||
entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
/* Remove from lookup */
|
/* Remove from lookup */
|
||||||
struct entity_lookup_key key = entity_lookup_key_from_two_handles(constraint->e0, constraint->e1);
|
struct entity_lookup_key key = entity_lookup_key_from_two_handles(constraint->e0, constraint->e1);
|
||||||
struct entity_lookup_entry *entry = entity_lookup_get(contact_lookup, key);
|
struct entity_lookup_entry *entry = entity_lookup_get(contact_lookup, key);
|
||||||
@ -392,7 +392,7 @@ void phys_prepare_contacts(struct phys_ctx *ctx)
|
|||||||
|| !(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) {
|
|| !(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) {
|
||||||
/* Mark dbg ent for removal */
|
/* Mark dbg ent for removal */
|
||||||
entity_disable_prop(dbg_ent, ENTITY_PROP_ACTIVE);
|
entity_disable_prop(dbg_ent, ENTITY_PROP_ACTIVE);
|
||||||
entity_enable_prop(dbg_ent, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
entity_enable_prop(dbg_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
|
|
||||||
/* Remove from lookup */
|
/* Remove from lookup */
|
||||||
struct entity_lookup_key key = entity_lookup_key_from_two_handles(dbg->e0, dbg->e1);
|
struct entity_lookup_key key = entity_lookup_key_from_two_handles(dbg->e0, dbg->e1);
|
||||||
@ -660,7 +660,7 @@ void phys_prepare_motor_joints(struct phys_ctx *ctx)
|
|||||||
} else {
|
} else {
|
||||||
/* Mark joint for removal */
|
/* Mark joint for removal */
|
||||||
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -887,7 +887,7 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx)
|
|||||||
} else {
|
} else {
|
||||||
/* Mark joint for removal */
|
/* Mark joint for removal */
|
||||||
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_BEFORE_PUBLISH);
|
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/user.c
14
src/user.c
@ -541,6 +541,8 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
||||||
e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, tick_blend);
|
e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, tick_blend);
|
||||||
|
|
||||||
|
e->tracer_tail = v2_lerp(e0->tracer_tail, e1->tracer_tail, tick_blend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -862,7 +864,7 @@ INTERNAL void user_update(void)
|
|||||||
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
|
||||||
__profscope(user_entity_iter);
|
__profscope(user_entity_iter);
|
||||||
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 (!entity_is_valid_and_active(ent)) continue;
|
||||||
//if (sprite_tag_is_nil(ent->sprite)) continue;
|
//if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
struct sprite_tag sprite = ent->sprite;
|
struct sprite_tag sprite = ent->sprite;
|
||||||
@ -907,6 +909,16 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Draw tracer */
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_TRACER)) {
|
||||||
|
struct v2 start = ent->tracer_tail;
|
||||||
|
struct v2 end = xf.og;
|
||||||
|
|
||||||
|
f32 thickness = 0.0025;
|
||||||
|
u32 color = RGBA_32_F(1, 1, 1, 1);
|
||||||
|
draw_solid_line(G.world_canvas, start, end, thickness, color);
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw sprite */
|
/* Draw sprite */
|
||||||
//if ((false)) {
|
//if ((false)) {
|
||||||
if (!sprite_tag_is_nil(sprite)) {
|
if (!sprite_tag_is_nil(sprite)) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user