@@ -87,6 +87,18 @@ typedef struct eval_enemy_obj_struct {
8787 int nearest_objnum;
8888} eval_enemy_obj_struct;
8989
90+ // the current world orientation of the turret matrix, corresponding to its fvec and uvec defined in the model
91+ // is NOT affected by the turret's current aiming
92+ void turret_instance_find_world_orient (matrix* out_mat, int model_instance_num, int submodel_num, const matrix* objorient)
93+ {
94+ auto pmi = model_get_instance (model_instance_num);
95+ auto pm = model_get (pmi->model_num );
96+ vec3d fvec, uvec;
97+ model_instance_find_world_dir (&fvec, &pm->submodel [submodel_num].frame_of_reference .vec .fvec , pm, pmi, pm->submodel [submodel_num].parent , objorient);
98+ model_instance_find_world_dir (&uvec, &pm->submodel [submodel_num].frame_of_reference .vec .uvec , pm, pmi, pm->submodel [submodel_num].parent , objorient);
99+ vm_vector_2_matrix_norm (out_mat, &fvec, &uvec);
100+ }
101+
90102/* *
91103 * Is object in turret field of view?
92104 *
@@ -1177,7 +1189,7 @@ void ship_get_global_turret_info(const object *objp, const model_subsystem *tp,
11771189 if (gpos)
11781190 model_instance_find_world_point (gpos, &vmd_zero_vector, model_instance_num, tp->subobj_num , &objp->orient , &objp->pos );
11791191 if (gvec)
1180- model_instance_find_world_dir (gvec, &tp->turret_norm , model_instance_num, tp->subobj_num , &objp->orient );
1192+ model_instance_find_world_dir (gvec, &tp->turret_norm , model_instance_num, tp->subobj_num , &objp->orient , true );
11811193}
11821194
11831195void turret_ai_update_aim (ai_info *aip, object *En_Objp, ship_subsys *ss);
@@ -1238,7 +1250,7 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
12381250 } else {
12391251 if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance ].ship_info_index ].is_big_or_huge ())) {
12401252 // the turret norm here is from the perspective of the base submodel, not the gun submodel
1241- model_instance_find_world_dir (&turret_norm, &tp->turret_norm , pm, pmi, tp->subobj_num , &objp->orient );
1253+ model_instance_find_world_dir (&turret_norm, &tp->turret_norm , pm, pmi, pm-> submodel [ tp->subobj_num ]. parent , &objp->orient );
12421254 ai_big_pick_attack_point_turret (lep, ssp, &tmp_pos, &turret_norm, &enemy_point, MIN (wip->max_speed * wip->lifetime , wip->weapon_range ), tp->turret_fov );
12431255 }
12441256 else {
@@ -1407,7 +1419,7 @@ float aifft_compute_turret_dot(object *objp, object *enemy_objp, vec3d *abs_gunp
14071419 if (ship_subsystem_in_sight (enemy_objp, enemy_subsysp, abs_gunposp, &subobj_pos, 1 , &dot_out, &vector_out)) {
14081420 vec3d turret_norm;
14091421
1410- model_instance_find_world_dir (&turret_norm, &turret_subsysp->system_info ->turret_norm , Ships[objp->instance ].model_instance_num , turret_subsysp->system_info ->subobj_num , &objp->orient );
1422+ model_instance_find_world_dir (&turret_norm, &turret_subsysp->system_info ->turret_norm , Ships[objp->instance ].model_instance_num , turret_subsysp->system_info ->subobj_num , &objp->orient , true );
14111423 float dot_return = vm_vec_dot (&turret_norm, &vector_out);
14121424
14131425 if (Ai_info[Ships[objp->instance ].ai_index ].ai_profile_flags [AI::Profile_Flags::Smart_subsystem_targeting_for_turrets]) {
@@ -2728,25 +2740,20 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
27282740 model_subsystem *tp = ss->system_info ;
27292741 float dot = vm_vec_dot (v2e, gvec);
27302742 if (((dot + size_mod) >= tp->turret_fov ) && ((dot - size_mod) <= tp->turret_max_fov )) {
2731-
2732- // Since we no longer maintain world_to_turret_matrix, regenerate it here.
2733- object *objp = &Objects[ss->parent_objnum ];
2734- vec3d turret_norm;
2735- matrix turret_matrix, world_to_turret_matrix;
2736- model_instance_find_world_dir (&turret_norm, &tp->turret_norm , Ships[objp->instance ].model_instance_num , tp->subobj_num , &vmd_identity_matrix);
2737- vm_vector_2_matrix (&turret_matrix, &turret_norm, nullptr , nullptr );
2738- vm_matrix_x_matrix (&world_to_turret_matrix, &objp->orient , &turret_matrix);
2743+ object* objp = &Objects[ss->parent_objnum ];
2744+ matrix turret_matrix;
2745+ turret_instance_find_world_orient (&turret_matrix, Ships[objp->instance ].model_instance_num , tp->subobj_num , &objp->orient );
27392746
27402747 vec3d of_dst;
2741- vm_vec_rotate ( &of_dst, v2e, &world_to_turret_matrix );
2742- if ((of_dst.xyz .x == 0 ) && (of_dst.xyz .y == 0 )) {
2743- return true ;
2744- } else {
2745- of_dst.xyz .z = 0 ;
2748+ vm_vec_rotate (&of_dst, v2e, &turret_matrix );
2749+ if ((of_dst.xyz .x == 0 ) && (of_dst.xyz .z == 0 ))
2750+ return true ;
2751+ else {
2752+ of_dst.xyz .y = 0 ;
27462753 if (!IS_VEC_NULL_SQ_SAFE (&of_dst)) {
27472754 vm_vec_normalize (&of_dst);
27482755 // now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
2749- if ((- of_dst.xyz .y + size_mod) >= tp->turret_y_fov )
2756+ if ((of_dst.xyz .z + size_mod) >= tp->turret_base_fov )
27502757 return true ;
27512758 }
27522759 }
@@ -2757,7 +2764,7 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
27572764bool turret_fov_test (ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mod)
27582765{
27592766 bool in_fov = false ;
2760- if (ss->system_info ->flags [Model::Subsystem_Flags::Turret_alt_math ])
2767+ if (ss->system_info ->flags [Model::Subsystem_Flags::Turret_restricted_fov ])
27612768 in_fov = turret_adv_fov_test (ss, gvec, v2e, size_mod);
27622769 else
27632770 in_fov = turret_std_fov_test (ss, gvec, v2e, size_mod);
0 commit comments