rotation-agnostic crosshair movement
This commit is contained in:
parent
8405d039af
commit
f1eb4ea855
@ -453,7 +453,7 @@ Vec2 Vec2WithLen(Vec2 a, f32 len)
|
||||
return a;
|
||||
}
|
||||
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 max)
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 min, f32 max)
|
||||
{
|
||||
f32 l_sq = a.x * a.x + a.y * a.y;
|
||||
if (l_sq > max * max)
|
||||
@ -462,6 +462,12 @@ Vec2 ClampVec2Len(Vec2 a, f32 max)
|
||||
a.x *= denom;
|
||||
a.y *= denom;
|
||||
}
|
||||
else if (l_sq < min * min)
|
||||
{
|
||||
f32 denom = min / SqrtF32(l_sq);
|
||||
a.x *= denom;
|
||||
a.y *= denom;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@ -366,7 +366,7 @@ f32 Vec2LenSq(Vec2 a);
|
||||
Vec2 Vec2WithLen(Vec2 a, f32 len);
|
||||
f32 Vec2Distance(Vec2 a, Vec2 b);
|
||||
Vec2 NormVec2(Vec2 a);
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 max);
|
||||
Vec2 ClampVec2Len(Vec2 a, f32 min, f32 max);
|
||||
|
||||
//- Clamp
|
||||
Vec2 ClampVec2(Vec2 v, Rng2 r);
|
||||
|
||||
45
src/pp/pp.c
45
src/pp/pp.c
@ -2082,7 +2082,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
// Normalize controls
|
||||
for (P_Ent *ent = P_FirstEnt(frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
|
||||
{
|
||||
ent->control.move = ClampVec2Len(ent->control.move, 1);
|
||||
ent->control.move = ClampVec2Len(ent->control.move, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2133,7 +2133,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
}
|
||||
}
|
||||
}
|
||||
\
|
||||
|
||||
//////////////////////////////
|
||||
//- Setup constraints store
|
||||
|
||||
@ -2719,7 +2719,8 @@ void P_StepFrame(P_Frame *frame)
|
||||
|
||||
Vec2 fire_pos = Zi;
|
||||
Vec2 fire_dir = Zi;
|
||||
Vec2 fire_base = Zi;
|
||||
Vec2 fire_base0 = Zi;
|
||||
Vec2 fire_base1 = Zi;
|
||||
if (can_fire)
|
||||
{
|
||||
Vec2 look = firer->control.look;
|
||||
@ -2753,7 +2754,7 @@ void P_StepFrame(P_Frame *frame)
|
||||
SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_anchor_ray.dir));
|
||||
wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos));
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_ap_ray.dir));
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, NegVec2(body_ap_ray.dir));
|
||||
|
||||
SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, anchor_ray.dir);
|
||||
@ -2768,11 +2769,18 @@ void P_StepFrame(P_Frame *frame)
|
||||
fire_pos = MulAffineVec2(wep_pix_to_world_af, fire_ray.pos);
|
||||
fire_dir = NormRot(MulAffineBasisVec2(wep_pix_to_world_af, fire_ray.dir));
|
||||
|
||||
fire_base = MulVec2(PerpVec2(NegVec2(firer->xf.r)), WedgeVec2(firer->xf.r, SubVec2(firer->xf.t, fire_pos)));
|
||||
fire_base = AddVec2(fire_base, firer->xf.t);
|
||||
fire_base0 = MulVec2(PerpVec2(NegVec2(firer->xf.r)), WedgeVec2(firer->xf.r, SubVec2(firer->xf.t, fire_pos)));
|
||||
fire_base0 = AddVec2(fire_base0, firer->xf.t);
|
||||
|
||||
P_DebugDrawLine(fire_base, fire_pos, Color_Yellow);
|
||||
P_DebugDrawPoint(fire_base, Color_Yellow);
|
||||
Vec2 chamber_pos = MulAffineVec2(body_pix_to_world_af, body.rays[SPR_RayKind_Ap].pos);
|
||||
|
||||
fire_base1 = MulVec2(PerpVec2(fire_dir), WedgeVec2(fire_dir, SubVec2(fire_pos, chamber_pos)));
|
||||
fire_base1 = AddVec2(fire_base1, chamber_pos);
|
||||
|
||||
P_DebugDrawLine(fire_base0, fire_base1, Color_Yellow);
|
||||
P_DebugDrawLine(fire_base1, fire_pos, Color_Green);
|
||||
P_DebugDrawPoint(fire_base0, Color_Yellow);
|
||||
P_DebugDrawPoint(fire_base1, Color_Green);
|
||||
P_DebugDrawPoint(fire_pos, Color_Red);
|
||||
}
|
||||
|
||||
@ -2805,7 +2813,8 @@ void P_StepFrame(P_Frame *frame)
|
||||
|
||||
Vec2 dir = Vec2FromAngle(angle);
|
||||
|
||||
bullet->bullet_base = fire_base;
|
||||
bullet->bullet_base0 = fire_base0;
|
||||
bullet->bullet_base1 = fire_base1;
|
||||
bullet->bullet_start = fire_pos;
|
||||
bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed));
|
||||
bullet->bullet_firer = firer->key;
|
||||
@ -2844,10 +2853,20 @@ void P_StepFrame(P_Frame *frame)
|
||||
// wasn't obstructed (e.g. to prevent shooting through walls), so we
|
||||
// insert a path from the bullet's base to its starting position before
|
||||
// its actual firing path
|
||||
BulletPath *path = PushStruct(scratch.arena, BulletPath);
|
||||
SllQueuePush(first_bullet_path, last_bullet_path, path);
|
||||
path->start = bullet->bullet_base;
|
||||
path->end = bullet->bullet_start;
|
||||
{
|
||||
// Firer origin -> weapon base path
|
||||
BulletPath *path = PushStruct(scratch.arena, BulletPath);
|
||||
SllQueuePush(first_bullet_path, last_bullet_path, path);
|
||||
path->start = bullet->bullet_base0;
|
||||
path->end = bullet->bullet_base1;
|
||||
}
|
||||
{
|
||||
// Weapon base -> bullet start path
|
||||
BulletPath *path = PushStruct(scratch.arena, BulletPath);
|
||||
SllQueuePush(first_bullet_path, last_bullet_path, path);
|
||||
path->start = bullet->bullet_base1;
|
||||
path->end = bullet->bullet_start;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@ -130,7 +130,8 @@ Struct(P_Ent)
|
||||
|
||||
P_EntKey bullet_firer;
|
||||
b32 is_bullet;
|
||||
Vec2 bullet_base;
|
||||
Vec2 bullet_base0;
|
||||
Vec2 bullet_base1;
|
||||
Vec2 bullet_start;
|
||||
Vec2 bullet_end;
|
||||
|
||||
|
||||
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
Binary file not shown.
@ -841,7 +841,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Compute movement & look
|
||||
|
||||
f32 look_radius = 5;
|
||||
f32 max_look_radius = 5;
|
||||
f32 min_look_radius = 0.01;
|
||||
|
||||
frame->is_looking = !frame->is_editing && !frame->palette.is_showing && !frame->held_buttons[Button_Alt];
|
||||
frame->is_moving = !frame->is_editing;
|
||||
@ -854,17 +855,26 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
if (frame->held_buttons[Button_W]) move.y -= 1;
|
||||
if (frame->held_buttons[Button_S]) move.y += 1;
|
||||
}
|
||||
move = ClampVec2Len(move, 1);
|
||||
move = ClampVec2Len(move, 0, 1);
|
||||
f32 fire_held = frame->held_buttons[Button_M1];
|
||||
Vec2 look = Zi;
|
||||
f32 fire_presses = fire_held && !prev_frame->held_buttons[Button_M1];
|
||||
{
|
||||
// TODO: Adjustable sensitivity
|
||||
f32 mouse_sensitivity = TweakFloat("Mouse sensitivity", 1.0, 0.1, 5.0);
|
||||
f32 mouse_scale_factor = 0.007;
|
||||
|
||||
Vec2 look_delta = mouse_delta;
|
||||
look_delta = MulVec2(look_delta, mouse_sensitivity * mouse_scale_factor);
|
||||
|
||||
Vec2 prev_crosshair_rot = NormRot(SubVec2(prev_frame->world_crosshair, prev_frame->world_crosshair_base));
|
||||
Vec2 prev_look_rot = NormRot(prev_frame->look);
|
||||
Vec2 rot = RotateVec2(prev_look_rot, InvertRot(prev_crosshair_rot));
|
||||
|
||||
look_delta = RotateVec2(look_delta, rot);
|
||||
|
||||
look = frame->look;
|
||||
look = AddVec2(look, MulVec2(mouse_delta, mouse_sensitivity * mouse_scale_factor));
|
||||
look = ClampVec2Len(look, look_radius);
|
||||
look = AddVec2(look, look_delta);
|
||||
look = ClampVec2Len(look, min_look_radius, max_look_radius);
|
||||
}
|
||||
|
||||
if (frame->is_looking)
|
||||
@ -931,86 +941,24 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
}
|
||||
else
|
||||
{
|
||||
// // Vec2 look_ratio = VEC2(0.5, 0.5);
|
||||
// Vec2 look_ratio = VEC2(0.75, 0.75);
|
||||
// // Vec2 look_ratio = VEC2(1.0, 1.0);
|
||||
// {
|
||||
// // look_ratio.y = 0.5;
|
||||
// // look_ratio.x = look_ratio.y / (16.0 / 9.0);
|
||||
// }
|
||||
|
||||
// Vec2 look_ratio = Zi;
|
||||
// {
|
||||
// Vec2 max_look = Vec2WithLen(frame->look, look_radius);
|
||||
|
||||
// Vec2 look_ratio_of_max = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
|
||||
|
||||
// look_ratio = look_ratio_of_max;
|
||||
|
||||
// // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
|
||||
// // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
|
||||
|
||||
// // look_ratio.x = screen_look.x / frame->screen_dims.x;
|
||||
// // look_ratio.x = frame->look.x / look_radius;
|
||||
|
||||
|
||||
// if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
|
||||
// {
|
||||
// look_ratio = VEC2(0, 0);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Vec2 look_ratio = Zi;
|
||||
// {
|
||||
// Vec2 max_look = Vec2WithLen(frame->look, look_radius);
|
||||
|
||||
// Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius));
|
||||
|
||||
// look_ratio = look_ratio_of_radius;
|
||||
|
||||
// // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look);
|
||||
// // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look)
|
||||
|
||||
// // look_ratio.x = screen_look.x / frame->screen_dims.x;
|
||||
// // look_ratio.x = frame->look.x / look_radius;
|
||||
|
||||
|
||||
// if (IsNan(look_ratio.x) || IsNan(look_ratio.y))
|
||||
// {
|
||||
// look_ratio = VEC2(0, 0);
|
||||
// }
|
||||
|
||||
// // look_ratio = MulVec2(look_ratio, 0.5);
|
||||
// look_ratio = VEC2(0.5, 0.5);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Vec2 look_ratio = Zi;
|
||||
{
|
||||
look_ratio = VEC2(0.5, 0.5);
|
||||
// look_ratio = VEC2(0.5, 0.5 * (16.0 / 9.0));
|
||||
}
|
||||
|
||||
Vec2 prev_crosshair_rot = NormRot(SubVec2(prev_frame->world_crosshair, prev_frame->world_crosshair_base));
|
||||
Vec2 prev_look_rot = NormRot(prev_frame->look);
|
||||
Vec2 rot = RotateVec2(prev_look_rot, InvertRot(prev_crosshair_rot));
|
||||
|
||||
|
||||
|
||||
|
||||
Vec2 look_pos = frame->look;
|
||||
look_pos = RotateVec2(look_pos, InvertRot(rot));
|
||||
|
||||
P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key);
|
||||
P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy);
|
||||
Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid;
|
||||
Vec2 screen_center = MulVec2(frame->screen_dims, 0.5);
|
||||
target_camera_pos = guy_center;
|
||||
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(frame->look, look_ratio));
|
||||
target_camera_pos = AddVec2(target_camera_pos, MulVec2Vec2(look_pos, look_ratio));
|
||||
target_camera_zoom = 1;
|
||||
}
|
||||
target_camera_pos.x = ClampF32(target_camera_pos.x, -world_pitch / 2, world_pitch / 2);
|
||||
@ -1872,6 +1820,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//- Compute crosshair position
|
||||
|
||||
// TODO: Alive / weapon check
|
||||
|
||||
if (!P_IsEntNil(local_guy))
|
||||
{
|
||||
P_Ent *ent = local_guy;
|
||||
@ -1916,7 +1865,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_anchor_ray.dir));
|
||||
wep_pix_to_ent_af = TranslateAffine(wep_pix_to_ent_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos));
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, InvertRot(body_ap_ray.dir));
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, NegVec2(body_ap_ray.dir));
|
||||
|
||||
SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor];
|
||||
wep_pix_to_ent_af = RotateAffine(wep_pix_to_ent_af, anchor_ray.dir);
|
||||
@ -1936,25 +1885,31 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
Vec2 desired_fire_pos = MulAffineVec2(desired_wep_pix_to_world_af, fire_ray.pos);
|
||||
Vec2 desired_fire_dir = NormRot(MulAffineBasisVec2(desired_wep_pix_to_world_af, fire_ray.dir));
|
||||
|
||||
Vec2 desired_hold_pos = MulAffineVec2(desired_body_pix_to_world_af, body.rays[SPR_RayKind_Ap].pos);
|
||||
|
||||
Vec2 desired_chamber_pos = MulVec2(PerpVec2(desired_fire_dir), WedgeVec2(desired_fire_dir, SubVec2(desired_fire_pos, desired_hold_pos)));
|
||||
desired_chamber_pos = AddVec2(desired_chamber_pos, desired_hold_pos);
|
||||
|
||||
Vec2 desired_crosshair_base = MulVec2(PerpVec2(NegVec2(desired_ent_to_world_af.bx)), WedgeVec2(desired_ent_to_world_af.bx, SubVec2(desired_ent_to_world_af.og, desired_chamber_pos)));
|
||||
desired_crosshair_base = AddVec2(desired_crosshair_base, desired_ent_to_world_af.og);
|
||||
|
||||
frame->world_guy_origin = desired_ent_to_world_af.og;
|
||||
frame->world_crosshair_base = desired_crosshair_base;
|
||||
|
||||
Vec2 look_rot = NormRot(look);
|
||||
|
||||
Vec2 line_start = cur_fire_pos;
|
||||
Vec2 line_end = AddVec2(line_start, cur_fire_dir);
|
||||
// P_DebugDrawLine(line_start, line_end, Color_Yellow);
|
||||
|
||||
// Vec2 cross = fire_pos;
|
||||
// Vec2 cross = MulAffineVec2(frame->af.screen_to_world, look);
|
||||
f32 cross_dist = Vec2Len(look);
|
||||
|
||||
// f32 cross_dist = 1.0;
|
||||
f32 cross_dist = Vec2Len(look) - Vec2Len(SubVec2(desired_fire_pos, desired_ent_to_world_af.og));
|
||||
frame->world_crosshair = AddVec2(frame->world_crosshair_base, MulVec2(NormVec2(desired_fire_dir), cross_dist));
|
||||
|
||||
frame->world_crosshair = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist));
|
||||
frame->screen_crosshair = MulAffineVec2(frame->af.world_to_screen, frame->world_crosshair);
|
||||
frame->shade_crosshair = MulAffineVec2(frame->af.world_to_shade, frame->world_crosshair);
|
||||
|
||||
// P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red);
|
||||
// P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red);
|
||||
// P_DebugDrawPoint(frame->crosshair, Color_Green);
|
||||
P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red);
|
||||
P_DebugDrawPoint(frame->world_crosshair_base, Color_Yellow);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -2150,7 +2105,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
SPR_Ray body_ap_ray = body.rays[SPR_RayKind_Ap];
|
||||
wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, InvertRot(body_anchor_ray.dir));
|
||||
wep_pix_to_world_af = TranslateAffine(wep_pix_to_world_af, SubVec2(body_ap_ray.pos, body_anchor_ray.pos));
|
||||
wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, InvertRot(body_ap_ray.dir));
|
||||
// wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, InvertRot(body_ap_ray.dir));
|
||||
wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, NegVec2(body_ap_ray.dir));
|
||||
|
||||
SPR_Ray anchor_ray = wep.rays[SPR_RayKind_Anchor];
|
||||
wep_pix_to_world_af = RotateAffine(wep_pix_to_world_af, anchor_ray.dir);
|
||||
|
||||
@ -115,9 +115,11 @@ Struct(V_SharedFrame)
|
||||
|
||||
//- Crosshair
|
||||
|
||||
Vec2 world_guy_origin;
|
||||
Vec2 world_crosshair_base;
|
||||
Vec2 world_crosshair;
|
||||
Vec2 screen_crosshair;
|
||||
Vec2 shade_crosshair;
|
||||
Vec2 world_crosshair;
|
||||
|
||||
//- Control
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user