add entitity_get/set_xform functions
This commit is contained in:
parent
91f7299274
commit
f5e28a04af
90
src/entity.c
90
src/entity.c
@ -12,8 +12,9 @@ READONLY struct entity_store _g_entity_store_nil = {
|
|||||||
/* Accessed via entity_nil() */
|
/* Accessed via entity_nil() */
|
||||||
/* TODO: Allocate nil entity in nil store */
|
/* TODO: Allocate nil entity in nil store */
|
||||||
READONLY struct entity _g_entity_nil = {
|
READONLY struct entity _g_entity_nil = {
|
||||||
.xform = XFORM_IDENT_NOCAST,
|
.local_xform = XFORM_IDENT_NOCAST,
|
||||||
.xform_world = XFORM_IDENT_NOCAST,
|
.cached_global_xform = XFORM_IDENT_NOCAST,
|
||||||
|
.cached_global_xform_clean = true,
|
||||||
.sprite_xform = XFORM_IDENT_NOCAST,
|
.sprite_xform = XFORM_IDENT_NOCAST,
|
||||||
.sprite_tint = COLOR_WHITE
|
.sprite_tint = COLOR_WHITE
|
||||||
};
|
};
|
||||||
@ -32,6 +33,8 @@ struct entity_store *entity_store_alloc(void)
|
|||||||
|
|
||||||
struct entity *root = entity_alloc_unlinked(store);
|
struct entity *root = entity_alloc_unlinked(store);
|
||||||
root->root = true;
|
root->root = true;
|
||||||
|
root->cached_global_xform = root->local_xform;
|
||||||
|
root->cached_global_xform_clean = true;
|
||||||
store->root = root->handle;
|
store->root = root->handle;
|
||||||
|
|
||||||
return store;
|
return store;
|
||||||
@ -74,6 +77,7 @@ struct entity *entity_alloc_unlinked(struct entity_store *store)
|
|||||||
*entity = *entity_nil();
|
*entity = *entity_nil();
|
||||||
entity->handle = handle;
|
entity->handle = handle;
|
||||||
entity->valid = true;
|
entity->valid = true;
|
||||||
|
entity->cached_global_xform_clean = false;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,36 +178,70 @@ struct entity *entity_find_first_match_all(struct entity_store *store, struct en
|
|||||||
* Xform
|
* Xform
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL void entity_mark_xform_dirty(struct entity_store *store, struct entity *ent)
|
||||||
|
{
|
||||||
|
ent->cached_global_xform_clean = false;
|
||||||
|
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
|
||||||
|
if (child->cached_global_xform_clean) {
|
||||||
|
entity_mark_xform_dirty(store, ent);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL struct xform entity_get_xform_w_store(struct entity_store *store, struct entity *ent)
|
||||||
|
{
|
||||||
|
struct entity_handle parent_handle = ent->parent;
|
||||||
|
|
||||||
|
struct xform xf;
|
||||||
|
if (entity_handle_eq(parent_handle, store->root)) {
|
||||||
|
xf = ent->local_xform;
|
||||||
|
} else if (ent->cached_global_xform_clean) {
|
||||||
|
xf = ent->cached_global_xform;
|
||||||
|
} else {
|
||||||
|
struct entity *parent = entity_from_handle(store, parent_handle);
|
||||||
|
xf = entity_get_xform_w_store(store, parent);
|
||||||
|
xf = xform_mul(xf, ent->local_xform);
|
||||||
|
ent->cached_global_xform = xf;
|
||||||
|
ent->cached_global_xform_clean = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct xform entity_get_xform(struct entity *ent)
|
||||||
|
{
|
||||||
|
struct entity_store *store = entity_get_store(ent);
|
||||||
|
struct xform xf = entity_get_xform_w_store(store, ent);
|
||||||
|
return xf;
|
||||||
|
}
|
||||||
|
|
||||||
struct xform entity_get_local_xform(struct entity *ent)
|
struct xform entity_get_local_xform(struct entity *ent)
|
||||||
{
|
{
|
||||||
return ent->xform;
|
return ent->local_xform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entity_set_xform(struct entity *ent, struct xform xf)
|
||||||
|
{
|
||||||
|
/* TODO: Instead of calculating & storing derived local xform, maybe just cache global xform and update local if retrieved? */
|
||||||
|
struct entity_store *store = entity_get_store(ent);
|
||||||
|
struct entity *parent = entity_from_handle(store, ent->parent);
|
||||||
|
|
||||||
|
struct xform child_global = xf;
|
||||||
|
|
||||||
|
struct xform parent_global = entity_get_xform_w_store(store, parent);
|
||||||
|
struct xform child_local = xform_mul(xform_invert(parent_global), child_global);
|
||||||
|
|
||||||
|
ent->local_xform = child_local;
|
||||||
|
ent->cached_global_xform = child_global;
|
||||||
|
ent->cached_global_xform_clean = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void entity_set_local_xform(struct entity *ent, struct xform xf)
|
void entity_set_local_xform(struct entity *ent, struct xform xf)
|
||||||
{
|
{
|
||||||
ent->xform = xf;
|
ent->local_xform = xf;
|
||||||
}
|
entity_mark_xform_dirty(entity_get_store(ent), ent);
|
||||||
|
|
||||||
struct xform entity_get_global_xform(struct entity *ent)
|
|
||||||
{
|
|
||||||
/* TODO: Remove this */
|
|
||||||
return ent->xform_world;
|
|
||||||
}
|
|
||||||
|
|
||||||
void entity_set_global_xform(struct entity *ent, struct xform xf)
|
|
||||||
{
|
|
||||||
/* TODO: Remove this */
|
|
||||||
struct entity_store *store = entity_get_store(ent);
|
|
||||||
|
|
||||||
struct entity *parent = entity_from_handle(store, ent->parent);
|
|
||||||
|
|
||||||
struct xform parent_global = parent->xform_world;
|
|
||||||
struct xform child_global = xf;
|
|
||||||
|
|
||||||
struct xform child_local = xform_mul(xform_invert(parent_global), child_global);
|
|
||||||
|
|
||||||
ent->xform = child_local;
|
|
||||||
ent->xform_world = child_global;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
13
src/entity.h
13
src/entity.h
@ -56,8 +56,9 @@ struct entity {
|
|||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
|
|
||||||
struct xform xform; /* Transform in relation to parent entity (or the world if entity has no parent) */
|
struct xform local_xform; /* Transform in relation to parent entity (or the world if entity has no parent) */
|
||||||
struct xform xform_world; /* Calculated from entity tree */
|
struct xform cached_global_xform; /* Calculated from entity tree */
|
||||||
|
b32 cached_global_xform_clean;
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Physics */
|
/* Physics */
|
||||||
@ -92,7 +93,7 @@ struct entity {
|
|||||||
|
|
||||||
/* ENTITY_PROP_TEST */
|
/* ENTITY_PROP_TEST */
|
||||||
b32 test_initialized;
|
b32 test_initialized;
|
||||||
struct xform test_start_rel_xform;
|
struct xform test_start_local_xform;
|
||||||
struct xform test_start_sprite_xform;
|
struct xform test_start_sprite_xform;
|
||||||
|
|
||||||
/* ENTITY_PROP_TEST_SOUND_EMITTER */
|
/* ENTITY_PROP_TEST_SOUND_EMITTER */
|
||||||
@ -108,7 +109,7 @@ struct entity {
|
|||||||
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
||||||
|
|
||||||
u32 camera_lerp_continuity_gen;
|
u32 camera_lerp_continuity_gen;
|
||||||
struct xform camera_rel_xform_target; /* Calculated from camera_follow */
|
struct xform camera_xform_target; /* Calculated from camera_follow */
|
||||||
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
|
u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,10 +196,10 @@ struct entity *entity_alloc_child(struct entity *parent);
|
|||||||
void entity_release(struct entity_store *store, struct entity *entity);
|
void entity_release(struct entity_store *store, struct entity *entity);
|
||||||
|
|
||||||
/* Xform */
|
/* Xform */
|
||||||
|
struct xform entity_get_xform(struct entity *ent);
|
||||||
struct xform entity_get_local_xform(struct entity *ent);
|
struct xform entity_get_local_xform(struct entity *ent);
|
||||||
|
void entity_set_xform(struct entity *ent, struct xform xf);
|
||||||
void entity_set_local_xform(struct entity *ent, struct xform xf);
|
void entity_set_local_xform(struct entity *ent, struct xform xf);
|
||||||
struct xform entity_get_global_xform(struct entity *ent);
|
|
||||||
void entity_set_global_xform(struct entity *ent, struct xform xf);
|
|
||||||
|
|
||||||
/* Query */
|
/* Query */
|
||||||
struct entity_store *entity_get_store(struct entity *ent);
|
struct entity_store *entity_get_store(struct entity *ent);
|
||||||
|
|||||||
66
src/game.c
66
src/game.c
@ -111,7 +111,7 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
f32 r = 0;
|
f32 r = 0;
|
||||||
|
|
||||||
struct entity *e = entity_alloc_top(G.world.entity_store);
|
struct entity *e = entity_alloc_top(G.world.entity_store);
|
||||||
e->xform = XFORM_TRS(.t = pos, .r = r, .s = size);
|
entity_set_xform(e, XFORM_TRS(.t = pos, .r = r, .s = size));
|
||||||
|
|
||||||
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
|
||||||
//e->sprite_span_name = STR("idle.unarmed");
|
//e->sprite_span_name = STR("idle.unarmed");
|
||||||
@ -133,7 +133,7 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
/* Camera ent */
|
/* Camera ent */
|
||||||
{
|
{
|
||||||
struct entity *e = entity_alloc_top(G.world.entity_store);
|
struct entity *e = entity_alloc_top(G.world.entity_store);
|
||||||
e->xform = XFORM_IDENT;
|
entity_set_xform(e, XFORM_IDENT);
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_CAMERA);
|
entity_enable_prop(e, ENTITY_PROP_CAMERA);
|
||||||
entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE);
|
entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE);
|
||||||
@ -158,6 +158,13 @@ INTERNAL void publish_game_tick(void)
|
|||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Remove this(?) */
|
||||||
|
#if 0
|
||||||
INTERNAL void recalculate_world_xforms_recurse(struct entity *parent)
|
INTERNAL void recalculate_world_xforms_recurse(struct entity *parent)
|
||||||
{
|
{
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
@ -179,8 +186,8 @@ INTERNAL void recalculate_world_xforms_recurse(struct entity *parent)
|
|||||||
struct entity *child = node.entity;
|
struct entity *child = node.entity;
|
||||||
|
|
||||||
/* Calculate world xform */
|
/* Calculate world xform */
|
||||||
struct xform xform_world = xform_mul(node.parent_xform_world, child->xform);
|
struct xform xform_world = xform_mul(node.parent_xform_world, child->_xform);
|
||||||
child->xform_world = xform_world;
|
child->_xform_world = xform_world;
|
||||||
|
|
||||||
/* Calculate sprite world xform */
|
/* Calculate sprite world xform */
|
||||||
struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform);
|
struct xform sprite_xform_world = xform_mul(xform_world, child->sprite_xform);
|
||||||
@ -197,6 +204,22 @@ INTERNAL void recalculate_world_xforms_recurse(struct entity *parent)
|
|||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
INTERNAL void recalculate_world_xforms_recurse(struct entity *ent)
|
||||||
|
{
|
||||||
|
struct entity_store *store = G.world.entity_store;
|
||||||
|
struct xform sprite_xform_world = xform_mul(entity_get_xform(ent), ent->sprite_xform);
|
||||||
|
ent->sprite_xform_world = sprite_xform_world;
|
||||||
|
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
|
||||||
|
recalculate_world_xforms_recurse(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INTERNAL void game_update(void)
|
INTERNAL void game_update(void)
|
||||||
{
|
{
|
||||||
@ -354,7 +377,7 @@ INTERNAL void game_update(void)
|
|||||||
/* ENTITY_PROP_TEST */
|
/* ENTITY_PROP_TEST */
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) {
|
if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) {
|
||||||
ent->test_initialized = true;
|
ent->test_initialized = true;
|
||||||
ent->test_start_rel_xform = entity_get_local_xform(ent);
|
ent->test_start_local_xform = entity_get_local_xform(ent);
|
||||||
ent->test_start_sprite_xform = ent->sprite_xform;
|
ent->test_start_sprite_xform = ent->sprite_xform;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +389,7 @@ INTERNAL void game_update(void)
|
|||||||
/* Update focus */
|
/* Update focus */
|
||||||
ent->focus = G.world.player_aim;
|
ent->focus = G.world.player_aim;
|
||||||
|
|
||||||
struct xform xf = entity_get_global_xform(ent);
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|
||||||
/* Solve for final angle using law of sines */
|
/* Solve for final angle using law of sines */
|
||||||
f32 final_xf_angle;
|
f32 final_xf_angle;
|
||||||
@ -400,7 +423,7 @@ INTERNAL void game_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!F32_IS_NAN(final_xf_angle)) {
|
if (!F32_IS_NAN(final_xf_angle)) {
|
||||||
entity_set_global_xform(ent, xform_with_rotation(ent->xform_world, final_xf_angle));
|
entity_set_xform(ent, xform_with_rotation(xf, final_xf_angle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,15 +441,15 @@ INTERNAL void game_update(void)
|
|||||||
(UNUSED)r;
|
(UNUSED)r;
|
||||||
(UNUSED)s;
|
(UNUSED)s;
|
||||||
|
|
||||||
og = v2_add(og, ent->test_start_rel_xform.og);
|
og = v2_add(og, ent->test_start_local_xform.og);
|
||||||
r += xform_get_rotation(ent->test_start_rel_xform);
|
r += xform_get_rotation(ent->test_start_local_xform);
|
||||||
s = v2_add(s, xform_get_scale(ent->test_start_rel_xform));
|
s = v2_add(s, xform_get_scale(ent->test_start_local_xform));
|
||||||
|
|
||||||
|
|
||||||
struct xform xf = entity_get_local_xform(ent);
|
struct xform xf = entity_get_local_xform(ent);
|
||||||
xf.og = og;
|
xf.og = og;
|
||||||
xf= xform_with_rotation(xf, r);
|
xf= xform_with_rotation(xf, r);
|
||||||
xf= xform_with_scale(ent->xform, s);
|
xf= xform_with_scale(xf, s);
|
||||||
entity_set_local_xform(ent, xf);
|
entity_set_local_xform(ent, xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,9 +495,9 @@ INTERNAL void game_update(void)
|
|||||||
ent->velocity = v2_add(ent->velocity, a);
|
ent->velocity = v2_add(ent->velocity, a);
|
||||||
|
|
||||||
/* Apply velocity to position */
|
/* Apply velocity to position */
|
||||||
struct xform xf = entity_get_global_xform(ent);
|
struct xform xf = entity_get_xform(ent);
|
||||||
xf.og = v2_add(xf.og, v2_mul(ent->velocity, dt));
|
xf.og = v2_add(xf.og, v2_mul(ent->velocity, dt));
|
||||||
entity_set_global_xform(ent, xf);
|
entity_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,10 +525,12 @@ INTERNAL void game_update(void)
|
|||||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
|
||||||
struct entity *follow = entity_from_handle(G.world.entity_store, ent->camera_follow);
|
struct entity *follow = entity_from_handle(G.world.entity_store, ent->camera_follow);
|
||||||
|
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|
||||||
if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(follow, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
f32 aspect_ratio = 1.0;
|
f32 aspect_ratio = 1.0;
|
||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(entity_get_global_xform(ent), ent->camera_quad_xform);
|
struct xform quad_xf = xform_mul(entity_get_xform(ent), ent->camera_quad_xform);
|
||||||
struct v2 camera_size = xform_get_scale(quad_xf);
|
struct v2 camera_size = xform_get_scale(quad_xf);
|
||||||
if (!v2_eq(camera_size, V2(0, 0))) {
|
if (!v2_eq(camera_size, V2(0, 0))) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
@ -514,20 +539,21 @@ INTERNAL void game_update(void)
|
|||||||
f32 ratio_y = 0.33f;
|
f32 ratio_y = 0.33f;
|
||||||
f32 ratio_x = ratio_y / aspect_ratio;
|
f32 ratio_x = ratio_y / aspect_ratio;
|
||||||
struct v2 camera_focus_dir = v2_mul_v2(follow->focus, V2(ratio_x, ratio_y));
|
struct v2 camera_focus_dir = v2_mul_v2(follow->focus, V2(ratio_x, ratio_y));
|
||||||
struct v2 camera_focus_pos = v2_add(entity_get_global_xform(follow).og, camera_focus_dir);
|
struct v2 camera_focus_pos = v2_add(entity_get_xform(follow).og, camera_focus_dir);
|
||||||
ent->camera_rel_xform_target = ent->xform;
|
ent->camera_xform_target = xf;
|
||||||
ent->camera_rel_xform_target.og = camera_focus_pos;
|
ent->camera_xform_target.og = camera_focus_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lerp camera */
|
/* Lerp camera */
|
||||||
if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) {
|
if (ent->camera_applied_lerp_continuity_gen_plus_one == ent->camera_lerp_continuity_gen + 1) {
|
||||||
f32 t = 1 - math_pow(2.f, -20.f * (f32)G.world.dt);
|
f32 t = 1 - math_pow(2.f, -20.f * (f32)G.world.dt);
|
||||||
ent->xform = xform_lerp(ent->xform, ent->camera_rel_xform_target, t);
|
xf = xform_lerp(xf, ent->camera_xform_target, t);
|
||||||
} else {
|
} else {
|
||||||
/* Skip lerp */
|
/* Skip lerp */
|
||||||
ent->xform = ent->camera_rel_xform_target;
|
xf = ent->camera_xform_target;
|
||||||
}
|
}
|
||||||
ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1;
|
ent->camera_applied_lerp_continuity_gen_plus_one = ent->camera_lerp_continuity_gen + 1;
|
||||||
|
entity_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -538,7 +564,7 @@ INTERNAL void game_update(void)
|
|||||||
struct mixer_desc desc = ent->sound_desc;
|
struct mixer_desc desc = ent->sound_desc;
|
||||||
desc.speed = G.world.timescale;
|
desc.speed = G.world.timescale;
|
||||||
|
|
||||||
desc.pos = ent->xform_world.og;
|
desc.pos = entity_get_xform(ent).og;
|
||||||
struct sound *sound = sound_load_async(ent->sound_name, 0);
|
struct sound *sound = sound_load_async(ent->sound_name, 0);
|
||||||
b32 played = ent->sound_handle.gen != 0;
|
b32 played = ent->sound_handle.gen != 0;
|
||||||
if (sound) {
|
if (sound) {
|
||||||
|
|||||||
38
src/user.c
38
src/user.c
@ -376,7 +376,9 @@ INTERNAL void debug_draw_movement(struct entity *ent)
|
|||||||
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
|
||||||
u32 color_acc = RGBA_32_F(1, 1, 0.5, 1);
|
u32 color_acc = RGBA_32_F(1, 1, 0.5, 1);
|
||||||
|
|
||||||
struct v2 pos = xform_mul_v2(G.world_view, ent->xform_world.og);
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|
||||||
|
struct v2 pos = xform_mul_v2(G.world_view, xf.og);
|
||||||
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, ent->velocity);
|
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, ent->velocity);
|
||||||
struct v2 acc_ray = xform_basis_mul_v2(G.world_view, ent->acceleration);
|
struct v2 acc_ray = xform_basis_mul_v2(G.world_view, ent->acceleration);
|
||||||
|
|
||||||
@ -451,8 +453,8 @@ INTERNAL void user_update(void)
|
|||||||
struct entity *e1 = &t1_entities.entities[i];
|
struct entity *e1 = &t1_entities.entities[i];
|
||||||
struct entity *e = &world_entities.entities[i];
|
struct entity *e = &world_entities.entities[i];
|
||||||
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
||||||
e->xform = xform_lerp(e0->xform, e1->xform, tick_blend);
|
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
||||||
e->xform_world = xform_lerp(e0->xform_world, e1->xform_world, tick_blend);
|
e->cached_global_xform = xform_lerp(e0->cached_global_xform, e1->cached_global_xform, tick_blend);
|
||||||
|
|
||||||
e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend);
|
e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend);
|
||||||
e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend);
|
e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend);
|
||||||
@ -465,7 +467,7 @@ INTERNAL void user_update(void)
|
|||||||
e->animation_frame = (u32)math_round_to_int(math_lerp(e0->animation_frame, e1->animation_frame, tick_blend));
|
e->animation_frame = (u32)math_round_to_int(math_lerp(e0->animation_frame, e1->animation_frame, tick_blend));
|
||||||
|
|
||||||
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
e->camera_quad_xform = xform_lerp(e0->camera_quad_xform, e1->camera_quad_xform, tick_blend);
|
||||||
e->camera_rel_xform_target = xform_lerp(e0->camera_rel_xform_target, e1->camera_rel_xform_target, tick_blend);
|
e->camera_xform_target = xform_lerp(e0->camera_xform_target, e1->camera_xform_target, tick_blend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,7 +615,7 @@ INTERNAL void user_update(void)
|
|||||||
/* Determine viewport size by camera & window dimensions */
|
/* Determine viewport size by camera & window dimensions */
|
||||||
f32 aspect_ratio = 1.0;
|
f32 aspect_ratio = 1.0;
|
||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(active_camera->xform_world, active_camera->camera_quad_xform);
|
struct xform quad_xf = xform_mul(entity_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_eq(camera_size, V2(0, 0))) {
|
if (!v2_eq(camera_size, V2(0, 0))) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
@ -671,13 +673,15 @@ INTERNAL void user_update(void)
|
|||||||
G.world_view = xform_translate(G.world_view, v2_neg(world_cursor));
|
G.world_view = xform_translate(G.world_view, v2_neg(world_cursor));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct v2 center = active_camera->xform_world.og;
|
struct xform xf = entity_get_xform(active_camera);
|
||||||
f32 rot = xform_get_rotation(active_camera->xform_world);
|
|
||||||
|
struct v2 center = xf.og;
|
||||||
|
f32 rot = xform_get_rotation(xf);
|
||||||
|
|
||||||
/* Scale view into viewport based on camera size */
|
/* Scale view into viewport based on camera size */
|
||||||
struct v2 size = G.viewport_size;
|
struct v2 size = G.viewport_size;
|
||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(active_camera->xform_world, active_camera->camera_quad_xform);
|
struct xform quad_xf = xform_mul(xf, 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_eq(camera_size, V2(0, 0))) {
|
if (!v2_eq(camera_size, V2(0, 0))) {
|
||||||
size = v2_div_v2(size, camera_size);
|
size = v2_div_v2(size, camera_size);
|
||||||
@ -771,6 +775,11 @@ INTERNAL void user_update(void)
|
|||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
if (ent->root) continue;
|
if (ent->root) continue;
|
||||||
|
|
||||||
|
struct entity *parent = entity_from_handle(G.world.entity_store, ent->parent);
|
||||||
|
|
||||||
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
struct xform parent_xf = entity_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 = ent == active_camera;
|
b32 skip_debug_draw_transform = ent == active_camera;
|
||||||
|
|
||||||
@ -836,7 +845,7 @@ INTERNAL void user_update(void)
|
|||||||
debug_draw_movement(ent);
|
debug_draw_movement(ent);
|
||||||
|
|
||||||
if (!skip_debug_draw_transform) {
|
if (!skip_debug_draw_transform) {
|
||||||
debug_draw_xform(ent->xform_world);
|
debug_draw_xform(xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw aim arrow */
|
/* Draw aim arrow */
|
||||||
@ -845,7 +854,7 @@ INTERNAL void user_update(void)
|
|||||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), ent->animation_frame);
|
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("hold"), ent->animation_frame);
|
||||||
struct v2 start = xform_mul_v2(ent->sprite_xform_world, slice.center);
|
struct v2 start = xform_mul_v2(ent->sprite_xform_world, slice.center);
|
||||||
start = xform_mul_v2(G.world_view, start);
|
start = xform_mul_v2(G.world_view, start);
|
||||||
struct v2 end = v2_add(ent->xform.og, ent->focus);
|
struct v2 end = v2_add(xf.og, ent->focus);
|
||||||
end = xform_mul_v2(G.world_view, end);
|
end = xform_mul_v2(G.world_view, end);
|
||||||
draw_solid_arrow_line(G.viewport_canvas, start, end, 3, 10, RGBA_32_F(1, 1, 1, 0.5));
|
draw_solid_arrow_line(G.viewport_canvas, start, end, 3, 10, RGBA_32_F(1, 1, 1, 0.5));
|
||||||
}
|
}
|
||||||
@ -885,14 +894,13 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw hierarchy */
|
/* Draw hierarchy */
|
||||||
struct entity *parent = entity_from_handle(G.world.entity_store, ent->parent);
|
|
||||||
if (parent->valid && !parent->root) {
|
if (parent->valid && !parent->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 = 5;
|
f32 thickness = 5;
|
||||||
f32 arrow_height = 15;
|
f32 arrow_height = 15;
|
||||||
|
|
||||||
struct v2 start = xform_mul_v2(G.world_view, ent->xform_world.og);
|
struct v2 start = xform_mul_v2(G.world_view, xf.og);
|
||||||
struct v2 end = xform_mul_v2(G.world_view, parent->xform_world.og);
|
struct v2 end = xform_mul_v2(G.world_view, parent_xf.og);
|
||||||
draw_solid_arrow_line(G.viewport_canvas, start, end, thickness, arrow_height, color);
|
draw_solid_arrow_line(G.viewport_canvas, start, end, thickness, arrow_height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,7 +910,7 @@ INTERNAL void user_update(void)
|
|||||||
f32 thickness = 3;
|
f32 thickness = 3;
|
||||||
|
|
||||||
|
|
||||||
struct xform quad_xf = xform_mul(ent->xform_world, ent->camera_quad_xform);
|
struct xform quad_xf = xform_mul(xf, ent->camera_quad_xform);
|
||||||
struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, quad_xf);
|
struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, quad_xf);
|
||||||
quad = quad_mul_xform(quad, G.world_view);
|
quad = quad_mul_xform(quad, G.world_view);
|
||||||
|
|
||||||
@ -985,7 +993,7 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Queue aim cmd */
|
/* Queue aim cmd */
|
||||||
if (!G.debug_camera) {
|
if (!G.debug_camera) {
|
||||||
struct v2 input_aim = v2_sub(G.world_cursor, player->xform_world.og);
|
struct v2 input_aim = v2_sub(G.world_cursor, entity_get_xform(player).og);
|
||||||
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
||||||
.kind = GAME_CMD_KIND_PLAYER_AIM,
|
.kind = GAME_CMD_KIND_PLAYER_AIM,
|
||||||
.aim = input_aim,
|
.aim = input_aim,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user