start on glitchy collision resolution
This commit is contained in:
parent
e3055062e6
commit
2012d0705d
@ -246,7 +246,7 @@ void draw_solid_arrow_line(struct renderer_canvas *canvas, struct v2 start, stru
|
|||||||
|
|
||||||
struct v2 head_start = v2_add(end, head_start_dir);
|
struct v2 head_start = v2_add(end, head_start_dir);
|
||||||
|
|
||||||
struct v2 head_p1_dir = v2_mul(v2_perp_cw(head_start_dir), head_width_ratio);
|
struct v2 head_p1_dir = v2_perp_mul(head_start_dir, head_width_ratio);
|
||||||
struct v2 head_p2_dir = v2_neg(head_p1_dir);
|
struct v2 head_p2_dir = v2_neg(head_p1_dir);
|
||||||
|
|
||||||
struct v2 head_p1 = v2_add(head_start, head_p1_dir);
|
struct v2 head_p1 = v2_add(head_start, head_p1_dir);
|
||||||
|
|||||||
@ -101,14 +101,8 @@ struct entity {
|
|||||||
struct gjk_simplex simplex;
|
struct gjk_simplex simplex;
|
||||||
struct gjk_prototype prototype;
|
struct gjk_prototype prototype;
|
||||||
struct v2 pendir;
|
struct v2 pendir;
|
||||||
struct xform xf0;
|
|
||||||
struct xform xf1;
|
|
||||||
b32 solved;
|
b32 solved;
|
||||||
|
|
||||||
struct xform predicted_xform;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
b32 test_torque_applied;
|
b32 test_torque_applied;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
162
src/game.c
162
src/game.c
@ -189,7 +189,7 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
|
||||||
e->mass_unscaled = 70;
|
e->mass_unscaled = 70;
|
||||||
e->ground_friction = 1000;
|
//e->ground_friction = 1000;
|
||||||
|
|
||||||
entity_set_xform(e, XFORM_TRS(.t = pos, .s = size, .r = rot));
|
entity_set_xform(e, XFORM_TRS(.t = pos, .s = size, .r = rot));
|
||||||
}
|
}
|
||||||
@ -749,11 +749,11 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
|
||||||
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
|
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
|
||||||
if (ent->ground_friction != 0) {
|
if (ent->ground_friction != 0) {
|
||||||
#if 1
|
#if 0
|
||||||
/* Linear velocity */
|
/* Linear velocity */
|
||||||
{
|
{
|
||||||
struct v2 linear_velocity = ent->linear_velocity;
|
struct v2 linear_velocity = ent->linear_velocity;
|
||||||
if (!v2_eq(linear_velocity, V2(0, 0))) {
|
if (!v2_is_zero(linear_velocity)) {
|
||||||
/* FIXME: Incorrect behavior at low FPS & low entity density */
|
/* FIXME: Incorrect behavior at low FPS & low entity density */
|
||||||
const f32 clamp_epsilon = 0.01;
|
const f32 clamp_epsilon = 0.01;
|
||||||
f32 linear_velocity_len = v2_len(linear_velocity);
|
f32 linear_velocity_len = v2_len(linear_velocity);
|
||||||
@ -849,9 +849,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
f32 tick_angular_velocity = (ent->angular_velocity * dt) + (tick_angular_acceleration * dt);
|
f32 tick_angular_velocity = (ent->angular_velocity * dt) + (tick_angular_acceleration * dt);
|
||||||
xf.og = v2_add(xf.og, tick_linear_velocity);
|
xf.og = v2_add(xf.og, tick_linear_velocity);
|
||||||
xf = xform_rotated(xf, tick_angular_velocity);
|
xf = xform_rotated(xf, tick_angular_velocity);
|
||||||
ent->predicted_xform = xf;
|
|
||||||
ent->linear_velocity = v2_div(tick_linear_velocity, dt);
|
ent->linear_velocity = v2_div(tick_linear_velocity, dt);
|
||||||
ent->angular_velocity = tick_angular_velocity / dt;
|
ent->angular_velocity = tick_angular_velocity / dt;
|
||||||
|
entity_set_xform(ent, xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -868,6 +868,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Collision
|
* Collision
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -878,32 +879,28 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue;
|
if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue;
|
||||||
if (!entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED) && !entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
|
if (!entity_has_prop(e0, ENTITY_PROP_PLAYER_CONTROLLED) && !entity_has_prop(e0, ENTITY_PROP_BULLET)) continue;
|
||||||
|
|
||||||
struct xform xf0 = entity_get_xform(e0);
|
struct xform e0_xf = entity_get_xform(e0);
|
||||||
struct xform xf1 = e0->predicted_xform;
|
|
||||||
struct quad e0_quad;
|
struct quad e0_quad;
|
||||||
struct v2_array e0_poly;
|
struct v2_array e0_poly;
|
||||||
{
|
{
|
||||||
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, e0->sprite);
|
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, e0->sprite);
|
||||||
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), e0->animation_frame);
|
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), e0->animation_frame);
|
||||||
e0_quad = xform_mul_quad(e0->sprite_local_xform, quad_from_rect(slice.rect));
|
e0_quad = xform_mul_quad(e0->sprite_local_xform, quad_from_rect(slice.rect));
|
||||||
e0_quad = xform_mul_quad(xf1, e0_quad);
|
e0_quad = xform_mul_quad(e0_xf, e0_quad);
|
||||||
e0_poly = (struct v2_array) {
|
e0_poly = (struct v2_array) {
|
||||||
.count = ARRAY_COUNT(e0_quad.e),
|
.count = ARRAY_COUNT(e0_quad.e),
|
||||||
.points = e0_quad.e
|
.points = e0_quad.e
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 any_collision = false;
|
|
||||||
b32 colliding = false;
|
b32 colliding = false;
|
||||||
struct v2 point0 = V2(0, 0);
|
struct v2 p0 = V2(0, 0);
|
||||||
struct v2 point1 = V2(0, 0);
|
struct v2 p1 = V2(0, 0);
|
||||||
struct entity *colliding_with = entity_nil();
|
struct entity *colliding_with = entity_nil();
|
||||||
struct gjk_simplex simplex = { 0 };
|
struct gjk_simplex simplex = { 0 };
|
||||||
struct gjk_prototype prototype = { 0 };
|
struct gjk_prototype prototype = { 0 };
|
||||||
struct v2 velocity = V2(0, 0);
|
struct v2 velocity = V2(0, 0);
|
||||||
struct v2 pen = V2(0, 0);
|
|
||||||
b32 solved = false;
|
b32 solved = false;
|
||||||
(UNUSED)pen;
|
|
||||||
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
|
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
|
||||||
struct entity *e1 = &store->entities[e1_index];
|
struct entity *e1 = &store->entities[e1_index];
|
||||||
if (e1 == e0) continue;
|
if (e1 == e0) continue;
|
||||||
@ -925,69 +922,140 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Testing */
|
|
||||||
{
|
|
||||||
/* TODO: Continuity gen check */
|
|
||||||
|
|
||||||
velocity = v2_sub(xf1.og, xf0.og);
|
|
||||||
//velocity = V2(0.014992147684, -0.000010356307);
|
|
||||||
//velocity = V2(-0.0001, -0.01);
|
|
||||||
//velocity = V2(0.005, 0);
|
|
||||||
//velocity = V2(-500, -500);
|
|
||||||
|
|
||||||
//velocity = V2(-1, -1);
|
|
||||||
//velocity = v2_neg(velocity);
|
|
||||||
|
|
||||||
|
|
||||||
//velocity = v2_neg(velocity);
|
|
||||||
//xf0.og = v2_sub(xf1.og, velocity);
|
|
||||||
xf1.og = v2_add(xf0.og, velocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gjk_extended_result res = gjk_extended(e0_poly, e1_poly);
|
struct gjk_extended_result res = gjk_extended(e0_poly, e1_poly);
|
||||||
|
|
||||||
colliding = res.colliding;
|
colliding = res.colliding;
|
||||||
point0 = res.p0;
|
p0 = res.p0;
|
||||||
point1 = res.p1;
|
p1 = res.p1;
|
||||||
colliding_with = e1;
|
colliding_with = e1;
|
||||||
simplex = res.simplex;
|
simplex = res.simplex;
|
||||||
prototype = res.prototype;
|
prototype = res.prototype;
|
||||||
solved = res.solved;
|
solved = res.solved;
|
||||||
|
|
||||||
if (colliding) {
|
|
||||||
any_collision = true;
|
|
||||||
pen = v2_sub(point1, point0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e0->colliding = colliding;
|
e0->colliding = colliding;
|
||||||
e0->colliding_with = colliding_with->handle;
|
e0->colliding_with = colliding_with->handle;
|
||||||
e0->point = point0;
|
e0->point = p0;
|
||||||
e0->simplex = simplex;
|
e0->simplex = simplex;
|
||||||
e0->prototype = prototype;
|
e0->prototype = prototype;
|
||||||
e0->xf0 = xf0;
|
|
||||||
e0->xf1 = xf1;
|
|
||||||
e0->pendir = velocity;
|
e0->pendir = velocity;
|
||||||
e0->solved = solved;
|
e0->solved = solved;
|
||||||
|
|
||||||
if (colliding_with->valid) {
|
if (colliding_with->valid) {
|
||||||
colliding_with->colliding = colliding;
|
colliding_with->colliding = colliding;
|
||||||
colliding_with->colliding_with = e0->handle;
|
colliding_with->colliding_with = e0->handle;
|
||||||
colliding_with->point = point1;
|
colliding_with->point = p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(UNUSED)any_collision;
|
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
if (any_collision) {
|
if (colliding) {
|
||||||
xf1.og = v2_add(xf1.og, pen);
|
xf1.og = v2_add(xf1.og, pen);
|
||||||
//e0->verlet_xform.og = xf0.og;
|
//e0->verlet_xform.og = xf0.og;
|
||||||
e0->verlet_xform.og = v2_sub(xf1.og, velocity);
|
//e0->verlet_xform.og = v2_sub(xf1.og, velocity);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (colliding) {
|
||||||
|
struct entity *e1 = colliding_with;
|
||||||
|
struct xform e1_xf = entity_get_xform(e1);
|
||||||
|
|
||||||
|
f32 scale0 = math_fabs(xform_get_determinant(e0_xf));
|
||||||
|
f32 scale1 = math_fabs(xform_get_determinant(e1_xf));
|
||||||
|
f32 m0 = e0->mass_unscaled * scale0;
|
||||||
|
f32 m1 = e1->mass_unscaled * scale1;
|
||||||
|
f32 i0 = e0->inertia_unscaled * scale0;
|
||||||
|
f32 i1 = e1->inertia_unscaled * scale1;
|
||||||
|
f32 inv_m0 = 1.f / m0;
|
||||||
|
f32 inv_m1 = 1.f / m1;
|
||||||
|
f32 inv_i0 = 1.f / i0;
|
||||||
|
f32 inv_i1 = 1.f / i1;
|
||||||
|
(UNUSED)inv_m0;
|
||||||
|
(UNUSED)inv_m1;
|
||||||
|
(UNUSED)inv_i0;
|
||||||
|
(UNUSED)inv_i1;
|
||||||
|
|
||||||
|
struct v2 pen = v2_sub(p1, p0);
|
||||||
|
struct v2 pen_norm = v2_norm(pen);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
f32 bias_factor = 0.3;
|
||||||
|
f32 bias_slop = 0.05;
|
||||||
|
struct v2 bias = v2_sub(v2_mul(pen, bias_factor), v2_mul(pen_norm, bias_slop));
|
||||||
|
if (v2_dot(pen, bias) < 0) {
|
||||||
|
bias = V2(0, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct v2 vcp0 = v2_sub(p0, e0_xf.og);
|
||||||
|
struct v2 vcp1 = v2_sub(p1, e1_xf.og);
|
||||||
|
|
||||||
|
struct v2 p0_vel = v2_add(e0->linear_velocity, v2_perp_mul(vcp0, e0->angular_velocity));
|
||||||
|
struct v2 p1_vel = v2_add(e1->linear_velocity, v2_perp_mul(vcp1, e1->angular_velocity));
|
||||||
|
|
||||||
|
struct v2 vrel = v2_sub(p1_vel, p0_vel);
|
||||||
|
|
||||||
|
f32 vn = v2_dot(vrel, pen_norm);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//f32 ma = 1 / (vcp0 / v2_len(vcp0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct v2 idk0 = v2_perp_mul(vcp0, v2_wedge(vcp0, pen_norm) * inv_i0);
|
||||||
|
struct v2 idk1 = v2_perp_mul(vcp1, v2_wedge(vcp1, pen_norm) * inv_i1);
|
||||||
|
|
||||||
|
f32 k = inv_m0 + inv_m1 + v2_dot(pen_norm, v2_add(idk0, idk1));
|
||||||
|
|
||||||
|
|
||||||
|
/* (to be applied along n) */
|
||||||
|
f32 j = vn / k;
|
||||||
|
//j = max_f32(j, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
DEBUGBREAKABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct v2 imp = v2_mul(pen_norm, j);
|
||||||
|
(UNUSED)imp;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
{
|
||||||
|
struct entity *impulse = entity_alloc(e0);
|
||||||
|
entity_enable_prop(impulse, ENTITY_PROP_LINEAR_IMPULSE);
|
||||||
|
impulse->force = v2_mul(imp, m0);
|
||||||
|
activate_now(impulse);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
struct entity *impulse = entity_alloc(e1);
|
||||||
|
entity_enable_prop(impulse, ENTITY_PROP_LINEAR_IMPULSE);
|
||||||
|
impulse->force = v2_mul(v2_neg(imp), m1);
|
||||||
|
activate_now(impulse);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
entity_set_xform(e0, xf1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Initialize bullet kinematics from sources
|
* Initialize bullet kinematics from sources
|
||||||
@ -1036,7 +1104,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(entity_get_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_is_zero(camera_size)) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -176,7 +176,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
|
|||||||
voronoi_mask |= (v2_dot(rbc_dir, v2_neg(s.b.p)) >= 0) << 2; /* Regions bc, b, and c */
|
voronoi_mask |= (v2_dot(rbc_dir, v2_neg(s.b.p)) >= 0) << 2; /* Regions bc, b, and c */
|
||||||
/* Remove point or edge and determine next direction based on voronoi region */
|
/* Remove point or edge and determine next direction based on voronoi region */
|
||||||
switch (voronoi_mask) {
|
switch (voronoi_mask) {
|
||||||
case 0: { /* No region, must be in simplex */
|
default: { /* No region, must be in simplex */
|
||||||
colliding = true;
|
colliding = true;
|
||||||
} break;
|
} break;
|
||||||
case 1: { /* Region ab, remove c */
|
case 1: { /* Region ab, remove c */
|
||||||
|
|||||||
43
src/math.h
43
src/math.h
@ -645,23 +645,23 @@ INLINE f32 v2_wedge(struct v2 a, struct v2 b)
|
|||||||
return a.x * b.y - a.y * b.x;
|
return a.x * b.y - a.y * b.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clockwise perpendicular vector */
|
/* Right (clockwise) perpendicular vector */
|
||||||
INLINE struct v2 v2_perp_cw(struct v2 a)
|
INLINE struct v2 v2_perp(struct v2 a)
|
||||||
{
|
{
|
||||||
return V2(-a.y, a.x);
|
return V2(-a.y, a.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Counterclockwise perpendicular vector */
|
/* Perpendicular vector scaled by s */
|
||||||
INLINE struct v2 v2_perp_ccw(struct v2 a)
|
INLINE struct v2 v2_perp_mul(struct v2 a, f32 s)
|
||||||
{
|
{
|
||||||
return V2(a.y, -a.x);
|
return V2(s * -a.y, s * a.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_perp_towards_dir(struct v2 v, struct v2 dir)
|
INLINE struct v2 v2_perp_towards_dir(struct v2 v, struct v2 dir)
|
||||||
{
|
{
|
||||||
struct v2 perp = v2_perp_cw(v);
|
struct v2 perp = v2_perp(v);
|
||||||
i32 sign = 1 - ((v2_dot(perp, dir) < 0) << 1);
|
f32 dot = v2_dot(perp, dir);
|
||||||
return v2_mul(perp, sign);
|
return v2_mul(perp, (dot >= 0) - (dot < 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_norm(struct v2 a)
|
INLINE struct v2 v2_norm(struct v2 a)
|
||||||
@ -677,26 +677,17 @@ INLINE struct v2 v2_norm(struct v2 a)
|
|||||||
|
|
||||||
INLINE struct v2 v2_round(struct v2 a)
|
INLINE struct v2 v2_round(struct v2 a)
|
||||||
{
|
{
|
||||||
return V2(
|
return V2(math_round(a.x), math_round(a.y));
|
||||||
math_round(a.x),
|
|
||||||
math_round(a.y)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_floor(struct v2 a)
|
INLINE struct v2 v2_floor(struct v2 a)
|
||||||
{
|
{
|
||||||
return V2(
|
return V2(math_floor(a.x), math_floor(a.y));
|
||||||
math_floor(a.x),
|
|
||||||
math_floor(a.y)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_ceil(struct v2 a)
|
INLINE struct v2 v2_ceil(struct v2 a)
|
||||||
{
|
{
|
||||||
return V2(
|
return V2(math_ceil(a.x), math_ceil(a.y));
|
||||||
math_ceil(a.x),
|
|
||||||
math_ceil(a.y)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE f32 v2_distance(struct v2 a, struct v2 b)
|
INLINE f32 v2_distance(struct v2 a, struct v2 b)
|
||||||
@ -711,12 +702,14 @@ INLINE b32 v2_eq(struct v2 a, struct v2 b)
|
|||||||
return a.x == b.x && a.y == b.y;
|
return a.x == b.x && a.y == b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INLINE b32 v2_is_zero(struct v2 a)
|
||||||
|
{
|
||||||
|
return a.x == 0 && a.y == 0;
|
||||||
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
INLINE struct v2 v2_lerp(struct v2 val0, struct v2 val1, f32 t)
|
||||||
{
|
{
|
||||||
struct v2 res;
|
return V2(math_lerp(val0.x, val1.x, t), math_lerp(val0.y, val1.y, t));
|
||||||
res.x = math_lerp(val0.x, val1.x, t);
|
|
||||||
res.y = math_lerp(val0.y, val1.y, t);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE struct v2 v2_rotated(struct v2 v, f32 a)
|
INLINE struct v2 v2_rotated(struct v2 v, f32 a)
|
||||||
@ -1093,7 +1086,7 @@ INLINE struct quad quad_from_line(struct v2 start, struct v2 end, f32 thickness)
|
|||||||
f32 width = thickness / 2.f;
|
f32 width = thickness / 2.f;
|
||||||
|
|
||||||
struct v2 dir = v2_norm(v2_sub(end, start));
|
struct v2 dir = v2_norm(v2_sub(end, start));
|
||||||
struct v2 dir_perp = v2_perp_cw(dir);
|
struct v2 dir_perp = v2_perp(dir);
|
||||||
|
|
||||||
struct v2 left = v2_mul(dir_perp, -width);
|
struct v2 left = v2_mul(dir_perp, -width);
|
||||||
struct v2 right = v2_mul(dir_perp, width);
|
struct v2 right = v2_mul(dir_perp, width);
|
||||||
|
|||||||
12
src/user.c
12
src/user.c
@ -669,7 +669,7 @@ INTERNAL void user_update(void)
|
|||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(entity_get_xform(active_camera), 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_is_zero(camera_size)) {
|
||||||
aspect_ratio = camera_size.x / camera_size.y;
|
aspect_ratio = camera_size.x / camera_size.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,7 +735,7 @@ INTERNAL void user_update(void)
|
|||||||
{
|
{
|
||||||
struct xform quad_xf = xform_mul(xf, 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_is_zero(camera_size)) {
|
||||||
size = v2_div_v2(size, camera_size);
|
size = v2_div_v2(size, camera_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1331,12 +1331,8 @@ INTERNAL void user_update(void)
|
|||||||
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("player angular velocity: %F"), FMT_FLOAT_P((f64)player_angular_vel, 12)));
|
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("player angular velocity: %F"), FMT_FLOAT_P((f64)player_angular_vel, 12)));
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
struct v2 xf0_pos = entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)->xf0.og;
|
struct v2 plaeyr_pos = entity_get_xform(entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)).og;
|
||||||
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("player collision xf0 pos: (%F, %F)"), FMT_FLOAT_P((f64)xf0_pos.x, 12), FMT_FLOAT_P((f64)xf0_pos.y, 12)));
|
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("player pos: (%F, %F)"), FMT_FLOAT_P((f64)plaeyr_pos.x, 12), FMT_FLOAT_P((f64)plaeyr_pos.y, 12)));
|
||||||
pos.y += spacing;
|
|
||||||
|
|
||||||
struct v2 xf1_pos = entity_find_first_match_one(store, ENTITY_PROP_PLAYER_CONTROLLED)->xf1.og;
|
|
||||||
draw_text(G.viewport_canvas, font, pos, string_format(temp.arena, STR("player collision xf1 pos: (%F, %F)"), FMT_FLOAT_P((f64)xf1_pos.x, 12), FMT_FLOAT_P((f64)xf1_pos.y, 12)));
|
|
||||||
pos.y += spacing;
|
pos.y += spacing;
|
||||||
|
|
||||||
#if RTC
|
#if RTC
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user