@@ -110,121 +110,51 @@ void turret_instance_find_world_orient(matrix* out_mat, int model_instance_num,
110110 *
111111 * @return 1 if objp is in fov of the specified turret. Otherwise return 0.
112112 */
113- int object_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
113+ bool object_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, float dist)
114114{
115115 vec3d v2e;
116116 float size_mod;
117- bool in_fov;
117+ bool in_fov = false ;
118118
119- vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
120- size_mod = objp->radius / (dist + objp->radius );
121-
122- in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
123-
124- if ( in_fov ) {
125- return 1 ;
126- }
119+ if (ss->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
120+ int model_num;
121+ switch (objp->type ) {
122+ case OBJ_SHIP:
123+ model_num = Ship_info[Ships[objp->instance ].ship_info_index ].model_num ;
124+ break ;
125+ case OBJ_ASTEROID:
126+ model_num = Asteroid_info[Asteroids[objp->instance ].asteroid_type ].model_num [Asteroids[objp->instance ].asteroid_subtype ];
127+ break ;
128+ default :
129+ vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
130+ size_mod = objp->radius / (dist + objp->radius );
127131
128- return 0 ;
129- }
132+ in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
130133
131- bool is_object_radius_in_turret_fov (object *objp, ship_subsys *ss, vec3d *tvec, vec3d *tpos, vec3d *v2e, vec3d *predicted_pos, float distance)
132- {
133- float target_dist = distance;
134- if (distance == 0 .0f )
135- target_dist = vm_vec_dist (predicted_pos,tpos);
136-
137- if (object_in_turret_fov (objp, ss, tvec, tpos, target_dist + objp->radius )) {
138- // so the targeted spot in not in fov but the enemy + radius is
139- // lets align the darn gun and try shooting there
140- vec3d temp_vec;
141- float multiplier = 0 ;
142- model_subsystem *tp = ss->system_info ;
134+ return in_fov;
135+ }
143136
144- // project v2e_from_turret to turret normal
145- // substract resultant vector from the temp_vec (v2e_from_turret)
146- // adjust z component as necessary
147- // calculate multiplier for the resultant vector
148- // use multiplier and the z component and compose a new vector
149- float dot = vm_vec_dot (v2e, tvec);
137+ auto pm = model_get (model_num);
138+ for (int i = 0 ; i < 8 ; i++) {
139+ vec3d bbox_point;
140+ vm_vec_unrotate (&bbox_point, &pm->bounding_box [i], &objp->orient );
141+ bbox_point += objp->pos ;
150142
151- vm_vec_scale_add (&temp_vec, v2e, tvec, -dot);
143+ vm_vec_normalized_dir (&v2e, &bbox_point, tpos);
144+ in_fov = turret_fov_test (ss, tvec, &v2e, -0 .2f );
152145
153- if (IS_VEC_NULL_SQ_SAFE (&temp_vec)) {
154- // return false, target is perfectly aligned over or below the turret
155- // safe bet is to allow turret to reacquire better target
156- return false ;
146+ if (in_fov)
147+ return true ;
157148 }
158149
159- // normalize the vec, it needs to be done regardless
160- vm_vec_normalize (&temp_vec);
161- bool fix_elevation = false ;
162- bool fix_base_rot = false ;
163-
164- if (dot < tp->turret_fov ) {
165- dot = tp->turret_fov ;
166- fix_elevation = true ;
167- }
168- if (dot > tp->turret_max_fov ) {
169- dot = tp->turret_max_fov ;
170- fix_elevation = true ;
171- }
172-
173- if (tp->flags [Model::Subsystem_Flags::Turret_restricted_fov]) {
174- // Since we no longer maintain world_to_turret_matrix, regenerate it here.
175- matrix turret_matrix;
176- turret_instance_find_world_orient (&turret_matrix, Ships[Objects[ss->parent_objnum ].instance ].model_instance_num , tp->subobj_num , &vmd_identity_matrix);
177-
178- vec3d turret_v2e;
179- vm_vec_rotate (&turret_v2e, &temp_vec, &turret_matrix);
180-
181- // now in turrets frame of reference
182- // check if math is actually possible
183- if (!((turret_v2e.xyz .x == 0 ) && (turret_v2e.xyz .z == 0 ))) {
184- float temp_y = turret_v2e.xyz .y ;
185- turret_v2e.xyz .y = 0 .0f ;
186- // make sure null vecs wont happen
187- if (!IS_VEC_NULL_SQ_SAFE (&turret_v2e)) {
188- vm_vec_normalize (&turret_v2e);
189- // only do this if it actually is required
190- if (turret_v2e.xyz .z < tp->turret_base_fov ) {
191- float check_pos = 1 ;
192-
193- fix_base_rot = true ;
194- turret_v2e.xyz .z = tp->turret_base_fov ;
195- if (turret_v2e.xyz .x < 0 )
196- check_pos = -1 ;
197- turret_v2e.xyz .x = check_pos * sqrtf (1 - (turret_v2e.xyz .z * turret_v2e.xyz .z ));
198-
199- // restore y component
200- float scalar = sqrtf (1 - (temp_y*temp_y));
201- vm_vec_scale (&turret_v2e, scalar);
202- turret_v2e.xyz .z = temp_y;
203- // back to world frame
204- vm_vec_unrotate (&temp_vec, &turret_v2e, &turret_matrix);
205- }
206- }
207- }
208- }
150+ } else {
151+ vm_vec_normalized_dir (&v2e, &objp->pos , tpos);
152+ size_mod = objp->radius / (dist + objp->radius );
209153
210- if (fix_elevation || fix_base_rot) {
211- if (fix_elevation) {
212- multiplier = sqrtf (1 - (dot*dot));
213- // keep the temp_vec scaled with the tweaked vector
214- vm_vec_scale (&temp_vec, multiplier);
215- }
216- vm_vec_scale_add (v2e, &temp_vec, tvec, dot);
217- // and we are done with v2e...
218- vm_vec_scale_add (predicted_pos, tpos, v2e, target_dist);
219- // and we are done with predicted position
220- return true ;
221- } else {
222- mprintf ((" Warning: Function 'is_object_radius_in_turret_fov' was called\n without need to fix turret alignments\n " ));
223- return false ;
224- }
154+ in_fov = turret_fov_test (ss, tvec, &v2e, size_mod);
225155 }
226- // outside of the expanded radii, unable to align, return false
227- return false ;
156+
157+ return in_fov ;
228158}
229159
230160/* *
@@ -1205,17 +1135,11 @@ int find_turret_enemy(ship_subsys *turret_subsys, int objnum, vec3d *tpos, vec3d
12051135 if ( tagged_only_flag && ship_is_tagged (&Objects[aip->target_objnum ]) ) {
12061136 // select new target if aip->target_objnum is out of field of view
12071137 vec3d v2e;
1208- float dist;
12091138 bool in_fov;
1210- dist = vm_vec_normalized_dir (&v2e, &Objects[aip->target_objnum ].pos , tpos);
1139+ vm_vec_normalized_dir (&v2e, &Objects[aip->target_objnum ].pos , tpos);
12111140
12121141 in_fov = turret_fov_test (turret_subsys, tvec, &v2e);
12131142
1214- if (turret_subsys->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
1215- if (in_fov == false )
1216- if (object_in_turret_fov (&Objects[aip->target_objnum ], turret_subsys, tvec, tpos, dist + Objects[aip->target_objnum ].radius ))
1217- in_fov = true ;
1218- }
12191143 // MODIFY FOR ATTACKING BIG SHIP
12201144 // dot += (0.5f * Objects[aip->target_objnum].radius / dist);
12211145 if (in_fov) {
@@ -1457,11 +1381,6 @@ int aifft_rotate_turret(object *objp, ship *shipp, ship_subsys *ss, object *lep,
14571381
14581382 in_fov = turret_fov_test (ss, gvec, &v2e);
14591383
1460- if (ss->flags [Ship::Subsystem_Flags::FOV_edge_check]) {
1461- if (in_fov == false )
1462- in_fov = is_object_radius_in_turret_fov (&Objects[ss->turret_enemy_objnum ], ss, gvec, &gun_pos, &v2e, predicted_enemy_pos, 0 .0f );
1463- }
1464-
14651384 if (in_fov) {
14661385 ret_val = model_rotate_gun (objp, pm, pmi, tp, predicted_enemy_pos);
14671386 } else if ((tp->flags [Model::Subsystem_Flags::Turret_reset_idle]) &&(timestamp_elapsed (ss->rotation_timestamp ))) {
0 commit comments