change type mtx3x3 to xform
This commit is contained in:
parent
fa5fdbe955
commit
77421d7c09
@ -411,8 +411,12 @@ struct v4_array {
|
||||
u64 count;
|
||||
};
|
||||
|
||||
struct mat3x3 {
|
||||
f32 e[3][3];
|
||||
struct xform {
|
||||
struct {
|
||||
struct v2 bx; /* X basis vector */
|
||||
struct v2 by; /* Y basis vector */
|
||||
struct v2 t; /* Translation vector */
|
||||
};
|
||||
};
|
||||
|
||||
struct mat4x4 {
|
||||
|
||||
@ -48,7 +48,7 @@ struct entity {
|
||||
/* Translation, rotation, scale in relation to parent entity */
|
||||
|
||||
struct trs rel_trs;
|
||||
struct mat3x3 world_xform; /* Calculated post-physics */
|
||||
struct xform world_xform; /* Calculated post-physics */
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Physics */
|
||||
|
||||
21
src/game.c
21
src/game.c
@ -197,7 +197,7 @@ INTERNAL void game_update(void)
|
||||
|
||||
player_ent = e;
|
||||
|
||||
//entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||
entity_enable_prop(e, ENTITY_PROP_TEST);
|
||||
//entity_enable_prop(e, ENTITY_PROP_TEST_FOLLOW_MOUSE);
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ INTERNAL void game_update(void)
|
||||
entity_enable_prop(e, ENTITY_PROP_CAMERA);
|
||||
e->camera_active = true;
|
||||
e->camera_follow = player_ent->handle;
|
||||
e->camera_zoom = 1.5;
|
||||
e->camera_zoom = 1;
|
||||
|
||||
}
|
||||
}
|
||||
@ -366,12 +366,9 @@ INTERNAL void game_update(void)
|
||||
* ========================== */
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||
struct v2 ent_pos = ent->rel_trs.t;
|
||||
struct v2 look_pos = L.tick.player_focus;
|
||||
struct v2 look_dir = v2_sub(ent->rel_trs.t, look_pos);
|
||||
look_dir = v2_norm(look_dir);
|
||||
if (!v2_eq(look_dir, V2(0, 0))) {
|
||||
ent->rel_trs.r = -math_atan2(look_dir.y, look_dir.x);
|
||||
}
|
||||
ent->rel_trs.r = v2_angle_to_point(ent_pos, look_pos);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
@ -388,12 +385,12 @@ INTERNAL void game_update(void)
|
||||
* Calculate xforms
|
||||
* ========================== */
|
||||
|
||||
ent->world_xform = mat3x3_from_trs(ent->rel_trs);
|
||||
ent->world_xform = xform_from_trs(ent->rel_trs);
|
||||
|
||||
struct entity *child = entity_from_handle(ent->first);
|
||||
struct mat3x3 parent_xform = ent->world_xform;
|
||||
struct xform parent_xform = ent->world_xform;
|
||||
while (child->valid) {
|
||||
child->world_xform = mat3x3_trs(parent_xform, child->rel_trs);
|
||||
child->world_xform = xform_trs(parent_xform, child->rel_trs);
|
||||
|
||||
/* Depth first iteration */
|
||||
if (child->first.gen) {
|
||||
@ -433,7 +430,7 @@ INTERNAL void game_update(void)
|
||||
struct v2 pos = follow->rel_trs.t;
|
||||
|
||||
ent->rel_trs.t = pos;
|
||||
ent->world_xform = mat3x3_from_trs(ent->rel_trs);
|
||||
ent->world_xform = xform_from_trs(ent->rel_trs);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
@ -443,7 +440,7 @@ INTERNAL void game_update(void)
|
||||
if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) {
|
||||
struct mixer_desc desc = ent->sound_desc;
|
||||
desc.speed = L.timescale;
|
||||
desc.pos = mat3x3_get_pos(ent->world_xform);
|
||||
desc.pos = xform_get_pos(ent->world_xform);
|
||||
struct sound *sound = sound_load_async(ent->sound_name, 0);
|
||||
b32 played = ent->sound_handle.gen != 0;
|
||||
if (sound) {
|
||||
|
||||
466
src/math.h
466
src/math.h
@ -6,8 +6,10 @@
|
||||
#define PI ((f32)3.14159265358979323846)
|
||||
#define TAU ((f32)6.28318530717958647693)
|
||||
|
||||
INLINE struct trs trs_from_mat3x3(struct mat3x3 m);
|
||||
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_determinant(struct xform xf);
|
||||
INLINE struct xform xform_invert(struct xform xf);
|
||||
|
||||
/* ========================== *
|
||||
* Rounding
|
||||
@ -231,7 +233,7 @@ INLINE f32 math_cos(f32 x)
|
||||
}
|
||||
|
||||
/* https://mazzo.li/posts/vectorized-atan2.html */
|
||||
INLINE f32 math_atan2(f32 x, f32 y) {
|
||||
INLINE f32 math_atan2(f32 y, f32 x) {
|
||||
const f32 a1 = 0.99997726f;
|
||||
const f32 a3 = -0.33262347f;
|
||||
const f32 a5 = 0.19354346f;
|
||||
@ -251,6 +253,7 @@ INLINE f32 math_atan2(f32 x, f32 y) {
|
||||
/* Adjust quadrants */
|
||||
if (x < 0.0f && y >= 0.0f) { res = PI + res; } /* 2nd quadrant */
|
||||
else if (x <= 0.0f && y < 0.0f) { res = -PI + res; } /* 3rd quadrant */
|
||||
else if (x == 0.0f && y == 0.0f) { res = 0; } /* NaN -> 0 */
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -331,7 +334,6 @@ INLINE struct v2 v2_norm(struct v2 a)
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
INLINE struct v2 v2_round(struct v2 a)
|
||||
{
|
||||
return V2(
|
||||
@ -370,249 +372,41 @@ INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Mat3x3
|
||||
* ========================== */
|
||||
|
||||
INLINE struct mat3x3 mat3x3_ident(void)
|
||||
INLINE struct v2 v2_from_angle(f32 a)
|
||||
{
|
||||
return (struct mat3x3) {
|
||||
.e = {
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ 0, 0, 1 }
|
||||
}
|
||||
};
|
||||
return V2(math_cos(a), math_sin(a));
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_mul(struct mat3x3 a, struct mat3x3 b)
|
||||
INLINE f32 v2_angle(struct v2 v)
|
||||
{
|
||||
f32 a00 = a.e[0][0], a01 = a.e[0][1], a02 = a.e[0][2],
|
||||
a10 = a.e[1][0], a11 = a.e[1][1], a12 = a.e[1][2],
|
||||
a20 = a.e[2][0], a21 = a.e[2][1], a22 = a.e[2][2],
|
||||
b00 = b.e[0][0], b01 = b.e[0][1], b02 = b.e[0][2],
|
||||
b10 = b.e[1][0], b11 = b.e[1][1], b12 = b.e[1][2],
|
||||
b20 = b.e[2][0], b21 = b.e[2][1], b22 = b.e[2][2];
|
||||
|
||||
struct mat3x3 res;
|
||||
|
||||
res.e[0][0] = a00 * b00 + a10 * b01 + a20 * b02;
|
||||
res.e[0][1] = a01 * b00 + a11 * b01 + a21 * b02;
|
||||
res.e[0][2] = a02 * b00 + a12 * b01 + a22 * b02;
|
||||
res.e[1][0] = a00 * b10 + a10 * b11 + a20 * b12;
|
||||
res.e[1][1] = a01 * b10 + a11 * b11 + a21 * b12;
|
||||
res.e[1][2] = a02 * b10 + a12 * b11 + a22 * b12;
|
||||
res.e[2][0] = a00 * b20 + a10 * b21 + a20 * b22;
|
||||
res.e[2][1] = a01 * b20 + a11 * b21 + a21 * b22;
|
||||
res.e[2][2] = a02 * b20 + a12 * b21 + a22 * b22;
|
||||
|
||||
return res;
|
||||
|
||||
return math_atan2(v.y, v.x);
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_from_translate(struct v2 v)
|
||||
INLINE f32 v2_angle_to_dir(struct v2 a, struct v2 b)
|
||||
{
|
||||
return (struct mat3x3) {
|
||||
.e = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{v.x, v.y, 1}
|
||||
}
|
||||
};
|
||||
return math_atan2(v2_wedge(a, b), v2_dot(a, b));
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_translate(struct mat3x3 m, struct v2 v)
|
||||
INLINE f32 v2_angle_to_point(struct v2 a, struct v2 b)
|
||||
{
|
||||
m.e[2][0] = m.e[0][0] * v.x + m.e[1][0] * v.y + m.e[2][0];
|
||||
m.e[2][1] = m.e[0][1] * v.x + m.e[1][1] * v.y + m.e[2][1];
|
||||
m.e[2][2] = m.e[0][2] * v.x + m.e[1][2] * v.y + m.e[2][2];
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_rotate(struct mat3x3 m, f32 angle)
|
||||
{
|
||||
f32 c = math_cos(angle);
|
||||
f32 s = math_sin(angle);
|
||||
|
||||
struct mat3x3 res = m;
|
||||
|
||||
f32 m00 = m.e[0][0], m10 = m.e[1][0],
|
||||
m01 = m.e[0][1], m11 = m.e[1][1],
|
||||
m02 = m.e[0][2], m12 = m.e[1][2];
|
||||
|
||||
res.e[0][0] = m00 * c + m10 * s;
|
||||
res.e[0][1] = m01 * c + m11 * s;
|
||||
res.e[0][2] = m02 * c + m12 * s;
|
||||
|
||||
res.e[1][0] = m00 * -s + m10 * c;
|
||||
res.e[1][1] = m01 * -s + m11 * c;
|
||||
res.e[1][2] = m02 * -s + m12 * c;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_scale(struct mat3x3 m, struct v3 v)
|
||||
{
|
||||
m.e[0][0] *= v.x;
|
||||
m.e[0][1] *= v.x;
|
||||
m.e[0][2] *= v.x;
|
||||
m.e[1][0] *= v.y;
|
||||
m.e[1][1] *= v.y;
|
||||
m.e[1][2] *= v.y;
|
||||
m.e[2][0] *= v.z;
|
||||
m.e[2][1] *= v.z;
|
||||
m.e[2][2] *= v.z;
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_from_trs(struct trs trs)
|
||||
{
|
||||
struct mat3x3 m = mat3x3_from_translate(trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_trs(struct mat3x3 m, struct trs trs)
|
||||
{
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_trs_pivot_r(struct mat3x3 m, struct trs trs, struct v2 pivot)
|
||||
{
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_translate(m, v2_neg(pivot));
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_trs_pivot_rs(struct mat3x3 m, struct trs trs, struct v2 pivot)
|
||||
{
|
||||
m = mat3x3_translate(m, trs.t);
|
||||
m = mat3x3_rotate(m, trs.r);
|
||||
m = mat3x3_scale(m, V3(trs.s.x, trs.s.y, 1));
|
||||
m = mat3x3_translate(m, v2_neg(pivot));
|
||||
return m;
|
||||
}
|
||||
|
||||
INLINE struct v3 mat3x3_mul_v3(struct mat3x3 m, struct v3 v)
|
||||
{
|
||||
struct v3 res;
|
||||
res.x = m.e[0][0] * v.x + m.e[1][0] * v.y + m.e[2][0] * v.z;
|
||||
res.y = m.e[0][1] * v.x + m.e[1][1] * v.y + m.e[2][1] * v.z;
|
||||
res.z = m.e[0][2] * v.x + m.e[1][2] * v.y + m.e[2][2] * v.z;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Equivalent to multiplying by V3(v.x, v.y, 1.0) */
|
||||
INLINE struct v2 mat3x3_mul_v2(struct mat3x3 m, struct v2 v)
|
||||
{
|
||||
struct v2 res;
|
||||
res.x = m.e[0][0] * v.x + m.e[1][0] * v.y + m.e[2][0];
|
||||
res.y = m.e[0][1] * v.x + m.e[1][1] * v.y + m.e[2][1];
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_inverse(struct mat3x3 m)
|
||||
{
|
||||
f32 a = m.e[0][0], b = m.e[0][1], c = m.e[0][2],
|
||||
d = m.e[1][0], e = m.e[1][1], f = m.e[1][2],
|
||||
g = m.e[2][0], h = m.e[2][1], i = m.e[2][2];
|
||||
|
||||
struct mat3x3 res;
|
||||
res.e[0][0] = e * i - f * h;
|
||||
res.e[0][1] = -(b * i - h * c);
|
||||
res.e[0][2] = b * f - e * c;
|
||||
res.e[1][0] = -(d * i - g * f);
|
||||
res.e[1][1] = a * i - c * g;
|
||||
res.e[1][2] = -(a * f - d * c);
|
||||
res.e[2][0] = d * h - g * e;
|
||||
res.e[2][1] = -(a * h - g * b);
|
||||
res.e[2][2] = a * e - b * d;
|
||||
|
||||
f32 det = 1.0f / (a * res.e[0][0] + b * res.e[1][0] + c * res.e[2][0]);
|
||||
res = mat3x3_scale(res, V3(det, det, det));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_right(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[0][0], m.e[0][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_left(struct mat3x3 m)
|
||||
{
|
||||
return V2(-m.e[0][0], -m.e[0][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_up(struct mat3x3 m)
|
||||
{
|
||||
return V2(-m.e[1][0], -m.e[1][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_down(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[1][0], m.e[1][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_pos(struct mat3x3 m)
|
||||
{
|
||||
return V2(m.e[2][0], m.e[2][1]);
|
||||
}
|
||||
|
||||
INLINE f32 mat3x3_get_determinant(struct mat3x3 m)
|
||||
{
|
||||
return m.e[0][0] * m.e[1][1] - m.e[0][1] * m.e[1][0];
|
||||
}
|
||||
|
||||
INLINE f32 mat3x3_get_rot(struct mat3x3 m)
|
||||
{
|
||||
return math_atan2(m.e[0][0], m.e[0][1]);
|
||||
}
|
||||
|
||||
INLINE struct v2 mat3x3_get_scale(struct mat3x3 m)
|
||||
{
|
||||
f32 det_sign = math_sign_f32(mat3x3_get_determinant(m));
|
||||
struct v2 bx = V2(m.e[0][0], m.e[0][1]);
|
||||
struct v2 by = V2(m.e[1][0], m.e[1][1]);
|
||||
return V2(v2_len(bx), det_sign * v2_len(by));
|
||||
}
|
||||
|
||||
INLINE f32 mat3x3_get_skew(struct mat3x3 m)
|
||||
{
|
||||
f32 det = mat3x3_get_determinant(m);
|
||||
i32 det_sign = math_sign_f32(det);
|
||||
|
||||
struct v2 bx_norm = v2_norm(V2(m.e[0][0], m.e[0][1]));
|
||||
|
||||
struct v2 by_norm = v2_norm(V2(m.e[1][0], m.e[1][1]));
|
||||
by_norm = v2_mul(by_norm, det_sign);
|
||||
|
||||
f32 dot = v2_dot(bx_norm, by_norm);
|
||||
|
||||
return math_acos(dot) - (PI * 0.5f);
|
||||
}
|
||||
|
||||
INLINE struct mat3x3 mat3x3_lerp(struct mat3x3 a, struct mat3x3 b, f32 t)
|
||||
{
|
||||
struct trs trs_a = trs_from_mat3x3(a);
|
||||
struct trs trs_b = trs_from_mat3x3(b);
|
||||
|
||||
struct trs trs = trs_lerp(trs_a, trs_b, t);
|
||||
|
||||
return mat3x3_from_trs(trs);
|
||||
return v2_angle(v2_sub(b, a));
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Mat4x4
|
||||
* ========================== */
|
||||
|
||||
/* NOTE: Mat4x4 only used for projection matrix */
|
||||
INLINE struct mat4x4 mat4x4_from_xform(struct xform xf)
|
||||
{
|
||||
return (struct mat4x4) {
|
||||
.e = {
|
||||
{xf.bx.x, xf.bx.y, 0, 0},
|
||||
{xf.by.x, xf.by.y, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{xf.t.x, xf.t.y, 0, 1},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
INLINE struct mat4x4 mat4x4_from_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
|
||||
{
|
||||
@ -666,6 +460,200 @@ INLINE struct mat4x4 mat4x4_mul(struct mat4x4 m1, struct mat4x4 m2)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Xform
|
||||
* ========================== */
|
||||
|
||||
INLINE struct xform xform_ident(void)
|
||||
{
|
||||
return (struct xform) {
|
||||
.bx = { 1, 0 },
|
||||
.by = { 0, 1 },
|
||||
.t = { 0, 0 }
|
||||
};
|
||||
}
|
||||
|
||||
INLINE struct xform xform_from_translate(struct v2 v)
|
||||
{
|
||||
return (struct xform) {
|
||||
.bx = {1, 0},
|
||||
.by = {0, 1},
|
||||
.t = {v.x, v.y}
|
||||
};
|
||||
}
|
||||
|
||||
INLINE struct xform xform_translate(struct xform xf, struct v2 v)
|
||||
{
|
||||
xf.t = V2(
|
||||
xf.bx.x * v.x + xf.by.x * v.y + xf.t.x,
|
||||
xf.bx.y * v.x + xf.by.y * v.y + xf.t.y
|
||||
);
|
||||
return xf;
|
||||
}
|
||||
|
||||
INLINE struct xform xform_rotate(struct xform xf, f32 angle)
|
||||
{
|
||||
f32 c = math_cos(angle);
|
||||
f32 s = math_sin(angle);
|
||||
|
||||
struct xform res = xf;
|
||||
res.bx = V2(
|
||||
xf.bx.x * c + xf.by.x * s,
|
||||
xf.bx.y * c + xf.by.y * s
|
||||
);
|
||||
res.by = V2(
|
||||
xf.bx.x * -s + xf.by.x * c,
|
||||
xf.bx.y * -s + xf.by.y * c
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct xform xform_scale(struct xform xf, struct v2 v)
|
||||
{
|
||||
xf.bx = v2_mul(xf.bx, v.y);
|
||||
xf.by = v2_mul(xf.by, v.y);
|
||||
return xf;
|
||||
}
|
||||
|
||||
INLINE struct xform xform_from_trs(struct trs trs)
|
||||
{
|
||||
struct xform m = xform_from_translate(trs.t);
|
||||
m = xform_rotate(m, trs.r);
|
||||
m = xform_scale(m, trs.s);
|
||||
return m;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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));
|
||||
return xf;
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_basis_mul_v2(struct xform xf, struct v2 v)
|
||||
{
|
||||
return V2(
|
||||
xf.bx.x * v.x + xf.by.x * v.y,
|
||||
xf.bx.y * v.x + xf.by.y * v.y
|
||||
);
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_mul_v2(struct xform xf, struct v2 v)
|
||||
{
|
||||
struct v2 res = xform_basis_mul_v2(xf, v);
|
||||
res = v2_add(res, xf.t);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_mul_v2_invert(struct xform xf, struct v2 v)
|
||||
{
|
||||
struct xform inv = xform_invert(xf);
|
||||
struct v2 res = xform_basis_mul_v2(inv, v);
|
||||
res = v2_add(res, inv.t);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct xform xform_invert(struct xform xf)
|
||||
{
|
||||
f32 det = xform_get_determinant(xf);
|
||||
f32 inv_det = 1.0f / det;
|
||||
|
||||
f32 old_bx_x = xf.bx.x;
|
||||
xf.bx.x = xf.by.y;
|
||||
xf.by.y = old_bx_x;
|
||||
|
||||
xf.bx = v2_mul_v2(xf.bx, V2(inv_det, -inv_det));
|
||||
xf.by = v2_mul_v2(xf.by, V2(-inv_det, inv_det));
|
||||
|
||||
xf.t = xform_basis_mul_v2(xf, v2_neg(xf.t));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_right(struct xform xf)
|
||||
{
|
||||
return xf.bx;
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_left(struct xform xf)
|
||||
{
|
||||
return v2_neg(xf.bx);
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_up(struct xform xf)
|
||||
{
|
||||
return v2_neg(xf.by);
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_down(struct xform xf)
|
||||
{
|
||||
return xf.by;
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_pos(struct xform xf)
|
||||
{
|
||||
return xf.t;
|
||||
}
|
||||
|
||||
INLINE f32 xform_get_determinant(struct xform xf)
|
||||
{
|
||||
return v2_wedge(xf.bx, xf.by);
|
||||
}
|
||||
|
||||
INLINE f32 xform_get_rot(struct xform xf)
|
||||
{
|
||||
return v2_angle(xf.bx);
|
||||
}
|
||||
|
||||
INLINE struct v2 xform_get_scale(struct xform xf)
|
||||
{
|
||||
f32 det_sign = math_sign_f32(xform_get_determinant(xf));
|
||||
return V2(v2_len(xf.bx), det_sign * v2_len(xf.by));
|
||||
}
|
||||
|
||||
INLINE f32 xform_get_skew(struct xform xf)
|
||||
{
|
||||
f32 det = xform_get_determinant(xf);
|
||||
i32 det_sign = math_sign_f32(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);
|
||||
|
||||
return math_acos(dot) - (PI / 2.0f);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Trs
|
||||
* ========================== */
|
||||
@ -679,12 +667,12 @@ INLINE struct trs trs_lerp(struct trs a, struct trs b, f32 t)
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE struct trs trs_from_mat3x3(struct mat3x3 m)
|
||||
INLINE struct trs trs_from_xform(struct xform m)
|
||||
{
|
||||
struct trs trs = { 0 };
|
||||
trs.t = mat3x3_get_pos(m);
|
||||
trs.r = mat3x3_get_rot(m);
|
||||
trs.s = mat3x3_get_scale(m);
|
||||
trs.t = xform_get_pos(m);
|
||||
trs.r = xform_get_rot(m);
|
||||
trs.s = xform_get_scale(m);
|
||||
return trs;
|
||||
}
|
||||
|
||||
@ -736,13 +724,13 @@ INLINE struct quad quad_scale(struct quad q, f32 s)
|
||||
return q;
|
||||
}
|
||||
|
||||
INLINE struct quad quad_mul_mat3x3(struct quad quad, struct mat3x3 m)
|
||||
INLINE struct quad quad_mul_xform(struct quad quad, struct xform m)
|
||||
{
|
||||
return (struct quad) {
|
||||
mat3x3_mul_v2(m, quad.p1),
|
||||
mat3x3_mul_v2(m, quad.p2),
|
||||
mat3x3_mul_v2(m, quad.p3),
|
||||
mat3x3_mul_v2(m, quad.p4)
|
||||
xform_mul_v2(m, quad.p1),
|
||||
xform_mul_v2(m, quad.p2),
|
||||
xform_mul_v2(m, quad.p3),
|
||||
xform_mul_v2(m, quad.p4)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -51,10 +51,10 @@ struct renderer_canvas *renderer_canvas_alloc(void);
|
||||
|
||||
void renderer_canvas_release(struct renderer_canvas *canvas);
|
||||
|
||||
/* Set the canvas view matrix to be used when presenting the canvas.
|
||||
/* Set the canvas view xform to be used when presenting the canvas.
|
||||
* NOTE: `view` should be in row-major order.
|
||||
*/
|
||||
void renderer_canvas_set_view(struct renderer_canvas *canvas, struct mat3x3 view);
|
||||
void renderer_canvas_set_view(struct renderer_canvas *canvas, struct xform view);
|
||||
|
||||
/* Pushes array of vertices based on `vertices_count` & `indices_count`.
|
||||
* Sets `vertices_out` and `indices_out` to start of the pushed arrays, to be filled out by the caller.
|
||||
|
||||
@ -83,7 +83,7 @@ struct renderer_canvas {
|
||||
struct cmd_store cpu_cmd_store;
|
||||
struct cmd_store gpu_cmd_store;
|
||||
|
||||
struct mat3x3 view;
|
||||
struct xform view;
|
||||
|
||||
b32 valid; /* False if uninitialized (in sparse array) */
|
||||
};
|
||||
@ -150,23 +150,11 @@ GLOBAL struct {
|
||||
* ========================== */
|
||||
|
||||
/* Calculate the view projection matrix */
|
||||
INLINE struct mat4x4 calculate_vp(struct mat3x3 view, f32 viewport_width, f32 viewport_height)
|
||||
INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height)
|
||||
{
|
||||
struct mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0);
|
||||
|
||||
/* Convert view from 3x3 to 4x4 matrix */
|
||||
struct mat4x4 view4x4 = {
|
||||
.e = {
|
||||
{view.e[0][0], view.e[0][1], 0, view.e[0][2]},
|
||||
{view.e[1][0], view.e[1][1], 0, view.e[1][2]},
|
||||
{0, 0, 1, 0},
|
||||
{view.e[2][0], view.e[2][1], 0, view.e[2][2]},
|
||||
}
|
||||
};
|
||||
|
||||
struct mat4x4 res = mat4x4_mul(projection, view4x4);
|
||||
|
||||
return res;
|
||||
struct mat4x4 view4x4 = mat4x4_from_xform(view);
|
||||
return mat4x4_mul(projection, view4x4);
|
||||
}
|
||||
|
||||
INTERNAL void send_constant_buffer_data(ID3D11Buffer *buffer, struct mat4x4 vp)
|
||||
@ -632,7 +620,7 @@ struct renderer_canvas *renderer_canvas_alloc(void)
|
||||
MEMZERO_STRUCT(canvas);
|
||||
canvas->cpu_cmd_store.arena = arena_alloc(GIGABYTE(8));
|
||||
canvas->gpu_cmd_store.arena = arena_alloc(GIGABYTE(8));
|
||||
canvas->view = mat3x3_from_trs(TRS());
|
||||
canvas->view = xform_from_trs(TRS());
|
||||
canvas->valid = true;
|
||||
|
||||
/* Initialize buffers, skipping index 0 (SHADER_NONE) */
|
||||
@ -664,7 +652,7 @@ void renderer_canvas_release(struct renderer_canvas *canvas)
|
||||
}
|
||||
}
|
||||
|
||||
void renderer_canvas_set_view(struct renderer_canvas *canvas, struct mat3x3 view)
|
||||
void renderer_canvas_set_view(struct renderer_canvas *canvas, struct xform view)
|
||||
{
|
||||
canvas->view = view;
|
||||
}
|
||||
|
||||
48
src/user.c
48
src/user.c
@ -210,7 +210,7 @@ INTERNAL void push_game_cmds(struct game_cmd_list *list)
|
||||
* View
|
||||
* ========================== */
|
||||
|
||||
INTERNAL struct mat3x3 view_get_xform(struct view view)
|
||||
INTERNAL struct xform view_get_xform(struct view view)
|
||||
{
|
||||
f32 scale = view.zoom * view.px_per_unit;
|
||||
struct trs trs = TRS(
|
||||
@ -220,22 +220,22 @@ INTERNAL struct mat3x3 view_get_xform(struct view view)
|
||||
);
|
||||
|
||||
struct v2 pivot = view.center;
|
||||
struct mat3x3 res = mat3x3_from_translate(pivot);
|
||||
res = mat3x3_trs_pivot_rs(res, trs, pivot);
|
||||
struct xform res = xform_ident();
|
||||
res = xform_translate(res, pivot);
|
||||
res = xform_trs_pivot_rs(res, trs, pivot);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERNAL struct v2 view_xform_point(struct view view, struct v2 p)
|
||||
{
|
||||
struct mat3x3 mtx = view_get_xform(view);
|
||||
return mat3x3_mul_v2(mtx, p);
|
||||
struct xform mtx = view_get_xform(view);
|
||||
return xform_mul_v2(mtx, p);
|
||||
}
|
||||
|
||||
INTERNAL struct v2 view_inverse_xform_point(struct view view, struct v2 p)
|
||||
{
|
||||
struct mat3x3 mtx_inverse = mat3x3_inverse(view_get_xform(view));
|
||||
return mat3x3_mul_v2(mtx_inverse, p);
|
||||
return xform_mul_v2_invert(view_get_xform(view), p);
|
||||
}
|
||||
|
||||
INTERNAL struct v2 view_mouse_pos(struct view view)
|
||||
@ -248,19 +248,19 @@ INTERNAL struct v2 view_mouse_pos(struct view view)
|
||||
* ========================== */
|
||||
|
||||
/* TODO: remove this (testing) */
|
||||
INTERNAL void debug_draw_xform(struct mat3x3 mtx)
|
||||
INTERNAL void debug_draw_xform(struct xform mtx)
|
||||
{
|
||||
f32 thickness = 2.f / PIXELS_PER_UNIT / L.world_view.zoom;
|
||||
u32 color = RGBA_F(0, 1, 1, 0.3);
|
||||
u32 color_x = RGBA_F(1, 0, 0, 0.3);
|
||||
u32 color_y = RGBA_F(0, 1, 0, 0.3);
|
||||
|
||||
struct v2 pos = mat3x3_get_pos(mtx);
|
||||
struct v2 x_ray = mat3x3_get_right(mtx);
|
||||
struct v2 y_ray = mat3x3_get_up(mtx);
|
||||
struct v2 pos = xform_get_pos(mtx);
|
||||
struct v2 x_ray = xform_get_right(mtx);
|
||||
struct v2 y_ray = xform_get_up(mtx);
|
||||
|
||||
struct quad quad = quad_from_rect(RECT(0, 0, 1, -1));
|
||||
quad = quad_mul_mat3x3(quad_scale(quad, 0.075), mtx);
|
||||
quad = quad_mul_xform(quad_scale(quad, 0.075), mtx);
|
||||
|
||||
draw_solid_ray(L.world_canvas, pos, x_ray, thickness, color_x);
|
||||
draw_solid_ray(L.world_canvas, pos, y_ray, thickness, color_y);
|
||||
@ -275,7 +275,7 @@ INTERNAL void debug_draw_movement(struct entity *ent)
|
||||
u32 color_vel = RGBA_F(1, 0.5, 0, 1);
|
||||
u32 color_acc = RGBA_F(1, 1, 0.5, 1);
|
||||
|
||||
struct v2 pos = mat3x3_get_pos(ent->world_xform);
|
||||
struct v2 pos = xform_get_pos(ent->world_xform);
|
||||
struct v2 vel_ray = ent->velocity;
|
||||
struct v2 acc_ray = ent->acceleration;
|
||||
|
||||
@ -502,7 +502,7 @@ INTERNAL void user_update(void)
|
||||
struct entity *e1 = &t1->entities[i];
|
||||
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
||||
e->rel_trs = trs_lerp(e0->rel_trs, e1->rel_trs, tick_blend);
|
||||
e->world_xform = mat3x3_lerp(e0->world_xform, e1->world_xform, tick_blend);
|
||||
e->world_xform = xform_lerp(e0->world_xform, e1->world_xform, tick_blend);
|
||||
|
||||
e->acceleration = v2_lerp(e0->acceleration, e1->acceleration, tick_blend);
|
||||
e->velocity = v2_lerp(e0->velocity, e1->velocity, tick_blend);
|
||||
@ -530,7 +530,7 @@ INTERNAL void user_update(void)
|
||||
if (!ent->valid) continue;
|
||||
|
||||
if (entity_has_prop(ent, ENTITY_PROP_CAMERA) && ent->camera_active && !L.debug_camera) {
|
||||
struct v2 center = mat3x3_get_pos(ent->world_xform);
|
||||
struct v2 center = xform_get_pos(ent->world_xform);
|
||||
f32 rot = ent->camera_rot;
|
||||
f32 zoom = ent->camera_zoom;
|
||||
zoom = zoom > 0 ? zoom : 1;
|
||||
@ -599,13 +599,13 @@ INTERNAL void user_update(void)
|
||||
/* Draw texture */
|
||||
struct quad quad = QUAD_UNIT_SQUARE_CENTERED;
|
||||
|
||||
struct mat3x3 mtx;
|
||||
struct xform mtx;
|
||||
{
|
||||
struct v2 scale_div_2 = v2_mul(ent->sprite_trs.s, 0.5f);
|
||||
struct v2 pivot = v2_mul_v2(ent->sprite_pivot_norm, scale_div_2);
|
||||
mtx = mat3x3_trs_pivot_r(ent->world_xform, ent->sprite_trs, pivot);
|
||||
mtx = xform_trs_pivot_r(ent->world_xform, ent->sprite_trs, pivot);
|
||||
|
||||
quad = quad_mul_mat3x3(quad, mtx);
|
||||
quad = quad_mul_xform(quad, mtx);
|
||||
}
|
||||
|
||||
struct texture *texture = texture_load_async(tex_name);
|
||||
@ -663,10 +663,10 @@ INTERNAL void user_update(void)
|
||||
{
|
||||
u32 color = RGBA_F(1, 0, 0, 1);
|
||||
|
||||
struct mat3x3 mtx_pre_pivot = ent->world_xform;
|
||||
mtx_pre_pivot = mat3x3_trs(mtx_pre_pivot, ent->sprite_trs);
|
||||
struct xform mtx_pre_pivot = ent->world_xform;
|
||||
mtx_pre_pivot = xform_trs(mtx_pre_pivot, ent->sprite_trs);
|
||||
|
||||
draw_solid_circle(L.world_canvas, mat3x3_get_pos(mtx_pre_pivot), 0.02, color, 20);
|
||||
draw_solid_circle(L.world_canvas, xform_get_pos(mtx_pre_pivot), 0.02, color, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -675,13 +675,13 @@ INTERNAL void user_update(void)
|
||||
if (L.debug_draw && !is_camera) {
|
||||
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
|
||||
if (disp_font) {
|
||||
struct mat3x3 mtx = ent->world_xform;
|
||||
struct trs trs = trs_from_mat3x3(mtx);
|
||||
struct xform mtx = ent->world_xform;
|
||||
struct trs trs = trs_from_xform(mtx);
|
||||
struct v2 velocity = ent->velocity;
|
||||
struct v2 acceleration = ent->acceleration;
|
||||
|
||||
f32 offset = 1;
|
||||
struct v2 pos = v2_add(mat3x3_get_pos(mtx), v2_mul(V2(0, -1), offset));
|
||||
struct v2 pos = v2_add(xform_get_pos(mtx), v2_mul(V2(0, -1), offset));
|
||||
pos = view_xform_point(L.world_view, pos);
|
||||
pos = v2_round(pos);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user