@@ -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