skew testing

This commit is contained in:
jacob 2024-08-26 14:48:40 -05:00
parent 8bcc0bd356
commit 4ce85c1bef
3 changed files with 72 additions and 82 deletions

View File

@ -124,10 +124,12 @@ INTERNAL void spawn_test_entities(void)
struct v2 pos = V2(-1, -1);
struct v2 size = V2(1, 1);
f32 r = 0;
f32 skew = PI / 4;
struct entity *e = entity_alloc(root);
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
xf = xform_skewed_to(xf, skew);
entity_set_xform(e, xf);
e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
@ -463,9 +465,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
f32 rot = v2_angle(dir) + PI / 2;
struct xform xf = XFORM_IDENT;
xf = xform_rotate(xf, -rot);
xf = xform_scale(xf, sprite_size);
xf = xform_translate(xf, v2_neg(slice.center));
xf = xform_rotated(xf, -rot);
xf = xform_scaled(xf, sprite_size);
xf = xform_translated(xf, v2_neg(slice.center));
ent->sprite_local_xform = xf;
}
@ -491,7 +493,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct xform xf = entity_get_xform(ent);
xf.og = attach_pos;
xf = xform_with_rotation(xf, v2_angle(attach_dir) + PI / 2);
xf = xform_rotated_to(xf, v2_angle(attach_dir) + PI / 2);
entity_set_xform(ent, xf);
}
}
@ -586,8 +588,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct xform xf = entity_get_local_xform(ent);
xf.og = og;
xf = xform_with_rotation(xf, r);
xf = xform_with_scale(xf, s);
xf = xform_rotated_to(xf, r);
xf = xform_scaled_to(xf, s);
entity_set_local_xform(ent, xf);
}
}
@ -797,7 +799,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
f32 forward_hold_angle_offset;
{
struct xform xf_unrotated = xform_with_rotation(xf, 0);
struct xform xf_unrotated = xform_rotated_to(xf, 0);
struct v2 hold_pos_unrotated = xform_mul_v2(xf_unrotated, xform_mul_v2(ent->sprite_local_xform, slice.center));
forward_hold_angle_offset = v2_angle_from_dirs(V2(0, -1), v2_sub(hold_pos_unrotated, xf_unrotated.og));
}
@ -807,15 +809,15 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct v2 hold_pos;
{
struct xform hold_pos_xf = xform_translate(ent->sprite_local_xform, slice.center);
struct xform hold_pos_xf = xform_translated(ent->sprite_local_xform, slice.center);
hold_pos_xf = xform_mul(xf, hold_pos_xf);
struct v2 hold_pos_xf_dir = xform_basis_mul_v2(hold_pos_xf, slice.dir);
hold_pos_xf = xform_with_rotation(hold_pos_xf, v2_angle(hold_pos_xf_dir) + PI / 2);
hold_pos_xf = xform_rotated_to(hold_pos_xf, v2_angle(hold_pos_xf_dir) + PI / 2);
if (v2_eq(hold_pos_xf.og, ent_pos)) {
/* If hold pos is same as origin (E.G if pivot is being used as hold pos), then move hold pos forward a tad to avoid issue */
hold_pos_xf = xform_translate(hold_pos_xf, V2(0, -1));
hold_pos_xf = xform_translated(hold_pos_xf, V2(0, -1));
}
hold_pos = hold_pos_xf.og;
}
@ -837,7 +839,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
if (!F32_IS_NAN(final_xf_angle)) {
const f32 angle_error_allowed = 0.001;
if (math_fabs(final_xf_angle - v2_angle(xf.bx)) > angle_error_allowed) {
xf = xform_with_rotation(xf, final_xf_angle);
xf = xform_rotated_to(xf, final_xf_angle);
}
}

View File

@ -629,6 +629,13 @@ INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
return res;
}
INLINE struct v2 v2_rotated(struct v2 v, f32 a)
{
f32 sin = math_sin(a);
f32 cos = math_cos(a);
return V2(v.x * cos - v.y * sin, v.x * sin + v.y * cos);
}
INLINE struct v2 v2_from_angle(f32 a)
{
return V2(math_cos(a), math_sin(a));
@ -738,15 +745,15 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
/* Takes a translation, rotation, and scale as optional parameters for constructing an xform */
#define XFORM_TRS(...) xform_from_trs((struct trs) { .t = V2(0,0), .s = V2(1, 1), .r = 0, __VA_ARGS__ })
INLINE struct xform xform_rotate(struct xform xf, f32 angle);
INLINE struct xform xform_scale(struct xform xf, struct v2 v);
INLINE struct xform xform_rotated(struct xform xf, f32 angle);
INLINE struct xform xform_scaled(struct xform xf, struct v2 v);
INLINE struct v2 xform_basis_mul_v2(struct xform xf, struct v2 v);
INLINE struct v2 xform_mul_v2(struct xform xf, struct v2 v);
INLINE struct xform xform_with_scale(struct xform xf, struct v2 s);
INLINE struct xform xform_scaled_to(struct xform xf, struct v2 s);
INLINE f32 xform_get_determinant(struct xform xf);
INLINE struct v2 xform_get_scale(struct xform xf);
INLINE struct trs trs_from_xform(struct xform m);
INLINE struct trs trs_lerp(struct trs a, struct trs b, f32 t);
INLINE f32 xform_get_skew(struct xform xf);
INLINE struct xform xform_skewed_to(struct xform xf, f32 s);
INLINE b32 xform_eq(struct xform xf1, struct xform xf2)
{
@ -765,93 +772,105 @@ INLINE struct xform xform_from_pos(struct v2 v)
INLINE struct xform xform_from_trs(struct trs trs)
{
struct xform xf = XFORM_POS(trs.t);
xf = xform_rotate(xf, trs.r);
xf = xform_scale(xf, trs.s);
xf = xform_rotated(xf, trs.r);
xf = xform_scaled(xf, trs.s);
return xf;
}
INLINE struct xform xform_translate(struct xform xf, struct v2 v)
INLINE struct xform xform_translated(struct xform xf, struct v2 v)
{
xf.og = V2(
xf.bx.x * v.x + xf.by.x * v.y + xf.og.x,
xf.bx.y * v.x + xf.by.y * v.y + xf.og.y
);
return xf;
}
INLINE struct xform xform_rotate(struct xform xf, f32 angle)
INLINE struct xform xform_rotated(struct xform xf, f32 angle)
{
f32 c = math_cos(angle);
f32 s = math_sin(angle);
struct xform res = xf;
res.bx.x = xf.bx.x * c + xf.by.x * s;
res.bx.y = xf.bx.y * c + xf.by.y * s;
res.by.x = xf.bx.x * -s + xf.by.x * c;
res.by.y = xf.bx.y * -s + xf.by.y * c;
return res;
}
INLINE struct xform xform_scale(struct xform xf, struct v2 v)
INLINE struct xform xform_scaled(struct xform xf, struct v2 v)
{
xf.bx = v2_mul(xf.bx, v.x);
xf.by = v2_mul(xf.by, v.y);
return xf;
}
INLINE struct xform xform_with_rotation(struct xform xf, f32 r)
INLINE struct xform xform_rotated_to(struct xform xf, f32 r)
{
struct v2 scale = xform_get_scale(xf);
f32 skew = xform_get_skew(xf);
f32 c = math_cos(r);
f32 s = math_sin(r);
xf.bx = V2(c, s);
xf.by = V2(-s, c);
xf = xform_with_scale(xf, scale);
xf = xform_scaled_to(xf, scale);
xf = xform_skewed_to(xf, skew);
return xf;
}
INLINE struct xform xform_with_scale(struct xform xf, struct v2 s)
INLINE struct xform xform_scaled_to(struct xform xf, struct v2 s)
{
xf.bx = v2_mul(v2_norm(xf.bx), s.x);
xf.by = v2_mul(v2_norm(xf.by), s.y);
return xf;
}
INLINE struct xform xform_skewed_to(struct xform xf, f32 s)
{
i32 det_sign = math_fsign(xform_get_determinant(xf));
struct v2 by = xf.by;
f32 len = v2_len(by);
/* TODO: Is norm & mul by len really necessary? */
by = v2_mul(v2_norm(v2_rotated(xf.bx, PI * 0.5f + s)), len);
by = v2_mul(by, det_sign);
xf.by = by;
return xf;
}
INLINE struct xform xform_trs(struct xform xf, struct trs trs)
{
xf = xform_translate(xf, trs.t);
xf = xform_rotate(xf, trs.r);
xf = xform_scale(xf, trs.s);
xf = xform_translated(xf, trs.t);
xf = xform_rotated(xf, trs.r);
xf = xform_scaled(xf, trs.s);
return xf;
}
INLINE struct xform xform_trs_pivot_r(struct xform xf, struct trs trs, struct v2 pivot)
{
xf = xform_translate(xf, trs.t);
xf = xform_rotate(xf, trs.r);
xf = xform_translate(xf, v2_neg(pivot));
xf = xform_scale(xf, trs.s);
xf = xform_translated(xf, trs.t);
xf = xform_rotated(xf, trs.r);
xf = xform_translated(xf, v2_neg(pivot));
xf = xform_scaled(xf, trs.s);
return xf;
}
INLINE struct xform xform_trs_pivot_rs(struct xform xf, struct trs trs, struct v2 pivot)
{
xf = xform_translate(xf, trs.t);
xf = xform_rotate(xf, trs.r);
xf = xform_scale(xf, trs.s);
xf = xform_translate(xf, v2_neg(pivot));
xf = xform_translated(xf, trs.t);
xf = xform_rotated(xf, trs.r);
xf = xform_scaled(xf, trs.s);
xf = xform_translated(xf, v2_neg(pivot));
return xf;
}
INLINE struct xform xform_lerp(struct xform a, struct xform b, f32 t)
{
struct trs trs_a = trs_from_xform(a);
struct trs trs_b = trs_from_xform(b);
struct trs trs = trs_lerp(trs_a, trs_b, t);
return xform_from_trs(trs);
struct xform res;
res.og = v2_lerp(a.og, b.og, t);
res.bx = v2_lerp(a.bx, b.bx, t);
res.by = v2_lerp(a.by, b.by, t);
return res;
}
INLINE struct xform xform_invert(struct xform xf)
@ -874,13 +893,11 @@ INLINE struct xform xform_invert(struct xform xf)
INLINE struct xform xform_mul(struct xform a, struct xform b)
{
struct xform res;
res.bx.x = a.bx.x * b.bx.x + a.by.x * b.bx.y;
res.bx.y = a.bx.y * b.bx.x + a.by.y * b.bx.y;
res.by.x = a.bx.x * b.by.x + a.by.x * b.by.y;
res.by.y = a.bx.y * b.by.x + a.by.y * b.by.y;
res.og = xform_mul_v2(a, b.og);
return res;
}
@ -931,15 +948,8 @@ INLINE f32 xform_get_determinant(struct xform xf)
INLINE f32 xform_get_skew(struct xform xf)
{
f32 det = xform_get_determinant(xf);
i32 det_sign = math_fsign(det);
struct v2 bx_norm = v2_norm(xf.bx);
struct v2 by_norm = v2_norm(xf.by);
by_norm = v2_mul(by_norm, det_sign);
f32 dot = v2_dot(bx_norm, by_norm);
i32 det_sign = math_fsign(xform_get_determinant(xf));
f32 dot = v2_dot(v2_norm(xf.bx), v2_norm(xf.by)) * det_sign;
return math_acos(dot) - (PI / 2.0f);
}
@ -974,28 +984,6 @@ INLINE struct v2 xform_get_scale(struct xform xf)
return V2(v2_len(xf.bx), det_sign * v2_len(xf.by));
}
/* ========================== *
* Trs
* ========================== */
INLINE struct trs trs_lerp(struct trs a, struct trs b, f32 t)
{
struct trs res;
res.t = v2_lerp(a.t, b.t, t);
res.r = math_lerp_angle(a.r, b.r, t);
res.s = v2_lerp(a.s, b.s, t);
return res;
}
INLINE struct trs trs_from_xform(struct xform xf)
{
struct trs trs = { 0 };
trs.t = xf.og;
trs.r = xform_get_rotation(xf);
trs.s = xform_get_scale(xf);
return trs;
}
/* ========================== *
* Quad
* ========================== */

View File

@ -661,7 +661,7 @@ INTERNAL void user_update(void)
* ========================== */
if (G.debug_camera) {
G.world_view = xform_with_rotation(G.world_view, 0);
G.world_view = xform_rotated_to(G.world_view, 0);
/* Pan view */
if (G.bind_states[USER_BIND_KIND_PAN].is_held) {
@ -670,7 +670,7 @@ INTERNAL void user_update(void)
}
G.debug_camera_panning = true;
struct v2 offset = v2_sub(G.debug_camera_pan_start, xform_invert_mul_v2(G.world_view, G.viewport_cursor));
G.world_view = xform_translate(G.world_view, v2_neg(offset));
G.world_view = xform_translated(G.world_view, v2_neg(offset));
G.debug_camera_pan_start = xform_invert_mul_v2(G.world_view, G.viewport_cursor);
} else {
G.debug_camera_panning = false;
@ -683,9 +683,9 @@ INTERNAL void user_update(void)
f32 zoom_rate = 2;
f32 zoom = math_pow(zoom_rate, input_zooms);
struct v2 world_cursor = xform_invert_mul_v2(G.world_view, G.viewport_cursor);
G.world_view = xform_translate(G.world_view, world_cursor);
G.world_view = xform_scale(G.world_view, V2(zoom, zoom));
G.world_view = xform_translate(G.world_view, v2_neg(world_cursor));
G.world_view = xform_translated(G.world_view, world_cursor);
G.world_view = xform_scaled(G.world_view, V2(zoom, zoom));
G.world_view = xform_translated(G.world_view, v2_neg(world_cursor));
}
} else {
struct xform xf = entity_get_xform(active_camera);
@ -712,7 +712,7 @@ INTERNAL void user_update(void)
struct v2 pivot = center;
G.world_view = XFORM_IDENT;
G.world_view = xform_translate(G.world_view, pivot);
G.world_view = xform_translated(G.world_view, pivot);
G.world_view = xform_trs_pivot_rs(G.world_view, trs, pivot);
}
G.world_cursor = xform_invert_mul_v2(G.world_view, G.viewport_cursor);