calculate sprite xform from pivot in game thread
This commit is contained in:
parent
1dd8a4d659
commit
fd3ab6146b
@ -1,7 +1,7 @@
|
|||||||
/* Project-wide configurable constants */
|
/* Project-wide configurable constants */
|
||||||
|
|
||||||
#define WRITE_DIR "power_play"
|
#define WRITE_DIR "power_play"
|
||||||
#define SETTINGS_FILENAME "settings.json"
|
#define SETTINGS_FILENAME "settings.txt"
|
||||||
|
|
||||||
/* Window title */
|
/* Window title */
|
||||||
#if RTC
|
#if RTC
|
||||||
|
|||||||
@ -56,11 +56,11 @@ struct entity {
|
|||||||
|
|
||||||
struct v2 acceleration;
|
struct v2 acceleration;
|
||||||
struct v2 velocity;
|
struct v2 velocity;
|
||||||
|
struct v2 focus; /* Focus is a vector relative to the entity */
|
||||||
|
|
||||||
/* ENTITY_PROP_PLAYER_CONTROLLED */
|
/* ENTITY_PROP_PLAYER_CONTROLLED */
|
||||||
f32 player_max_speed;
|
f32 player_max_speed;
|
||||||
f32 player_acceleration;
|
f32 player_acceleration;
|
||||||
struct v2 player_aim;
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* Sprite */
|
/* Sprite */
|
||||||
|
|||||||
73
src/game.c
73
src/game.c
@ -134,10 +134,7 @@ INTERNAL void recalculate_world_xform_recurse(struct entity *parent)
|
|||||||
/* Append sub-children to stack */
|
/* Append sub-children to stack */
|
||||||
struct entity *subchild = entity_from_handle(&G.world.entity_store, child->last);
|
struct entity *subchild = entity_from_handle(&G.world.entity_store, child->last);
|
||||||
while (subchild->valid) {
|
while (subchild->valid) {
|
||||||
*arena_push(scratch.arena, struct stack_node) = (struct stack_node) {
|
*arena_push(scratch.arena, struct stack_node) = (struct stack_node) { .entity = subchild, .parent_xform = world_xform };
|
||||||
.entity = subchild,
|
|
||||||
.parent_xform = world_xform
|
|
||||||
};
|
|
||||||
++stack_count;
|
++stack_count;
|
||||||
subchild = entity_from_handle(&G.world.entity_store, subchild->prev);
|
subchild = entity_from_handle(&G.world.entity_store, subchild->prev);
|
||||||
}
|
}
|
||||||
@ -146,21 +143,6 @@ INTERNAL void recalculate_world_xform_recurse(struct entity *parent)
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
INTERNAL struct v2 sprite_sheet_size_meters(struct sprite_tag s)
|
|
||||||
{
|
|
||||||
struct v2 size = { 0 };
|
|
||||||
struct sprite_scope *scope = sprite_scope_begin();
|
|
||||||
{
|
|
||||||
struct sheet *sheet = sprite_sheet_from_tag_await(scope, s);
|
|
||||||
size.x = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
|
|
||||||
size.y = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
|
|
||||||
}
|
|
||||||
sprite_scope_end(scope);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INTERNAL void game_update(void)
|
INTERNAL void game_update(void)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
@ -193,11 +175,12 @@ INTERNAL void game_update(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_span_name = STR("idle.unarmed");
|
e->sprite_span_name = STR("idle.unarmed");
|
||||||
//e->sprite_span_name = STR("idle.two_handed");
|
//e->sprite_span_name = STR("idle.two_handed");
|
||||||
|
e->sprite_quad_xform = XFORM_TRS(.s = size);
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||||
e->player_max_speed = 4.f;
|
e->player_max_speed = 4.f;
|
||||||
e->player_acceleration = 20.0f;
|
e->player_acceleration = 20.0f;
|
||||||
e->player_aim = V2(0, -1);
|
e->focus = V2(0, -1);
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
||||||
|
|
||||||
@ -340,6 +323,39 @@ INTERNAL void game_update(void)
|
|||||||
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
||||||
ent->rel_xform = xform_with_scale(ent->rel_xform, s);
|
ent->rel_xform = xform_with_scale(ent->rel_xform, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Calculate sprite xform
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
if (ent->sprite.hash != 0) {
|
||||||
|
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||||
|
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
||||||
|
|
||||||
|
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
|
||||||
|
struct v2 pivot_pos = v2_mul_v2(slice.center_norm, sprite_size);
|
||||||
|
|
||||||
|
/* Apply Pivot */
|
||||||
|
struct xform sprite_xf = XFORM_POS(v2_neg(pivot_pos));
|
||||||
|
sprite_xf = xform_scale(sprite_xf, sprite_size);
|
||||||
|
|
||||||
|
ent->sprite_quad_xform = sprite_xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Calculate player aim angle
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
|
/* Update focus */
|
||||||
|
ent->focus = G.world.player_aim;
|
||||||
|
|
||||||
|
/* Update view angle */
|
||||||
|
struct v2 ent_pos = ent->rel_xform.og;
|
||||||
|
struct v2 look_pos = v2_add(ent_pos, ent->focus);
|
||||||
|
f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2;
|
||||||
|
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -379,21 +395,6 @@ INTERNAL void game_update(void)
|
|||||||
ent->rel_xform.og = v2_add(ent->rel_xform.og, v2_mul(ent->velocity, dt));
|
ent->rel_xform.og = v2_add(ent->rel_xform.og, v2_mul(ent->velocity, dt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Player aim
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
|
||||||
/* Update aim */
|
|
||||||
ent->player_aim = G.world.player_aim;
|
|
||||||
|
|
||||||
/* Update view angle */
|
|
||||||
struct v2 ent_pos = ent->rel_xform.og;
|
|
||||||
struct v2 look_pos = v2_add(ent_pos, ent->player_aim);
|
|
||||||
f32 r = v2_angle_to_point(ent_pos, look_pos) + PI / 2;
|
|
||||||
ent->rel_xform = xform_with_rotation(ent->rel_xform, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Calculate xforms
|
* Calculate xforms
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -428,7 +429,7 @@ 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->player_aim, 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(follow->world_xform.og, camera_focus_dir);
|
struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir);
|
||||||
ent->camera_rel_xform_target = ent->rel_xform;
|
ent->camera_rel_xform_target = ent->rel_xform;
|
||||||
ent->camera_rel_xform_target.og = camera_focus_pos;
|
ent->camera_rel_xform_target.og = camera_focus_pos;
|
||||||
|
|||||||
@ -878,13 +878,18 @@ void renderer_canvas_present(struct renderer_canvas **canvases, u32 canvases_cou
|
|||||||
struct dx11_shader *shader = cmd->shader;
|
struct dx11_shader *shader = cmd->shader;
|
||||||
struct dx11_buffer *buffer = &canvas->buffers[shader->kind];
|
struct dx11_buffer *buffer = &canvas->buffers[shader->kind];
|
||||||
|
|
||||||
|
b32 texture_loaded;
|
||||||
struct renderer_handle texture_handle;
|
struct renderer_handle texture_handle;
|
||||||
if (handle_is_nil(cmd->texture_handle)) {
|
if (handle_is_nil(cmd->texture_handle)) {
|
||||||
texture_handle = sprite_texture_from_tag_async(sprite_scope, cmd->sprite)->renderer_handle;
|
struct sprite_texture *sprite_texture = sprite_texture_from_tag_async(sprite_scope, cmd->sprite);
|
||||||
|
texture_loaded = sprite_texture->loaded;
|
||||||
|
texture_handle = sprite_texture->renderer_handle;
|
||||||
} else {
|
} else {
|
||||||
|
texture_loaded = true;
|
||||||
texture_handle = cmd->texture_handle;
|
texture_handle = cmd->texture_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (texture_loaded) {
|
||||||
/* Activate shader */
|
/* Activate shader */
|
||||||
if (shader != last_shader) {
|
if (shader != last_shader) {
|
||||||
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
ID3D11DeviceContext_VSSetShader(G.devcon, shader->vs, 0, 0);
|
||||||
@ -915,6 +920,7 @@ void renderer_canvas_present(struct renderer_canvas **canvases, u32 canvases_cou
|
|||||||
ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset);
|
ID3D11DeviceContext_DrawIndexed(G.devcon, index_count, index_offset, vertex_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Present */
|
/* Present */
|
||||||
{
|
{
|
||||||
|
|||||||
66
src/sprite.c
66
src/sprite.c
@ -232,10 +232,16 @@ struct sprite_startup_receipt sprite_startup(struct renderer_startup_receipt *re
|
|||||||
G.nil_texture->renderer_handle = renderer_texture_alloc(purple_black_image);
|
G.nil_texture->renderer_handle = renderer_texture_alloc(purple_black_image);
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init loading sheet */
|
/* Init loading sheet */
|
||||||
G.loading_sheet = arena_push_zero(&G.perm_arena, struct sprite_sheet);
|
G.loading_sheet = arena_push_zero(&G.perm_arena, struct sprite_sheet);
|
||||||
|
G.loading_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
|
G.loading_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
|
|
||||||
/* Init nil sheet */
|
/* Init nil sheet */
|
||||||
G.nil_sheet = arena_push_zero(&G.perm_arena, struct sprite_sheet);
|
G.nil_sheet = arena_push_zero(&G.perm_arena, struct sprite_sheet);
|
||||||
|
G.nil_sheet->image_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
|
G.nil_sheet->frame_size = V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
|
||||||
G.nil_sheet->loaded = true;
|
G.nil_sheet->loaded = true;
|
||||||
}
|
}
|
||||||
arena_set_readonly(&G.perm_arena);
|
arena_set_readonly(&G.perm_arena);
|
||||||
@ -394,6 +400,9 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
|
|||||||
|
|
||||||
ASSERT(ase.num_frames >= 1);
|
ASSERT(ase.num_frames >= 1);
|
||||||
|
|
||||||
|
struct v2 frame_size = ase.frame_size;
|
||||||
|
struct v2 frame_center = v2_mul(ase.frame_size, 0.5f);
|
||||||
|
|
||||||
/* Init frames */
|
/* Init frames */
|
||||||
{
|
{
|
||||||
__profscope(init_frames);
|
__profscope(init_frames);
|
||||||
@ -513,10 +522,35 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
|
|||||||
f32 y1 = ase_slice->y1;
|
f32 y1 = ase_slice->y1;
|
||||||
f32 x2 = ase_slice->x2;
|
f32 x2 = ase_slice->x2;
|
||||||
f32 y2 = ase_slice->y2;
|
f32 y2 = ase_slice->y2;
|
||||||
|
f32 width = x2 - x1;
|
||||||
|
f32 height = y2 - y1;
|
||||||
|
|
||||||
slice->rect = RECT(x1, y1, x2 - x1, y2 - y1);
|
f32 x1_norm = (x1 - frame_center.x) / frame_size.x;
|
||||||
slice->center = V2(x1 + ((x2 - x1) / 2.f), y1 + ((y2 - y1) / 2.f));
|
f32 y1_norm = (y1 - frame_center.y) / frame_size.y;
|
||||||
slice->dir = V2(0, -1);
|
f32 x2_norm = (x2 - frame_center.x) / frame_size.x;
|
||||||
|
f32 y2_norm = (y2 - frame_center.y) / frame_size.y;
|
||||||
|
f32 width_norm = x2_norm - x1_norm;
|
||||||
|
f32 height_norm = y2_norm - y1_norm;
|
||||||
|
|
||||||
|
/* Rect */
|
||||||
|
struct rect rect = RECT(x1, y1, width, height);
|
||||||
|
/* Rect norm */
|
||||||
|
struct rect rect_norm = RECT(x1_norm, y1_norm, width_norm, height_norm);
|
||||||
|
/* Center */
|
||||||
|
struct v2 center = V2(x1 + (width * 0.5f), y1 + (height * 0.5f));
|
||||||
|
/* Center norm */
|
||||||
|
struct v2 center_norm = V2(x1_norm + (width_norm * 0.5f), y1_norm + (height_norm * 0.5f));
|
||||||
|
/* Dir */
|
||||||
|
struct v2 dir = V2(center.x, 0);
|
||||||
|
/* Dir norm */
|
||||||
|
struct v2 dir_norm = V2(0, -0.5);
|
||||||
|
|
||||||
|
slice->rect = rect;
|
||||||
|
slice->rect_norm = rect_norm;
|
||||||
|
slice->center = center;
|
||||||
|
slice->center_norm = center_norm;
|
||||||
|
slice->dir = dir;
|
||||||
|
slice->dir_norm = dir_norm;
|
||||||
|
|
||||||
node->index_in_frame = index_in_frame;
|
node->index_in_frame = index_in_frame;
|
||||||
if (start < node->earliest_frame) {
|
if (start < node->earliest_frame) {
|
||||||
@ -567,7 +601,7 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate rays */
|
/* Calculate dirs */
|
||||||
for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) {
|
for (struct temp_slice_group_node *temp_slice_group_node = temp_slice_group_head; temp_slice_group_node; temp_slice_group_node = temp_slice_group_node->next) {
|
||||||
struct string ray_suffix = STR(".ray");
|
struct string ray_suffix = STR(".ray");
|
||||||
|
|
||||||
@ -585,11 +619,13 @@ INTERNAL struct sprite_sheet init_sheet_from_ase_result(struct arena *arena, str
|
|||||||
/* Use ray slice in ray group */
|
/* Use ray slice in ray group */
|
||||||
struct sprite_sheet_slice *ray_slice = &ray_slice_group->frame_slices[i * point_slices_per_frame];
|
struct sprite_sheet_slice *ray_slice = &ray_slice_group->frame_slices[i * point_slices_per_frame];
|
||||||
struct v2 ray_end = ray_slice->center;
|
struct v2 ray_end = ray_slice->center;
|
||||||
|
struct v2 ray_end_norm = ray_slice->center_norm;
|
||||||
|
|
||||||
/* Apply to each point slice in point group */
|
/* Apply to each point slice in point group */
|
||||||
for (u32 j = 0; j < point_slices_per_frame; ++j) {
|
for (u32 j = 0; j < point_slices_per_frame; ++j) {
|
||||||
struct sprite_sheet_slice *point_slice = &point_slice_group->frame_slices[(i * point_slices_per_frame) + j];
|
struct sprite_sheet_slice *point_slice = &point_slice_group->frame_slices[(i * point_slices_per_frame) + j];
|
||||||
point_slice->dir = v2_sub(ray_end, point_slice->center);
|
point_slice->dir = v2_sub(ray_end, point_slice->center);
|
||||||
|
point_slice->dir_norm = v2_sub(ray_end_norm, point_slice->center_norm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,17 +941,14 @@ struct sprite_sheet *sprite_sheet_from_tag_async(struct sprite_scope *scope, str
|
|||||||
struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32 index)
|
struct sprite_sheet_frame sprite_sheet_get_frame(struct sprite_sheet *sheet, u32 index)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
if (sheet->frames_count > 0) {
|
if (index < sheet->frames_count ) {
|
||||||
index = min_u32(sheet->frames_count - 1, index);
|
|
||||||
return sheet->frames[index];
|
return sheet->frames[index];
|
||||||
} else {
|
|
||||||
return (struct sprite_sheet_frame)
|
|
||||||
{
|
|
||||||
.index = 0,
|
|
||||||
.duration = 0.1,
|
|
||||||
.clip = CLIP_ALL
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
struct sprite_sheet_frame res = { 0 };
|
||||||
|
res.index = 0;
|
||||||
|
res.duration = 0.1;
|
||||||
|
res.clip = CLIP_ALL;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struct string name)
|
struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struct string name)
|
||||||
@ -933,13 +966,16 @@ struct sprite_sheet_span sprite_sheet_get_span(struct sprite_sheet *sheet, struc
|
|||||||
|
|
||||||
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, struct string name, u32 frame_index)
|
struct sprite_sheet_slice sprite_sheet_get_slice(struct sprite_sheet *sheet, struct string name, u32 frame_index)
|
||||||
{
|
{
|
||||||
struct sprite_sheet_slice res = { 0 };
|
|
||||||
if (sheet->slice_groups_count > 0) {
|
if (sheet->slice_groups_count > 0) {
|
||||||
struct sprite_sheet_slice_group *group = fixed_dict_get(&sheet->slice_groups_dict, name);
|
struct sprite_sheet_slice_group *group = fixed_dict_get(&sheet->slice_groups_dict, name);
|
||||||
if (group) {
|
if (group) {
|
||||||
res = group->frame_slices[frame_index * group->per_frame_count];
|
return group->frame_slices[frame_index * group->per_frame_count];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct sprite_sheet_slice res = { 0 };
|
||||||
|
res.center = v2_mul(sheet->frame_size, 0.5f);
|
||||||
|
res.dir = V2(res.center.x, 0);
|
||||||
|
res.dir_norm = V2(0, -0.5);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -93,10 +93,14 @@ struct sprite_sheet_span {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sprite_sheet_slice {
|
struct sprite_sheet_slice {
|
||||||
|
/* Values suffixed with '_norm' are in the range -0.5 (top / left edge) -> +0.5 (bottom / right edge) */
|
||||||
b32 original;
|
b32 original;
|
||||||
struct rect rect;
|
struct rect rect;
|
||||||
|
struct rect rect_norm;
|
||||||
struct v2 center;
|
struct v2 center;
|
||||||
|
struct v2 center_norm;
|
||||||
struct v2 dir;
|
struct v2 dir;
|
||||||
|
struct v2 dir_norm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sprite_sheet_slice_array {
|
struct sprite_sheet_slice_array {
|
||||||
|
|||||||
40
src/user.c
40
src/user.c
@ -453,7 +453,7 @@ INTERNAL void user_update(void)
|
|||||||
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);
|
||||||
e->player_acceleration = math_lerp(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
e->player_acceleration = math_lerp(e0->player_acceleration, e1->player_acceleration, tick_blend);
|
||||||
e->player_aim = v2_lerp(e0->player_aim, e1->player_aim, tick_blend);
|
e->focus = v2_lerp(e0->focus, e1->focus, tick_blend);
|
||||||
|
|
||||||
e->sprite_quad_xform = xform_lerp(e0->sprite_quad_xform, e1->sprite_quad_xform, tick_blend);
|
e->sprite_quad_xform = xform_lerp(e0->sprite_quad_xform, e1->sprite_quad_xform, tick_blend);
|
||||||
e->animation_time_in_frame = math_lerp64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
e->animation_time_in_frame = math_lerp64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
||||||
@ -785,41 +785,7 @@ INTERNAL void user_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct quad quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xform_mul(ent->world_xform, ent->sprite_quad_xform));
|
||||||
struct quad quad;
|
|
||||||
{
|
|
||||||
struct xform sprite_xf = XFORM_IDENT;
|
|
||||||
{
|
|
||||||
struct v2 sprite_size_meters = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
|
|
||||||
|
|
||||||
/* TODO: Cache these in slice */
|
|
||||||
struct v2 pivot_pos;
|
|
||||||
f32 pivot_rot;
|
|
||||||
{
|
|
||||||
struct sprite_sheet_slice pivot_slice = sprite_sheet_get_slice(sheet, STR("pivot"), frame.index);
|
|
||||||
|
|
||||||
/* Pivot pos */
|
|
||||||
struct v2 pivot_pos_norm = pivot_slice.center;
|
|
||||||
pivot_pos_norm = v2_mul(pivot_pos_norm, 2);
|
|
||||||
pivot_pos_norm = v2_sub(pivot_pos_norm, sheet->frame_size);
|
|
||||||
pivot_pos_norm = v2_div_v2(pivot_pos_norm, sheet->frame_size);
|
|
||||||
pivot_pos = v2_mul_v2(pivot_pos_norm, v2_mul(sprite_size_meters, 0.5f));
|
|
||||||
|
|
||||||
/* Pivot rot */
|
|
||||||
pivot_rot = -v2_angle(pivot_slice.dir) - (TAU / 4.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply entity sprite xform */
|
|
||||||
sprite_xf = xform_mul(sprite_xf, ent->sprite_quad_xform);
|
|
||||||
|
|
||||||
/* Apply Pivot */
|
|
||||||
sprite_xf = xform_rotate(sprite_xf, pivot_rot);
|
|
||||||
sprite_xf = xform_translate(sprite_xf, v2_neg(pivot_pos));
|
|
||||||
sprite_xf = xform_scale(sprite_xf, sprite_size_meters);
|
|
||||||
}
|
|
||||||
|
|
||||||
quad = quad_mul_xform(QUAD_UNIT_SQUARE_CENTERED, xform_mul(ent->world_xform, sprite_xf));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Fade in placeholder if texture isn't loaded */
|
/* TODO: Fade in placeholder if texture isn't loaded */
|
||||||
struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip);
|
struct draw_sprite_params params = DRAW_SPRITE_PARAMS(.sprite = sprite, .tint = ent->sprite_tint, .clip = frame.clip);
|
||||||
@ -908,7 +874,7 @@ INTERNAL void user_update(void)
|
|||||||
f32 thickness = 3;
|
f32 thickness = 3;
|
||||||
f32 arrow_height = 10;
|
f32 arrow_height = 10;
|
||||||
struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og);
|
struct v2 pos = xform_mul_v2(G.world_view, ent->world_xform.og);
|
||||||
struct v2 aim_ray = xform_basis_mul_v2(G.world_view, ent->player_aim);
|
struct v2 aim_ray = xform_basis_mul_v2(G.world_view, ent->focus);
|
||||||
draw_solid_arrow_ray(G.viewport_canvas, pos, aim_ray, thickness, arrow_height, color);
|
draw_solid_arrow_ray(G.viewport_canvas, pos, aim_ray, thickness, arrow_height, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user