@@ -98,124 +98,51 @@ typedef struct eval_enemy_obj_struct {
9898 *
9999 * @return 1 if objp is in fov of the specified turret. Otherwise return 0.
100100 */
101- int object_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
101+ bool object_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
102102{
103103 vec3d v2e;
104104 float size_mod;
105- bool in_fov;
105+ bool in_fov = false ;
106106
107- vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
108- size_mod = objp->radius / (dist + objp->radius );
109-
110- in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
111-
112- if ( in_fov ) {
113- return 1 ;
114- }
107+ if (ss->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
108+ int model_num;
109+ switch (objp->type ) {
110+ case OBJ_SHIP:
111+ model_num = Ship_info[Ships[objp->instance ].ship_info_index ].model_num ;
112+ break ;
113+ case OBJ_ASTEROID:
114+ model_num = Asteroid_info[Asteroids[objp->instance ].asteroid_type ].model_num [Asteroids[objp->instance ].asteroid_subtype ];
115+ break ;
116+ default :
117+ vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
118+ size_mod = objp->radius / (dist + objp->radius );
115119
116- return 0 ;
117- }
120+ in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
118121
119- bool is_object_radius_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
120- {
121- float target_dist = distance;
122- if (distance == 0 .0f )
123- target_dist = vm_vec_dist (predicted_pos,tpos);
124-
125- if (object_in_turret_fov (objp, ss, tvec, tpos, target_dist + objp->radius )) {
126- // so the targeted spot in not in fov but the enemy + radius is
127- // lets align the darn gun and try shooting there
128- vec3d temp_vec;
129- float multiplier = 0 ;
130- model_subsystem *tp = ss->system_info ;
122+ return in_fov;
123+ }
131124
132- // project v2e_from_turret to turret normal
133- // substract resultant vector from the temp_vec (v2e_from_turret)
134- // adjust z component as necessary
135- // calculate multiplier for the resultant vector
136- // use multiplier and the z component and compose a new vector
137- float dot = vm_vec_dot (v2e, tvec);
125+ auto pm = model_get (model_num);
126+ for (int i = 0 ; i < 8 ; i++) {
127+ vec3d bbox_point;
128+ vm_vec_unrotate (&bbox_point, &pm->bounding_box [i], &objp->orient );
129+ bbox_point += objp->pos ;
138130
139- vm_vec_scale_add (&temp_vec, v2e, tvec, -dot);
131+ vm_vec_normalized_dir (&v2e, &bbox_point, tpos);
132+ in_fov = turret_fov_test (ss, tvec, &v2e, -0 .2f );
140133
141- if (IS_VEC_NULL_SQ_SAFE (&temp_vec)) {
142- // return false, target is perfectly aligned over or below the turret
143- // safe bet is to allow turret to reacquire better target
144- return false ;
134+ if (in_fov)
135+ return true ;
145136 }
146137
147- // normalize the vec, it needs to be done regardless
148- vm_vec_normalize (&temp_vec);
149- bool fix_elevation = false ;
150- bool fix_base_rot = false ;
151-
152- if (dot < tp->turret_fov ) {
153- dot = tp->turret_fov ;
154- fix_elevation = true ;
155- }
156- if (dot > tp->turret_max_fov ) {
157- dot = tp->turret_max_fov ;
158- fix_elevation = true ;
159- }
160-
161- if (tp->flags [Model::Subsystem_Flags::Turret_alt_math]) {
162- // Since we no longer maintain world_to_turret_matrix, regenerate it here.
163- vec3d turret_norm;
164- matrix turret_matrix, world_to_turret_matrix;
165- model_instance_find_world_dir (&turret_norm, &tp->turret_norm , Ships[objp->instance ].model_instance_num , tp->subobj_num , &vmd_identity_matrix);
166- vm_vector_2_matrix (&turret_matrix, &turret_norm, nullptr , nullptr );
167- vm_matrix_x_matrix (&world_to_turret_matrix, &objp->orient , &turret_matrix);
168-
169- vec3d temp_vec2;
170- vm_vec_rotate (&temp_vec2, &temp_vec, &world_to_turret_matrix);
171-
172- // now in turrets frame of reference
173- // check if math is actually possible
174- if (!((temp_vec2.xyz .x == 0 ) && (temp_vec2.xyz .y == 0 ))) {
175- float temp_z = temp_vec2.xyz .z ;
176- temp_vec2.xyz .z = 0 .0f ;
177- // make sure null vecs wont happen
178- if (!IS_VEC_NULL_SQ_SAFE (&temp_vec2)) {
179- vm_vec_normalize (&temp_vec2);
180- // only do this if it actually is required
181- if (-temp_vec2.xyz .y < tp->turret_y_fov ) {
182- float check_pos = 1 ;
183-
184- fix_base_rot = true ;
185- temp_vec2.xyz .y = -tp->turret_y_fov ;
186- if (temp_vec2.xyz .x < 0 )
187- check_pos = -1 ;
188- temp_vec2.xyz .x = check_pos * sqrtf (1 - (temp_vec2.xyz .y *temp_vec2.xyz .y ));
189-
190- // restore z component
191- float scaler = sqrtf (1 - (temp_z*temp_z));
192- vm_vec_scale (&temp_vec2,scaler);
193- temp_vec2.xyz .z = temp_z;
194- // back to world frame
195- vm_vec_unrotate (&temp_vec, &temp_vec2, &world_to_turret_matrix);
196- }
197- }
198- }
199- }
138+ } else {
139+ vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
140+ size_mod = objp->radius / (dist + objp->radius );
200141
201- if (fix_elevation || fix_base_rot) {
202- if (fix_elevation) {
203- multiplier = sqrtf (1 - (dot*dot));
204- // keep the temp_vec scaled with the tweaked vector
205- vm_vec_scale (&temp_vec, multiplier);
206- }
207- vm_vec_scale_add (v2e, &temp_vec, tvec, dot);
208- // and we are done with v2e...
209- vm_vec_scale_add (predicted_pos, tpos, v2e, target_dist);
210- // and we are done with predicted position
211- return true ;
212- } else {
213- mprintf ((" Warning: Function 'is_object_radius_in_turret_fov' was called\n without need to fix turret alignments\n " ));
214- return false ;
215- }
142+ in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
216143 }
217- // outside of the expanded radii, unable to align, return false
218- return false ;
144+
145+ return in_fov ;
219146}
220147
221148/* *
@@ -1196,17 +1123,11 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
11961123 if ( tagged_only_flag && ship_is_tagged (&Objects[aip->target_objnum ]) ) {
11971124 // select new target if aip->target_objnum is out of field of view
11981125 vec3d v2e;
1199- float dist;
12001126 bool in_fov;
1201- dist = vm_vec_normalized_dir (&v2e, &Objects[aip->target_objnum ].pos , tpos);
1127+ vm_vec_normalized_dir (&v2e, &Objects[aip->target_objnum ].pos , tpos);
12021128
12031129 in_fov = turret_fov_test (turret_subsys, tvec, &v2e);
12041130
1205- if (turret_subsys->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
1206- if (in_fov == false )
1207- if (object_in_turret_fov (&Objects[aip->target_objnum ], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum ].radius ))
1208- in_fov = true ;
1209- }
12101131 // MODIFY FOR ATTACKING BIG SHIP
12111132 // dot += (0.5f * Objects[aip->target_objnum].radius / dist);
12121133 if (in_fov) {
@@ -1448,11 +1369,6 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
14481369
14491370 in_fov = turret_fov_test (ss, gvec, &v2e);
14501371
1451- if (ss->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
1452- if (in_fov == false )
1453- in_fov = is_object_radius_in_turret_fov (&Objects[ss->turret_enemy_objnum ], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0 .0f );
1454- }
1455-
14561372 if (in_fov) {
14571373 ret_val = model_rotate_gun (objp, pm, pmi, tp, predicted_enemy_pos);
14581374 } else if ((tp->flags [Model::Subsystem_Flags::Turret_reset_idle]) &&(timestamp_elapsed (ss->rotation_timestamp ))) {
0 commit comments