sorted layers first pass

This commit is contained in:
jacob 2025-01-16 11:42:26 -06:00
parent c361becc73
commit d2cfeed161
6 changed files with 94 additions and 3 deletions

View File

@ -104,6 +104,12 @@ struct entity {
struct entity_handle first; struct entity_handle first;
struct entity_handle last; struct entity_handle last;
/* ====================================================================== */
/* Layer */
i32 layer;
i32 final_layer; /* Calculated each tick from entity tree */
/* ====================================================================== */ /* ====================================================================== */
/* Collider */ /* Collider */

View File

@ -202,6 +202,7 @@ INTERNAL void spawn_test_entities(void)
//e->sprite_span_name = STR("idle.unarmed"); //e->sprite_span_name = STR("idle.unarmed");
//e->sprite_span_name = STR("idle.one_handed"); //e->sprite_span_name = STR("idle.one_handed");
e->sprite_span_name = STR("idle.two_handed"); e->sprite_span_name = STR("idle.two_handed");
e->layer = GAME_LAYER_SHOULDERS;
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size); struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
//xf.bx.y = -1.f; //xf.bx.y = -1.f;
@ -235,6 +236,7 @@ INTERNAL void spawn_test_entities(void)
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
e->sprite_collider_slice = STR("shape"); e->sprite_collider_slice = STR("shape");
e->layer = GAME_LAYER_SHOULDERS;
entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC); entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC);
e->mass_unscaled = 10; e->mass_unscaled = 10;
@ -258,6 +260,7 @@ INTERNAL void spawn_test_entities(void)
e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase")); e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase"));
e->sprite_collider_slice = STR("shape"); e->sprite_collider_slice = STR("shape");
e->layer = GAME_LAYER_SHOULDERS;
entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC); entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC);
e->mass_unscaled = 100; e->mass_unscaled = 100;
@ -280,6 +283,7 @@ INTERNAL void spawn_test_entities(void)
e->sprite = sprite_tag_from_path(STR("res/graphics/bullet.ase")); e->sprite = sprite_tag_from_path(STR("res/graphics/bullet.ase"));
e->sprite_collider_slice = STR("shape"); e->sprite_collider_slice = STR("shape");
e->layer = GAME_LAYER_SHOULDERS;
entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC); entity_enable_prop(e, ENTITY_PROP_PHYSICAL_DYNAMIC);
e->mass_unscaled = 0.5; e->mass_unscaled = 0.5;
@ -295,6 +299,7 @@ INTERNAL void spawn_test_entities(void)
entity_enable_prop(e, ENTITY_PROP_ATTACHED); entity_enable_prop(e, ENTITY_PROP_ATTACHED);
e->attach_slice = STR("attach.wep"); e->attach_slice = STR("attach.wep");
e->layer = GAME_LAYER_RELATIVE_WEAPON;
entity_enable_prop(e, ENTITY_PROP_WEAPON); entity_enable_prop(e, ENTITY_PROP_WEAPON);
e->trigger_delay = 1.0f / 10.0f; e->trigger_delay = 1.0f / 10.0f;
@ -418,6 +423,7 @@ INTERNAL PHYS_COLLISION_CALLBACK_FUNC_DEF(on_collision, array)
struct entity *decal = entity_alloc(root); struct entity *decal = entity_alloc(root);
decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase")); decal->sprite = sprite_tag_from_path(STR("res/graphics/blood.ase"));
decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f); decal->sprite_tint = RGBA_32_F(1, 1, 1, 0.25f);
decal->layer = GAME_LAYER_FLOOR_DECALS;
entity_set_xform(decal, xf); entity_set_xform(decal, xf);
f32 perp_range = 0.5; f32 perp_range = 0.5;
@ -860,6 +866,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
bullet->bullet_knockback = 10; bullet->bullet_knockback = 10;
bullet->mass_unscaled = 0.04f; bullet->mass_unscaled = 0.04f;
bullet->inertia_unscaled = 0.00001f; bullet->inertia_unscaled = 0.00001f;
bullet->layer = GAME_LAYER_BULLETS;
#if 1 #if 1
/* Point collider */ /* Point collider */
@ -878,6 +885,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
{ {
struct entity *tracer = entity_alloc(root); struct entity *tracer = entity_alloc(root);
tracer->tracer_fade_duration = 0.025f; tracer->tracer_fade_duration = 0.025f;
tracer->layer = GAME_LAYER_TRACERS;
entity_enable_prop(tracer, ENTITY_PROP_TRACER); entity_enable_prop(tracer, ENTITY_PROP_TRACER);
bullet->bullet_tracer = tracer->handle; bullet->bullet_tracer = tracer->handle;
@ -1228,6 +1236,35 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
} }
/* ========================== *
* Update relative layers
* ========================== */
{
struct temp_arena temp = arena_temp_begin(scratch.arena);
struct entity **stack = arena_push(temp.arena, struct entity *);
u64 stack_count = 1;
*stack = root;
while (stack_count > 0) {
struct entity *parent;
arena_pop(temp.arena, struct entity *, &parent);
--stack_count;
i32 parent_layer = parent->final_layer;
for (struct entity *child = entity_from_handle(store, parent->first); child->valid; child = entity_from_handle(store, child->next)) {
if (entity_is_valid_and_active(child)) {
child->final_layer = parent_layer + child->layer;
*arena_push(temp.arena, struct entity *) = child;
++stack_count;
}
}
}
arena_temp_end(temp);
}
/* ========================== * /* ========================== *
* Update sound emitters * Update sound emitters
* ========================== */ * ========================== */

View File

@ -30,6 +30,16 @@ enum game_cmd_kind {
GAME_CMD_KIND_COUNT GAME_CMD_KIND_COUNT
}; };
/* Absolute layers */
#define GAME_LAYER_FLOOR_DECALS -300
#define GAME_LAYER_BULLETS -200
#define GAME_LAYER_TRACERS -100
#define GAME_LAYER_SHOULDERS 0
/* Relative layers */
#define GAME_LAYER_RELATIVE_DEFAULT 0
#define GAME_LAYER_RELATIVE_WEAPON 1
struct game_cmd { struct game_cmd {
enum game_cmd_kind kind; enum game_cmd_kind kind;
enum game_cmd_state state; enum game_cmd_state state;

View File

@ -312,6 +312,25 @@ b32 string_eq(struct string str1, struct string str2)
return eq; return eq;
} }
i32 string_cmp(struct string str1, struct string str2)
{
i32 res = 0;
for (u64 i = 0; i < min_u64(str1.len, str2.len); ++i) {
res = str1.text[i] - str2.text[i];
if (res != 0) {
break;
}
}
if (res == 0) {
if (str1.len > str2.len) {
res = str1.text[str2.len];
} else if (str2.len > str1.len) {
res = str2.text[str1.len];
}
}
return res;
}
b32 string_contains(struct string str, struct string substring) b32 string_contains(struct string str, struct string substring)
{ {
if (substring.len > str.len) { if (substring.len > str.len) {

View File

@ -28,6 +28,7 @@ struct string_array string_split(struct arena *arena, struct string str, struct
struct string string_indent(struct arena *arena, struct string str, u32 indent); struct string string_indent(struct arena *arena, struct string str, u32 indent);
struct string string_lower(struct arena *arena, struct string str); struct string string_lower(struct arena *arena, struct string str);
b32 string_eq(struct string str1, struct string str2); b32 string_eq(struct string str1, struct string str2);
i32 string_cmp(struct string str1, struct string str2);
b32 string_contains(struct string str, struct string substring); b32 string_contains(struct string str, struct string substring);
b32 string_starts_with(struct string str, struct string substring); b32 string_starts_with(struct string str, struct string substring);
b32 string_ends_with(struct string str, struct string substring); b32 string_ends_with(struct string str, struct string substring);

View File

@ -439,10 +439,28 @@ INTERNAL SORT_COMPARE_FUNC_DEF(sort_entities, arg_a, arg_b, udata)
struct entity *a = *(struct entity **)arg_a; struct entity *a = *(struct entity **)arg_a;
struct entity *b = *(struct entity **)arg_b; struct entity *b = *(struct entity **)arg_b;
u64 a_index = a->handle.idx; i32 res = 0;
u64 b_index = b->handle.idx;
return (a_index < b_index) - (a_index > b_index); if (res == 0) {
/* Sort by layer */
i32 a_cmp = a->layer;
i32 b_cmp = b->layer;
res = (a_cmp < b_cmp) - (a_cmp > b_cmp);
}
if (res == 0) {
/* Sort by sprite */
u64 a_cmp = a->sprite.hash;
u64 b_cmp = b->sprite.hash;
res = (a_cmp < b_cmp) - (a_cmp > b_cmp);
}
if (res == 0) {
/* Sort by activation */
u64 a_cmp = a->activation_tick;
u64 b_cmp = b->activation_tick;
res = (a_cmp < b_cmp) - (a_cmp > b_cmp);
}
return res;
} }
/* ========================== * /* ========================== *