Skip to content

Commit 7fe62aa

Browse files
authored
Add some chase view Improvements (#3571)
* improve chase view cam * fix comment * comment description of acceleration
1 parent d2859f4 commit 7fe62aa

File tree

5 files changed

+86
-50
lines changed

5 files changed

+86
-50
lines changed

code/physics/physics.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,11 @@ void physics_init( physics_info * pi )
5858
pi->max_vel.xyz.z = 100.0f; //forward
5959
pi->max_rear_vel = 100.0f; //backward -- controlled seperately
6060

61-
pi->max_rotvel.xyz.x = 2.0f; //pitch
62-
pi->max_rotvel.xyz.y = 1.0f; //heading
63-
pi->max_rotvel.xyz.z = 2.0f; //bank
61+
pi->max_rotvel = vm_vec_new(2.0f, 1.0f, 2.0f);
6462

65-
pi->prev_ramp_vel.xyz.x = 0.0f;
66-
pi->prev_ramp_vel.xyz.y = 0.0f;
67-
pi->prev_ramp_vel.xyz.z = 0.0f;
63+
vm_vec_zero(&pi->prev_ramp_vel);
6864

69-
pi->desired_vel.xyz.x = 0.0f;
70-
pi->desired_vel.xyz.y = 0.0f;
71-
pi->desired_vel.xyz.z = 0.0f;
65+
vm_vec_zero(&pi->desired_vel);
7266

7367
pi->slide_accel_time_const=pi->side_slip_time_const; // slide using max_vel.xyz.x & .xyz.y
7468
pi->slide_decel_time_const=pi->side_slip_time_const; // slide using max_vel.xyz.x & .xyz.y
@@ -87,6 +81,7 @@ void physics_init( physics_info * pi )
8781

8882
pi->ai_desired_orient = vmd_zero_matrix; // Asteroth - initialize to the "invalid" orientation, which will be ignored by physics unless set otherwise
8983

84+
vm_vec_zero(&pi->acceleration);
9085
}
9186

9287

@@ -281,6 +276,8 @@ void physics_sim_vel(vec3d * position, physics_info * pi, float sim_time, matrix
281276
vec3d local_v_out; // velocity in local coords following this frame
282277
vec3d damp;
283278

279+
vec3d old_vel = pi->vel;
280+
284281
// Maybe clear the reduced_damp flag.
285282
// This fixes the problem of the player getting near-instantaneous acceleration under unknown circumstances.
286283
// The larger problem is probably that PF_USE_VEL is getting stuck set.
@@ -373,6 +370,10 @@ void physics_sim_vel(vec3d * position, physics_info * pi, float sim_time, matrix
373370
// update world velocity
374371
vm_vec_unrotate(&pi->vel, &local_v_out, orient);
375372

373+
// update acceleration
374+
vm_vec_sub(&pi->acceleration, &pi->vel, &old_vel);
375+
vm_vec_scale(&pi->acceleration, 1 / sim_time);
376+
376377
if (special_warp_in) {
377378
vm_vec_rotate(&pi->prev_ramp_vel, &pi->vel, orient);
378379
}

code/physics/physics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ typedef struct physics_info {
100100

101101
matrix ai_desired_orient; // Asteroth - This is only set to something other than the zero matrix if Framerate_independent_turning is enabled, and
102102
// only by the AI after calls to angular_move. It is read and then zeroed out for the rest of the frame by physics_sim_rot
103+
vec3d acceleration; // this is only the current trend of velocity in m/s^2, does NOT determine future velocity
103104
} physics_info;
104105

105106
// control info override flags

code/ship/ship.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,9 @@ void ship_info::clone(const ship_info& other)
10481048
closeup_pos_targetbox = other.closeup_pos_targetbox;
10491049
closeup_zoom_targetbox = other.closeup_zoom_targetbox;
10501050

1051+
chase_view_offset = other.chase_view_offset;
1052+
chase_view_rigidity = other.chase_view_rigidity;
1053+
10511054
allowed_weapons = other.allowed_weapons;
10521055

10531056
restricted_loadout_flag = other.restricted_loadout_flag;
@@ -1359,6 +1362,9 @@ void ship_info::move(ship_info&& other)
13591362
std::swap(closeup_pos_targetbox, other.closeup_pos_targetbox);
13601363
closeup_zoom_targetbox = other.closeup_zoom_targetbox;
13611364

1365+
std::swap(chase_view_offset, other.chase_view_offset);
1366+
chase_view_rigidity = other.chase_view_rigidity;
1367+
13621368
std::swap(allowed_weapons, other.allowed_weapons);
13631369

13641370
std::swap(restricted_loadout_flag, other.restricted_loadout_flag);
@@ -1775,6 +1781,9 @@ ship_info::ship_info()
17751781
vm_vec_zero(&closeup_pos_targetbox);
17761782
closeup_zoom_targetbox = 0.5f;
17771783

1784+
vm_vec_zero(&chase_view_offset);
1785+
chase_view_rigidity = 5.0f;
1786+
17781787
allowed_weapons.clear();
17791788

17801789
restricted_loadout_flag.clear();
@@ -4096,6 +4105,18 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
40964105
stuff_vec3d(&sip->topdown_offset);
40974106
}
40984107

4108+
if (optional_string("$Chase View Offset:")) {
4109+
stuff_vec3d(&sip->chase_view_offset);
4110+
}
4111+
4112+
if (optional_string("$Chase View Rigidity:")) {
4113+
stuff_float(&sip->chase_view_rigidity);
4114+
if (sip->chase_view_rigidity <= 0) {
4115+
Warning(LOCATION, "Ship \'%s\' must have a Chase View Rigidity greater than 0.", sip->name);
4116+
sip->chase_view_rigidity = 5.0f;
4117+
}
4118+
}
4119+
40994120
if (optional_string("$Shield_icon:")) {
41004121
stuff_string(name_tmp, F_NAME, sizeof(name_tmp));
41014122
hud_shield_assign_info(sip, name_tmp);

code/ship/ship.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,9 @@ class ship_info
12471247
vec3d closeup_pos_targetbox; // position for camera when using ship in closeup view for hud target monitor
12481248
float closeup_zoom_targetbox; // zoom when using ship in closeup view for hud target monitor
12491249

1250+
vec3d chase_view_offset; // special offset for chase view
1251+
float chase_view_rigidity; // how 'floaty' this ship is when viewed in chase view
1252+
12501253
allowed_weapon_bank allowed_weapons; // specifies which weapons can be loaded out by the
12511254
// player during weapons loadout.
12521255

freespace2/freespace.cpp

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,7 +2955,7 @@ camid game_render_frame_setup()
29552955

29562956
vec3d eye_pos;
29572957
matrix eye_orient = vmd_identity_matrix;
2958-
vec3d tmp_dir;
2958+
vec3d eye_vec;
29592959

29602960
static int last_Viewer_mode = 0;
29612961
static int last_Game_mode = 0;
@@ -2975,6 +2975,7 @@ camid game_render_frame_setup()
29752975

29762976
// This code is supposed to detect camera "cuts"... like going between
29772977
// different views.
2978+
bool camera_cut = false;
29782979
if ( (last_Viewer_mode != Viewer_mode)
29792980
|| (last_Game_mode != Game_mode)
29802981
|| (fov_changed)
@@ -2985,7 +2986,8 @@ camid game_render_frame_setup()
29852986
last_FOV = main_cam->get_fov();
29862987

29872988
// Camera moved. Tell stars & debris to not do blurring.
2988-
stars_camera_cut();
2989+
stars_camera_cut();
2990+
camera_cut = true;
29892991
}
29902992

29912993
say_view_target();
@@ -3022,8 +3024,8 @@ camid game_render_frame_setup()
30223024
// View target from player ship.
30233025
Viewer_obj = nullptr;
30243026
eye_pos = Player_obj->pos;
3025-
vm_vec_normalized_dir(&tmp_dir, &Objects[Player_ai->target_objnum].pos, &eye_pos);
3026-
vm_vector_2_matrix(&eye_orient, &tmp_dir, nullptr, nullptr);
3027+
vm_vec_normalized_dir(&eye_vec, &Objects[Player_ai->target_objnum].pos, &eye_pos);
3028+
vm_vector_2_matrix(&eye_orient, &eye_vec, nullptr, nullptr);
30273029
//rtn_cid = ship_get_followtarget_eye( Player_obj );
30283030
}
30293031
} else {
@@ -3054,9 +3056,9 @@ camid game_render_frame_setup()
30543056

30553057
eye_pos = Dead_camera_pos;
30563058

3057-
vm_vec_normalized_dir(&tmp_dir, &Player_obj->pos, &eye_pos);
3059+
vm_vec_normalized_dir(&eye_vec, &Player_obj->pos, &eye_pos);
30583060

3059-
vm_vector_2_matrix(&eye_orient, &tmp_dir, nullptr, nullptr);
3061+
vm_vector_2_matrix(&eye_orient, &eye_vec, nullptr, nullptr);
30603062
Viewer_obj = nullptr;
30613063
}
30623064
}
@@ -3101,50 +3103,58 @@ camid game_render_frame_setup()
31013103

31023104
vm_vec_scale_add(&eye_pos, &Viewer_obj->pos, &tm.vec.fvec, Viewer_external_info.current_distance);
31033105

3104-
vm_vec_sub(&tmp_dir, &Viewer_obj->pos, &eye_pos);
3105-
vm_vec_normalize(&tmp_dir);
3106-
vm_vector_2_matrix(&eye_orient, &tmp_dir, &Viewer_obj->orient.vec.uvec, nullptr);
3106+
vm_vec_sub(&eye_vec, &Viewer_obj->pos, &eye_pos);
3107+
vm_vec_normalize(&eye_vec);
3108+
vm_vector_2_matrix(&eye_orient, &eye_vec, &Viewer_obj->orient.vec.uvec, nullptr);
31073109
Viewer_obj = nullptr;
31083110

31093111
// Modify the orientation based on head orientation.
31103112
compute_slew_matrix(&eye_orient, &Viewer_slew_angles);
31113113

31123114
} else if ( Viewer_mode & VM_CHASE ) {
3113-
vec3d move_dir;
31143115
vec3d aim_pt;
3115-
3116-
if ( Viewer_obj->phys_info.speed < 62.5f )
3117-
move_dir = Viewer_obj->phys_info.vel;
3118-
else {
3119-
move_dir = Viewer_obj->phys_info.vel;
3120-
vm_vec_scale(&move_dir, (62.5f/Viewer_obj->phys_info.speed));
3121-
}
31223116

31233117
vec3d tmp_up;
31243118
matrix eyemat;
31253119
ship_get_eye(&tmp_up, &eyemat, Viewer_obj, false, false);
31263120

3127-
//create a better 3rd person view if this is the player ship
3128-
if (Viewer_obj==Player_obj)
3129-
{
3130-
//get a point 1000m forward of ship
3131-
vm_vec_copy_scale(&aim_pt,&Viewer_obj->orient.vec.fvec,1000.0f);
3132-
vm_vec_add2(&aim_pt,&Viewer_obj->pos);
3133-
3134-
vm_vec_scale_add(&eye_pos, &Viewer_obj->pos, &move_dir, -0.02f * Viewer_obj->radius);
3135-
vm_vec_scale_add2(&eye_pos, &eyemat.vec.fvec, -2.125f * Viewer_obj->radius - Viewer_chase_info.distance);
3136-
vm_vec_scale_add2(&eye_pos, &eyemat.vec.uvec, 0.625f * Viewer_obj->radius + 0.35f * Viewer_chase_info.distance);
3137-
vm_vec_sub(&tmp_dir, &aim_pt, &eye_pos);
3138-
vm_vec_normalize(&tmp_dir);
3139-
}
3140-
else
3141-
{
3142-
vm_vec_scale_add(&eye_pos, &Viewer_obj->pos, &move_dir, -0.02f * Viewer_obj->radius);
3143-
vm_vec_scale_add2(&eye_pos, &eyemat.vec.fvec, -2.5f * Viewer_obj->radius - Viewer_chase_info.distance);
3144-
vm_vec_scale_add2(&eye_pos, &eyemat.vec.uvec, 0.75f * Viewer_obj->radius + 0.35f * Viewer_chase_info.distance);
3145-
vm_vec_sub(&tmp_dir, &Viewer_obj->pos, &eye_pos);
3146-
vm_vec_normalize(&tmp_dir);
3121+
eye_pos = Viewer_obj->pos;
3122+
3123+
//get a point far in front of the ship to point the camera at
3124+
vm_vec_copy_scale(&aim_pt,&Viewer_obj->orient.vec.fvec, Viewer_obj->radius * 100.0f);
3125+
vm_vec_add2(&aim_pt,&Viewer_obj->pos);
3126+
3127+
vec3d chase_view_offset = Ship_info[Ships[Viewer_obj->instance].ship_info_index].chase_view_offset;
3128+
if (IS_VEC_NULL(&chase_view_offset)) {
3129+
if (Viewer_obj == Player_obj)
3130+
chase_view_offset = vm_vec_new(0.0f, 0.625f * Viewer_obj->radius, -2.125f * Viewer_obj->radius);
3131+
else
3132+
chase_view_offset = vm_vec_new(0.0f, 0.75f * Viewer_obj->radius, -2.5f * Viewer_obj->radius);
31473133
}
3134+
3135+
//position the camera based on the offset and external camera distance
3136+
vec3d rotated_chase_view_offset;
3137+
vm_vec_unrotate(&rotated_chase_view_offset, &chase_view_offset, &Viewer_obj->orient);
3138+
vm_vec_add2(&eye_pos, &rotated_chase_view_offset);
3139+
vm_vec_scale_add2(&eye_pos, &eyemat.vec.fvec, -Viewer_chase_info.distance);
3140+
vm_vec_scale_add2(&eye_pos, &eyemat.vec.uvec, 0.35f * Viewer_chase_info.distance);
3141+
3142+
vec3d old_pos;
3143+
main_cam->get_info(&old_pos, nullptr);
3144+
if (camera_cut)
3145+
old_pos = eye_pos;
3146+
3147+
// "push" the camera backwards in the direction of its old position based on acceleration to to make it
3148+
// feel like the camera is trying to keep up with the ship (based on the rigidity value)
3149+
vec3d velocity_comp = Viewer_obj->phys_info.vel;
3150+
vm_vec_scale_add2(&velocity_comp, &Viewer_obj->phys_info.acceleration, (-5.0f / (vm_vec_mag(&Viewer_obj->phys_info.rotvel) * 2.0f + 1)) * flFrametime);
3151+
vm_vec_scale_add2(&old_pos, &velocity_comp, flFrametime);
3152+
vec3d eye_mov = eye_pos - old_pos;
3153+
eye_mov *= exp(-Ship_info[Ships[Viewer_obj->instance].ship_info_index].chase_view_rigidity * flFrametime);
3154+
eye_pos -= eye_mov;
3155+
3156+
vm_vec_sub(&eye_vec, &aim_pt, &eye_pos);
3157+
vm_vec_normalize(&eye_vec);
31483158

31493159
// JAS: I added the following code because if you slew up using
31503160
// Descent-style physics, tmp_dir and Viewer_obj->orient.vec.uvec are
@@ -3155,7 +3165,7 @@ camid game_render_frame_setup()
31553165
tmp_up = eyemat.vec.uvec;
31563166
vm_vec_scale_add2( &tmp_up, &eyemat.vec.rvec, 0.00001f );
31573167

3158-
vm_vector_2_matrix(&eye_orient, &tmp_dir, &tmp_up, nullptr);
3168+
vm_vector_2_matrix(&eye_orient, &eye_vec, &tmp_up, nullptr);
31593169
Viewer_obj = nullptr;
31603170

31613171
// Modify the orientation based on head orientation.
@@ -3167,9 +3177,9 @@ camid game_render_frame_setup()
31673177

31683178
vec3d warp_pos = Player_obj->pos;
31693179
shipp->warpout_effect->getWarpPosition(&warp_pos);
3170-
vm_vec_sub(&tmp_dir, &warp_pos, &eye_pos);
3171-
vm_vec_normalize(&tmp_dir);
3172-
vm_vector_2_matrix(&eye_orient, &tmp_dir, &Player_obj->orient.vec.uvec, nullptr);
3180+
vm_vec_sub(&eye_vec, &warp_pos, &eye_pos);
3181+
vm_vec_normalize(&eye_vec);
3182+
vm_vector_2_matrix(&eye_orient, &eye_vec, &Player_obj->orient.vec.uvec, nullptr);
31733183
Viewer_obj = nullptr;
31743184
} else if (Viewer_mode & VM_TOPDOWN) {
31753185
angles rot_angles = { PI_2, 0.0f, 0.0f };

0 commit comments

Comments
 (0)