rename 'entity' -> 'sim_ent'
This commit is contained in:
parent
01274013e6
commit
d9ebdc4df2
@ -496,7 +496,7 @@ struct pcm {
|
|||||||
i16 *samples;
|
i16 *samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_handle {
|
struct sim_ent_handle {
|
||||||
u64 idx;
|
u64 idx;
|
||||||
u64 gen;
|
u64 gen;
|
||||||
};
|
};
|
||||||
|
|||||||
426
src/phys.c
426
src/phys.c
@ -1,7 +1,7 @@
|
|||||||
#include "phys.h"
|
#include "phys.h"
|
||||||
|
#include "sim_ent.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "scratch.h"
|
#include "scratch.h"
|
||||||
#include "entity.h"
|
|
||||||
#include "space.h"
|
#include "space.h"
|
||||||
|
|
||||||
GLOBAL struct {
|
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;
|
struct phys_collision_data_array res = ZI;
|
||||||
res.a = arena_dry_push(arena, struct phys_collision_data);
|
res.a = arena_dry_push(arena, struct phys_collision_data);
|
||||||
u64 tick_id = ctx->tick_id;
|
u64 tick_id = ctx->tick_id;
|
||||||
struct entity_lookup *contact_lookup = ctx->contact_lookup;
|
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
|
||||||
struct entity_lookup *debug_lookup = ctx->debug_lookup;
|
struct sim_ent_lookup *debug_lookup = ctx->debug_lookup;
|
||||||
struct space *space = ctx->space;
|
struct space *space = ctx->space;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
struct entity *root = entity_from_handle(store, store->root);
|
struct sim_ent *root = sim_ent_from_handle(store, store->root);
|
||||||
|
|
||||||
for (u64 check0_index = 0; check0_index < store->num_reserved; ++check0_index) {
|
for (u64 check0_index = 0; check0_index < store->num_reserved; ++check0_index) {
|
||||||
struct entity *check0 = &store->entities[check0_index];
|
struct sim_ent *check0 = &store->entities[check0_index];
|
||||||
if (!entity_is_valid_and_active(check0)) continue;
|
if (!sim_ent_is_valid_and_active(check0)) continue;
|
||||||
if (!(entity_has_prop(check0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(check0, ENTITY_PROP_PHYSICAL_KINEMATIC))) 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;
|
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 collider_shape check0_collider = check0->local_collider;
|
||||||
struct aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
|
struct aabb aabb = collider_aabb_from_collider(&check0_collider, check0_xf);
|
||||||
|
|
||||||
struct space_iter iter = space_iter_begin_aabb(space, aabb);
|
struct space_iter iter = space_iter_begin_aabb(space, aabb);
|
||||||
struct space_entry *space_entry;
|
struct space_entry *space_entry;
|
||||||
while ((space_entry = space_iter_next(&iter))) {
|
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 (check1 == check0) continue;
|
||||||
if (!entity_is_valid_and_active(check1)) continue;
|
if (!sim_ent_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_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;
|
if (check1->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
/* Deterministic order based on entity index */
|
/* Deterministic order based on entity index */
|
||||||
struct entity *e0;
|
struct sim_ent *e0;
|
||||||
struct entity *e1;
|
struct sim_ent *e1;
|
||||||
struct xform e0_xf;
|
struct xform e0_xf;
|
||||||
struct xform e1_xf;
|
struct xform e1_xf;
|
||||||
struct collider_shape e0_collider;
|
struct collider_shape e0_collider;
|
||||||
@ -82,25 +82,25 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
e0 = check0;
|
e0 = check0;
|
||||||
e1 = check1;
|
e1 = check1;
|
||||||
e0_xf = check0_xf;
|
e0_xf = check0_xf;
|
||||||
e1_xf = entity_get_xform(check1);
|
e1_xf = sim_ent_get_xform(check1);
|
||||||
e0_collider = check0_collider;
|
e0_collider = check0_collider;
|
||||||
e1_collider = check1->local_collider;
|
e1_collider = check1->local_collider;
|
||||||
} else {
|
} else {
|
||||||
e0 = check1;
|
e0 = check1;
|
||||||
e1 = check0;
|
e1 = check0;
|
||||||
e0_xf = entity_get_xform(check1);
|
e0_xf = sim_ent_get_xform(check1);
|
||||||
e1_xf = check0_xf;
|
e1_xf = check0_xf;
|
||||||
e0_collider = check1->local_collider;
|
e0_collider = check1->local_collider;
|
||||||
e1_collider = check0_collider;
|
e1_collider = check0_collider;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity_lookup_key key = entity_lookup_key_from_two_handles(e0->handle, e1->handle);
|
struct sim_ent_lookup_key key = sim_ent_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_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) {
|
if (constraint_entry) {
|
||||||
constraint_ent = entity_from_handle(store, constraint_entry->entity);
|
constraint_ent = sim_ent_from_handle(store, constraint_entry->entity);
|
||||||
if (entity_is_valid_and_active(constraint_ent)) {
|
if (sim_ent_is_valid_and_active(constraint_ent)) {
|
||||||
if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) {
|
if (constraint_ent->contact_constraint_data.last_phys_iteration >= phys_iteration) {
|
||||||
/* Already processed constraint this iteration */
|
/* Already processed constraint this iteration */
|
||||||
continue;
|
continue;
|
||||||
@ -109,7 +109,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Constraint ent no longer valid, delete constraint_entry*/
|
/* 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;
|
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;
|
struct phys_contact_constraint *constraint = NULL;
|
||||||
if (collider_res.num_points > 0) {
|
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 */
|
/* 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.e1 = e1->handle;
|
||||||
constraint_ent->contact_constraint_data.e0 = e0->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)
|
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)
|
||||||
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC));
|
|| !(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e1, SIM_ENT_PROP_PHYSICAL_DYNAMIC));
|
||||||
entity_enable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
|
|
||||||
/* TODO: Should we recalculate normal as more contact points are added? */
|
/* TODO: Should we recalculate normal as more contact points are added? */
|
||||||
entity_enable_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT);
|
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_CONTACT_CONSTRAINT);
|
||||||
entity_activate(constraint_ent, tick_id);
|
sim_ent_activate(constraint_ent, tick_id);
|
||||||
ASSERT(!constraint_entry); /* Existing entry should never be present here */
|
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 */
|
/* Push collision data */
|
||||||
@ -235,17 +235,17 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
|
|||||||
/* TODO: Remove this (debugging) */
|
/* TODO: Remove this (debugging) */
|
||||||
#if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED
|
#if COLLIDER_DEBUG && COLLIDER_DEBUG_DETAILED
|
||||||
{
|
{
|
||||||
struct entity *dbg_ent = entity_nil();
|
struct sim_ent *dbg_ent = sim_ent_nil();
|
||||||
struct entity_lookup_entry *dbg_entry = entity_lookup_get(debug_lookup, key);
|
struct sim_ent_lookup_entry *dbg_entry = sim_ent_lookup_get(debug_lookup, key);
|
||||||
if (dbg_entry) {
|
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) {
|
if (!dbg_ent->valid) {
|
||||||
/* FIXME: Entity never released */
|
/* FIXME: Entity never released */
|
||||||
dbg_ent = entity_alloc(root);
|
dbg_ent = sim_ent_alloc(root);
|
||||||
entity_enable_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG);
|
sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_COLLISION_DEBUG);
|
||||||
entity_lookup_set(debug_lookup, key, dbg_ent->handle);
|
sim_ent_lookup_set(debug_lookup, key, dbg_ent->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
|
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)
|
void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_lookup *contact_lookup = ctx->contact_lookup;
|
struct sim_ent_lookup *contact_lookup = ctx->contact_lookup;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *constraint_ent = &store->entities[entity_index];
|
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(constraint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||||
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) 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 phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||||
|
|
||||||
u32 num_points = constraint->num_points;
|
u32 num_points = constraint->num_points;
|
||||||
struct entity *e0 = entity_from_handle(store, constraint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, constraint->e1);
|
struct sim_ent *e1 = sim_ent_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)) {
|
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 normal = constraint->normal;
|
||||||
struct v2 tangent = v2_perp(normal);
|
struct v2 tangent = v2_perp(normal);
|
||||||
|
|
||||||
struct xform e0_xf = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
/* TODO: Cache this */
|
/* TODO: Cache this */
|
||||||
/* Calculate masses */
|
/* Calculate masses */
|
||||||
@ -322,11 +322,11 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
|||||||
constraint->inv_i0 = inv_i0;
|
constraint->inv_i0 = inv_i0;
|
||||||
constraint->inv_i1 = inv_i1;
|
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_m0 = 0;
|
||||||
constraint->inv_i0 = 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_m1 = 0;
|
||||||
constraint->inv_i1 = 0;
|
constraint->inv_i1 = 0;
|
||||||
}
|
}
|
||||||
@ -362,13 +362,13 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
|||||||
} else {
|
} else {
|
||||||
/* Mark constraint for removal */
|
/* Mark constraint for removal */
|
||||||
constraint_ent->contact_constraint_data.num_points = 0;
|
constraint_ent->contact_constraint_data.num_points = 0;
|
||||||
entity_disable_prop(constraint_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_disable_prop(constraint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
entity_enable_prop(constraint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
sim_ent_enable_prop(constraint_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
||||||
/* Remove from lookup */
|
/* Remove from lookup */
|
||||||
struct entity_lookup_key key = entity_lookup_key_from_two_handles(constraint->e0, constraint->e1);
|
struct sim_ent_lookup_key key = sim_ent_lookup_key_from_two_handles(constraint->e0, constraint->e1);
|
||||||
struct entity_lookup_entry *entry = entity_lookup_get(contact_lookup, key);
|
struct sim_ent_lookup_entry *entry = sim_ent_lookup_get(contact_lookup, key);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entity_lookup_remove(contact_lookup, entry);
|
sim_ent_lookup_remove(contact_lookup, entry);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(false); /* This should always exist */
|
ASSERT(false); /* This should always exist */
|
||||||
}
|
}
|
||||||
@ -376,30 +376,30 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if COLLIDER_DEBUG
|
#if COLLIDER_DEBUG
|
||||||
struct entity_lookup *debug_lookup = ctx->debug_lookup;
|
struct sim_ent_lookup *debug_lookup = ctx->debug_lookup;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *dbg_ent = &store->entities[entity_index];
|
struct sim_ent *dbg_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(dbg_ent)) continue;
|
if (!sim_ent_is_valid_and_active(dbg_ent)) continue;
|
||||||
if (!entity_has_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG)) 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 phys_collision_debug *dbg = &dbg_ent->collision_debug_data;
|
||||||
struct entity *e0 = entity_from_handle(store, dbg->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, dbg->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, dbg->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, dbg->e1);
|
||||||
|
|
||||||
|
|
||||||
if (!entity_is_valid_and_active(e0) || !entity_is_valid_and_active(e1)
|
if (!sim_ent_is_valid_and_active(e0) || !sim_ent_is_valid_and_active(e1)
|
||||||
|| !(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))
|
|| !(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))
|
||||||
|| !(entity_has_prop(e1, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e1, ENTITY_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 */
|
/* Mark dbg ent for removal */
|
||||||
entity_disable_prop(dbg_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_disable_prop(dbg_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
entity_enable_prop(dbg_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
sim_ent_enable_prop(dbg_ent, SIM_ENT_PROP_RELEASE_THIS_TICK);
|
||||||
|
|
||||||
/* Remove from lookup */
|
/* Remove from lookup */
|
||||||
struct entity_lookup_key key = entity_lookup_key_from_two_handles(dbg->e0, dbg->e1);
|
struct sim_ent_lookup_key key = sim_ent_lookup_key_from_two_handles(dbg->e0, dbg->e1);
|
||||||
struct entity_lookup_entry *entry = entity_lookup_get(debug_lookup, key);
|
struct sim_ent_lookup_entry *entry = sim_ent_lookup_get(debug_lookup, key);
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entity_lookup_remove(debug_lookup, entry);
|
sim_ent_lookup_remove(debug_lookup, entry);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(false); /* This should always exist */
|
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)
|
void phys_warm_start_contacts(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *constraint_ent = &store->entities[entity_index];
|
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(constraint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||||
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) 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 phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||||
|
|
||||||
u32 num_points = constraint->num_points;
|
u32 num_points = constraint->num_points;
|
||||||
struct entity *e0 = entity_from_handle(store, constraint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, constraint->e1);
|
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) {
|
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 = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
f32 inv_m0 = constraint->inv_m0;
|
f32 inv_m0 = constraint->inv_m0;
|
||||||
f32 inv_m1 = constraint->inv_m1;
|
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;
|
w1 += v2_wedge(vcp1, impulse) * inv_i1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_set_linear_velocity(e0, v0);
|
sim_ent_set_linear_velocity(e0, v0);
|
||||||
entity_set_angular_velocity(e0, w0);
|
sim_ent_set_angular_velocity(e0, w0);
|
||||||
entity_set_linear_velocity(e1, v1);
|
sim_ent_set_linear_velocity(e1, v1);
|
||||||
entity_set_angular_velocity(e1, w1);
|
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)
|
void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *constraint_ent = &store->entities[entity_index];
|
struct sim_ent *constraint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(constraint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(constraint_ent)) continue;
|
||||||
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) 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 phys_contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||||
|
|
||||||
struct entity *e0 = entity_from_handle(store, constraint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, constraint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, constraint->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, constraint->e1);
|
||||||
|
|
||||||
struct v2 v0 = e0->linear_velocity;
|
struct v2 v0 = e0->linear_velocity;
|
||||||
struct v2 v1 = e1->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;
|
f32 w1 = e1->angular_velocity;
|
||||||
|
|
||||||
u32 num_points = constraint->num_points;
|
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) {
|
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 = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
f32 inv_m0 = constraint->inv_m0;
|
f32 inv_m0 = constraint->inv_m0;
|
||||||
f32 inv_m1 = constraint->inv_m1;
|
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;
|
w1 += v2_wedge(vcp1, impulse) * inv_i1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_set_linear_velocity(e0, v0);
|
sim_ent_set_linear_velocity(e0, v0);
|
||||||
entity_set_angular_velocity(e0, w0);
|
sim_ent_set_angular_velocity(e0, w0);
|
||||||
entity_set_linear_velocity(e1, v1);
|
sim_ent_set_linear_velocity(e1, v1);
|
||||||
entity_set_angular_velocity(e1, w1);
|
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)
|
void phys_prepare_motor_joints(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) 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 phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||||
|
|
||||||
struct entity *e0 = entity_from_handle(store, joint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, joint->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
|
||||||
|
|
||||||
if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
|
if (sim_ent_is_valid_and_active(e0) && sim_ent_is_valid_and_active(e1)) {
|
||||||
struct xform e0_xf = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
/* TODO: Cache this */
|
/* TODO: Cache this */
|
||||||
/* Calculate masses */
|
/* Calculate masses */
|
||||||
@ -652,8 +652,8 @@ void phys_prepare_motor_joints(struct phys_ctx *ctx)
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* Mark joint for removal */
|
/* Mark joint for removal */
|
||||||
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
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)
|
void phys_warm_start_motor_joints(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) 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 phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||||
|
|
||||||
struct entity *e0 = entity_from_handle(store, joint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, joint->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
|
||||||
|
|
||||||
struct xform e0_xf = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
f32 inv_m0 = joint->inv_m0;
|
f32 inv_m0 = joint->inv_m0;
|
||||||
f32 inv_m1 = joint->inv_m1;
|
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 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);
|
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)));
|
sim_ent_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(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;
|
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;
|
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)
|
void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) 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 phys_motor_joint *joint = &joint_ent->motor_joint_data;
|
||||||
|
|
||||||
struct entity *e0 = entity_from_handle(store, joint->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, joint->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, joint->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, joint->e1);
|
||||||
|
|
||||||
struct xform e0_xf = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
|
|
||||||
f32 inv_m0 = joint->inv_m0;
|
f32 inv_m0 = joint->inv_m0;
|
||||||
f32 inv_m1 = joint->inv_m1;
|
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;
|
w1 += v2_wedge(vcp1, delta) * inv_i1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_set_linear_velocity(e0, v0);
|
sim_ent_set_linear_velocity(e0, v0);
|
||||||
entity_set_angular_velocity(e0, w0);
|
sim_ent_set_angular_velocity(e0, w0);
|
||||||
entity_set_linear_velocity(e1, v1);
|
sim_ent_set_linear_velocity(e1, v1);
|
||||||
entity_set_angular_velocity(e1, w1);
|
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)
|
void phys_create_mouse_joints(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
struct v2 cursor = ctx->dbg_cursor_pos;
|
struct v2 cursor = ctx->dbg_cursor_pos;
|
||||||
b32 start_dragging = ctx->dbg_start_dragging;
|
b32 start_dragging = ctx->dbg_start_dragging;
|
||||||
b32 stop_dragging = ctx->dbg_stop_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 sim_ent *joint_ent = sim_ent_find_first_match_one(store, SIM_ENT_PROP_MOUSE_JOINT);
|
||||||
struct entity *target_ent = entity_from_handle(store, joint_ent->mouse_joint_data.target);
|
struct sim_ent *target_ent = sim_ent_from_handle(store, joint_ent->mouse_joint_data.target);
|
||||||
|
|
||||||
if (start_dragging) {
|
if (start_dragging) {
|
||||||
struct xform mouse_xf = xform_from_pos(cursor);
|
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.points[0] = V2(0, 0);
|
||||||
mouse_shape.count = 1;
|
mouse_shape.count = 1;
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) continue;
|
if (!sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) continue;
|
||||||
|
|
||||||
struct collider_shape ent_collider = ent->local_collider;
|
struct collider_shape ent_collider = ent->local_collider;
|
||||||
if (ent_collider.count > 0) {
|
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 */
|
/* TODO: Can just use boolean GJK */
|
||||||
struct collider_collision_points_result res = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
|
struct collider_collision_points_result res = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
|
||||||
if (res.num_points > 0) {
|
if (res.num_points > 0) {
|
||||||
@ -806,24 +806,24 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (stop_dragging) {
|
} else if (stop_dragging) {
|
||||||
target_ent = entity_nil();
|
target_ent = sim_ent_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity_is_valid_and_active(target_ent)) {
|
if (sim_ent_is_valid_and_active(target_ent)) {
|
||||||
if (!entity_is_valid_and_active(joint_ent)) {
|
if (!sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = entity_alloc(root);
|
joint_ent = sim_ent_alloc(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT);
|
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOUSE_JOINT);
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
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));
|
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->point_local_start = xform_invert_mul_v2(xf, cursor);
|
||||||
joint->target = target_ent->handle;
|
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->angular_softness = G.mouse_joint_angular_softness;
|
||||||
joint->max_force = G.mouse_joint_max_force * mass;
|
joint->max_force = G.mouse_joint_max_force * mass;
|
||||||
} else {
|
} else {
|
||||||
if (entity_is_valid_and_active(joint_ent)) {
|
if (sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent->mouse_joint_data.target = entity_handle_nil();
|
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)
|
void phys_prepare_mouse_joints(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) 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 phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||||
struct entity *ent = entity_from_handle(store, joint->target);
|
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
|
||||||
if (entity_is_valid_and_active(ent)) {
|
if (sim_ent_is_valid_and_active(ent)) {
|
||||||
struct xform xf = entity_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
|
|
||||||
/* TODO: Cache this */
|
/* TODO: Cache this */
|
||||||
/* Calculate masses */
|
/* Calculate masses */
|
||||||
@ -880,8 +880,8 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx)
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* Mark joint for removal */
|
/* Mark joint for removal */
|
||||||
entity_disable_prop(joint_ent, ENTITY_PROP_ACTIVE);
|
sim_ent_disable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
entity_enable_prop(joint_ent, ENTITY_PROP_RELEASE_THIS_TICK);
|
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)
|
void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) 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 phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||||
struct entity *ent = entity_from_handle(store, joint->target);
|
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
|
||||||
if (entity_is_valid_and_active(ent)) {
|
if (sim_ent_is_valid_and_active(ent)) {
|
||||||
f32 inv_m = joint->inv_m;
|
f32 inv_m = joint->inv_m;
|
||||||
f32 inv_i = joint->inv_i;
|
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);
|
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;
|
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)
|
void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *joint_ent = &store->entities[entity_index];
|
struct sim_ent *joint_ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(joint_ent)) continue;
|
if (!sim_ent_is_valid_and_active(joint_ent)) continue;
|
||||||
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) 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 phys_mouse_joint *joint = &joint_ent->mouse_joint_data;
|
||||||
struct entity *ent = entity_from_handle(store, joint->target);
|
struct sim_ent *ent = sim_ent_from_handle(store, joint->target);
|
||||||
if (entity_is_valid_and_active(ent)) {
|
if (sim_ent_is_valid_and_active(ent)) {
|
||||||
struct v2 v = ent->linear_velocity;
|
struct v2 v = ent->linear_velocity;
|
||||||
f32 w = ent->angular_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;
|
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_start = xform_mul_v2(xf, joint->point_local_start);
|
||||||
struct v2 point_end = xform_mul_v2(xf, joint->point_local_end);
|
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;
|
w += v2_wedge(vcp, impulse) * inv_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_set_linear_velocity(ent, v);
|
sim_ent_set_linear_velocity(ent, v);
|
||||||
entity_set_angular_velocity(ent, w);
|
sim_ent_set_angular_velocity(ent, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -983,9 +983,9 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
|
|||||||
* Integration
|
* 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);
|
struct v2 step_linear_velocity = v2_mul(ent->linear_velocity, dt);
|
||||||
f32 step_angular_velocity = ent->angular_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)
|
void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
|
|
||||||
b32 is_dynamic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC);
|
b32 is_dynamic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC);
|
||||||
b32 is_kinematic = entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC);
|
b32 is_kinematic = sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_KINEMATIC);
|
||||||
if (is_dynamic || is_kinematic) {
|
if (is_dynamic || is_kinematic) {
|
||||||
struct v2 linear_velocity = ent->linear_velocity;
|
struct v2 linear_velocity = ent->linear_velocity;
|
||||||
f32 angular_velocity = ent->angular_velocity;
|
f32 angular_velocity = ent->angular_velocity;
|
||||||
@ -1013,7 +1013,7 @@ void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
|
|||||||
|
|
||||||
/* Integrate forces */
|
/* Integrate forces */
|
||||||
if (is_dynamic) {
|
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 det_abs = math_fabs(xform_get_determinant(xf));
|
||||||
f32 mass = ent->mass_unscaled * det_abs;
|
f32 mass = ent->mass_unscaled * det_abs;
|
||||||
f32 inertia = ent->inertia_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;
|
angular_velocity *= angular_damping_factor;
|
||||||
|
|
||||||
/* Update entity */
|
/* Update entity */
|
||||||
entity_set_linear_velocity(ent, linear_velocity);
|
sim_ent_set_linear_velocity(ent, linear_velocity);
|
||||||
entity_set_angular_velocity(ent, angular_velocity);
|
sim_ent_set_angular_velocity(ent, angular_velocity);
|
||||||
ent->force = V2(0, 0);
|
ent->force = V2(0, 0);
|
||||||
ent->torque = 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)
|
void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) 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);
|
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);
|
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
|
||||||
if (space_entry->valid) {
|
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)
|
f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f32 tolerance, u32 max_iterations)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
struct space *space = ctx->space;
|
struct space *space = ctx->space;
|
||||||
f32 smallest_t = 1;
|
f32 smallest_t = 1;
|
||||||
|
|
||||||
for (u64 e0_index = 0; e0_index < store->num_reserved; ++e0_index) {
|
for (u64 e0_index = 0; e0_index < store->num_reserved; ++e0_index) {
|
||||||
struct entity *e0 = &store->entities[e0_index];
|
struct sim_ent *e0 = &store->entities[e0_index];
|
||||||
if (!entity_is_valid_and_active(e0)) continue;
|
if (!sim_ent_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 (!(sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_DYNAMIC) || sim_ent_has_prop(e0, SIM_ENT_PROP_PHYSICAL_KINEMATIC))) continue;
|
||||||
if (!entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
|
if (!sim_ent_has_prop(e0, SIM_ENT_PROP_BULLET)) continue;
|
||||||
if (e0->local_collider.count <= 0) continue;
|
if (e0->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct collider_shape e0_collider = e0->local_collider;
|
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);
|
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. */
|
/* 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_iter iter = space_iter_begin_aabb(space, combined_aabb);
|
||||||
struct space_entry *entry;
|
struct space_entry *entry;
|
||||||
while ((entry = space_iter_next(&iter))) {
|
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 (e1 == e0) continue;
|
||||||
if (!entity_is_valid_and_active(e1)) continue;
|
if (!sim_ent_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_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;
|
if (e1->local_collider.count <= 0) continue;
|
||||||
|
|
||||||
struct collider_shape e1_collider = e1->local_collider;
|
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);
|
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);
|
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)
|
void phys_update_aabbs(struct phys_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct entity_store *store = ctx->store;
|
struct sim_ent_store *store = ctx->store;
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 sim_ent_index = 0; sim_ent_index < store->num_reserved; ++sim_ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[sim_ent_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
if (ent->local_collider.count <= 0) 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);
|
struct space_entry *space_entry = space_entry_from_handle(ctx->space, ent->space_handle);
|
||||||
if (!space_entry->valid) {
|
if (!space_entry->valid) {
|
||||||
space_entry = space_entry_alloc(ctx->space, ent->handle);
|
space_entry = space_entry_alloc(ctx->space, ent->handle);
|
||||||
|
|||||||
32
src/phys.h
32
src/phys.h
@ -5,14 +5,14 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
struct space;
|
struct space;
|
||||||
struct entity_store;
|
struct sim_ent_store;
|
||||||
struct entity_lookup;
|
struct sim_ent_lookup;
|
||||||
|
|
||||||
struct phys_contact_constraint;
|
struct phys_contact_constraint;
|
||||||
struct phys_collision_data {
|
struct phys_collision_data {
|
||||||
struct phys_contact_constraint *constraint;
|
struct phys_contact_constraint *constraint;
|
||||||
struct entity_handle e0;
|
struct sim_ent_handle e0;
|
||||||
struct entity_handle e1;
|
struct sim_ent_handle e1;
|
||||||
struct v2 point;
|
struct v2 point;
|
||||||
struct v2 normal; /* Normal of the collision from e0 to e1 */
|
struct v2 normal; /* Normal of the collision from e0 to e1 */
|
||||||
struct v2 vrel; /* Relative velocity at point of collision */
|
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 {
|
struct phys_ctx {
|
||||||
u64 tick_id;
|
u64 tick_id;
|
||||||
struct space *space;
|
struct space *space;
|
||||||
struct entity_store *store;
|
struct sim_ent_store *store;
|
||||||
struct entity_lookup *contact_lookup;
|
struct sim_ent_lookup *contact_lookup;
|
||||||
|
|
||||||
phys_collision_callback_func *pre_solve_callback;
|
phys_collision_callback_func *pre_solve_callback;
|
||||||
phys_collision_callback_func *post_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;
|
struct v2 dbg_cursor_pos;
|
||||||
b32 dbg_start_dragging;
|
b32 dbg_start_dragging;
|
||||||
b32 dbg_stop_dragging;
|
b32 dbg_stop_dragging;
|
||||||
@ -78,8 +78,8 @@ struct phys_contact_point {
|
|||||||
struct phys_contact_constraint {
|
struct phys_contact_constraint {
|
||||||
u64 last_phys_iteration; /* To avoid checking collisions for the same constraint twice in one tick */
|
u64 last_phys_iteration; /* To avoid checking collisions for the same constraint twice in one tick */
|
||||||
b32 skip_solve;
|
b32 skip_solve;
|
||||||
struct entity_handle e0;
|
struct sim_ent_handle e0;
|
||||||
struct entity_handle e1;
|
struct sim_ent_handle e1;
|
||||||
f32 inv_m0;
|
f32 inv_m0;
|
||||||
f32 inv_m1;
|
f32 inv_m1;
|
||||||
f32 inv_i0;
|
f32 inv_i0;
|
||||||
@ -97,8 +97,8 @@ struct phys_contact_constraint {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct phys_collision_debug {
|
struct phys_collision_debug {
|
||||||
struct entity_handle e0;
|
struct sim_ent_handle e0;
|
||||||
struct entity_handle e1;
|
struct sim_ent_handle e1;
|
||||||
struct collider_collision_points_result res;
|
struct collider_collision_points_result res;
|
||||||
|
|
||||||
struct phys_contact_point points[2];
|
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 phys_motor_joint_def {
|
||||||
struct entity_handle e0;
|
struct sim_ent_handle e0;
|
||||||
struct entity_handle e1;
|
struct sim_ent_handle e1;
|
||||||
f32 correction_rate;
|
f32 correction_rate;
|
||||||
f32 max_force;
|
f32 max_force;
|
||||||
f32 max_torque;
|
f32 max_torque;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct phys_motor_joint {
|
struct phys_motor_joint {
|
||||||
struct entity_handle e0;
|
struct sim_ent_handle e0;
|
||||||
struct entity_handle e1;
|
struct sim_ent_handle e1;
|
||||||
f32 correction_rate;
|
f32 correction_rate;
|
||||||
f32 max_force;
|
f32 max_force;
|
||||||
f32 max_torque;
|
f32 max_torque;
|
||||||
@ -160,7 +160,7 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt);
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct phys_mouse_joint {
|
struct phys_mouse_joint {
|
||||||
struct entity_handle target;
|
struct sim_ent_handle target;
|
||||||
struct v2 point_local_start;
|
struct v2 point_local_start;
|
||||||
struct v2 point_local_end;
|
struct v2 point_local_end;
|
||||||
struct math_spring_result linear_softness;
|
struct math_spring_result linear_softness;
|
||||||
|
|||||||
@ -111,7 +111,7 @@ struct sim_event {
|
|||||||
struct string snapshot_data;
|
struct string snapshot_data;
|
||||||
struct string disconnect_reason;
|
struct string disconnect_reason;
|
||||||
|
|
||||||
//struct entity_handle entity;
|
//struct sim_ent_handle entity;
|
||||||
//struct string update_data;
|
//struct string update_data;
|
||||||
|
|
||||||
struct sim_event *next;
|
struct sim_event *next;
|
||||||
|
|||||||
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Accessed via client_nil() */
|
/* Accessed via client_nil() */
|
||||||
READONLY struct sim_client _g_client_nil = { .valid = false };
|
READONLY struct sim_client _g_sim_client_nil = { .valid = false };
|
||||||
READONLY struct sim_client_store _g_client_store_nil = { .valid = false };
|
READONLY struct sim_client_store _g_sim_client_store_nil = { .valid = false };
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Store
|
* Store
|
||||||
@ -97,7 +97,7 @@ struct sim_client *client_alloc(struct sim_client_store *store, struct host_chan
|
|||||||
handle.idx = store->clients_reserved;
|
handle.idx = store->clients_reserved;
|
||||||
++store->clients_reserved;
|
++store->clients_reserved;
|
||||||
}
|
}
|
||||||
*client = _g_client_nil;
|
*client = _g_sim_client_nil;
|
||||||
client->valid = true;
|
client->valid = true;
|
||||||
client->handle = handle;
|
client->handle = handle;
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ struct sim_client {
|
|||||||
struct sim_client *next_hash;
|
struct sim_client *next_hash;
|
||||||
struct sim_client *prev_hash;
|
struct sim_client *prev_hash;
|
||||||
|
|
||||||
struct entity_handle ent;
|
struct sim_ent_handle ent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct channel_lookup_bucket {
|
struct channel_lookup_bucket {
|
||||||
@ -40,14 +40,14 @@ struct sim_client_store {
|
|||||||
|
|
||||||
INLINE struct sim_client *client_nil(void)
|
INLINE struct sim_client *client_nil(void)
|
||||||
{
|
{
|
||||||
extern READONLY struct sim_client _g_client_nil;
|
extern READONLY struct sim_client _g_sim_client_nil;
|
||||||
return &_g_client_nil;
|
return &_g_sim_client_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct sim_client_store *client_store_nil(void)
|
INLINE struct sim_client_store *client_store_nil(void)
|
||||||
{
|
{
|
||||||
extern READONLY struct sim_client_store _g_client_store_nil;
|
extern READONLY struct sim_client_store _g_sim_client_store_nil;
|
||||||
return &_g_client_store_nil;
|
return &_g_sim_client_store_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sim_client_store *client_store_alloc(void);
|
struct sim_client_store *client_store_alloc(void);
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
#include "entity.h"
|
#include "sim_ent.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
/* Offset in bytes from start of store struct to start of entities array (assume adjacently allocated) */
|
/* 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() */
|
/* Accessed via sim_ent_store_nil() */
|
||||||
READONLY struct entity_store _g_entity_store_nil = { .valid = false };
|
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 */
|
/* TODO: Allocate nil entity in nil store */
|
||||||
READONLY struct entity _g_entity_nil = {
|
READONLY struct sim_ent _g_sim_ent_nil = {
|
||||||
.valid = false,
|
.valid = false,
|
||||||
.local_xform = XFORM_IDENT_NOCAST,
|
.local_xform = XFORM_IDENT_NOCAST,
|
||||||
.cached_global_xform = XFORM_IDENT_NOCAST,
|
.cached_global_xform = XFORM_IDENT_NOCAST,
|
||||||
@ -25,11 +25,11 @@ READONLY struct entity _g_entity_nil = {
|
|||||||
* Store allocation
|
* 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->is_root = true;
|
||||||
root->local_xform = XFORM_IDENT;
|
root->local_xform = XFORM_IDENT;
|
||||||
root->cached_global_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;
|
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 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->valid = true;
|
||||||
store->arena = arena;
|
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 */
|
ASSERT((u64)store->entities - (u64)store == STORE_ENTITIES_OFFSET); /* Offset must be correct */
|
||||||
store_make_root(store);
|
store_make_root(store);
|
||||||
return 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);
|
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 arena dest_arena = dest->arena;
|
||||||
struct entity *dest_entities = dest->entities;
|
struct sim_ent *dest_entities = dest->entities;
|
||||||
MEMCPY_STRUCT(dest, src);
|
MEMCPY_STRUCT(dest, src);
|
||||||
arena_copy_replace(&dest_arena, &src->arena);
|
arena_copy_replace(&dest_arena, &src->arena);
|
||||||
dest->arena = dest_arena;
|
dest->arena = dest_arena;
|
||||||
@ -68,22 +68,22 @@ void entity_store_copy_replace(struct entity_store *dest, struct entity_store *s
|
|||||||
* Entity allocation
|
* 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 sim_ent *entity = NULL;
|
||||||
struct entity_handle handle = ZI;
|
struct sim_ent_handle handle = ZI;
|
||||||
if (store->first_free.gen) {
|
if (store->first_free.gen) {
|
||||||
/* Reuse from free list */;
|
/* 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 = entity->handle;
|
||||||
++handle.gen;
|
++handle.gen;
|
||||||
store->first_free = entity->next_free;
|
store->first_free = entity->next_free;
|
||||||
} else {
|
} else {
|
||||||
/* Make new */
|
/* Make new */
|
||||||
entity = arena_push(&store->arena, struct entity);
|
entity = arena_push(&store->arena, struct sim_ent);
|
||||||
handle = (struct entity_handle) { .gen = 1, .idx = store->num_reserved++ };
|
handle = (struct sim_ent_handle) { .gen = 1, .idx = store->num_reserved++ };
|
||||||
}
|
}
|
||||||
*entity = _g_entity_nil;
|
*entity = _g_sim_ent_nil;
|
||||||
entity->valid = true;
|
entity->valid = true;
|
||||||
entity->handle = handle;
|
entity->handle = handle;
|
||||||
entity->cached_global_xform_dirty = true;
|
entity->cached_global_xform_dirty = true;
|
||||||
@ -91,22 +91,22 @@ INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity *entity_alloc(struct entity *parent)
|
struct sim_ent *sim_ent_alloc(struct sim_ent *parent)
|
||||||
{
|
{
|
||||||
ASSERT(parent->valid);
|
ASSERT(parent->valid);
|
||||||
struct entity_store *store = entity_store_from_entity(parent);
|
struct sim_ent_store *store = sim_ent_store_from_ent(parent);
|
||||||
struct entity *e = entity_alloc_internal(store);
|
struct sim_ent *e = sim_ent_alloc_internal(store);
|
||||||
entity_link_parent(e, parent);
|
sim_ent_link_parent(e, parent);
|
||||||
return e;
|
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 */
|
/* Release children */
|
||||||
struct entity_handle first_handle = ent->first;
|
struct sim_ent_handle first_handle = ent->first;
|
||||||
if (first_handle.gen) {
|
if (first_handle.gen) {
|
||||||
for (struct entity *child = entity_from_handle(store, first_handle); child->valid; child = entity_from_handle(store, child->next)) {
|
for (struct sim_ent *child = sim_ent_from_handle(store, first_handle); child->valid; child = sim_ent_from_handle(store, child->next)) {
|
||||||
entity_release_internal(store, child);
|
sim_ent_release_internal(store, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,65 +118,65 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
|
|||||||
--store->num_allocated;
|
--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) {
|
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
|
* 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) {
|
if (ent->valid) {
|
||||||
u64 first_entity_addr = (u64)(ent - ent->handle.idx);
|
u64 first_ent_addr = (u64)(ent - ent->handle.idx);
|
||||||
struct entity_store *store = (struct entity_store *)(first_entity_addr - STORE_ENTITIES_OFFSET);
|
struct sim_ent_store *store = (struct sim_ent_store *)(first_ent_addr - STORE_ENTITIES_OFFSET);
|
||||||
ASSERT(store->entities == (struct entity *)first_entity_addr);
|
ASSERT(store->entities == (struct sim_ent *)first_ent_addr);
|
||||||
return store;
|
return store;
|
||||||
} else {
|
} 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. */
|
/* 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) {
|
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) {
|
if (entity->handle.gen == handle.gen) {
|
||||||
return entity;
|
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;
|
u64 count = store->num_reserved;
|
||||||
struct entity *entities = store->entities;
|
struct sim_ent *entities = store->entities;
|
||||||
for (u64 entity_index = 0; entity_index < count; ++entity_index) {
|
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
|
||||||
struct entity *ent = &entities[entity_index];
|
struct sim_ent *ent = &entities[ent_index];
|
||||||
if (ent->valid && entity_has_prop(ent, prop)) {
|
if (ent->valid && sim_ent_has_prop(ent, prop)) {
|
||||||
return ent;
|
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;
|
u64 count = store->num_reserved;
|
||||||
struct entity *entities = store->entities;
|
struct sim_ent *entities = store->entities;
|
||||||
for (u64 entity_index = 0; entity_index < count; ++entity_index) {
|
for (u64 ent_index = 0; ent_index < count; ++ent_index) {
|
||||||
struct entity *ent = &entities[entity_index];
|
struct sim_ent *ent = &entities[ent_index];
|
||||||
if (ent->valid) {
|
if (ent->valid) {
|
||||||
b32 all = true;
|
b32 all = true;
|
||||||
for (u64 i = 0; i < props.count; ++i) {
|
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;
|
all = false;
|
||||||
break;
|
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
|
* 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) {
|
if (child->cached_global_xform_dirty) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
child->cached_global_xform_dirty = true;
|
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;
|
struct xform xf;
|
||||||
if (ent->cached_global_xform_dirty) {
|
if (ent->cached_global_xform_dirty) {
|
||||||
if (ent->is_top) {
|
if (ent->is_top) {
|
||||||
xf = ent->local_xform;
|
xf = ent->local_xform;
|
||||||
} else {
|
} else {
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
|
||||||
xf = entity_get_xform_w_store(store, parent);
|
xf = sim_ent_get_xform_w_store(store, parent);
|
||||||
xf = xform_mul(xf, ent->local_xform);
|
xf = xform_mul(xf, ent->local_xform);
|
||||||
ent->cached_global_xform = xf;
|
ent->cached_global_xform = xf;
|
||||||
ent->cached_global_xform_dirty = false;
|
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;
|
return xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct xform entity_get_xform(struct entity *ent)
|
struct xform sim_ent_get_xform(struct sim_ent *ent)
|
||||||
{
|
{
|
||||||
struct xform xf;
|
struct xform xf;
|
||||||
if (ent->cached_global_xform_dirty) {
|
if (ent->cached_global_xform_dirty) {
|
||||||
if (ent->is_top) {
|
if (ent->is_top) {
|
||||||
xf = ent->local_xform;
|
xf = ent->local_xform;
|
||||||
} else {
|
} else {
|
||||||
struct entity_store *store = entity_store_from_entity(ent);
|
struct sim_ent_store *store = sim_ent_store_from_ent(ent);
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
|
||||||
xf = entity_get_xform_w_store(store, parent);
|
xf = sim_ent_get_xform_w_store(store, parent);
|
||||||
xf = xform_mul(xf, ent->local_xform);
|
xf = xform_mul(xf, ent->local_xform);
|
||||||
ent->cached_global_xform = xf;
|
ent->cached_global_xform = xf;
|
||||||
ent->cached_global_xform_dirty = false;
|
ent->cached_global_xform_dirty = false;
|
||||||
@ -248,35 +248,35 @@ struct xform entity_get_xform(struct entity *ent)
|
|||||||
return xf;
|
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;
|
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)) {
|
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 */
|
/* Update local xform */
|
||||||
if (ent->is_top) {
|
if (ent->is_top) {
|
||||||
ent->local_xform = xf;
|
ent->local_xform = xf;
|
||||||
} else {
|
} else {
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
struct sim_ent *parent = sim_ent_from_handle(store, ent->parent);
|
||||||
struct xform parent_global = entity_get_xform_w_store(store, parent);
|
struct xform parent_global = sim_ent_get_xform_w_store(store, parent);
|
||||||
ent->local_xform = xform_mul(xform_invert(parent_global), xf);
|
ent->local_xform = xform_mul(xform_invert(parent_global), xf);
|
||||||
}
|
}
|
||||||
ent->cached_global_xform = xf;
|
ent->cached_global_xform = xf;
|
||||||
ent->cached_global_xform_dirty = false;
|
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)) {
|
if (!xform_eq(xf, ent->local_xform)) {
|
||||||
ent->local_xform = xf;
|
ent->local_xform = xf;
|
||||||
ent->cached_global_xform_dirty = true;
|
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
|
* 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;
|
struct v2 center = xf.og;
|
||||||
f32 scale = math_fabs(xform_get_determinant(xf));
|
f32 scale = math_fabs(xform_get_determinant(xf));
|
||||||
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
||||||
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
||||||
|
|
||||||
struct v2 vcp = v2_sub(point, center);
|
struct v2 vcp = v2_sub(point, center);
|
||||||
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)));
|
||||||
entity_set_angular_velocity(ent, v2_wedge(vcp, impulse) * inv_inertia);
|
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 scale = math_fabs(xform_get_determinant(xf));
|
||||||
f32 inv_mass = 1.f / (ent->mass_unscaled * scale);
|
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);
|
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 scale = math_fabs(xform_get_determinant(xf));
|
||||||
f32 inv_inertia = 1.f / (ent->inertia_unscaled * scale);
|
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;
|
ent->torque += torque;
|
||||||
}
|
}
|
||||||
@ -328,22 +328,22 @@ void entity_apply_torque(struct entity *ent, f32 torque)
|
|||||||
* Tree
|
* 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) {
|
if (ent->parent.gen) {
|
||||||
/* Unlink from current parent */
|
/* Unlink from current parent */
|
||||||
entity_unlink_from_parent(ent);
|
sim_ent_unlink_from_parent(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity_handle handle = ent->handle;
|
struct sim_ent_handle handle = ent->handle;
|
||||||
struct entity_handle parent_handle = parent->handle;
|
struct sim_ent_handle parent_handle = parent->handle;
|
||||||
|
|
||||||
ent->parent = parent_handle;
|
ent->parent = parent_handle;
|
||||||
|
|
||||||
struct entity_handle last_child_handle = parent->last;
|
struct sim_ent_handle last_child_handle = parent->last;
|
||||||
struct entity *last_child = entity_from_handle(store, last_child_handle);
|
struct sim_ent *last_child = sim_ent_from_handle(store, last_child_handle);
|
||||||
if (last_child->valid) {
|
if (last_child->valid) {
|
||||||
ent->prev = last_child_handle;
|
ent->prev = last_child_handle;
|
||||||
last_child->next = 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. */
|
/* 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 sim_ent_handle parent_handle = ent->parent;
|
||||||
struct entity *parent = entity_from_handle(store, parent_handle);
|
struct sim_ent *parent = sim_ent_from_handle(store, parent_handle);
|
||||||
struct entity *prev = entity_from_handle(store, ent->prev);
|
struct sim_ent *prev = sim_ent_from_handle(store, ent->prev);
|
||||||
struct entity *next = entity_from_handle(store, ent->next);
|
struct sim_ent *next = sim_ent_from_handle(store, ent->next);
|
||||||
|
|
||||||
/* Unlink from parent & siblings */
|
/* Unlink from parent & siblings */
|
||||||
if (prev->valid) {
|
if (prev->valid) {
|
||||||
@ -381,35 +381,35 @@ void entity_unlink_from_parent(struct entity *ent)
|
|||||||
} else {
|
} else {
|
||||||
parent->last = prev->handle;
|
parent->last = prev->handle;
|
||||||
}
|
}
|
||||||
ent->prev = entity_handle_nil();
|
ent->prev = sim_ent_handle_nil();
|
||||||
ent->next = entity_handle_nil();
|
ent->next = sim_ent_handle_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Entity lookup
|
* 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);
|
ASSERT(num_buckets > 0);
|
||||||
struct entity_lookup l = ZI;
|
struct sim_ent_lookup l = ZI;
|
||||||
l.arena = arena_alloc(GIGABYTE(64));
|
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;
|
l.num_buckets = num_buckets;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void entity_lookup_release(struct entity_lookup *l)
|
void sim_ent_lookup_release(struct sim_ent_lookup *l)
|
||||||
{
|
{
|
||||||
arena_release(&l->arena);
|
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;
|
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 *res = NULL;
|
struct sim_ent_lookup_entry *res = NULL;
|
||||||
for (struct entity_lookup_entry *e = bucket->first; e; e = e->next) {
|
for (struct sim_ent_lookup_entry *e = bucket->first; e; e = e->next) {
|
||||||
if (e->key.hash == key.hash) {
|
if (e->key.hash == key.hash) {
|
||||||
res = e;
|
res = e;
|
||||||
break;
|
break;
|
||||||
@ -418,13 +418,13 @@ struct entity_lookup_entry *entity_lookup_get(struct entity_lookup *l, struct en
|
|||||||
return res;
|
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;
|
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 sim_ent_lookup_entry *prev = NULL;
|
||||||
struct entity_lookup_entry **slot = &bucket->first;
|
struct sim_ent_lookup_entry **slot = &bucket->first;
|
||||||
while (*slot) {
|
while (*slot) {
|
||||||
if ((*slot)->key.hash == key.hash) {
|
if ((*slot)->key.hash == key.hash) {
|
||||||
break;
|
break;
|
||||||
@ -433,7 +433,7 @@ void entity_lookup_set(struct entity_lookup *l, struct entity_lookup_key key, st
|
|||||||
slot = &(*slot)->next;
|
slot = &(*slot)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity_lookup_entry *entry = *slot;
|
struct sim_ent_lookup_entry *entry = *slot;
|
||||||
if (entry) {
|
if (entry) {
|
||||||
/* Set existing entry */
|
/* Set existing entry */
|
||||||
entry->entity = handle;
|
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->prev = NULL;
|
||||||
l->first_free_entry = entry->next;
|
l->first_free_entry = entry->next;
|
||||||
} else {
|
} else {
|
||||||
entry = arena_push(&l->arena, struct entity_lookup_entry);
|
entry = arena_push(&l->arena, struct sim_ent_lookup_entry);
|
||||||
}
|
}
|
||||||
MEMZERO_STRUCT(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 sim_ent_lookup_bucket *bucket = &l->buckets[entry->key.hash % l->num_buckets];
|
||||||
struct entity_lookup_entry *prev = entry->prev;
|
struct sim_ent_lookup_entry *prev = entry->prev;
|
||||||
struct entity_lookup_entry *next = entry->next;
|
struct sim_ent_lookup_entry *next = entry->next;
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev->next = next;
|
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;
|
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 b0 = STRING_FROM_STRUCT(&h0);
|
||||||
struct string b1 = STRING_FROM_STRUCT(&h1);
|
struct string b1 = STRING_FROM_STRUCT(&h1);
|
||||||
key.hash = hash_fnv64(HASH_FNV64_BASIS, b0);
|
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
|
* 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->activation_tick = current_tick_id;
|
||||||
++ent->continuity_gen;
|
++ent->continuity_gen;
|
||||||
}
|
}
|
||||||
@ -1,94 +1,94 @@
|
|||||||
#ifndef ENTITY_H
|
#ifndef SIM_ENT_H
|
||||||
#define ENTITY_H
|
#define SIM_ENT_H
|
||||||
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
#include "phys.h"
|
#include "phys.h"
|
||||||
#include "sim_client.h"
|
#include "sim_client.h"
|
||||||
|
|
||||||
enum entity_prop {
|
enum sim_ent_prop {
|
||||||
ENTITY_PROP_NONE,
|
SIM_ENT_PROP_NONE,
|
||||||
|
|
||||||
ENTITY_PROP_ACTIVE,
|
SIM_ENT_PROP_ACTIVE,
|
||||||
|
|
||||||
ENTITY_PROP_RELEASE_THIS_TICK,
|
SIM_ENT_PROP_RELEASE_THIS_TICK,
|
||||||
ENTITY_PROP_RELEASE_NEXT_TICK,
|
SIM_ENT_PROP_RELEASE_NEXT_TICK,
|
||||||
|
|
||||||
ENTITY_PROP_PHYSICAL_DYNAMIC,
|
SIM_ENT_PROP_PHYSICAL_DYNAMIC,
|
||||||
ENTITY_PROP_PHYSICAL_KINEMATIC,
|
SIM_ENT_PROP_PHYSICAL_KINEMATIC,
|
||||||
|
|
||||||
ENTITY_PROP_COLLISION_DEBUG,
|
SIM_ENT_PROP_COLLISION_DEBUG,
|
||||||
ENTITY_PROP_CONTACT_CONSTRAINT,
|
SIM_ENT_PROP_CONTACT_CONSTRAINT,
|
||||||
ENTITY_PROP_MOTOR_JOINT,
|
SIM_ENT_PROP_MOTOR_JOINT,
|
||||||
ENTITY_PROP_MOUSE_JOINT,
|
SIM_ENT_PROP_MOUSE_JOINT,
|
||||||
ENTITY_PROP_SENSOR,
|
SIM_ENT_PROP_SENSOR,
|
||||||
|
|
||||||
ENTITY_PROP_PLAYER_CONTROLLED,
|
SIM_ENT_PROP_PLAYER_CONTROLLED,
|
||||||
ENTITY_PROP_CAMERA,
|
SIM_ENT_PROP_CAMERA,
|
||||||
ENTITY_PROP_CAMERA_ACTIVE,
|
SIM_ENT_PROP_CAMERA_ACTIVE,
|
||||||
|
|
||||||
ENTITY_PROP_WEAPON,
|
SIM_ENT_PROP_WEAPON,
|
||||||
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
SIM_ENT_PROP_TRIGGERING_EQUIPPED,
|
||||||
ENTITY_PROP_TRIGGERED_THIS_TICK,
|
SIM_ENT_PROP_TRIGGERED_THIS_TICK,
|
||||||
ENTITY_PROP_TRIGGER_NEXT_TICK,
|
SIM_ENT_PROP_TRIGGER_NEXT_TICK,
|
||||||
|
|
||||||
ENTITY_PROP_BULLET,
|
SIM_ENT_PROP_BULLET,
|
||||||
ENTITY_PROP_TRACER,
|
SIM_ENT_PROP_TRACER,
|
||||||
|
|
||||||
ENTITY_PROP_QUAKE,
|
SIM_ENT_PROP_QUAKE,
|
||||||
|
|
||||||
ENTITY_PROP_ATTACHED,
|
SIM_ENT_PROP_ATTACHED,
|
||||||
|
|
||||||
/* Test props */
|
/* Test props */
|
||||||
|
|
||||||
ENTITY_PROP_TEST,
|
SIM_ENT_PROP_TEST,
|
||||||
ENTITY_PROP_TEST_SOUND_EMITTER,
|
SIM_ENT_PROP_TEST_SOUND_EMITTER,
|
||||||
|
|
||||||
ENTITY_PROP_COUNT
|
SIM_ENT_PROP_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_store {
|
struct sim_ent_store {
|
||||||
b32 valid;
|
b32 valid;
|
||||||
struct arena arena;
|
struct arena arena;
|
||||||
u64 num_allocated;
|
u64 num_allocated;
|
||||||
u64 num_reserved;
|
u64 num_reserved;
|
||||||
struct entity_handle first_free;
|
struct sim_ent_handle first_free;
|
||||||
struct entity_handle root;
|
struct sim_ent_handle root;
|
||||||
struct entity *entities;
|
struct sim_ent *entities;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_lookup_key {
|
struct sim_ent_lookup_key {
|
||||||
u64 hash;
|
u64 hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_lookup_entry {
|
struct sim_ent_lookup_entry {
|
||||||
struct entity_lookup_key key;
|
struct sim_ent_lookup_key key;
|
||||||
struct entity_handle entity;
|
struct sim_ent_handle entity;
|
||||||
struct entity_lookup_entry *next;
|
struct sim_ent_lookup_entry *next;
|
||||||
struct entity_lookup_entry *prev;
|
struct sim_ent_lookup_entry *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_lookup_bucket {
|
struct sim_ent_lookup_bucket {
|
||||||
struct entity_lookup_entry *first;
|
struct sim_ent_lookup_entry *first;
|
||||||
struct entity_lookup_entry *last;
|
struct sim_ent_lookup_entry *last;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_lookup {
|
struct sim_ent_lookup {
|
||||||
struct arena arena;
|
struct arena arena;
|
||||||
struct entity_lookup_bucket *buckets;
|
struct sim_ent_lookup_bucket *buckets;
|
||||||
u64 num_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 */
|
/* Metadata */
|
||||||
|
|
||||||
b32 valid; /* Is this entity allocated in memory that can be written to (can always be read) */
|
b32 valid; /* Is this ent allocated in memory that can be written to (can always be read) */
|
||||||
struct entity_handle handle;
|
struct sim_ent_handle handle;
|
||||||
u64 continuity_gen;
|
u64 continuity_gen;
|
||||||
u64 props[(ENTITY_PROP_COUNT + 63) / 64];
|
u64 props[(SIM_ENT_PROP_COUNT + 63) / 64];
|
||||||
struct entity_handle next_free;
|
struct sim_ent_handle next_free;
|
||||||
|
|
||||||
/* Is this the root entity */
|
/* Is this the root entity */
|
||||||
b32 is_root;
|
b32 is_root;
|
||||||
@ -97,14 +97,14 @@ struct entity {
|
|||||||
b32 is_top;
|
b32 is_top;
|
||||||
|
|
||||||
/* The handle of the top level parent of the entity */
|
/* The handle of the top level parent of the entity */
|
||||||
struct entity_handle top;
|
struct sim_ent_handle top;
|
||||||
|
|
||||||
/* Tree */
|
/* Tree */
|
||||||
struct entity_handle parent;
|
struct sim_ent_handle parent;
|
||||||
struct entity_handle next;
|
struct sim_ent_handle next;
|
||||||
struct entity_handle prev;
|
struct sim_ent_handle prev;
|
||||||
struct entity_handle first;
|
struct sim_ent_handle first;
|
||||||
struct entity_handle last;
|
struct sim_ent_handle last;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Position */
|
/* Position */
|
||||||
@ -140,25 +140,25 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Contact constraint */
|
/* Contact constraint */
|
||||||
|
|
||||||
/* ENTITY_PROP_CONSTRAINT_CONTACT */
|
/* SIM_ENT_PROP_CONSTRAINT_CONTACT */
|
||||||
struct phys_contact_constraint contact_constraint_data;
|
struct phys_contact_constraint contact_constraint_data;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Motor joint */
|
/* Motor joint */
|
||||||
|
|
||||||
/* ENTITY_PROP_MOTOR_JOINT */
|
/* SIM_ENT_PROP_MOTOR_JOINT */
|
||||||
struct phys_motor_joint motor_joint_data;
|
struct phys_motor_joint motor_joint_data;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Mouse joint */
|
/* Mouse joint */
|
||||||
|
|
||||||
/* ENTITY_PROP_MOUSE_JOINT */
|
/* SIM_ENT_PROP_MOUSE_JOINT */
|
||||||
struct phys_mouse_joint mouse_joint_data;
|
struct phys_mouse_joint mouse_joint_data;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Player */
|
/* Player */
|
||||||
|
|
||||||
/* ENTITY_PROP_PLAYER_CONTROLLED */
|
/* SIM_ENT_PROP_PLAYER_CONTROLLED */
|
||||||
struct client_handle controlling_client;
|
struct client_handle controlling_client;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
@ -174,13 +174,13 @@ struct entity {
|
|||||||
struct v2 focus; /* Focus direction vector (where should the entity look) */
|
struct v2 focus; /* Focus direction vector (where should the entity look) */
|
||||||
} control;
|
} control;
|
||||||
|
|
||||||
struct entity_handle move_joint;
|
struct sim_ent_handle move_joint;
|
||||||
struct entity_handle aim_joint;
|
struct sim_ent_handle aim_joint;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Physics */
|
/* Physics */
|
||||||
|
|
||||||
/* ENTITY_PROP_PHYSICAL_DYNAMIC */
|
/* SIM_ENT_PROP_PHYSICAL_DYNAMIC */
|
||||||
|
|
||||||
//f32 density; /* Density in kg/m^2 */
|
//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 mass_unscaled; /* Mass of entity in kg before any transformations */
|
||||||
f32 inertia_unscaled; /* Inertia of entity in kg*m^2 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 linear_ground_friction;
|
||||||
f32 angular_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 */
|
struct v2 linear_velocity; /* m/s */
|
||||||
f32 angular_velocity; /* rad/s */
|
f32 angular_velocity; /* rad/s */
|
||||||
|
|
||||||
@ -217,34 +217,34 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Animation */
|
/* Animation */
|
||||||
|
|
||||||
/* ENTITY_PROP_ANIMATING */
|
/* SIM_ENT_PROP_ANIMATING */
|
||||||
f64 animation_time_in_frame;
|
f64 animation_time_in_frame;
|
||||||
u32 animation_frame;
|
u32 animation_frame;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Attachment */
|
/* Attachment */
|
||||||
|
|
||||||
/* ENTITY_PROP_ATTACHED */
|
/* SIM_ENT_PROP_ATTACHED */
|
||||||
/* Slice name on the parent entity's sprite to attach to */
|
/* Slice name on the parent entity's sprite to attach to */
|
||||||
struct string attach_slice;
|
struct string attach_slice;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Equip */
|
/* Equip */
|
||||||
|
|
||||||
struct entity_handle equipped;
|
struct sim_ent_handle equipped;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Triggers */
|
/* Triggers */
|
||||||
|
|
||||||
/* ENTITY_PROP_TRIGGERED_THIS_TICK */
|
/* SIM_ENT_PROP_TRIGGERED_THIS_TICK */
|
||||||
f32 trigger_delay; /* Minimum time between triggers */
|
f32 trigger_delay; /* Minimum time between triggers */
|
||||||
f32 last_triggered;
|
f32 last_triggered;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Bullet */
|
/* Bullet */
|
||||||
|
|
||||||
struct entity_handle bullet_src;
|
struct sim_ent_handle bullet_src;
|
||||||
struct entity_handle bullet_tracer;
|
struct sim_ent_handle bullet_tracer;
|
||||||
struct v2 bullet_src_pos;
|
struct v2 bullet_src_pos;
|
||||||
struct v2 bullet_src_dir;
|
struct v2 bullet_src_dir;
|
||||||
f32 bullet_impulse;
|
f32 bullet_impulse;
|
||||||
@ -254,7 +254,7 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Tracer */
|
/* Tracer */
|
||||||
|
|
||||||
/* ENTITY_PROP_TRACER */
|
/* SIM_ENT_PROP_TRACER */
|
||||||
|
|
||||||
struct v2 tracer_start;
|
struct v2 tracer_start;
|
||||||
struct v2 tracer_start_velocity;
|
struct v2 tracer_start_velocity;
|
||||||
@ -267,7 +267,7 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Quake */
|
/* Quake */
|
||||||
|
|
||||||
/* ENTITY_PROP_QUAKE */
|
/* SIM_ENT_PROP_QUAKE */
|
||||||
|
|
||||||
f32 quake_intensity;
|
f32 quake_intensity;
|
||||||
f32 quake_frequency;
|
f32 quake_frequency;
|
||||||
@ -276,12 +276,12 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Testing */
|
/* Testing */
|
||||||
|
|
||||||
/* ENTITY_PROP_TEST */
|
/* SIM_ENT_PROP_TEST */
|
||||||
b32 test_initialized;
|
b32 test_initialized;
|
||||||
struct xform test_start_local_xform;
|
struct xform test_start_local_xform;
|
||||||
struct xform test_start_sprite_xform;
|
struct xform test_start_sprite_xform;
|
||||||
|
|
||||||
/* ENTITY_PROP_TEST_SOUND_EMITTER */
|
/* SIM_ENT_PROP_TEST_SOUND_EMITTER */
|
||||||
struct string sound_name;
|
struct string sound_name;
|
||||||
struct mixer_desc sound_desc;
|
struct mixer_desc sound_desc;
|
||||||
struct mixer_track_handle sound_handle;
|
struct mixer_track_handle sound_handle;
|
||||||
@ -289,8 +289,8 @@ struct entity {
|
|||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Camera */
|
/* Camera */
|
||||||
|
|
||||||
/* ENTITY_PROP_CAMERA */
|
/* SIM_ENT_PROP_CAMERA */
|
||||||
struct entity_handle camera_follow;
|
struct sim_ent_handle camera_follow;
|
||||||
struct xform camera_quad_xform;
|
struct xform camera_quad_xform;
|
||||||
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
||||||
|
|
||||||
@ -301,13 +301,13 @@ struct entity {
|
|||||||
f32 shake;
|
f32 shake;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_array {
|
struct sim_ent_array {
|
||||||
struct entity *entities;
|
struct sim_ent *entities;
|
||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entity_prop_array {
|
struct sim_ent_prop_array {
|
||||||
enum entity_prop *props;
|
enum sim_ent_prop *props;
|
||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,12 +315,12 @@ struct entity_prop_array {
|
|||||||
* Handle helpers
|
* 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;
|
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
|
* Nil
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INLINE struct entity *entity_nil(void)
|
INLINE struct sim_ent *sim_ent_nil(void)
|
||||||
{
|
{
|
||||||
extern READONLY struct entity _g_entity_nil;
|
extern READONLY struct sim_ent _g_sim_ent_nil;
|
||||||
return &_g_entity_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;
|
extern READONLY struct sim_ent_store _g_sim_ent_store_nil;
|
||||||
return &_g_entity_store_nil;
|
return &_g_sim_ent_store_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Property helpers
|
* 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 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
ent->props[index] |= ((u64)1 << bit);
|
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 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
ent->props[index] &= ~((u64)1 << bit);
|
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 index = prop / 64;
|
||||||
u64 bit = prop % 64;
|
u64 bit = prop % 64;
|
||||||
return !!(ent->props[index] & ((u64)1 << bit));
|
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 */
|
/* Entity store */
|
||||||
struct entity_store *entity_store_alloc(void);
|
struct sim_ent_store *sim_ent_store_alloc(void);
|
||||||
void entity_store_release(struct entity_store *store);
|
void sim_ent_store_release(struct sim_ent_store *store);
|
||||||
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);
|
||||||
|
|
||||||
/* Entity */
|
/* Entity */
|
||||||
struct entity *entity_alloc(struct entity *parent);
|
struct sim_ent *sim_ent_alloc(struct sim_ent *parent);
|
||||||
void entity_release(struct entity_store *store, struct entity *ent);
|
void sim_ent_release(struct sim_ent_store *store, struct sim_ent *ent);
|
||||||
|
|
||||||
/* Xform */
|
/* Xform */
|
||||||
struct xform entity_get_xform(struct entity *ent);
|
struct xform sim_ent_get_xform(struct sim_ent *ent);
|
||||||
struct xform entity_get_local_xform(struct entity *ent);
|
struct xform sim_ent_get_local_xform(struct sim_ent *ent);
|
||||||
void entity_set_xform(struct entity *ent, struct xform xf);
|
void sim_ent_set_xform(struct sim_ent *ent, struct xform xf);
|
||||||
void entity_set_local_xform(struct entity *ent, struct xform xf);
|
void sim_ent_set_local_xform(struct sim_ent *ent, struct xform xf);
|
||||||
|
|
||||||
/* Movement */
|
/* 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 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 entity_set_angular_velocity(struct entity *ent, f32 velocity) { ent->angular_velocity = clamp_f32(velocity, -SIM_MAX_ANGULAR_VELOCITY, SIM_MAX_ANGULAR_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 entity_apply_linear_impulse(struct entity *ent, struct v2 impulse, struct v2 world_point);
|
void sim_ent_apply_linear_impulse(struct sim_ent *ent, struct v2 impulse, struct v2 world_point);
|
||||||
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);
|
||||||
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);
|
||||||
void entity_apply_angular_impulse(struct entity *ent, f32 impulse);
|
void sim_ent_apply_angular_impulse(struct sim_ent *ent, f32 impulse);
|
||||||
void entity_apply_torque(struct entity *ent, f32 torque);
|
void sim_ent_apply_torque(struct sim_ent *ent, f32 torque);
|
||||||
|
|
||||||
/* Query */
|
/* Query */
|
||||||
struct entity_store *entity_store_from_entity(struct entity *ent);
|
struct sim_ent_store *sim_ent_store_from_ent(struct sim_ent *ent);
|
||||||
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);
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
/* Tree */
|
/* Tree */
|
||||||
void entity_link_parent(struct entity *parent, struct entity *child);
|
void sim_ent_link_parent(struct sim_ent *parent, struct sim_ent *child);
|
||||||
void entity_unlink_from_parent(struct entity *ent);
|
void sim_ent_unlink_from_parent(struct sim_ent *ent);
|
||||||
|
|
||||||
/* Lookup */
|
/* Lookup */
|
||||||
struct entity_lookup entity_lookup_alloc(u64 num_buckets);
|
struct sim_ent_lookup sim_ent_lookup_alloc(u64 num_buckets);
|
||||||
void entity_lookup_release(struct entity_lookup *l);
|
void sim_ent_lookup_release(struct sim_ent_lookup *l);
|
||||||
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);
|
||||||
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);
|
||||||
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_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);
|
||||||
|
|
||||||
/* Activate */
|
/* Activate */
|
||||||
void entity_activate(struct entity *ent, u64 current_tick_id);
|
void sim_ent_activate(struct sim_ent *ent, u64 current_tick_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* Offset in bytes from start of space struct to start of entry array (assume adjacently allocated) */
|
/* 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)))
|
#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_entry _g_space_entry_nil = { .valid = false };
|
||||||
READONLY struct space_cell _g_space_cell_nil = { .valid = false };
|
READONLY struct space_cell _g_space_cell_nil = { .valid = false };
|
||||||
READONLY struct space _g_space_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;
|
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 *entry = NULL;
|
||||||
struct space_entry_handle handle = ZI;
|
struct space_entry_handle handle = ZI;
|
||||||
|
|||||||
@ -11,7 +11,7 @@ struct space_entry {
|
|||||||
struct space_cell_node *last_node;
|
struct space_cell_node *last_node;
|
||||||
|
|
||||||
struct aabb aabb;
|
struct aabb aabb;
|
||||||
struct entity_handle ent;
|
struct sim_ent_handle ent;
|
||||||
|
|
||||||
struct space_entry *next_free;
|
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_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_release(struct space_entry *entry);
|
||||||
void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb);
|
void space_entry_update_aabb(struct space_entry *entry, struct aabb new_aabb);
|
||||||
|
|
||||||
|
|||||||
120
src/user.c
120
src/user.c
@ -1,19 +1,19 @@
|
|||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
#include "sim.h"
|
||||||
|
#include "sim_ent.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "intrinsics.h"
|
#include "intrinsics.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "sim.h"
|
|
||||||
#include "asset_cache.h"
|
#include "asset_cache.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "scratch.h"
|
#include "scratch.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "entity.h"
|
|
||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "collider.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) */
|
/* 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 thickness = 2.f;
|
||||||
f32 arrow_len = 15.f;
|
f32 arrow_len = 15.f;
|
||||||
|
|
||||||
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
struct xform xf = sim_ent_get_xform(ent);
|
||||||
struct v2 velocity = ent->linear_velocity;
|
struct v2 velocity = ent->linear_velocity;
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
|
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
|
* 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;
|
(UNUSED)udata;
|
||||||
struct entity *a = *(struct entity **)arg_a;
|
struct sim_ent *a = *(struct sim_ent **)arg_a;
|
||||||
struct entity *b = *(struct entity **)arg_b;
|
struct sim_ent *b = *(struct sim_ent **)arg_b;
|
||||||
|
|
||||||
i32 res = 0;
|
i32 res = 0;
|
||||||
|
|
||||||
@ -517,7 +517,7 @@ INTERNAL void user_update(void)
|
|||||||
G.time_ns += G.dt_ns;
|
G.time_ns += G.dt_ns;
|
||||||
G.screen_size = sys_window_get_size(G.window);
|
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 sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
||||||
struct sim_cmd_list cmd_list = ZI;
|
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);
|
G.world.dt_ns = math_lerp_i64(t0->dt_ns, t1->dt_ns, (f64)tick_blend);
|
||||||
|
|
||||||
/* Blend entities */
|
/* 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);
|
__profscope(tick_blending);
|
||||||
for (u64 i = 0; i < num_entities; ++i) {
|
for (u64 i = 0; i < num_entities; ++i) {
|
||||||
struct entity *e = &store->entities[i];
|
struct sim_ent *e = &store->entities[i];
|
||||||
struct entity *e0 = &t0->entity_store->entities[i];
|
struct sim_ent *e0 = &t0->ent_store->entities[i];
|
||||||
struct entity *e1 = &t1->entity_store->entities[i];
|
struct sim_ent *e1 = &t1->ent_store->entities[i];
|
||||||
|
|
||||||
if (e0->valid && e1->valid
|
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->handle.gen == e1->handle.gen
|
||||||
&& e0->continuity_gen == e1->continuity_gen) {
|
&& e0->continuity_gen == e1->continuity_gen) {
|
||||||
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
||||||
|
|
||||||
if (e->is_top) {
|
if (e->is_top) {
|
||||||
/* TODO: Cache parent & child xforms in sim thread */
|
/* TODO: Cache parent & child xforms in sim thread */
|
||||||
struct xform e0_xf = entity_get_xform(e0);
|
struct xform e0_xf = sim_ent_get_xform(e0);
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = sim_ent_get_xform(e1);
|
||||||
entity_set_xform(e, xform_lerp(e0_xf, e1_xf, tick_blend));
|
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);
|
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) {
|
for (u64 ent_index = 0; ent_index < events.count; ++ent_index) {
|
||||||
struct sys_event *event = &events.events[entity_index];
|
struct sys_event *event = &events.events[ent_index];
|
||||||
|
|
||||||
if (event->kind == SYS_EVENT_KIND_QUIT) {
|
if (event->kind == SYS_EVENT_KIND_QUIT) {
|
||||||
app_exit();
|
app_exit();
|
||||||
@ -729,16 +729,16 @@ INTERNAL void user_update(void)
|
|||||||
* Find important entities
|
* Find important entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct entity *active_camera;
|
struct sim_ent *active_camera;
|
||||||
{
|
{
|
||||||
enum entity_prop props[] = { ENTITY_PROP_CAMERA, ENTITY_PROP_CAMERA_ACTIVE };
|
enum sim_ent_prop props[] = { SIM_ENT_PROP_CAMERA, SIM_ENT_PROP_CAMERA_ACTIVE };
|
||||||
active_camera = entity_find_first_match_all(store, (struct entity_prop_array) { .count = ARRAY_COUNT(props), .props = props });
|
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 };
|
enum sim_ent_prop props[] = { SIM_ENT_PROP_PLAYER_CONTROLLED, SIM_ENT_PROP_ACTIVE };
|
||||||
active_player = entity_find_first_match_all(store, (struct entity_prop_array) { .count = ARRAY_COUNT(props), .props = props });
|
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
|
* Apply shake
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 ent_index = 0; ent_index < store->num_reserved; ++ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[ent_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
|
|
||||||
/* How much time between camera shakes */
|
/* How much time between camera shakes */
|
||||||
i64 frequency_ns = NS_FROM_SECONDS(0.01f);
|
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;
|
f32 blend = (f32)(G.world.time_ns % frequency_ns) / (f32)frequency_ns;
|
||||||
struct v2 vec = v2_lerp(vec0, vec1, blend);
|
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));
|
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 */
|
/* Determine ui size by camera & window dimensions */
|
||||||
f32 aspect_ratio = 1.0;
|
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);
|
struct v2 camera_size = xform_get_scale(quad_xf);
|
||||||
if (!v2_is_zero(camera_size)) {
|
if (!v2_is_zero(camera_size)) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
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));
|
G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(world_cursor));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct xform xf = entity_get_xform(active_camera);
|
struct xform xf = sim_ent_get_xform(active_camera);
|
||||||
|
|
||||||
struct v2 center = xf.og;
|
struct v2 center = xf.og;
|
||||||
f32 rot = xform_get_rotation(xf);
|
f32 rot = xform_get_rotation(xf);
|
||||||
@ -969,16 +969,16 @@ INTERNAL void user_update(void)
|
|||||||
* Sort entities
|
* 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;
|
u64 sorted_count = 0;
|
||||||
{
|
{
|
||||||
/* Copy valid entities */
|
/* Copy valid entities */
|
||||||
{
|
{
|
||||||
__profscope(copy_sprites_for_sorting);
|
__profscope(copy_sprites_for_sorting);
|
||||||
for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
|
for (u64 ent_index = 0; ent_index < store->num_reserved; ++ent_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct sim_ent *ent = &store->entities[ent_index];
|
||||||
if (entity_is_valid_and_active(ent)) {
|
if (sim_ent_is_valid_and_active(ent)) {
|
||||||
*arena_push(scratch.arena, struct entity *) = ent;
|
*arena_push(scratch.arena, struct sim_ent *) = ent;
|
||||||
++sorted_count;
|
++sorted_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -986,7 +986,7 @@ INTERNAL void user_update(void)
|
|||||||
/* Sort */
|
/* Sort */
|
||||||
{
|
{
|
||||||
__profscope(sort_sprites);
|
__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);
|
__profscope(draw_entities);
|
||||||
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index) {
|
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index) {
|
||||||
struct entity *ent = sorted[sorted_index];
|
struct sim_ent *ent = sorted[sorted_index];
|
||||||
if (!entity_is_valid_and_active(ent)) continue;
|
if (!sim_ent_is_valid_and_active(ent)) continue;
|
||||||
//if (sprite_tag_is_nil(ent->sprite)) continue;
|
//if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
struct sprite_tag sprite = ent->sprite;
|
struct sprite_tag sprite = ent->sprite;
|
||||||
|
|
||||||
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 xf = sim_ent_get_xform(ent);
|
||||||
struct xform parent_xf = entity_get_xform(parent);
|
struct xform parent_xf = sim_ent_get_xform(parent);
|
||||||
|
|
||||||
b32 skip_debug_draw = !G.debug_camera && ent == active_camera;
|
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;
|
skip_debug_draw_transform = true;
|
||||||
|
|
||||||
struct xform sprite_xform = xf;
|
struct xform sprite_xform = xf;
|
||||||
|
|
||||||
/* Draw tracer */
|
/* 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 velocity = ent->tracer_start_velocity;
|
||||||
|
|
||||||
struct v2 a = ent->tracer_start;
|
struct v2 a = ent->tracer_start;
|
||||||
@ -1073,7 +1073,7 @@ INTERNAL void user_update(void)
|
|||||||
if (G.debug_draw && !skip_debug_draw) {
|
if (G.debug_draw && !skip_debug_draw) {
|
||||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
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);
|
debug_draw_movement(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1095,7 +1095,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw focus arrow */
|
/* 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 *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 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);
|
struct v2 start = xform_mul_v2(sprite_xform, slice.center);
|
||||||
@ -1149,7 +1149,7 @@ INTERNAL void user_update(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Draw collider */
|
/* 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;
|
struct collider_shape collider = ent->local_collider;
|
||||||
u32 color = RGBA_32_F(1, 1, 0, 0.5);
|
u32 color = RGBA_32_F(1, 1, 0, 0.5);
|
||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
@ -1186,10 +1186,10 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw contact constraint */
|
/* 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 phys_contact_constraint *data = &ent->contact_constraint_data;
|
||||||
struct entity *e0 = entity_from_handle(store, data->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, data->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, data->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, data->e1);
|
||||||
(UNUSED)e0;
|
(UNUSED)e0;
|
||||||
(UNUSED)e1;
|
(UNUSED)e1;
|
||||||
|
|
||||||
@ -1262,11 +1262,11 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Draw collision debug */
|
/* Draw collision debug */
|
||||||
#if COLLIDER_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 phys_collision_debug *data = &ent->collision_debug_data;
|
||||||
struct collider_collision_points_result collider_res = data->res;
|
struct collider_collision_points_result collider_res = data->res;
|
||||||
struct entity *e0 = entity_from_handle(store, data->e0);
|
struct sim_ent *e0 = sim_ent_from_handle(store, data->e0);
|
||||||
struct entity *e1 = entity_from_handle(store, data->e1);
|
struct sim_ent *e1 = sim_ent_from_handle(store, data->e1);
|
||||||
struct collider_shape e0_collider = e0->local_collider;
|
struct collider_shape e0_collider = e0->local_collider;
|
||||||
struct collider_shape e1_collider = e1->local_collider;
|
struct collider_shape e1_collider = e1->local_collider;
|
||||||
(UNUSED)e0_collider;
|
(UNUSED)e0_collider;
|
||||||
@ -1453,7 +1453,7 @@ INTERNAL void user_update(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Draw hierarchy */
|
/* 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);
|
u32 color = RGBA_32_F(0.6, 0.6, 1, 0.75);
|
||||||
f32 thickness = 2;
|
f32 thickness = 2;
|
||||||
f32 arrow_height = 15;
|
f32 arrow_height = 15;
|
||||||
@ -1464,7 +1464,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw camera rect */
|
/* 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);
|
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;
|
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 = 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);
|
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 cursor move cmd */
|
||||||
queue_sim_cmd(scratch.arena, &cmd_list, (struct sim_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))));
|
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;
|
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;
|
||||||
|
|
||||||
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"))));
|
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;
|
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)));
|
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;
|
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)));
|
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;
|
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)));
|
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;
|
pos.y += spacing;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
10
src/world.c
10
src/world.c
@ -1,17 +1,17 @@
|
|||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "entity.h"
|
#include "sim_ent.h"
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
#include "scratch.h"
|
#include "scratch.h"
|
||||||
|
|
||||||
void world_alloc(struct world *world)
|
void world_alloc(struct world *world)
|
||||||
{
|
{
|
||||||
MEMZERO_STRUCT(world);
|
MEMZERO_STRUCT(world);
|
||||||
world->entity_store = entity_store_alloc();
|
world->ent_store = sim_ent_store_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void world_release(struct world *world)
|
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)
|
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;
|
*old = *dest;
|
||||||
|
|
||||||
MEMCPY_STRUCT(dest, src);
|
MEMCPY_STRUCT(dest, src);
|
||||||
dest->entity_store = old->entity_store;
|
dest->ent_store = old->ent_store;
|
||||||
entity_store_copy_replace(dest->entity_store, src->entity_store);
|
sim_ent_store_copy_replace(dest->ent_store, src->ent_store);
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#ifndef WORLD_H
|
#ifndef WORLD_H
|
||||||
#define WORLD_H
|
#define WORLD_H
|
||||||
|
|
||||||
#include "entity.h"
|
#include "sim_ent.h"
|
||||||
|
|
||||||
struct world {
|
struct world {
|
||||||
u64 continuity_gen; /* Starts at 1 */
|
u64 continuity_gen; /* Starts at 1 */
|
||||||
@ -13,7 +13,7 @@ struct world {
|
|||||||
i64 dt_ns;
|
i64 dt_ns;
|
||||||
i64 time_ns;
|
i64 time_ns;
|
||||||
|
|
||||||
struct entity_store *entity_store;
|
struct sim_ent_store *ent_store;
|
||||||
};
|
};
|
||||||
|
|
||||||
void world_alloc(struct world *world);
|
void world_alloc(struct world *world);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user