Skip to content

Commit 9dc5070

Browse files
authored
Merge pull request #3309 from Baezon/turret-alt-math-fix
Update Turret_alt_math for moving subsystems
2 parents f2a0e35 + 5e10fcc commit 9dc5070

File tree

7 files changed

+37
-30
lines changed

7 files changed

+37
-30
lines changed

code/ai/aiturret.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

11831195
void 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
27572764
bool 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);

code/model/model.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class model_subsystem { /* contains rotation rate info */
159159
vec3d turret_norm; // direction this turret faces (i.e. the normal to the turret base, or the center of the field of view)
160160
float turret_fov; // dot of turret_norm:vec_to_enemy > this means can see
161161
float turret_max_fov; // dot of turret_norm:vec_to_enemy <= this means barrels can elevate up to the target
162-
float turret_y_fov; // turret's base's fov
162+
float turret_base_fov; // turret's base's fov
163163
int turret_num_firing_points; // number of firing points on this turret
164164
vec3d turret_firing_point[MAX_TFP]; // in parent object's reference frame, point from which to fire.
165165
int turret_gun_sobj; // Which subobject in this model the firing points are linked to.
@@ -962,7 +962,7 @@ void model_init_submodel_axis_pt(polymodel *pm, polymodel_instance *pmi, int sub
962962
// return the point in 3-space in outpnt.
963963
extern void model_find_world_dir(vec3d *out_dir, const vec3d *in_dir, int model_num, int submodel_num, const matrix *objorient);
964964
extern void model_find_world_dir(vec3d *out_dir, const vec3d *in_dir, const polymodel *pm, int submodel_num, const matrix *objorient);
965-
extern void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, int model_instance_num, int submodel_num, const matrix *objorient);
965+
extern void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, int model_instance_num, int submodel_num, const matrix *objorient, bool use_submodel_parent = false);
966966
extern void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, const polymodel *pm, const polymodel_instance *pmi, int submodel_num, const matrix *objorient);
967967

968968
// Clears all the submodel instances stored in a model to their defaults.

code/model/model_flags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Model {
2323
Fire_on_target, // prevents turret from firing unless it is pointing at the firingpoints are pointing at the target
2424
No_ss_targeting, // toggles the subsystem targeting for the turret
2525
Turret_reset_idle, // makes turret reset to their initial position if the target is out of field of view
26-
Turret_alt_math, // tells the game to use additional calculations should turret have a defined y fov
26+
Turret_restricted_fov, // tells the game to use additional calculations should turret have a limited base fov or elevation
2727
Dum_rotates, // Bobboau
2828
Carry_shockwave, // subsystem - even with 'carry no damage' flag - will carry shockwave damage to the hull
2929
Allow_landing, // This subsystem can be landed on

code/model/modelread.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3813,7 +3813,7 @@ int model_rotate_gun(object *objp, polymodel *pm, polymodel_instance *pmi, model
38133813
}
38143814
}
38153815

3816-
if (turret->flags[Model::Subsystem_Flags::Turret_alt_math])
3816+
if (turret->flags[Model::Subsystem_Flags::Turret_restricted_fov])
38173817
limited_base_rotation = true;
38183818

38193819
//------------
@@ -4237,11 +4237,11 @@ void model_find_world_dir(vec3d *out_dir, const vec3d *in_dir, const polymodel *
42374237
}
42384238

42394239
// the same as model_find_world_dir - just taking model instance data into account
4240-
void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, int model_instance_num, int submodel_num, const matrix *objorient)
4240+
void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, int model_instance_num, int submodel_num, const matrix *objorient, bool use_submodel_parent)
42414241
{
42424242
auto pmi = model_get_instance(model_instance_num);
42434243
auto pm = model_get(pmi->model_num);
4244-
model_instance_find_world_dir(out_dir, in_dir, pm, pmi, submodel_num, objorient);
4244+
model_instance_find_world_dir(out_dir, in_dir, pm, pmi, use_submodel_parent ? pm->submodel[submodel_num].parent : submodel_num, objorient);
42454245
}
42464246

42474247
void model_instance_find_world_dir(vec3d *out_dir, const vec3d *in_dir, const polymodel *pm, const polymodel_instance *pmi, int submodel_num, const matrix *objorient)
@@ -5370,7 +5370,7 @@ void model_subsystem::reset()
53705370

53715371
turret_fov = 0;
53725372
turret_max_fov = 0;
5373-
turret_y_fov = 0;
5373+
turret_base_fov = 0;
53745374
turret_num_firing_points = 0;
53755375
for (auto it = std::begin(turret_firing_point); it != std::end(turret_firing_point); ++it)
53765376
it->xyz.x = it->xyz.y = it->xyz.z = 0.0f;

code/scripting/api/objs/subsystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ ADE_FUNC(getFOVs, l_Subsystem, nullptr, "Returns current turrets FOVs", "number,
697697

698698
fov = tp->turret_fov;
699699
fov_e = tp->turret_max_fov;
700-
fov_y = tp->turret_y_fov;
700+
fov_y = tp->turret_base_fov;
701701

702702
return ade_set_args(L, "fff", fov, fov_e, fov_y);
703703
}

code/ship/ship.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4816,7 +4816,7 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
48164816
stuff_int(&value);
48174817
CAP(value, 0, 359);
48184818
float angle = fl_radians(value)/2.0f;
4819-
sp->turret_y_fov = cosf(angle);
4819+
sp->turret_base_fov = cosf(angle);
48204820
turret_has_base_fov = true;
48214821
}
48224822

@@ -4915,7 +4915,7 @@ static void parse_ship_values(ship_info* sip, const bool is_template, const bool
49154915
}
49164916

49174917
if (turret_has_base_fov)
4918-
sp->flags.set(Model::Subsystem_Flags::Turret_alt_math);
4918+
sp->flags.set(Model::Subsystem_Flags::Turret_restricted_fov);
49194919

49204920
if (optional_string("+non-targetable")) {
49214921
Warning(LOCATION, "Grammar error in table file. Please change \"+non-targetable\" to \"+untargetable\".");

code/weapon/beam.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,9 +3586,9 @@ int beam_ok_to_fire(beam *b)
35863586

35873587
if (b->flags & BF_IS_FIGHTER_BEAM) {
35883588
turret_normal = b->objp->orient.vec.fvec;
3589-
b->subsys->system_info->flags.remove(Model::Subsystem_Flags::Turret_alt_math);
3589+
b->subsys->system_info->flags.remove(Model::Subsystem_Flags::Turret_restricted_fov);
35903590
} else {
3591-
model_instance_find_world_dir(&turret_normal, &b->subsys->system_info->turret_norm, Ships[b->objp->instance].model_instance_num, b->subsys->system_info->subobj_num, &b->objp->orient);
3591+
model_instance_find_world_dir(&turret_normal, &b->subsys->system_info->turret_norm, Ships[b->objp->instance].model_instance_num, b->subsys->system_info->subobj_num, &b->objp->orient, true);
35923592
}
35933593

35943594
if (!(turret_fov_test(b->subsys, &turret_normal, &aim_dir))) {

0 commit comments

Comments
 (0)