rename 'entity' -> 'sim_ent'

This commit is contained in:
jacob 2025-02-08 10:07:49 -06:00
parent 01274013e6
commit d9ebdc4df2
14 changed files with 788 additions and 788 deletions

View File

@ -496,7 +496,7 @@ struct pcm {
i16 *samples;
};
struct entity_handle {
struct sim_ent_handle {
u64 idx;
u64 gen;
};

View File

@ -1,7 +1,7 @@
#include "phys.h"
#include "sim_ent.h"
#include "math.h"
#include "scratch.h"
#include "entity.h"
#include "space.h"
GLOBAL struct {
@ -46,34 +46,34 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
struct phys_collision_data_array res = ZI;
res.a = arena_dry_push(arena, struct phys_collision_data);
u64 tick_id = ctx->tick_id;
struct entity_lookup *contact_lookup = ctx->contact_lookup;
struct entity_lookup *debug_lookup = ctx->debug_lookup;
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
struct sim_ent_lookup *debug_lookup = ctx->debug_lookup;
struct space *space = ctx->space;
struct entity_store *store = ctx->store;
struct entity *root = entity_from_handle(store, store->root);
struct sim_ent_store *store = ctx->store;
struct sim_ent *root = sim_ent_from_handle(store, store->root);
for (u64 check0_index = 0; check0_index < store->num_reserved; ++check0_index) {
struct entity *check0 = &store->entities[check0_index];
if (!entity_is_valid_and_active(check0)) continue;
if (!(entity_has_prop(check0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(check0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
struct sim_ent *check0 = &store->entities[check0_index];
if (!sim_ent_is_valid_and_active(check0)) continue;
if (!(sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
if (check0->local_collider.count <= 0) continue;
struct xform check0_xf = entity_get_xform(check0);
struct xform check0_xf = sim_ent_get_xform(check0);
struct collider_shape check0_collider = check0->local_collider;
struct aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
struct space_iter iter = space_iter_begin_aabb(space, aabb);
struct space_entry *space_entry;
while ((space_entry = space_iter_next(&iter))) {
struct entity *check1 = entity_from_handle(store, space_entry->ent);
struct sim_ent *check1 = sim_ent_from_handle(store, space_entry->ent);
if (check1 == check0) continue;
if (!entity_is_valid_and_active(check1)) continue;
if (!(entity_has_prop(check1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(check1, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
if (!sim_ent_is_valid_and_active(check1)) continue;
if (!(sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(check1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
if (check1->local_collider.count <= 0) continue;
/* Deterministic order based on entity index */
struct entity *e0;
struct entity *e1;
struct sim_ent *e0;
struct sim_ent *e1;
struct xform e0_xf;
struct xform e1_xf;
struct collider_shape e0_collider;
@ -82,25 +82,25 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
e0 = check0;
e1 = check1;
e0_xf = check0_xf;
e1_xf = entity_get_xform(check1);
e1_xf = sim_ent_get_xform(check1);
e0_collider = check0_collider;
e1_collider = check1->local_collider;
} else {
e0 = check1;
e1 = check0;
e0_xf = entity_get_xform(check1);
e0_xf = sim_ent_get_xform(check1);
e1_xf = check0_xf;
e0_collider = check1->local_collider;
e1_collider = check0_collider;
}
struct entity_lookup_key key = entity_lookup_key_from_two_handles(e0->handle, e1->handle);
struct entity_lookup_entry *constraint_entry= entity_lookup_get(contact_lookup, key);
struct sim_ent_lookup_key key = sim_ent_lookup_key_from_two_handles(e0->handle, e1->handle);
struct sim_ent_lookup_entry *constraint_entry= sim_ent_lookup_get(contact_lookup, key);
struct entity *constraint_ent = entity_nil();
struct sim_ent *constraint_ent = sim_ent_nil();
if (constraint_entry) {
constraint_ent = entity_from_handle(store, constraint_entry->entity);
if (entity_is_valid_and_active(constraint_ent)) {
constraint_ent = sim_ent_from_handle(store, constraint_entry->entity);
if (sim_ent_is_valid_and_active(constraint_ent)) {
if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) {
/* Already processed constraint this iteration */
continue;
@ -109,7 +109,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
}
} else {
/* Constraint ent no longer valid, delete constraint_entry*/
entity_lookup_remove(contact_lookup, constraint_entry);
sim_ent_lookup_remove(contact_lookup, constraint_entry);
constraint_entry= NULL;
}
}
@ -123,21 +123,21 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
struct phys_contact_constraint *constraint = NULL;
if (collider_res.num_points > 0) {
if (!entity_is_valid_and_active(constraint_ent)) {
if (!sim_ent_is_valid_and_active(constraint_ent)) {
/* Create constraint */
{
constraint_ent = entity_alloc(root);
constraint_ent = sim_ent_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)
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC));
entity_enable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
constraint_ent->contact_constraint_data.skip_solve = sim_ent_has_prop(e0, SIM_ENT_PROP_SENSOR) || sim_ent_has_prop(e1, SIM_ENT_PROP_SENSOR)
|| !(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC));
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_ACTIVE);
/* TODO: Should we recalculate normal as more contact points are added? */
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
entity_activate(constraint_ent, tick_id);
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT);
sim_ent_activate(constraint_ent, tick_id);
ASSERT(!constraint_entry); /* Existing entry should never be present here */
entity_lookup_set(contact_lookup, key, constraint_ent->handle);
sim_ent_lookup_set(contact_lookup, key, constraint_ent->handle);
}
/* Push collision data */
@ -235,17 +235,17 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
/* TODO: Remove this (debugging) */
#if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED
{
struct entity *dbg_ent = entity_nil();
struct entity_lookup_entry *dbg_entry = entity_lookup_get(debug_lookup, key);
struct sim_ent *dbg_ent = sim_ent_nil();
struct sim_ent_lookup_entry *dbg_entry = sim_ent_lookup_get(debug_lookup, key);
if (dbg_entry) {
dbg_ent = entity_from_handle(store, dbg_entry->entity);
dbg_ent = sim_ent_from_handle(store, dbg_entry->sim_ent);
}
if (!dbg_ent->valid) {
/* FIXME: Entity never released */
dbg_ent = entity_alloc(root);
entity_enable_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG);
entity_lookup_set(debug_lookup, key, dbg_ent->handle);
dbg_ent = sim_ent_alloc(root);
sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_COLLISION_DEBUG);
sim_ent_lookup_set(debug_lookup, key, dbg_ent->handle);
}
struct phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
@ -283,25 +283,25 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
{
__prof;
struct entity_lookup *contact_lookup = ctx->contact_lookup;
struct entity_store *store = ctx->store;
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
struct sim_ent_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
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 (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, constraint->e1);
if (constraint->last_phys_iteration >= phys_iteration && num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
struct v2 normal = constraint->normal;
struct v2 tangent = v2_perp(normal);
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -322,11 +322,11 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
constraint->inv_i0 = inv_i0;
constraint->inv_i1 = inv_i1;
if (entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC)) {
if (sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC)) {
constraint->inv_m0 = 0;
constraint->inv_i0 = 0;
}
if (entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC)) {
if (sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_KINEMATIC)) {
constraint->inv_m1 = 0;
constraint->inv_i1 = 0;
}
@ -362,13 +362,13 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
} else {
/* Mark constraint for removal */
constraint_ent->contact_constraint_data.num_points = 0;
entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
sim_ent_disable_prop(constraint_ent, SIM_ENT_PROP_ACTIVE);
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
/* Remove from lookup */
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 sim_ent_lookup_key key = sim_ent_lookup_key_from_two_handles(constraint->e0, constraint->e1);
struct sim_ent_lookup_entry *entry = sim_ent_lookup_get(contact_lookup, key);
if (entry) {
entity_lookup_remove(contact_lookup, entry);
sim_ent_lookup_remove(contact_lookup, entry);
} else {
ASSERT(false); /* This should always exist */
}
@ -376,30 +376,30 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
}
#if COLLIDER_DEBUG
struct entity_lookup *debug_lookup = ctx->debug_lookup;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *dbg_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(dbg_ent)) continue;
if (!entity_has_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG)) continue;
struct sim_ent_lookup *debug_lookup = ctx->debug_lookup;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *dbg_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(dbg_ent)) continue;
if (!sim_ent_has_prop(dbg_ent, SIM_ENT_PROP_COLLISION_DEBUG)) continue;
struct phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
struct entity *e0 = entity_from_handle(store, dbg->e0);
struct entity *e1 = entity_from_handle(store, dbg->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, dbg->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, dbg->e1);
if (!entity_is_valid_and_active(e0) || !entity_is_valid_and_active(e1)
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))
|| !(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) {
if (!sim_ent_is_valid_and_active(e0) || !sim_ent_is_valid_and_active(e1)
|| !(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))
|| !(sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) {
/* Mark dbg ent for removal */
entity_disable_prop(dbg_ent, ENTITY_PROP_ACTIVE);
entity_enable_prop(dbg_ent, ENTITY_PROP_RELEASE_THIS_TICK);
sim_ent_disable_prop(dbg_ent, SIM_ENT_PROP_ACTIVE);
sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
/* Remove from lookup */
struct entity_lookup_key key = entity_lookup_key_from_two_handles(dbg->e0, dbg->e1);
struct entity_lookup_entry *entry = entity_lookup_get(debug_lookup, key);
struct sim_ent_lookup_key key = sim_ent_lookup_key_from_two_handles(dbg->e0, dbg->e1);
struct sim_ent_lookup_entry *entry = sim_ent_lookup_get(debug_lookup, key);
if (entry) {
entity_lookup_remove(debug_lookup, entry);
sim_ent_lookup_remove(debug_lookup, entry);
} else {
ASSERT(false); /* This should always exist */
}
@ -411,21 +411,21 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
void phys_warm_start_contacts(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
u32 num_points = constraint->num_points;
struct entity *e0 = entity_from_handle(store, constraint->e0);
struct entity *e1 = entity_from_handle(store, constraint->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, constraint->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);
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = constraint->inv_m0;
f32 inv_m1 = constraint->inv_m1;
@ -455,10 +455,10 @@ void phys_warm_start_contacts(struct phys_ctx *ctx)
w1 += v2_wedge(vcp1, impulse) * inv_i1;
}
entity_set_linear_velocity(e0, v0);
entity_set_angular_velocity(e0, w0);
entity_set_linear_velocity(e1, v1);
entity_set_angular_velocity(e1, w1);
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
}
}
}
@ -466,16 +466,16 @@ void phys_warm_start_contacts(struct phys_ctx *ctx)
void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
if (!sim_ent_has_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) continue;
struct phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
struct entity *e0 = entity_from_handle(store, constraint->e0);
struct entity *e1 = entity_from_handle(store, constraint->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, constraint->e1);
struct v2 v0 = e0->linear_velocity;
struct v2 v1 = e1->linear_velocity;
@ -483,9 +483,9 @@ void phys_solve_contacts(struct phys_ctx *ctx, 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) && !constraint->skip_solve) {
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
if (num_points > 0 && sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1) && !constraint->skip_solve) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = constraint->inv_m0;
f32 inv_m1 = constraint->inv_m1;
@ -571,10 +571,10 @@ void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
w1 += v2_wedge(vcp1, impulse) * inv_i1;
}
entity_set_linear_velocity(e0, v0);
entity_set_angular_velocity(e0, w0);
entity_set_linear_velocity(e1, v1);
entity_set_angular_velocity(e1, w1);
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
}
}
}
@ -597,20 +597,20 @@ struct phys_motor_joint motor_joint_from_def(struct phys_motor_joint_def def)
void phys_prepare_motor_joints(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
struct entity *e0 = entity_from_handle(store, joint->e0);
struct entity *e1 = entity_from_handle(store, joint->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
/* TODO: Cache this */
/* Calculate masses */
@ -652,8 +652,8 @@ void phys_prepare_motor_joints(struct phys_ctx *ctx)
#endif
} else {
/* Mark joint for removal */
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
}
}
}
@ -661,19 +661,19 @@ void phys_prepare_motor_joints(struct phys_ctx *ctx)
void phys_warm_start_motor_joints(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
struct entity *e0 = entity_from_handle(store, joint->e0);
struct entity *e1 = entity_from_handle(store, joint->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
@ -683,8 +683,8 @@ void phys_warm_start_motor_joints(struct phys_ctx *ctx)
struct v2 vcp0 = v2_sub(xform_mul_v2(e0_xf, joint->point_local_e0), e0_xf.og);
struct v2 vcp1 = v2_sub(xform_mul_v2(e1_xf, joint->point_local_e1), e1_xf.og);
entity_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
entity_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
sim_ent_set_linear_velocity(e0, v2_sub(e0->linear_velocity, v2_mul(joint->linear_impulse, inv_m0)));
sim_ent_set_linear_velocity(e1, v2_add(e1->linear_velocity, v2_mul(joint->linear_impulse, inv_m1)));
e0->angular_velocity -= (v2_wedge(vcp0, joint->linear_impulse) + joint->angular_impulse) * inv_i0;
e1->angular_velocity += (v2_wedge(vcp1, joint->linear_impulse) + joint->angular_impulse) * inv_i1;
}
@ -693,19 +693,19 @@ void phys_warm_start_motor_joints(struct phys_ctx *ctx)
void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT)) continue;
struct phys_motor_joint *joint = &joint_ent->motor_joint_data;
struct entity *e0 = entity_from_handle(store, joint->e0);
struct entity *e1 = entity_from_handle(store, joint->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
f32 inv_m0 = joint->inv_m0;
f32 inv_m1 = joint->inv_m1;
@ -760,10 +760,10 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
w1 += v2_wedge(vcp1, delta) * inv_i1;
}
entity_set_linear_velocity(e0, v0);
entity_set_angular_velocity(e0, w0);
entity_set_linear_velocity(e1, v1);
entity_set_angular_velocity(e1, w1);
sim_ent_set_linear_velocity(e0, v0);
sim_ent_set_angular_velocity(e0, w0);
sim_ent_set_linear_velocity(e1, v1);
sim_ent_set_angular_velocity(e1, w1);
}
}
@ -774,14 +774,14 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
void phys_create_mouse_joints(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
struct sim_ent_store *store = ctx->store;
struct v2 cursor = ctx->dbg_cursor_pos;
b32 start_dragging = ctx->dbg_start_dragging;
b32 stop_dragging = ctx->dbg_stop_dragging;
struct entity *root = entity_from_handle(store, store->root);
struct sim_ent *root = sim_ent_from_handle(store, store->root);
struct entity *joint_ent = entity_find_first_match_one(store, ENTITY_PROP_MOUSE_JOINT);
struct entity *target_ent = entity_from_handle(store, joint_ent->mouse_joint_data.target);
struct sim_ent *joint_ent = sim_ent_find_first_match_one(store, SIM_ENT_PROP_MOUSE_JOINT);
struct sim_ent *target_ent = sim_ent_from_handle(store, joint_ent->mouse_joint_data.target);
if (start_dragging) {
struct xform mouse_xf = xform_from_pos(cursor);
@ -789,14 +789,14 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
mouse_shape.points[0] = V2(0, 0);
mouse_shape.count = 1;
for (u64 entity_index = 0; entity_index < store->num_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_PHYSICAL_DYNAMIC)) continue;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue;
struct collider_shape ent_collider = ent->local_collider;
if (ent_collider.count > 0) {
struct xform ent_xf = entity_get_xform(ent);
struct xform ent_xf = sim_ent_get_xform(ent);
/* TODO: Can just use boolean GJK */
struct collider_collision_points_result res = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
if (res.num_points > 0) {
@ -806,24 +806,24 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
}
}
} else if (stop_dragging) {
target_ent = entity_nil();
target_ent = sim_ent_nil();
}
if (entity_is_valid_and_active(target_ent)) {
if (!entity_is_valid_and_active(joint_ent)) {
joint_ent = entity_alloc(root);
if (sim_ent_is_valid_and_active(target_ent)) {
if (!sim_ent_is_valid_and_active(joint_ent)) {
joint_ent = sim_ent_alloc(root);
joint_ent->mass_unscaled = F32_INFINITY;
joint_ent->inertia_unscaled = F32_INFINITY;
entity_enable_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT);
entity_enable_prop(joint_ent, ENTITY_PROP_ACTIVE);
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT);
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
}
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct xform xf = entity_get_xform(target_ent);
struct xform xf = sim_ent_get_xform(target_ent);
f32 mass = target_ent->mass_unscaled * math_fabs(xform_get_determinant(xf));
if (!entity_handle_eq(joint->target, target_ent->handle)) {
if (!sim_ent_handle_eq(joint->target, target_ent->handle)) {
joint->point_local_start = xform_invert_mul_v2(xf, cursor);
joint->target = target_ent->handle;
}
@ -833,8 +833,8 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
joint->angular_softness = G.mouse_joint_angular_softness;
joint->max_force = G.mouse_joint_max_force * mass;
} else {
if (entity_is_valid_and_active(joint_ent)) {
joint_ent->mouse_joint_data.target = entity_handle_nil();
if (sim_ent_is_valid_and_active(joint_ent)) {
joint_ent->mouse_joint_data.target = sim_ent_handle_nil();
}
}
}
@ -842,16 +842,16 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
void phys_prepare_mouse_joints(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct entity *ent = entity_from_handle(store, joint->target);
if (entity_is_valid_and_active(ent)) {
struct xform xf = entity_get_xform(ent);
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
if (sim_ent_is_valid_and_active(ent)) {
struct xform xf = sim_ent_get_xform(ent);
/* TODO: Cache this */
/* Calculate masses */
@ -880,8 +880,8 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx)
#endif
} else {
/* Mark joint for removal */
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
}
}
}
@ -889,20 +889,20 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx)
void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct entity *ent = entity_from_handle(store, joint->target);
if (entity_is_valid_and_active(ent)) {
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
if (sim_ent_is_valid_and_active(ent)) {
f32 inv_m = joint->inv_m;
f32 inv_i = joint->inv_i;
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct v2 vcp = v2_sub(xform_mul_v2(xf, joint->point_local_start), xf.og);
entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(joint->linear_impulse, inv_m)));
ent->angular_velocity += (v2_wedge(vcp, joint->linear_impulse) + joint->angular_impulse) * inv_i;
}
}
@ -911,15 +911,15 @@ void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
if (!sim_ent_has_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT)) continue;
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
struct entity *ent = entity_from_handle(store, joint->target);
if (entity_is_valid_and_active(ent)) {
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
if (sim_ent_is_valid_and_active(ent)) {
struct v2 v = ent->linear_velocity;
f32 w = ent->angular_velocity;
@ -940,7 +940,7 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
{
f32 max_impulse = joint->max_force / dt;
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct v2 point_start = xform_mul_v2(xf, joint->point_local_start);
struct v2 point_end = xform_mul_v2(xf, joint->point_local_end);
@ -973,8 +973,8 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
w += v2_wedge(vcp, impulse) * inv_i;
}
entity_set_linear_velocity(ent, v);
entity_set_angular_velocity(ent, w);
sim_ent_set_linear_velocity(ent, v);
sim_ent_set_angular_velocity(ent, w);
}
}
}
@ -983,9 +983,9 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
* Integration
* ========================== */
INTERNAL struct xform get_derived_xform(struct entity *ent, f32 dt)
INTERNAL struct xform get_derived_xform(struct sim_ent *ent, f32 dt)
{
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct v2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
f32 step_angular_velocity = ent->angular_velocity * dt;
@ -998,13 +998,13 @@ INTERNAL struct xform get_derived_xform(struct entity *ent, f32 dt)
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
b32 is_dynamic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC);
b32 is_kinematic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC);
b32 is_dynamic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
b32 is_kinematic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
if (is_dynamic || is_kinematic) {
struct v2 linear_velocity = ent->linear_velocity;
f32 angular_velocity = ent->angular_velocity;
@ -1013,7 +1013,7 @@ void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
/* Integrate forces */
if (is_dynamic) {
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
f32 det_abs = math_fabs(xform_get_determinant(xf));
f32 mass = ent->mass_unscaled * det_abs;
f32 inertia = ent->inertia_unscaled * det_abs;
@ -1028,8 +1028,8 @@ void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
angular_velocity *= angular_damping_factor;
/* Update entity */
entity_set_linear_velocity(ent, linear_velocity);
entity_set_angular_velocity(ent, angular_velocity);
sim_ent_set_linear_velocity(ent, linear_velocity);
sim_ent_set_angular_velocity(ent, angular_velocity);
ent->force = V2(0, 0);
ent->torque = 0;
}
@ -1040,14 +1040,14 @@ void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
{
__prof;
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_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_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC) && !sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC)) continue;
struct xform xf = get_derived_xform(ent, dt);
entity_set_xform(ent, xf);
sim_ent_set_xform(ent, xf);
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
if (space_entry->valid) {
@ -1063,19 +1063,19 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations)
{
__prof;
struct entity_store *store = ctx->store;
struct sim_ent_store *store = ctx->store;
struct space *space = ctx->space;
f32 smallest_t = 1;
for (u64 e0_index = 0; e0_index < store->num_reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index];
if (!entity_is_valid_and_active(e0)) continue;
if (!(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
if (!entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
struct sim_ent *e0 = &store->entities[e0_index];
if (!sim_ent_is_valid_and_active(e0)) continue;
if (!(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
if (!sim_ent_has_prop(e0, SIM_ENT_PROP_BULLET)) continue;
if (e0->local_collider.count <= 0) continue;
struct collider_shape e0_collider = e0->local_collider;
struct xform e0_xf_t0 = entity_get_xform(e0);
struct xform e0_xf_t0 = sim_ent_get_xform(e0);
struct xform e0_xf_t1 = get_derived_xform(e0, step_dt);
/* TODO: Use swept aabb rather than combined aabb. This should prevent spikes from bullets returning false positive TOIs with irrelevant entities. */
@ -1086,14 +1086,14 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
struct space_iter iter = space_iter_begin_aabb(space, combined_aabb);
struct space_entry *entry;
while ((entry = space_iter_next(&iter))) {
struct entity *e1 = entity_from_handle(store, entry->ent);
struct sim_ent *e1 = sim_ent_from_handle(store, entry->ent);
if (e1 == e0) continue;
if (!entity_is_valid_and_active(e1)) continue;
if (!(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
if (!sim_ent_is_valid_and_active(e1)) continue;
if (!(sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
if (e1->local_collider.count <= 0) continue;
struct collider_shape e1_collider = e1->local_collider;
struct xform e1_xf_t0 = entity_get_xform(e1);
struct xform e1_xf_t0 = sim_ent_get_xform(e1);
struct xform e1_xf_t1 = get_derived_xform(e1, step_dt);
f32 t = collider_time_of_impact(&e0_collider, &e1_collider, e0_xf_t0, e1_xf_t0, e0_xf_t1, e1_xf_t1, tolerance, max_iterations);
@ -1113,13 +1113,13 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
void phys_update_aabbs(struct phys_ctx *ctx)
{
struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
struct sim_ent_store *store = ctx->store;
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
struct sim_ent *ent = &store->entities[sim_ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (ent->local_collider.count <= 0) continue;
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
if (!space_entry->valid) {
space_entry = space_entry_alloc(ctx->space, ent->handle);

View File

@ -5,14 +5,14 @@
#include "math.h"
struct space;
struct entity_store;
struct entity_lookup;
struct sim_ent_store;
struct sim_ent_lookup;
struct phys_contact_constraint;
struct phys_collision_data {
struct phys_contact_constraint *constraint;
struct entity_handle e0;
struct entity_handle e1;
struct sim_ent_handle e0;
struct sim_ent_handle e1;
struct v2 point;
struct v2 normal; /* Normal of the collision from e0 to e1 */
struct v2 vrel; /* Relative velocity at point of collision */
@ -32,13 +32,13 @@ typedef PHYS_COLLISION_CALLBACK_FUNC_DEF(phys_collision_callback_func, data);
struct phys_ctx {
u64 tick_id;
struct space *space;
struct entity_store *store;
struct entity_lookup *contact_lookup;
struct sim_ent_store *store;
struct sim_ent_lookup *contact_lookup;
phys_collision_callback_func *pre_solve_callback;
phys_collision_callback_func *post_solve_callback;
struct entity_lookup *debug_lookup;
struct sim_ent_lookup *debug_lookup;
struct v2 dbg_cursor_pos;
b32 dbg_start_dragging;
b32 dbg_stop_dragging;
@ -78,8 +78,8 @@ struct phys_contact_point {
struct phys_contact_constraint {
u64 last_phys_iteration; /* To avoid checking collisions for the same constraint twice in one tick */
b32 skip_solve;
struct entity_handle e0;
struct entity_handle e1;
struct sim_ent_handle e0;
struct sim_ent_handle e1;
f32 inv_m0;
f32 inv_m1;
f32 inv_i0;
@ -97,8 +97,8 @@ struct phys_contact_constraint {
};
struct phys_collision_debug {
struct entity_handle e0;
struct entity_handle e1;
struct sim_ent_handle e0;
struct sim_ent_handle e1;
struct collider_collision_points_result res;
struct phys_contact_point points[2];
@ -121,16 +121,16 @@ void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias);
* ========================== */
struct phys_motor_joint_def {
struct entity_handle e0;
struct entity_handle e1;
struct sim_ent_handle e0;
struct sim_ent_handle e1;
f32 correction_rate;
f32 max_force;
f32 max_torque;
};
struct phys_motor_joint {
struct entity_handle e0;
struct entity_handle e1;
struct sim_ent_handle e0;
struct sim_ent_handle e1;
f32 correction_rate;
f32 max_force;
f32 max_torque;
@ -160,7 +160,7 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt);
* ========================== */
struct phys_mouse_joint {
struct entity_handle target;
struct sim_ent_handle target;
struct v2 point_local_start;
struct v2 point_local_end;
struct math_spring_result linear_softness;

470
src/sim.c

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,7 @@ struct sim_event {
struct string snapshot_data;
struct string disconnect_reason;
//struct entity_handle entity;
//struct sim_ent_handle entity;
//struct string update_data;
struct sim_event *next;

View File

@ -12,8 +12,8 @@
/* Accessed via client_nil() */
READONLY struct sim_client _g_client_nil = { .valid = false };
READONLY struct sim_client_store _g_client_store_nil = { .valid = false };
READONLY struct sim_client _g_sim_client_nil = { .valid = false };
READONLY struct sim_client_store _g_sim_client_store_nil = { .valid = false };
/* ========================== *
* Store
@ -97,7 +97,7 @@ struct sim_client *client_alloc(struct sim_client_store *store, struct host_chan
handle.idx = store->clients_reserved;
++store->clients_reserved;
}
*client = _g_client_nil;
*client = _g_sim_client_nil;
client->valid = true;
client->handle = handle;

View File

@ -18,7 +18,7 @@ struct sim_client {
struct sim_client *next_hash;
struct sim_client *prev_hash;
struct entity_handle ent;
struct sim_ent_handle ent;
};
struct channel_lookup_bucket {
@ -40,14 +40,14 @@ struct sim_client_store {
INLINE struct sim_client *client_nil(void)
{
extern READONLY struct sim_client _g_client_nil;
return &_g_client_nil;
extern READONLY struct sim_client _g_sim_client_nil;
return &_g_sim_client_nil;
}
INLINE struct sim_client_store *client_store_nil(void)
{
extern READONLY struct sim_client_store _g_client_store_nil;
return &_g_client_store_nil;
extern READONLY struct sim_client_store _g_sim_client_store_nil;
return &_g_sim_client_store_nil;
}
struct sim_client_store *client_store_alloc(void);

View File

@ -1,15 +1,15 @@
#include "entity.h"
#include "sim_ent.h"
#include "math.h"
/* Offset in bytes from start of store struct to start of entities array (assume adjacently allocated) */
#define STORE_ENTITIES_OFFSET (sizeof(struct entity_store) + (sizeof(struct entity_store) % alignof(struct entity)))
#define STORE_ENTITIES_OFFSET (sizeof(struct sim_ent_store) + (sizeof(struct sim_ent_store) % alignof(struct sim_ent)))
/* Accessed via entity_store_nil() */
READONLY struct entity_store _g_entity_store_nil = { .valid = false };
/* Accessed via sim_ent_store_nil() */
READONLY struct sim_ent_store _g_sim_ent_store_nil = { .valid = false };
/* Accessed via entity_nil() */
/* Accessed via sim_ent_nil() */
/* TODO: Allocate nil entity in nil store */
READONLY struct entity _g_entity_nil = {
READONLY struct sim_ent _g_sim_ent_nil = {
.valid = false,
.local_xform = XFORM_IDENT_NOCAST,
.cached_global_xform = XFORM_IDENT_NOCAST,
@ -25,11 +25,11 @@ READONLY struct entity _g_entity_nil = {
* Store allocation
* ========================== */
INTERNAL struct entity *entity_alloc_internal(struct entity_store *store);
INTERNAL struct sim_ent *sim_ent_alloc_internal(struct sim_ent_store *store);
INTERNAL void store_make_root(struct entity_store *store)
INTERNAL void store_make_root(struct sim_ent_store *store)
{
struct entity *root = entity_alloc_internal(store);
struct sim_ent *root = sim_ent_alloc_internal(store);
root->is_root = true;
root->local_xform = XFORM_IDENT;
root->cached_global_xform = XFORM_IDENT;
@ -37,27 +37,27 @@ INTERNAL void store_make_root(struct entity_store *store)
store->root = root->handle;
}
struct entity_store *entity_store_alloc(void)
struct sim_ent_store *sim_ent_store_alloc(void)
{
struct arena arena = arena_alloc(GIGABYTE(64));
struct entity_store *store = arena_push_zero(&arena, struct entity_store);
struct sim_ent_store *store = arena_push_zero(&arena, struct sim_ent_store);
store->valid = true;
store->arena = arena;
store->entities = arena_dry_push(&arena, struct entity);
store->entities = arena_dry_push(&arena, struct sim_ent);
ASSERT((u64)store->entities - (u64)store == STORE_ENTITIES_OFFSET); /* Offset must be correct */
store_make_root(store);
return store;
}
void entity_store_release(struct entity_store *store)
void sim_ent_store_release(struct sim_ent_store *store)
{
arena_release(&store->arena);
}
void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src)
void sim_ent_store_copy_replace(struct sim_ent_store *dest, struct sim_ent_store *src)
{
struct arena dest_arena = dest->arena;
struct entity *dest_entities = dest->entities;
struct sim_ent *dest_entities = dest->entities;
MEMCPY_STRUCT(dest, src);
arena_copy_replace(&dest_arena, &src->arena);
dest->arena = dest_arena;
@ -68,22 +68,22 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s
* Entity allocation
* ========================== */
INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
INTERNAL struct sim_ent *sim_ent_alloc_internal(struct sim_ent_store *store)
{
struct entity *entity = NULL;
struct entity_handle handle = ZI;
struct sim_ent *entity = NULL;
struct sim_ent_handle handle = ZI;
if (store->first_free.gen) {
/* Reuse from free list */;
entity = entity_from_handle(store, store->first_free);
entity = sim_ent_from_handle(store, store->first_free);
handle = entity->handle;
++handle.gen;
store->first_free = entity->next_free;
} else {
/* Make new */
entity = arena_push(&store->arena, struct entity);
handle = (struct entity_handle) { .gen = 1, .idx = store->num_reserved++ };
entity = arena_push(&store->arena, struct sim_ent);
handle = (struct sim_ent_handle) { .gen = 1, .idx = store->num_reserved++ };
}
*entity = _g_entity_nil;
*entity = _g_sim_ent_nil;
entity->valid = true;
entity->handle = handle;
entity->cached_global_xform_dirty = true;
@ -91,22 +91,22 @@ INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
return entity;
}
struct entity *entity_alloc(struct entity *parent)
struct sim_ent *sim_ent_alloc(struct sim_ent *parent)
{
ASSERT(parent->valid);
struct entity_store *store = entity_store_from_entity(parent);
struct entity *e = entity_alloc_internal(store);
entity_link_parent(e, parent);
struct sim_ent_store *store = sim_ent_store_from_ent(parent);
struct sim_ent *e = sim_ent_alloc_internal(store);
sim_ent_link_parent(e, parent);
return e;
}
INTERNAL void entity_release_internal(struct entity_store *store, struct entity *ent)
INTERNAL void sim_ent_release_internal(struct sim_ent_store *store, struct sim_ent *ent)
{
/* Release children */
struct entity_handle first_handle = ent->first;
struct sim_ent_handle first_handle = ent->first;
if (first_handle.gen) {
for (struct entity *child = entity_from_handle(store, first_handle); child->valid; child = entity_from_handle(store, child->next)) {
entity_release_internal(store, child);
for (struct sim_ent *child = sim_ent_from_handle(store, first_handle); child->valid; child = sim_ent_from_handle(store, child->next)) {
sim_ent_release_internal(store, child);
}
}
@ -118,65 +118,65 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
--store->num_allocated;
}
void entity_release(struct entity_store *store, struct entity *ent)
void sim_ent_release(struct sim_ent_store *store, struct sim_ent *ent)
{
if (ent->parent.gen) {
entity_unlink_from_parent(ent);
sim_ent_unlink_from_parent(ent);
}
entity_release_internal(store, ent);
sim_ent_release_internal(store, ent);
}
/* ========================== *
* Query
* ========================== */
struct entity_store *entity_store_from_entity(struct entity *ent)
struct sim_ent_store *sim_ent_store_from_ent(struct sim_ent *ent)
{
if (ent->valid) {
u64 first_entity_addr = (u64)(ent - ent->handle.idx);
struct entity_store *store = (struct entity_store *)(first_entity_addr - STORE_ENTITIES_OFFSET);
ASSERT(store->entities == (struct entity *)first_entity_addr);
u64 first_ent_addr = (u64)(ent - ent->handle.idx);
struct sim_ent_store *store = (struct sim_ent_store *)(first_ent_addr - STORE_ENTITIES_OFFSET);
ASSERT(store->entities == (struct sim_ent *)first_ent_addr);
return store;
} else {
return entity_store_nil();
return sim_ent_store_nil();
}
}
/* Returns a valid entity or read-only nil entity. Always safe to read result, need to check `valid` to write. */
struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle)
struct sim_ent *sim_ent_from_handle(struct sim_ent_store *store, struct sim_ent_handle handle)
{
if (handle.gen != 0 && handle.idx < store->num_reserved) {
struct entity *entity = &store->entities[handle.idx];
struct sim_ent *entity = &store->entities[handle.idx];
if (entity->handle.gen == handle.gen) {
return entity;
}
}
return entity_nil();
return sim_ent_nil();
}
struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop)
struct sim_ent *sim_ent_find_first_match_one(struct sim_ent_store *store, enum sim_ent_prop prop)
{
u64 count = store->num_reserved;
struct entity *entities = store->entities;
for (u64 entity_index = 0; entity_index < count; ++entity_index) {
struct entity *ent = &entities[entity_index];
if (ent->valid && entity_has_prop(ent, prop)) {
struct sim_ent *entities = store->entities;
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
struct sim_ent *ent = &entities[ent_index];
if (ent->valid && sim_ent_has_prop(ent, prop)) {
return ent;
}
}
return entity_nil();
return sim_ent_nil();
}
struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props)
struct sim_ent *sim_ent_find_first_match_all(struct sim_ent_store *store, struct sim_ent_prop_array props)
{
u64 count = store->num_reserved;
struct entity *entities = store->entities;
for (u64 entity_index = 0; entity_index < count; ++entity_index) {
struct entity *ent = &entities[entity_index];
struct sim_ent *entities = store->entities;
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
struct sim_ent *ent = &entities[ent_index];
if (ent->valid) {
b32 all = true;
for (u64 i = 0; i < props.count; ++i) {
if (!entity_has_prop(ent, props.props[i])) {
if (!sim_ent_has_prop(ent, props.props[i])) {
all = false;
break;
}
@ -186,34 +186,34 @@ struct entity *entity_find_first_match_all(struct entity_store *store, struct en
}
}
}
return entity_nil();
return sim_ent_nil();
}
/* ========================== *
* Xform
* ========================== */
INTERNAL void entity_mark_child_xforms_dirty(struct entity_store *store, struct entity *ent)
INTERNAL void sim_ent_mark_child_xforms_dirty(struct sim_ent_store *store, struct sim_ent *ent)
{
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
for (struct sim_ent *child = sim_ent_from_handle(store, ent->first); child->valid; child = sim_ent_from_handle(store, child->next)) {
if (child->cached_global_xform_dirty) {
break;
} else {
child->cached_global_xform_dirty = true;
entity_mark_child_xforms_dirty(store, child);
sim_ent_mark_child_xforms_dirty(store, child);
}
}
}
INTERNAL struct xform entity_get_xform_w_store(struct entity_store *store, struct entity *ent)
INTERNAL struct xform sim_ent_get_xform_w_store(struct sim_ent_store *store, struct sim_ent *ent)
{
struct xform xf;
if (ent->cached_global_xform_dirty) {
if (ent->is_top) {
xf = ent->local_xform;
} else {
struct entity *parent = entity_from_handle(store, ent->parent);
xf = entity_get_xform_w_store(store, parent);
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
xf = sim_ent_get_xform_w_store(store, parent);
xf = xform_mul(xf, ent->local_xform);
ent->cached_global_xform = xf;
ent->cached_global_xform_dirty = false;
@ -226,16 +226,16 @@ INTERNAL struct xform entity_get_xform_w_store(struct entity_store *store, struc
return xf;
}
struct xform entity_get_xform(struct entity *ent)
struct xform sim_ent_get_xform(struct sim_ent *ent)
{
struct xform xf;
if (ent->cached_global_xform_dirty) {
if (ent->is_top) {
xf = ent->local_xform;
} else {
struct entity_store *store = entity_store_from_entity(ent);
struct entity *parent = entity_from_handle(store, ent->parent);
xf = entity_get_xform_w_store(store, parent);
struct sim_ent_store *store = sim_ent_store_from_ent(ent);
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
xf = sim_ent_get_xform_w_store(store, parent);
xf = xform_mul(xf, ent->local_xform);
ent->cached_global_xform = xf;
ent->cached_global_xform_dirty = false;
@ -248,35 +248,35 @@ struct xform entity_get_xform(struct entity *ent)
return xf;
}
struct xform entity_get_local_xform(struct entity *ent)
struct xform sim_ent_get_local_xform(struct sim_ent *ent)
{
return ent->local_xform;
}
void entity_set_xform(struct entity *ent, struct xform xf)
void sim_ent_set_xform(struct sim_ent *ent, struct xform xf)
{
if (!xform_eq(xf, ent->cached_global_xform)) {
struct entity_store *store = entity_store_from_entity(ent);
struct sim_ent_store *store = sim_ent_store_from_ent(ent);
/* Update local xform */
if (ent->is_top) {
ent->local_xform = xf;
} else {
struct entity *parent = entity_from_handle(store, ent->parent);
struct xform parent_global = entity_get_xform_w_store(store, parent);
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
struct xform parent_global = sim_ent_get_xform_w_store(store, parent);
ent->local_xform = xform_mul(xform_invert(parent_global), xf);
}
ent->cached_global_xform = xf;
ent->cached_global_xform_dirty = false;
entity_mark_child_xforms_dirty(store, ent);
sim_ent_mark_child_xforms_dirty(store, ent);
}
}
void entity_set_local_xform(struct entity *ent, struct xform xf)
void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf)
{
if (!xform_eq(xf, ent->local_xform)) {
ent->local_xform = xf;
ent->cached_global_xform_dirty = true;
entity_mark_child_xforms_dirty(entity_store_from_entity(ent), ent);
sim_ent_mark_child_xforms_dirty(sim_ent_store_from_ent(ent), ent);
}
}
@ -284,42 +284,42 @@ void entity_set_local_xform(struct entity *ent, struct xform xf)
* Movement
* ========================== */
void entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v2 point)
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 point)
{
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct v2 center = xf.og;
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
struct v2 vcp = v2_sub(point, center);
entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
entity_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
sim_ent_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
}
void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse)
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse)
{
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
entity_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
sim_ent_set_linear_velocity(ent, v2_add(ent->linear_velocity, v2_mul(impulse, inv_mass)));
}
void entity_apply_force_to_center(struct entity *ent, struct v2 force)
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force)
{
ent->force = v2_add(ent->force, force);
}
void entity_apply_angular_impulse(struct entity *ent, f32 impulse)
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse)
{
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
f32 scale = math_fabs(xform_get_determinant(xf));
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
entity_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
sim_ent_set_angular_velocity(ent, ent->angular_velocity + impulse * inv_inertia);
}
void entity_apply_torque(struct entity *ent, f32 torque)
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque)
{
ent->torque += torque;
}
@ -328,22 +328,22 @@ void entity_apply_torque(struct entity *ent, f32 torque)
* Tree
* ========================== */
void entity_link_parent(struct entity *ent, struct entity *parent)
void sim_ent_link_parent(struct sim_ent *ent, struct sim_ent *parent)
{
struct entity_store *store = entity_store_from_entity(ent);
struct sim_ent_store *store = sim_ent_store_from_ent(ent);
if (ent->parent.gen) {
/* Unlink from current parent */
entity_unlink_from_parent(ent);
sim_ent_unlink_from_parent(ent);
}
struct entity_handle handle = ent->handle;
struct entity_handle parent_handle = parent->handle;
struct sim_ent_handle handle = ent->handle;
struct sim_ent_handle parent_handle = parent->handle;
ent->parent = parent_handle;
struct entity_handle last_child_handle = parent->last;
struct entity *last_child = entity_from_handle(store, last_child_handle);
struct sim_ent_handle last_child_handle = parent->last;
struct sim_ent *last_child = sim_ent_from_handle(store, last_child_handle);
if (last_child->valid) {
ent->prev = last_child_handle;
last_child->next = handle;
@ -361,14 +361,14 @@ void entity_link_parent(struct entity *ent, struct entity *parent)
}
/* NOTE: Entity will be dangling after calling this, should re-link to root entity. */
void entity_unlink_from_parent(struct entity *ent)
void sim_ent_unlink_from_parent(struct sim_ent *ent)
{
struct entity_store *store = entity_store_from_entity(ent);
struct sim_ent_store *store = sim_ent_store_from_ent(ent);
struct entity_handle parent_handle = ent->parent;
struct entity *parent = entity_from_handle(store, parent_handle);
struct entity *prev = entity_from_handle(store, ent->prev);
struct entity *next = entity_from_handle(store, ent->next);
struct sim_ent_handle parent_handle = ent->parent;
struct sim_ent *parent = sim_ent_from_handle(store, parent_handle);
struct sim_ent *prev = sim_ent_from_handle(store, ent->prev);
struct sim_ent *next = sim_ent_from_handle(store, ent->next);
/* Unlink from parent & siblings */
if (prev->valid) {
@ -381,35 +381,35 @@ void entity_unlink_from_parent(struct entity *ent)
} else {
parent->last = prev->handle;
}
ent->prev = entity_handle_nil();
ent->next = entity_handle_nil();
ent->prev = sim_ent_handle_nil();
ent->next = sim_ent_handle_nil();
}
/* ========================== *
* Entity lookup
* ========================== */
struct entity_lookup entity_lookup_alloc(u64 num_buckets)
struct sim_ent_lookup sim_ent_lookup_alloc(u64 num_buckets)
{
ASSERT(num_buckets > 0);
struct entity_lookup l = ZI;
struct sim_ent_lookup l = ZI;
l.arena = arena_alloc(GIGABYTE(64));
l.buckets = arena_push_array_zero(&l.arena, struct entity_lookup_bucket, num_buckets);
l.buckets = arena_push_array_zero(&l.arena, struct sim_ent_lookup_bucket, num_buckets);
l.num_buckets = num_buckets;
return l;
}
void entity_lookup_release(struct entity_lookup *l)
void sim_ent_lookup_release(struct sim_ent_lookup *l)
{
arena_release(&l->arena);
}
struct entity_lookup_entry *entity_lookup_get(struct entity_lookup *l, struct entity_lookup_key key)
struct sim_ent_lookup_entry *sim_ent_lookup_get(struct sim_ent_lookup *l, struct sim_ent_lookup_key key)
{
u64 index = key.hash % l->num_buckets;
struct entity_lookup_bucket *bucket = &l->buckets[index];
struct entity_lookup_entry *res = NULL;
for (struct entity_lookup_entry *e = bucket->first; e; e = e->next) {
struct sim_ent_lookup_bucket *bucket = &l->buckets[index];
struct sim_ent_lookup_entry *res = NULL;
for (struct sim_ent_lookup_entry *e = bucket->first; e; e = e->next) {
if (e->key.hash == key.hash) {
res = e;
break;
@ -418,13 +418,13 @@ struct entity_lookup_entry *entity_lookup_get(struct entity_lookup *l, struct en
return res;
}
void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, struct entity_handle handle)
void sim_ent_lookup_set(struct sim_ent_lookup *l, struct sim_ent_lookup_key key, struct sim_ent_handle handle)
{
u64 index = key.hash % l->num_buckets;
struct entity_lookup_bucket *bucket = &l->buckets[index];
struct sim_ent_lookup_bucket *bucket = &l->buckets[index];
struct entity_lookup_entry *prev = NULL;
struct entity_lookup_entry **slot = &bucket->first;
struct sim_ent_lookup_entry *prev = NULL;
struct sim_ent_lookup_entry **slot = &bucket->first;
while (*slot) {
if ((*slot)->key.hash == key.hash) {
break;
@ -433,7 +433,7 @@ void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, st
slot = &(*slot)->next;
}
struct entity_lookup_entry *entry = *slot;
struct sim_ent_lookup_entry *entry = *slot;
if (entry) {
/* Set existing entry */
entry->entity = handle;
@ -444,7 +444,7 @@ void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, st
l->first_free_entry->prev = NULL;
l->first_free_entry = entry->next;
} else {
entry = arena_push(&l->arena, struct entity_lookup_entry);
entry = arena_push(&l->arena, struct sim_ent_lookup_entry);
}
MEMZERO_STRUCT(entry);
@ -460,11 +460,11 @@ void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, st
}
}
void entity_lookup_remove(struct entity_lookup *l, struct entity_lookup_entry *entry)
void sim_ent_lookup_remove(struct sim_ent_lookup *l, struct sim_ent_lookup_entry *entry)
{
struct entity_lookup_bucket *bucket = &l->buckets[entry->key.hash % l->num_buckets];
struct entity_lookup_entry *prev = entry->prev;
struct entity_lookup_entry *next = entry->next;
struct sim_ent_lookup_bucket *bucket = &l->buckets[entry->key.hash % l->num_buckets];
struct sim_ent_lookup_entry *prev = entry->prev;
struct sim_ent_lookup_entry *next = entry->next;
if (prev) {
prev->next = next;
@ -486,9 +486,9 @@ void entity_lookup_remove(struct entity_lookup *l, struct entity_lookup_entry *e
l->first_free_entry = entry;
}
struct entity_lookup_key entity_lookup_key_from_two_handles(struct entity_handle h0, struct entity_handle h1)
struct sim_ent_lookup_key sim_ent_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1)
{
struct entity_lookup_key key = ZI;
struct sim_ent_lookup_key key = ZI;
struct string b0 = STRING_FROM_STRUCT(&h0);
struct string b1 = STRING_FROM_STRUCT(&h1);
key.hash = hash_fnv64(HASH_FNV64_BASIS, b0);
@ -500,9 +500,9 @@ struct entity_lookup_key entity_lookup_key_from_two_handles(struct entity_handle
* Activate
* ========================== */
void entity_activate(struct entity *ent, u64 current_tick_id)
void sim_ent_activate(struct sim_ent *ent, u64 current_tick_id)
{
entity_enable_prop(ent, ENTITY_PROP_ACTIVE);
sim_ent_enable_prop(ent, SIM_ENT_PROP_ACTIVE);
ent->activation_tick = current_tick_id;
++ent->continuity_gen;
}

View File

@ -1,94 +1,94 @@
#ifndef ENTITY_H
#define ENTITY_H
#ifndef SIM_ENT_H
#define SIM_ENT_H
#include "sprite.h"
#include "mixer.h"
#include "phys.h"
#include "sim_client.h"
enum entity_prop {
ENTITY_PROP_NONE,
enum sim_ent_prop {
SIM_ENT_PROP_NONE,
ENTITY_PROP_ACTIVE,
SIM_ENT_PROP_ACTIVE,
ENTITY_PROP_RELEASE_THIS_TICK,
ENTITY_PROP_RELEASE_NEXT_TICK,
SIM_ENT_PROP_RELEASE_THIS_TICK,
SIM_ENT_PROP_RELEASE_NEXT_TICK,
ENTITY_PROP_PHYSICAL_DYNAMIC,
ENTITY_PROP_PHYSICAL_KINEMATIC,
SIM_ENT_PROP_PHYSICAL_DYNAMIC,
SIM_ENT_PROP_PHYSICAL_KINEMATIC,
ENTITY_PROP_COLLISION_DEBUG,
ENTITY_PROP_CONTACT_CONSTRAINT,
ENTITY_PROP_MOTOR_JOINT,
ENTITY_PROP_MOUSE_JOINT,
ENTITY_PROP_SENSOR,
SIM_ENT_PROP_COLLISION_DEBUG,
SIM_ENT_PROP_CONTACT_CONSTRAINT,
SIM_ENT_PROP_MOTOR_JOINT,
SIM_ENT_PROP_MOUSE_JOINT,
SIM_ENT_PROP_SENSOR,
ENTITY_PROP_PLAYER_CONTROLLED,
ENTITY_PROP_CAMERA,
ENTITY_PROP_CAMERA_ACTIVE,
SIM_ENT_PROP_PLAYER_CONTROLLED,
SIM_ENT_PROP_CAMERA,
SIM_ENT_PROP_CAMERA_ACTIVE,
ENTITY_PROP_WEAPON,
ENTITY_PROP_TRIGGERING_EQUIPPED,
ENTITY_PROP_TRIGGERED_THIS_TICK,
ENTITY_PROP_TRIGGER_NEXT_TICK,
SIM_ENT_PROP_WEAPON,
SIM_ENT_PROP_TRIGGERING_EQUIPPED,
SIM_ENT_PROP_TRIGGERED_THIS_TICK,
SIM_ENT_PROP_TRIGGER_NEXT_TICK,
ENTITY_PROP_BULLET,
ENTITY_PROP_TRACER,
SIM_ENT_PROP_BULLET,
SIM_ENT_PROP_TRACER,
ENTITY_PROP_QUAKE,
SIM_ENT_PROP_QUAKE,
ENTITY_PROP_ATTACHED,
SIM_ENT_PROP_ATTACHED,
/* Test props */
ENTITY_PROP_TEST,
ENTITY_PROP_TEST_SOUND_EMITTER,
SIM_ENT_PROP_TEST,
SIM_ENT_PROP_TEST_SOUND_EMITTER,
ENTITY_PROP_COUNT
SIM_ENT_PROP_COUNT
};
struct entity_store {
struct sim_ent_store {
b32 valid;
struct arena arena;
u64 num_allocated;
u64 num_reserved;
struct entity_handle first_free;
struct entity_handle root;
struct entity *entities;
struct sim_ent_handle first_free;
struct sim_ent_handle root;
struct sim_ent *entities;
};
struct entity_lookup_key {
struct sim_ent_lookup_key {
u64 hash;
};
struct entity_lookup_entry {
struct entity_lookup_key key;
struct entity_handle entity;
struct entity_lookup_entry *next;
struct entity_lookup_entry *prev;
struct sim_ent_lookup_entry {
struct sim_ent_lookup_key key;
struct sim_ent_handle entity;
struct sim_ent_lookup_entry *next;
struct sim_ent_lookup_entry *prev;
};
struct entity_lookup_bucket {
struct entity_lookup_entry *first;
struct entity_lookup_entry *last;
struct sim_ent_lookup_bucket {
struct sim_ent_lookup_entry *first;
struct sim_ent_lookup_entry *last;
};
struct entity_lookup {
struct sim_ent_lookup {
struct arena arena;
struct entity_lookup_bucket *buckets;
struct sim_ent_lookup_bucket *buckets;
u64 num_buckets;
struct entity_lookup_entry *first_free_entry;
struct sim_ent_lookup_entry *first_free_entry;
};
struct entity {
struct sim_ent {
/* ====================================================================== */
/* Metadata */
b32 valid; /* Is this entity allocated in memory that can be written to (can always be read) */
struct entity_handle handle;
b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */
struct sim_ent_handle handle;
u64 continuity_gen;
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
struct entity_handle next_free;
u64 props[(SIM_ENT_PROP_COUNT + 63) / 64];
struct sim_ent_handle next_free;
/* Is this the root entity */
b32 is_root;
@ -97,14 +97,14 @@ struct entity {
b32 is_top;
/* The handle of the top level parent of the entity */
struct entity_handle top;
struct sim_ent_handle top;
/* Tree */
struct entity_handle parent;
struct entity_handle next;
struct entity_handle prev;
struct entity_handle first;
struct entity_handle last;
struct sim_ent_handle parent;
struct sim_ent_handle next;
struct sim_ent_handle prev;
struct sim_ent_handle first;
struct sim_ent_handle last;
/* ====================================================================== */
/* Position */
@ -140,25 +140,25 @@ struct entity {
/* ====================================================================== */
/* Contact constraint */
/* ENTITY_PROP_CONSTRAINT_CONTACT */
/* SIM_ENT_PROP_CONSTRAINT_CONTACT */
struct phys_contact_constraint contact_constraint_data;
/* ====================================================================== */
/* Motor joint */
/* ENTITY_PROP_MOTOR_JOINT */
/* SIM_ENT_PROP_MOTOR_JOINT */
struct phys_motor_joint motor_joint_data;
/* ====================================================================== */
/* Mouse joint */
/* ENTITY_PROP_MOUSE_JOINT */
/* SIM_ENT_PROP_MOUSE_JOINT */
struct phys_mouse_joint mouse_joint_data;
/* ====================================================================== */
/* Player */
/* ENTITY_PROP_PLAYER_CONTROLLED */
/* SIM_ENT_PROP_PLAYER_CONTROLLED */
struct client_handle controlling_client;
/* ====================================================================== */
@ -174,13 +174,13 @@ struct entity {
struct v2 focus; /* Focus direction vector (where should the entity look) */
} control;
struct entity_handle move_joint;
struct entity_handle aim_joint;
struct sim_ent_handle move_joint;
struct sim_ent_handle aim_joint;
/* ====================================================================== */
/* Physics */
/* ENTITY_PROP_PHYSICAL_DYNAMIC */
/* SIM_ENT_PROP_PHYSICAL_DYNAMIC */
//f32 density; /* Density in kg/m^2 */
@ -189,11 +189,11 @@ struct entity {
f32 mass_unscaled; /* Mass of entity in kg before any transformations */
f32 inertia_unscaled; /* Inertia of entity in kg*m^2 before any transformations */
struct entity_handle ground_friction_joint;
struct sim_ent_handle ground_friction_joint;
f32 linear_ground_friction;
f32 angular_ground_friction;
/* Use entity_set_linear_velocity & entity_set_angular_velocity to set */
/* Use sim_ent_set_linear_velocity & sim_ent_set_angular_velocity to set */
struct v2 linear_velocity; /* m/s */
f32 angular_velocity; /* rad/s */
@ -217,34 +217,34 @@ struct entity {
/* ====================================================================== */
/* Animation */
/* ENTITY_PROP_ANIMATING */
/* SIM_ENT_PROP_ANIMATING */
f64 animation_time_in_frame;
u32 animation_frame;
/* ====================================================================== */
/* Attachment */
/* ENTITY_PROP_ATTACHED */
/* SIM_ENT_PROP_ATTACHED */
/* Slice name on the parent entity's sprite to attach to */
struct string attach_slice;
/* ====================================================================== */
/* Equip */
struct entity_handle equipped;
struct sim_ent_handle equipped;
/* ====================================================================== */
/* Triggers */
/* ENTITY_PROP_TRIGGERED_THIS_TICK */
/* SIM_ENT_PROP_TRIGGERED_THIS_TICK */
f32 trigger_delay; /* Minimum time between triggers */
f32 last_triggered;
/* ====================================================================== */
/* Bullet */
struct entity_handle bullet_src;
struct entity_handle bullet_tracer;
struct sim_ent_handle bullet_src;
struct sim_ent_handle bullet_tracer;
struct v2 bullet_src_pos;
struct v2 bullet_src_dir;
f32 bullet_impulse;
@ -254,7 +254,7 @@ struct entity {
/* ====================================================================== */
/* Tracer */
/* ENTITY_PROP_TRACER */
/* SIM_ENT_PROP_TRACER */
struct v2 tracer_start;
struct v2 tracer_start_velocity;
@ -267,7 +267,7 @@ struct entity {
/* ====================================================================== */
/* Quake */
/* ENTITY_PROP_QUAKE */
/* SIM_ENT_PROP_QUAKE */
f32 quake_intensity;
f32 quake_frequency;
@ -276,12 +276,12 @@ struct entity {
/* ====================================================================== */
/* Testing */
/* ENTITY_PROP_TEST */
/* SIM_ENT_PROP_TEST */
b32 test_initialized;
struct xform test_start_local_xform;
struct xform test_start_sprite_xform;
/* ENTITY_PROP_TEST_SOUND_EMITTER */
/* SIM_ENT_PROP_TEST_SOUND_EMITTER */
struct string sound_name;
struct mixer_desc sound_desc;
struct mixer_track_handle sound_handle;
@ -289,8 +289,8 @@ struct entity {
/* ====================================================================== */
/* Camera */
/* ENTITY_PROP_CAMERA */
struct entity_handle camera_follow;
/* SIM_ENT_PROP_CAMERA */
struct sim_ent_handle camera_follow;
struct xform camera_quad_xform;
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
@ -301,13 +301,13 @@ struct entity {
f32 shake;
};
struct entity_array {
struct entity *entities;
struct sim_ent_array {
struct sim_ent *entities;
u64 count;
};
struct entity_prop_array {
enum entity_prop *props;
struct sim_ent_prop_array {
enum sim_ent_prop *props;
u64 count;
};
@ -315,12 +315,12 @@ struct entity_prop_array {
* Handle helpers
* ========================== */
INLINE struct entity_handle entity_handle_nil(void)
INLINE struct sim_ent_handle sim_ent_handle_nil(void)
{
return (struct entity_handle) { 0 };
return (struct sim_ent_handle) { 0 };
}
INLINE b32 entity_handle_eq(struct entity_handle a, struct entity_handle b)
INLINE b32 sim_ent_handle_eq(struct sim_ent_handle a, struct sim_ent_handle b)
{
return a.gen == b.gen && a.idx == b.idx;
}
@ -329,46 +329,46 @@ INLINE b32 entity_handle_eq(struct entity_handle a, struct entity_handle b)
* Nil
* ========================== */
INLINE struct entity *entity_nil(void)
INLINE struct sim_ent *sim_ent_nil(void)
{
extern READONLY struct entity _g_entity_nil;
return &_g_entity_nil;
extern READONLY struct sim_ent _g_sim_ent_nil;
return &_g_sim_ent_nil;
}
INLINE struct entity_store *entity_store_nil(void)
INLINE struct sim_ent_store *sim_ent_store_nil(void)
{
extern READONLY struct entity_store _g_entity_store_nil;
return &_g_entity_store_nil;
extern READONLY struct sim_ent_store _g_sim_ent_store_nil;
return &_g_sim_ent_store_nil;
}
/* ========================== *
* Property helpers
* ========================== */
INLINE void entity_enable_prop(struct entity *ent, enum entity_prop prop)
INLINE void sim_ent_enable_prop(struct sim_ent *ent, enum sim_ent_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] |= ((u64)1 << bit);
}
INLINE void entity_disable_prop(struct entity *ent, enum entity_prop prop)
INLINE void sim_ent_disable_prop(struct sim_ent *ent, enum sim_ent_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
ent->props[index] &= ~((u64)1 << bit);
}
INLINE b32 entity_has_prop(struct entity *ent, enum entity_prop prop)
INLINE b32 sim_ent_has_prop(struct sim_ent *ent, enum sim_ent_prop prop)
{
u64 index = prop / 64;
u64 bit = prop % 64;
return !!(ent->props[index] & ((u64)1 << bit));
}
INLINE b32 entity_is_valid_and_active(struct entity *ent)
INLINE b32 sim_ent_is_valid_and_active(struct sim_ent *ent)
{
return ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE);
return ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE);
}
/* ========================== *
@ -376,48 +376,48 @@ INLINE b32 entity_is_valid_and_active(struct entity *ent)
* ========================== */
/* Entity store */
struct entity_store *entity_store_alloc(void);
void entity_store_release(struct entity_store *store);
void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src);
struct sim_ent_store *sim_ent_store_alloc(void);
void sim_ent_store_release(struct sim_ent_store *store);
void sim_ent_store_copy_replace(struct sim_ent_store *dest, struct sim_ent_store *src);
/* Entity */
struct entity *entity_alloc(struct entity *parent);
void entity_release(struct entity_store *store, struct entity *ent);
struct sim_ent *sim_ent_alloc(struct sim_ent *parent);
void sim_ent_release(struct sim_ent_store *store, struct sim_ent *ent);
/* Xform */
struct xform entity_get_xform(struct entity *ent);
struct xform entity_get_local_xform(struct entity *ent);
void entity_set_xform(struct entity *ent, struct xform xf);
void entity_set_local_xform(struct entity *ent, struct xform xf);
struct xform sim_ent_get_xform(struct sim_ent *ent);
struct xform sim_ent_get_local_xform(struct sim_ent *ent);
void sim_ent_set_xform(struct sim_ent *ent, struct xform xf);
void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf);
/* Movement */
INLINE void entity_set_linear_velocity(struct entity *ent, struct v2 velocity) { ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY); }
INLINE void entity_set_angular_velocity(struct entity *ent, f32 velocity) { ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY); }
void entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v2 world_point);
void entity_apply_linear_impulse_to_center(struct entity *ent, struct v2 impulse);
void entity_apply_force_to_center(struct entity *ent, struct v2 force);
void entity_apply_angular_impulse(struct entity *ent, f32 impulse);
void entity_apply_torque(struct entity *ent, f32 torque);
INLINE void sim_ent_set_linear_velocity(struct sim_ent *ent, struct v2 velocity) { ent->linear_velocity = v2_clamp_len(velocity, SIM_MAX_LINEAR_VELOCITY); }
INLINE void sim_ent_set_angular_velocity(struct sim_ent *ent, f32 velocity) { ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_VELOCITY); }
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 world_point);
void sim_ent_apply_linear_impulse_to_center(struct sim_ent *ent, struct v2 impulse);
void sim_ent_apply_force_to_center(struct sim_ent *ent, struct v2 force);
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse);
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque);
/* Query */
struct entity_store *entity_store_from_entity(struct entity *ent);
struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle);
struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop);
struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props);
struct sim_ent_store *sim_ent_store_from_ent(struct sim_ent *ent);
struct sim_ent *sim_ent_from_handle(struct sim_ent_store *store, struct sim_ent_handle handle);
struct sim_ent *sim_ent_find_first_match_one(struct sim_ent_store *store, enum sim_ent_prop prop);
struct sim_ent *sim_ent_find_first_match_all(struct sim_ent_store *store, struct sim_ent_prop_array props);
/* Tree */
void entity_link_parent(struct entity *parent, struct entity *child);
void entity_unlink_from_parent(struct entity *ent);
void sim_ent_link_parent(struct sim_ent *parent, struct sim_ent *child);
void sim_ent_unlink_from_parent(struct sim_ent *ent);
/* Lookup */
struct entity_lookup entity_lookup_alloc(u64 num_buckets);
void entity_lookup_release(struct entity_lookup *l);
struct entity_lookup_entry *entity_lookup_get(struct entity_lookup *l, struct entity_lookup_key key);
void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, struct entity_handle handle);
void entity_lookup_remove(struct entity_lookup *l, struct entity_lookup_entry *entry);
struct entity_lookup_key entity_lookup_key_from_two_handles(struct entity_handle h0, struct entity_handle h1);
struct sim_ent_lookup sim_ent_lookup_alloc(u64 num_buckets);
void sim_ent_lookup_release(struct sim_ent_lookup *l);
struct sim_ent_lookup_entry *sim_ent_lookup_get(struct sim_ent_lookup *l, struct sim_ent_lookup_key key);
void sim_ent_lookup_set(struct sim_ent_lookup *l, struct sim_ent_lookup_key key, struct sim_ent_handle handle);
void sim_ent_lookup_remove(struct sim_ent_lookup *l, struct sim_ent_lookup_entry *entry);
struct sim_ent_lookup_key sim_ent_lookup_key_from_two_handles(struct sim_ent_handle h0, struct sim_ent_handle h1);
/* Activate */
void entity_activate(struct entity *ent, u64 current_tick_id);
void sim_ent_activate(struct sim_ent *ent, u64 current_tick_id);
#endif

View File

@ -6,7 +6,7 @@
/* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */
#define SPACE_ENTRIES_OFFSET (sizeof(struct space) + (sizeof(struct space) % alignof(struct space_entry)))
/* Accessed via entity_nil() */
/* Accessed via sim_ent_nil() */
READONLY struct space_entry _g_space_entry_nil = { .valid = false };
READONLY struct space_cell _g_space_cell_nil = { .valid = false };
READONLY struct space _g_space_nil = { .valid = false };
@ -256,7 +256,7 @@ struct space_entry *space_entry_from_handle(struct space *space, struct space_en
return entry;
}
struct space_entry *space_entry_alloc(struct space *space, struct entity_handle entity)
struct space_entry *space_entry_alloc(struct space *space, struct sim_ent_handle entity)
{
struct space_entry *entry = NULL;
struct space_entry_handle handle = ZI;

View File

@ -11,7 +11,7 @@ struct space_entry {
struct space_cell_node *last_node;
struct aabb aabb;
struct entity_handle ent;
struct sim_ent_handle ent;
struct space_entry *next_free;
};
@ -119,7 +119,7 @@ struct space_cell *space_get_cell(struct space *space, struct v2i32 cell_pos);
* ========================== */
struct space_entry *space_entry_from_handle(struct space *space, struct space_entry_handle handle);
struct space_entry *space_entry_alloc(struct space *space, struct entity_handle entity);
struct space_entry *space_entry_alloc(struct space *space, struct sim_ent_handle entity);
void space_entry_release(struct space_entry *entry);
void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb);

View File

@ -1,19 +1,19 @@
#include "user.h"
#include "app.h"
#include "sim.h"
#include "sim_ent.h"
#include "renderer.h"
#include "font.h"
#include "sprite.h"
#include "draw.h"
#include "intrinsics.h"
#include "app.h"
#include "sim.h"
#include "asset_cache.h"
#include "string.h"
#include "scratch.h"
#include "math.h"
#include "sys.h"
#include "world.h"
#include "entity.h"
#include "mixer.h"
#include "atomic.h"
#include "collider.h"
@ -407,14 +407,14 @@ INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y)
}
/* TODO: remove this (testing) */
INTERNAL void debug_draw_movement(struct entity *ent)
INTERNAL void debug_draw_movement(struct sim_ent *ent)
{
f32 thickness = 2.f;
f32 arrow_len = 15.f;
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
struct v2 velocity = ent->linear_velocity;
struct v2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
@ -429,11 +429,11 @@ INTERNAL void debug_draw_movement(struct entity *ent)
* Sort entities
* ========================== */
INTERNAL SORT_COMPARE_FUNC_DEF(entity_draw_order_cmp, arg_a, arg_b, udata)
INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata)
{
(UNUSED)udata;
struct entity *a = *(struct entity **)arg_a;
struct entity *b = *(struct entity **)arg_b;
struct sim_ent *a = *(struct sim_ent **)arg_a;
struct sim_ent *b = *(struct sim_ent **)arg_b;
i32 res = 0;
@ -517,7 +517,7 @@ INTERNAL void user_update(void)
G.time_ns += G.dt_ns;
G.screen_size = sys_window_get_size(G.window);
struct entity_store *store = G.world.entity_store;
struct sim_ent_store *store = G.world.ent_store;
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
struct sim_cmd_list cmd_list = ZI;
@ -558,25 +558,25 @@ INTERNAL void user_update(void)
G.world.dt_ns = math_lerp_i64(t0->dt_ns, t1->dt_ns, (f64)tick_blend);
/* Blend entities */
u64 num_entities = min_u64(t0->entity_store->num_reserved, t1->entity_store->num_reserved);
u64 num_entities = min_u64(t0->ent_store->num_reserved, t1->ent_store->num_reserved);
{
__profscope(tick_blending);
for (u64 i = 0; i < num_entities; ++i) {
struct entity *e = &store->entities[i];
struct entity *e0 = &t0->entity_store->entities[i];
struct entity *e1 = &t1->entity_store->entities[i];
struct sim_ent *e = &store->entities[i];
struct sim_ent *e0 = &t0->ent_store->entities[i];
struct sim_ent *e1 = &t1->ent_store->entities[i];
if (e0->valid && e1->valid
&& entity_has_prop(e0, ENTITY_PROP_ACTIVE) && entity_has_prop(e1, ENTITY_PROP_ACTIVE)
&& sim_ent_has_prop(e0, SIM_ENT_PROP_ACTIVE) && sim_ent_has_prop(e1, SIM_ENT_PROP_ACTIVE)
&& e0->handle.gen == e1->handle.gen
&& e0->continuity_gen == e1->continuity_gen) {
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
if (e->is_top) {
/* TODO: Cache parent & child xforms in sim thread */
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
entity_set_xform(e, xform_lerp(e0_xf, e1_xf, tick_blend));
struct xform e0_xf = sim_ent_get_xform(e0);
struct xform e1_xf = sim_ent_get_xform(e1);
sim_ent_set_xform(e, xform_lerp(e0_xf, e1_xf, tick_blend));
}
e->control_force = math_lerp_f32(e0->control_force, e1->control_force, tick_blend);
@ -672,8 +672,8 @@ INTERNAL void user_update(void)
};
}
for (u64 entity_index = 0; entity_index < events.count; ++entity_index) {
struct sys_event *event = &events.events[entity_index];
for (u64 ent_index = 0; ent_index < events.count; ++ent_index) {
struct sys_event *event = &events.events[ent_index];
if (event->kind == SYS_EVENT_KIND_QUIT) {
app_exit();
@ -729,16 +729,16 @@ INTERNAL void user_update(void)
* Find important entities
* ========================== */
struct entity *active_camera;
struct sim_ent *active_camera;
{
enum entity_prop props[] = { ENTITY_PROP_CAMERA, ENTITY_PROP_CAMERA_ACTIVE };
active_camera = entity_find_first_match_all(store, (struct entity_prop_array) { .count = ARRAY_COUNT(props), .props = props });
enum sim_ent_prop props[] = { SIM_ENT_PROP_CAMERA, SIM_ENT_PROP_CAMERA_ACTIVE };
active_camera = sim_ent_find_first_match_all(store, (struct sim_ent_prop_array) { .count = ARRAY_COUNT(props), .props = props });
}
struct entity *active_player;
struct sim_ent *active_player;
{
enum entity_prop props[] = { ENTITY_PROP_PLAYER_CONTROLLED, ENTITY_PROP_ACTIVE };
active_player = entity_find_first_match_all(store, (struct entity_prop_array) { .count = ARRAY_COUNT(props), .props = props });
enum sim_ent_prop props[] = { SIM_ENT_PROP_PLAYER_CONTROLLED, SIM_ENT_PROP_ACTIVE };
active_player = sim_ent_find_first_match_all(store, (struct sim_ent_prop_array) { .count = ARRAY_COUNT(props), .props = props });
}
/* ========================== *
@ -807,9 +807,9 @@ INTERNAL void user_update(void)
* Apply shake
* ========================== */
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue;
for (u64 ent_index = 0; ent_index < store->num_reserved; ++ent_index) {
struct sim_ent *ent = &store->entities[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
/* How much time between camera shakes */
i64 frequency_ns = NS_FROM_SECONDS(0.01f);
@ -829,9 +829,9 @@ INTERNAL void user_update(void)
f32 blend = (f32)(G.world.time_ns % frequency_ns) / (f32)frequency_ns;
struct v2 vec = v2_lerp(vec0, vec1, blend);
struct xform xf = entity_get_xform(ent);
struct xform xf = sim_ent_get_xform(ent);
xf.og = v2_add(xf.og, v2_mul(vec, shake));
entity_set_xform(ent, xf);
sim_ent_set_xform(ent, xf);
}
}
@ -848,7 +848,7 @@ INTERNAL void user_update(void)
/* Determine ui size by camera & window dimensions */
f32 aspect_ratio = 1.0;
{
struct xform quad_xf = xform_mul(entity_get_xform(active_camera), active_camera->camera_quad_xform);
struct xform quad_xf = xform_mul(sim_ent_get_xform(active_camera), active_camera->camera_quad_xform);
struct v2 camera_size = xform_get_scale(quad_xf);
if (!v2_is_zero(camera_size)) {
aspect_ratio = camera_size.x / camera_size.y;
@ -908,7 +908,7 @@ INTERNAL void user_update(void)
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(world_cursor));
}
} else {
struct xform xf = entity_get_xform(active_camera);
struct xform xf = sim_ent_get_xform(active_camera);
struct v2 center = xf.og;
f32 rot = xform_get_rotation(xf);
@ -969,16 +969,16 @@ INTERNAL void user_update(void)
* Sort entities
* ========================== */
struct entity **sorted = arena_dry_push(scratch.arena, struct entity *);
struct sim_ent **sorted = arena_dry_push(scratch.arena, struct sim_ent *);
u64 sorted_count = 0;
{
/* Copy valid entities */
{
__profscope(copy_sprites_for_sorting);
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (entity_is_valid_and_active(ent)) {
*arena_push(scratch.arena, struct entity *) = ent;
for (u64 ent_index = 0; ent_index < store->num_reserved; ++ent_index) {
struct sim_ent *ent = &store->entities[ent_index];
if (sim_ent_is_valid_and_active(ent)) {
*arena_push(scratch.arena, struct sim_ent *) = ent;
++sorted_count;
}
}
@ -986,7 +986,7 @@ INTERNAL void user_update(void)
/* Sort */
{
__profscope(sort_sprites);
merge_sort(sorted, sorted_count, sizeof(*sorted), entity_draw_order_cmp, NULL);
merge_sort(sorted, sorted_count, sizeof(*sorted), ent_draw_order_cmp, NULL);
}
}
@ -997,25 +997,25 @@ INTERNAL void user_update(void)
{
__profscope(draw_entities);
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index) {
struct entity *ent = sorted[sorted_index];
if (!entity_is_valid_and_active(ent)) continue;
struct sim_ent *ent = sorted[sorted_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
//if (sprite_tag_is_nil(ent->sprite)) continue;
struct sprite_tag sprite = ent->sprite;
struct entity *parent = entity_from_handle(store, ent->parent);
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
struct xform xf = entity_get_xform(ent);
struct xform parent_xf = entity_get_xform(parent);
struct xform xf = sim_ent_get_xform(ent);
struct xform parent_xf = sim_ent_get_xform(parent);
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
b32 skip_debug_draw_transform = entity_has_prop(ent, ENTITY_PROP_CAMERA);
b32 skip_debug_draw_transform = sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA);
skip_debug_draw_transform = true;
struct xform sprite_xform = xf;
/* Draw tracer */
if (entity_has_prop(ent, ENTITY_PROP_TRACER)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_TRACER)) {
struct v2 velocity = ent->tracer_start_velocity;
struct v2 a = ent->tracer_start;
@ -1073,7 +1073,7 @@ INTERNAL void user_update(void)
if (G.debug_draw && !skip_debug_draw) {
struct temp_arena temp = arena_temp_begin(scratch.arena);
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC)) {
debug_draw_movement(ent);
}
@ -1095,7 +1095,7 @@ INTERNAL void user_update(void)
}
/* Draw focus arrow */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_PLAYER_CONTROLLED)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
struct v2 start = xform_mul_v2(sprite_xform, slice.center);
@ -1149,7 +1149,7 @@ INTERNAL void user_update(void)
#endif
/* Draw collider */
if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) {
struct collider_shape collider = ent->local_collider;
u32 color = RGBA_32_F(1, 1, 0, 0.5);
f32 thickness = 2;
@ -1186,10 +1186,10 @@ INTERNAL void user_update(void)
}
/* Draw contact constraint */
if (entity_has_prop(ent, ENTITY_PROP_CONTACT_CONSTRAINT)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTACT_CONSTRAINT)) {
struct phys_contact_constraint *data = &ent->contact_constraint_data;
struct entity *e0 = entity_from_handle(store, data->e0);
struct entity *e1 = entity_from_handle(store, data->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, data->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, data->e1);
(UNUSED)e0;
(UNUSED)e1;
@ -1262,11 +1262,11 @@ INTERNAL void user_update(void)
/* Draw collision debug */
#if COLLIDER_DEBUG
if (entity_has_prop(ent, ENTITY_PROP_COLLISION_DEBUG)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_COLLISION_DEBUG)) {
struct phys_collision_debug *data = &ent->collision_debug_data;
struct collider_collision_points_result collider_res = data->res;
struct entity *e0 = entity_from_handle(store, data->e0);
struct entity *e1 = entity_from_handle(store, data->e1);
struct sim_ent *e0 = sim_ent_from_handle(store, data->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, data->e1);
struct collider_shape e0_collider = e0->local_collider;
struct collider_shape e1_collider = e1->local_collider;
(UNUSED)e0_collider;
@ -1453,7 +1453,7 @@ INTERNAL void user_update(void)
#endif
/* Draw hierarchy */
if (entity_has_prop(parent, ENTITY_PROP_ACTIVE) && !parent->is_root) {
if (sim_ent_has_prop(parent, SIM_ENT_PROP_ACTIVE) && !parent->is_root) {
u32 color = RGBA_32_F(0.6, 0.6, 1, 0.75);
f32 thickness = 2;
f32 arrow_height = 15;
@ -1464,7 +1464,7 @@ INTERNAL void user_update(void)
}
/* Draw camera rect */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CAMERA)) {
u32 color = ent == active_camera ? RGBA_32_F(1, 1, 1, 0.5) : RGBA_32_F(0, 0.75, 0, 0.5);
f32 thickness = 3;
@ -1551,7 +1551,7 @@ INTERNAL void user_update(void)
input_move_dir = xform_basis_invert_mul_v2(G.world_to_ui_xf, input_move_dir); /* Make move dir relative to world view */
input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed);
}
struct v2 input_aim_dir = v2_sub(G.world_cursor, entity_get_xform(active_player).og);
struct v2 input_aim_dir = v2_sub(G.world_cursor, sim_ent_get_xform(active_player).og);
/* Queue cursor move cmd */
queue_sim_cmd(scratch.arena, &cmd_list, (struct sim_cmd) {
@ -1616,7 +1616,7 @@ INTERNAL void user_update(void)
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("world time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.world.time_ns))));
pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("entities: %F/%F"), FMT_UINT(G.world.entity_store->num_allocated), FMT_UINT(G.world.entity_store->num_reserved)));
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("entities: %F/%F"), FMT_UINT(G.world.ent_store->num_allocated), FMT_UINT(G.world.ent_store->num_reserved)));
pos.y += spacing;
pos.y += spacing;
@ -1666,15 +1666,15 @@ INTERNAL void user_update(void)
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("debug_camera: %F"), FMT_STR(G.debug_camera ? LIT("true") : LIT("false"))));
pos.y += spacing;
struct v2 player_linear_vel = entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)->linear_velocity;
struct v2 player_linear_vel = sim_ent_find_first_match_one(store, SIM_ENT_PROP_PLAYER_CONTROLLED)->linear_velocity;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("player linear velocity: (%F, %F)"), FMT_FLOAT_P((f64)player_linear_vel.x, 12), FMT_FLOAT_P((f64)player_linear_vel.y, 12)));
pos.y += spacing;
f32 player_angular_vel = entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)->angular_velocity;
f32 player_angular_vel = sim_ent_find_first_match_one(store, SIM_ENT_PROP_PLAYER_CONTROLLED)->angular_velocity;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("player angular velocity: %F"), FMT_FLOAT_P((f64)player_angular_vel, 12)));
pos.y += spacing;
struct v2 player_pos = entity_get_xform(entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)).og;
struct v2 player_pos = sim_ent_get_xform(sim_ent_find_first_match_one(store, SIM_ENT_PROP_PLAYER_CONTROLLED)).og;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("player pos: (%F, %F)"), FMT_FLOAT_P((f64)player_pos.x, 12), FMT_FLOAT_P((f64)player_pos.y, 12)));
pos.y += spacing;
#endif

View File

@ -1,17 +1,17 @@
#include "world.h"
#include "entity.h"
#include "sim_ent.h"
#include "arena.h"
#include "scratch.h"
void world_alloc(struct world *world)
{
MEMZERO_STRUCT(world);
world->entity_store = entity_store_alloc();
world->ent_store = sim_ent_store_alloc();
}
void world_release(struct world *world)
{
entity_store_release(world->entity_store);
sim_ent_store_release(world->ent_store);
}
void world_copy_replace(struct world *dest, struct world *src)
@ -22,8 +22,8 @@ void world_copy_replace(struct world *dest, struct world *src)
*old = *dest;
MEMCPY_STRUCT(dest, src);
dest->entity_store = old->entity_store;
entity_store_copy_replace(dest->entity_store, src->entity_store);
dest->ent_store = old->ent_store;
sim_ent_store_copy_replace(dest->ent_store, src->ent_store);
scratch_end(scratch);
}

View File

@ -1,7 +1,7 @@
#ifndef WORLD_H
#define WORLD_H
#include "entity.h"
#include "sim_ent.h"
struct world {
u64 continuity_gen; /* Starts at 1 */
@ -13,7 +13,7 @@ struct world {
i64 dt_ns;
i64 time_ns;
struct entity_store *entity_store;
struct sim_ent_store *ent_store;
};
void world_alloc(struct world *world);