hit event testing
This commit is contained in:
parent
152656fbc5
commit
bac3256d1e
BIN
res/graphics/blood.ase
(Stored with Git LFS)
Normal file
BIN
res/graphics/blood.ase
(Stored with Git LFS)
Normal file
Binary file not shown.
23
src/entity.h
23
src/entity.h
@ -15,6 +15,9 @@ enum entity_prop {
|
||||
ENTITY_PROP_CONTACT_CONSTRAINT,
|
||||
ENTITY_PROP_MOTOR_JOINT,
|
||||
ENTITY_PROP_MOUSE_JOINT,
|
||||
ENTITY_PROP_SENSOR,
|
||||
|
||||
ENTITY_PROP_HIT_EVENT,
|
||||
|
||||
ENTITY_PROP_PLAYER_CONTROLLED,
|
||||
ENTITY_PROP_CAMERA,
|
||||
@ -80,6 +83,7 @@ struct contact_point {
|
||||
|
||||
struct contact_constraint {
|
||||
u64 last_updated_tick; /* To avoid checking collisions for the same constraint twice in one tick */
|
||||
b32 skip_solve;
|
||||
struct entity_handle e0;
|
||||
struct entity_handle e1;
|
||||
f32 inv_m0;
|
||||
@ -173,6 +177,16 @@ struct mouse_joint {
|
||||
|
||||
|
||||
|
||||
struct hit_event {
|
||||
struct entity_handle e0;
|
||||
struct entity_handle e1;
|
||||
struct v2 point;
|
||||
struct v2 normal;
|
||||
struct v2 vrel; /* Relative velocity */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -235,6 +249,11 @@ struct entity {
|
||||
/* ENTITY_PROP_MOUSE_JOINT */
|
||||
struct mouse_joint mouse_joint_data;
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Hit event */
|
||||
|
||||
struct hit_event hit_event;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -263,8 +282,8 @@ struct entity {
|
||||
f32 control_torque; /* How much torque is applied when turning towards desired focus */
|
||||
|
||||
struct {
|
||||
struct v2 move;
|
||||
struct v2 focus;
|
||||
struct v2 move; /* Movement direction vector (speed of 0 -> 1) */
|
||||
struct v2 focus; /* Focus direction vector (where should the entity look) */
|
||||
} control;
|
||||
|
||||
struct entity_handle move_joint;
|
||||
|
||||
108
src/game.c
108
src/game.c
@ -360,6 +360,25 @@ INTERNAL void spawn_test_entities(void)
|
||||
player_ent = e;
|
||||
}
|
||||
|
||||
/* Enemy */
|
||||
{
|
||||
struct entity *e = entity_alloc(root);
|
||||
|
||||
struct v2 pos = V2(1, -2);
|
||||
f32 r = 0;
|
||||
struct v2 size = V2(1, 1);
|
||||
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||
entity_set_xform(e, xf);
|
||||
|
||||
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
||||
e->mass_unscaled = 10;
|
||||
e->inertia_unscaled = 10;
|
||||
e->linear_ground_friction = 250;
|
||||
e->angular_ground_friction = 200;
|
||||
}
|
||||
|
||||
/* Player weapon */
|
||||
if (player_ent->valid) {
|
||||
struct entity *e = entity_alloc(player_ent);
|
||||
@ -395,15 +414,6 @@ INTERNAL void spawn_test_entities(void)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* TESTING CONTACT CONSTRAINT
|
||||
* ========================== */
|
||||
@ -481,9 +491,45 @@ INTERNAL void create_contacts(void)
|
||||
|
||||
if (collider_res.num_points > 0) {
|
||||
if (!entity_is_valid_and_active(constraint_ent)) {
|
||||
/* Create hit event */
|
||||
{
|
||||
struct entity *event = entity_alloc(root);
|
||||
entity_enable_prop(event, ENTITY_PROP_HIT_EVENT);
|
||||
event->hit_event.e0 = e0->handle;
|
||||
event->hit_event.e1 = e1->handle;
|
||||
event->hit_event.normal = collider_res.normal;
|
||||
entity_enable_prop(event, ENTITY_PROP_RELEASE_AT_END_OF_FRAME);
|
||||
entity_enable_prop(event, ENTITY_PROP_ACTIVE);
|
||||
|
||||
/* Calculate point */
|
||||
struct v2 point = collider_res.points[0].point;
|
||||
if (collider_res.num_points > 1) {
|
||||
point = v2_add(point, v2_mul(v2_sub(collider_res.points[1].point, point), 0.5f));
|
||||
}
|
||||
event->hit_event.point = point;
|
||||
|
||||
/* Calculate relative velocity */
|
||||
struct v2 vrel;
|
||||
{
|
||||
struct v2 v0 = e0->linear_velocity;
|
||||
struct v2 v1 = e1->linear_velocity;
|
||||
f32 w0 = e0->angular_velocity;
|
||||
f32 w1 = e1->angular_velocity;
|
||||
struct v2 vcp0 = v2_sub(point, e0_xf.og);
|
||||
struct v2 vcp1 = v2_sub(point, e1_xf.og);
|
||||
struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0));
|
||||
struct v2 vel1 = v2_add(v1, v2_perp_mul(vcp1, w1));
|
||||
vrel = v2_sub(vel0, vel1);
|
||||
}
|
||||
event->hit_event.vrel = vrel;
|
||||
}
|
||||
|
||||
/* Create constraint */
|
||||
{
|
||||
constraint_ent = entity_alloc(root);
|
||||
constraint_ent->contact_constraint_data.e1 = e1->handle;
|
||||
constraint_ent->contact_constraint_data.e0 = e0->handle;
|
||||
constraint_ent->contact_constraint_data.skip_solve = entity_has_prop(e0, ENTITY_PROP_SENSOR) || entity_has_prop(e1, ENTITY_PROP_SENSOR);
|
||||
/* TODO: Should we recalculate normal as more contact points are added? */
|
||||
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
|
||||
activate_now(constraint_ent);
|
||||
@ -491,6 +537,7 @@ INTERNAL void create_contacts(void)
|
||||
contact_lookup_set(&G.contact_lookup, lookup_hash, constraint_ent->handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
struct contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||
constraint->normal = collider_res.normal;
|
||||
|
||||
@ -663,7 +710,7 @@ INTERNAL void warm_start_contacts(void)
|
||||
u32 num_points = constraint->num_points;
|
||||
struct entity *e0 = entity_from_handle(store, constraint->e0);
|
||||
struct entity *e1 = entity_from_handle(store, constraint->e1);
|
||||
if (num_points > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
|
||||
if (num_points > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1) && !constraint->skip_solve) {
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
|
||||
@ -722,7 +769,7 @@ INTERNAL void solve_contacts(f32 dt, b32 apply_bias)
|
||||
f32 w1 = e1->angular_velocity;
|
||||
|
||||
u32 num_points = constraint->num_points;
|
||||
if (num_points > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
|
||||
if (num_points > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1) && !constraint->skip_solve) {
|
||||
struct xform e0_xf = entity_get_xform(e0);
|
||||
struct xform e1_xf = entity_get_xform(e1);
|
||||
|
||||
@ -1758,6 +1805,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
bullet->inertia_unscaled = 0.00001f;
|
||||
|
||||
entity_enable_prop(bullet, ENTITY_PROP_BULLET);
|
||||
entity_enable_prop(bullet, ENTITY_PROP_SENSOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1980,6 +2028,44 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================== *
|
||||
* Respond to hit events
|
||||
* ========================== */
|
||||
|
||||
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_HIT_EVENT)) continue;
|
||||
|
||||
struct hit_event *event = &ent->hit_event;
|
||||
|
||||
struct entity *e0 = entity_from_handle(store, event->e0);
|
||||
struct entity *e1 = entity_from_handle(store, event->e1);
|
||||
|
||||
if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
|
||||
/* Bullet hit entity */
|
||||
if (entity_has_prop(e0, ENTITY_PROP_BULLET) || entity_has_prop(e1, ENTITY_PROP_BULLET)) {
|
||||
struct entity *bullet = entity_has_prop(e0, ENTITY_PROP_BULLET) ? e0 : e1;
|
||||
struct entity *target = e0 == bullet ? e1 : e0;
|
||||
|
||||
(UNUSED)bullet;
|
||||
(UNUSED)target;
|
||||
entity_enable_prop(bullet, ENTITY_PROP_RELEASE_AT_END_OF_FRAME);
|
||||
|
||||
|
||||
|
||||
/* Create test blood */
|
||||
/* TODO: Remove this */
|
||||
{
|
||||
struct xform xf = XFORM_TRS(.t = event->point);
|
||||
struct entity *decal = entity_alloc(root);
|
||||
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
|
||||
entity_set_xform(decal, xf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Initialize bullet kinematics from sources
|
||||
* ========================== */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user