void update_overview_camera (camera *raw) { entity *en; vec3d rel_camera_position; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera attitude // get_3d_transformation_matrix (raw->attitude, get_local_entity_float_value (en, FLOAT_TYPE_HEADING) + rad (180.0), rad (-15.0), 0.0); // // get camera position // rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5f); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void update_drop_camera (camera *raw) { entity *en; vec3d pos, v; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera to entity vector // get_local_entity_target_point (en, &pos); v.x = pos.x - raw->position.x; v.y = pos.y - raw->position.y; v.z = pos.z - raw->position.z; // // prevent divide by zero // if (get_3d_vector_magnitude (&v) < 0.001) { v.x = 0.0; v.y = 0.0; v.z = 1.0; } // // get camera attitude // normalise_3d_vector (&v); get_matrix3x3_from_unit_vec3d (raw->attitude, &v); }
static void display_weapon_information (void) { entity_sub_types weapon_sub_type; float x, y, angle_of_drop, drop_hud_distance, roll; weapon_sub_type = get_local_entity_int_value (get_gunship_entity (), INT_TYPE_SELECTED_WEAPON); if (weapon_sub_type != ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { // // weapon specific // if ((weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S5) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S8) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_S13) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_GSH23L_23MM_ROUND) || (weapon_sub_type == ENTITY_SUB_TYPE_WEAPON_9A642_12P7MM_ROUND && target_acquisition_system != TARGET_ACQUISITION_SYSTEM_HMS)) { float x,y; angle_of_drop = 0.0; drop_hud_distance; roll = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_ROLL); angle_of_drop = get_ballistic_weapon_drop(weapon_sub_type); drop_hud_distance = atan(angle_of_drop) * hud_position_z / (0.5 * hud_height); y = cos(roll) * -drop_hud_distance; x = sin(roll) * drop_hud_distance; draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range); // draw target marker around target if having cpg assist if (get_global_cpg_assist_type() != CPG_ASSIST_TYPE_NONE && eo_is_locked()) { float az, el; get_eo_azimuth_and_elevation(&az, &el); if (angles_to_hud_coordinates(az, el, &x, &y, TRUE)) draw_2d_circle(x, y, 0.15, hud_colour); } } else { entity* target = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_TARGET); vec3d* tracking_point; // will use point lock if no target tracking_point = get_eo_tracking_point(); if (target || tracking_point) { vec3d target_position, *source_position; float elevation, azimuth; if (target) get_local_entity_target_point (target, &target_position); else target_position = *tracking_point; source_position = get_local_entity_vec3d_ptr(get_gunship_entity(), VEC3D_TYPE_POSITION); get_eo_azimuth_and_elevation(&azimuth, &elevation); hud_aim_range = get_triangulated_by_position_range(source_position, &target_position); if (angles_to_hud_coordinates(azimuth, elevation, &x, &y, TRUE)) draw_aim_marker(x, y, hud_aim_range, weapon_database[weapon_sub_type].min_range); } } } }
void reset_static_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max, radius, length; int fast_airborne; ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); radius = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min); fast_airborne = FALSE; if (get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT)) { if (get_local_entity_vec3d_magnitude (en, VEC3D_TYPE_MOTION_VECTOR) >= knots_to_metres_per_second (10.0)) { fast_airborne = TRUE; } } if (fast_airborne) { get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &v); normalise_3d_vector (&v); v.x *= radius; v.y *= radius; v.z *= radius; } else { heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); v.x = 0.0; v.y = 0.0; v.z = radius; multiply_matrix3x3_vec3d (&v, m, &v); } get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // attitude // v.x = pos.x - raw->position.x; v.y = pos.y - raw->position.y; v.z = pos.z - raw->position.z; length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&v, length); get_matrix3x3_from_unit_vec3d (raw->attitude, &v); } else { get_identity_matrix3x3 (raw->attitude); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.y = 0.0; raw->motion_vector.z = 0.0; }
void update_cinematic_camera_continued (camera *raw) { entity *en; object_3d_instance *inst3d; viewpoint vp; float normalised_timer; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera position and attitude // switch (raw->cinematic_camera_index) { //////////////////////////////////////// case OBJECT_3D_INVALID_CAMERA_INDEX: //////////////////////////////////////// { float combined_heading, z_min, z_max; vec3d rel_camera_position; combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); combined_heading += raw->cinematic_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->cinematic_camera_pitch, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * 0.1) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_MOVING: //////////////////////////////////////// { normalised_timer = raw->cinematic_camera_timer / raw->cinematic_camera_lifetime; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_STATIC: //////////////////////////////////////// { normalised_timer = 0.0; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } } // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void reset_drop_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // place camera behind object to prevent going inside object (especially when the object is stationary) // heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); v.x = 0.0; v.y = 0.0; v.z = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min); multiply_matrix3x3_vec3d (&v, m, &v); get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.y = 0.0; raw->motion_vector.z = 0.0; }
void update_chase_camera (camera *raw) { entity *en; float combined_heading, z_min, z_max; vec3d rel_camera_position; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // adjust camera heading // if (adjust_view_left_key || joystick_pov_left) { raw->chase_camera_heading += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } else if (adjust_view_right_key || joystick_pov_right) { raw->chase_camera_heading -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading); // // adjust camera pitch // if (adjust_view_up_key || joystick_pov_up) { raw->chase_camera_pitch -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = max (CHASE_CAMERA_ROTATE_DOWN_LIMIT, raw->chase_camera_pitch); } else if (adjust_view_down_key || joystick_pov_down) { raw->chase_camera_pitch += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = min (CHASE_CAMERA_ROTATE_UP_LIMIT, raw->chase_camera_pitch); } if (adjust_view_zoom_in_key) { raw->chase_camera_zoom -= CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = max (CHASE_CAMERA_ZOOM_IN_LIMIT, raw->chase_camera_zoom); } else if (adjust_view_zoom_out_key) { raw->chase_camera_zoom += CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = min (CHASE_CAMERA_ZOOM_OUT_LIMIT, raw->chase_camera_zoom); } // // get camera attitude // if (get_local_entity_int_value (en, INT_TYPE_ALIVE) && raw->chase_camera_lock_rotate) { combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); } else { combined_heading = 0.0; } combined_heading += raw->chase_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->chase_camera_pitch, 0.0); // // get camera position // if (in_flight_zoom_test) { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE_TEST); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE_TEST); } else { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); } ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * raw->chase_camera_zoom * raw->chase_camera_zoom) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void set_reverse_tactical_camera_values (entity *source, entity *target) { camera *raw; int airborne; object_3d_index_numbers object_3d_index; object_3d_bounds *bounding_box; float length, radius, z_min, z_max, rad_alt, dx, dy, dz; vec3d source_position, target_position, direction; ASSERT (source); ASSERT (target); ASSERT (get_camera_entity ()); raw = get_local_entity_data (get_camera_entity ()); // // get camera position // if (get_local_entity_int_value (target, INT_TYPE_IDENTIFY_FIXED)) { object_3d_index = get_local_entity_int_value (target, INT_TYPE_OBJECT_3D_SHAPE); bounding_box = get_object_3d_bounding_box (object_3d_index); dx = bounding_box->xmax - bounding_box->xmin; dy = bounding_box->ymax; dz = bounding_box->zmax - bounding_box->zmin; radius = sqrt ((dx * dx) + (dy * dy) + (dz * dz)) * 2.0; } else { z_min = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); radius = ((z_max - z_min) * 0.05) + z_min; } get_local_entity_target_point (source, &source_position); get_local_entity_target_point (target, &target_position); airborne = FALSE; if (get_local_entity_int_value (target, INT_TYPE_AIRBORNE_AIRCRAFT)) { if (point_inside_map_area (&target_position)) { rad_alt = max (target_position.y - get_3d_terrain_elevation (target_position.x, target_position.z), 0.0); if (rad_alt > z_min) { airborne = TRUE; } } } if (airborne) { direction.x = target_position.x - source_position.x; direction.y = target_position.y - source_position.y; direction.z = target_position.z - source_position.z; length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); } else { direction.x = 0.0; direction.y = 0.0; direction.z = -1.0; } } else { direction.x = target_position.x - source_position.x; direction.y = 0.0; direction.z = target_position.z - source_position.z; length = (direction.x * direction.x) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); } else { direction.x = 0.0; direction.z = -1.0; } direction.y = 0.5; normalise_3d_vector (&direction); } raw->position.x = target_position.x + (direction.x * radius); raw->position.y = target_position.y + (direction.y * radius); raw->position.z = target_position.z + (direction.z * radius); // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // get camera attitude // direction.x = target_position.x - raw->position.x; direction.y = target_position.y - raw->position.y; direction.z = target_position.z - raw->position.z; length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); get_matrix3x3_from_unit_vec3d (raw->attitude, &direction); } else { get_identity_matrix3x3 (raw->attitude); } // // motion vector // get_local_entity_vec3d (target, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
static void draw_2d_eo_display (eo_params *eo, target_acquisition_systems system, int damaged, int valid_3d) { const char *s; char buffer[200]; int heading_readout; float width, heading, marker_position, target_range = 0.0, y_adjust, i, j, x, y; entity *source, *target; vec3d *source_position, target_point; viewpoint tmp; object_3d_visibility visibility; ASSERT (eo); source = get_gunship_entity (); source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION); target = get_local_entity_parent (source, LIST_TYPE_TARGET); target_range = get_range_to_target(); //////////////////////////////////////// // // text // //////////////////////////////////////// set_mono_font_colour (MFD_EO_TEXT_COLOUR); set_mono_font_type (MONO_FONT_TYPE_7X12); // // sensor type // y_adjust = 5.0; set_2d_mono_font_position (-1.0, 1.0); set_mono_font_rel_position (1.0, y_adjust); switch (system) { case TARGET_ACQUISITION_SYSTEM_FLIR: { print_mono_font_string ("FLIR"); break; } case TARGET_ACQUISITION_SYSTEM_LLLTV: { print_mono_font_string ("LLLTV"); break; } case TARGET_ACQUISITION_SYSTEM_PERISCOPE: { print_mono_font_string ("SCOPE"); break; } default: { print_mono_font_string ("XXX"); break; } } // // damaged // if (damaged) { draw_2d_line (-0.5, -0.5, 0.5, 0.5, MFD_COLOUR1); draw_2d_line ( 0.5, -0.5, -0.5, 0.5, MFD_COLOUR1); return; } // // heading // heading = get_heading_from_attitude_matrix (eo_vp.attitude); if (heading < 0.0) { heading += rad (360.0); } heading_readout = (int) deg (heading); if (heading_readout == 0) { heading_readout = 360; } sprintf (buffer, "%d", heading_readout); width = get_mono_font_string_width (buffer); set_2d_mono_font_position (0.0, 1.0); set_mono_font_rel_position ((-width * 0.5) + 1.0, y_adjust); print_mono_font_string (buffer); // airspeed sprintf(buffer, "%+04.0f", current_flight_dynamics->indicated_airspeed.value); set_2d_mono_font_position (-1.0, 1.0); set_mono_font_rel_position(1.0, 18.0); print_mono_font_string(buffer); // altitude if (current_flight_dynamics->radar_altitude.value < 300.0) { sprintf(buffer, "R%03.0f", current_flight_dynamics->radar_altitude.value); set_2d_mono_font_position (1.0, 1.0); set_mono_font_rel_position(-get_mono_font_string_width(buffer) - 2.0, 18.0); print_mono_font_string(buffer); } // // low light // if (eo_low_light) { y_adjust = 32.0; set_2d_mono_font_position (-1.0, 1.0); set_mono_font_rel_position (1.0, y_adjust); print_mono_font_string ("LO LIGHT"); } // // field of view // switch (eo->field_of_view) { case EO_FOV_NARROW: case EO_FOV_MEDIUM: { s = "NARROW"; break; } case EO_FOV_WIDE: { s = "WIDE"; break; } default: { s = "XXX"; break; } } width = get_mono_font_string_width (s); width += 2.0; y_adjust = 5.0; set_2d_mono_font_position (1.0, 1.0); set_mono_font_rel_position (-width, y_adjust); print_mono_font_string (s); // // target name // y_adjust = -12.0; s = get_target_display_name (target, buffer, TRUE); if (s) { set_2d_mono_font_position (-1.0, -1.0); set_mono_font_rel_position (1.0, y_adjust); print_mono_font_string (s); } // // target range // if (target_range > 0.0) { sprintf (buffer, "%.1fKm", target_range * (1.0 / 1000.0)); width = get_mono_font_string_width (buffer); set_2d_mono_font_position (1.0, -1.0); width += 2.0; set_mono_font_rel_position (-width, y_adjust); print_mono_font_string (buffer); } // // locked // if (eo_is_locked()) { y_adjust = -25.0; set_2d_mono_font_position (-1.0, -1.0); set_mono_font_rel_position (1.0, y_adjust); print_mono_font_string ("LOCKED"); } // Jabberwock 031107 Designated targets target = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_TARGET); if (target && get_local_entity_parent (target, LIST_TYPE_DESIGNATED_TARGET)) { y_adjust = -25.0; width = get_mono_font_string_width ("MARKED"); set_2d_mono_font_position (1.0, -1.0); set_mono_font_rel_position (-width - 1.0, y_adjust); print_mono_font_string ("MARKED"); } // Jabberwock 031107 ends // added ground stabi by GCsDriver 08-12-2007 // // 030418 loke // draw an indication if ground stablisation is enabled // if (eo_ground_stabilised) { y_adjust = -38.0; width = get_mono_font_string_width ("S"); set_2d_mono_font_position (1.0, -1.0); set_mono_font_rel_position (-width, y_adjust); print_mono_font_string ("S"); } //////////////////////////////////////// // // line graphics // //////////////////////////////////////// // // datum // draw_2d_line (-0.075, 0.0, -0.025, 0.0, MFD_EO_TEXT_COLOUR); draw_2d_line (0.035, 0.0, 0.08, 0.0, MFD_EO_TEXT_COLOUR); draw_2d_line (0.0, -0.075, 0.0, -0.025, MFD_EO_TEXT_COLOUR); draw_2d_line (0.0, 0.035, 0.0, 0.08, MFD_EO_TEXT_COLOUR); // // azimuth // draw_2d_line (-0.5, 0.8, 0.5, 0.8, MFD_EO_TEXT_COLOUR); marker_position = (eo_azimuth / eo_max_azimuth) * 0.5; draw_2d_line (-0.5, 0.8 - 0.02, -0.5, 0.8 + 0.02, MFD_EO_TEXT_COLOUR); draw_2d_line (0.5, 0.8 - 0.02, 0.5, 0.8 + 0.02, MFD_EO_TEXT_COLOUR); draw_2d_line (0.0, 0.8 - 0.01, 0.0, 0.8 + 0.01, MFD_EO_TEXT_COLOUR); draw_2d_mono_sprite (large_azimuth_marker, marker_position, 0.8, MFD_EO_TEXT_COLOUR); // // elevation // draw_2d_line (-0.9, 0.1, -0.9, -0.3, MFD_EO_TEXT_COLOUR); if (eo_elevation < 0.0) { marker_position = (eo_elevation / eo_min_elevation) * -0.3; } else { marker_position = (eo_elevation / eo_max_elevation) * 0.1; } draw_2d_line (-0.9 - 0.02, 0.1, -0.9 + 0.02, 0.1, MFD_EO_TEXT_COLOUR); draw_2d_line (-0.9 - 0.02, -0.3, -0.9 + 0.02, -0.3, MFD_EO_TEXT_COLOUR); draw_2d_line (-0.9 - 0.01, 0.0, -0.9 + 0.01, 0.0, MFD_EO_TEXT_COLOUR); draw_2d_mono_sprite (large_elevation_marker, -0.9, marker_position, MFD_EO_TEXT_COLOUR); // // range // draw_2d_line (0.9, 0.0, 0.9, -0.5, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, 0.000, 0.9 + 0.02, 0.000, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.025, 0.9 + 0.01, -0.025, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.050, 0.9 + 0.01, -0.050, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.075, 0.9 + 0.01, -0.075, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.100, 0.9 + 0.02, -0.100, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.125, 0.9 + 0.01, -0.125, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.150, 0.9 + 0.01, -0.150, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.175, 0.9 + 0.01, -0.175, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.200, 0.9 + 0.02, -0.200, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.225, 0.9 + 0.01, -0.225, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.250, 0.9 + 0.01, -0.250, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.275, 0.9 + 0.01, -0.275, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.300, 0.9 + 0.02, -0.300, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.400, 0.9 + 0.02, -0.400, MFD_EO_TEXT_COLOUR); draw_2d_line (0.9, -0.500, 0.9 + 0.02, -0.500, MFD_EO_TEXT_COLOUR); if (target_range > 0.0) { marker_position = (min (target_range, eo_max_visual_range) / eo_max_visual_range) * -0.5; draw_2d_mono_sprite (large_range_marker, 0.9, marker_position, MFD_EO_TEXT_COLOUR); } // horizon { float roll = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_ROLL); float pitch = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_PITCH); float pitch_adjustment = -pitch / rad(90) * 0.5; draw_2d_half_thick_line(-0.35, 0.0, -0.3, 0.0, MFD_EO_TEXT_COLOUR); draw_2d_half_thick_line( 0.35, 0.0, 0.3, 0.0, MFD_EO_TEXT_COLOUR); // draw datum set_2d_instance_rotation (mfd_env, roll); draw_2d_half_thick_line(-0.75, pitch_adjustment, -0.4, pitch_adjustment, MFD_EO_TEXT_COLOUR); draw_2d_half_thick_line( 0.75, pitch_adjustment, 0.4, pitch_adjustment, MFD_EO_TEXT_COLOUR); reset_2d_instance (mfd_env); } // // target gates // if (valid_3d) { if (target) { if (!((!d3d_can_render_to_texture) && (!draw_large_mfd))) { tmp = main_vp; main_vp = eo_vp; get_local_entity_target_point (target, &target_point); visibility = get_position_3d_screen_coordinates (&target_point, &i, &j); if ((visibility == OBJECT_3D_COMPLETELY_VISIBLE) || (visibility == OBJECT_3D_PARTIALLY_VISIBLE)) { i -= i_translate_3d; j -= j_translate_3d; i *= i_scale_3d; j *= j_scale_3d; get_2d_world_position (i, j, &x, &y); draw_2d_line (x - 0.20, y + 0.20, x - 0.15, y + 0.20, MFD_EO_TEXT_COLOUR); draw_2d_line (x + 0.20, y + 0.20, x + 0.15, y + 0.20, MFD_EO_TEXT_COLOUR); draw_2d_line (x - 0.20, y - 0.20, x - 0.15, y - 0.20, MFD_EO_TEXT_COLOUR); draw_2d_line (x + 0.20, y - 0.20, x + 0.15, y - 0.20, MFD_EO_TEXT_COLOUR); draw_2d_line (x - 0.20, y + 0.20, x - 0.20, y + 0.15, MFD_EO_TEXT_COLOUR); draw_2d_line (x - 0.20, y - 0.20, x - 0.20, y - 0.15, MFD_EO_TEXT_COLOUR); draw_2d_line (x + 0.20, y + 0.20, x + 0.20, y + 0.15, MFD_EO_TEXT_COLOUR); draw_2d_line (x + 0.20, y - 0.20, x + 0.20, y - 0.15, MFD_EO_TEXT_COLOUR); } main_vp = tmp; } } } }
int collision_test_weapon_with_given_target (entity *weapon, entity *target, vec3d *weapon_old_position, vec3d *weapon_new_position) { float range, weapon_velocity, time_to_impact, sqr_velocity; vec3d *target_position, *target_motion_vector, target_old_position, target_new_position, weapon_intercept_point, target_intercept_point; ASSERT (weapon); ASSERT (target); ASSERT (weapon_old_position); ASSERT (weapon_new_position); ASSERT (get_comms_model () == COMMS_MODEL_SERVER); // // approximate time to impact (uses the target position rather than the intercept point) // target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); range = get_approx_3d_range (target_position, weapon_new_position); weapon_velocity = get_local_entity_float_value (weapon, FLOAT_TYPE_VELOCITY); time_to_impact = range / max (weapon_velocity, 1.0); // // only proceed if close to impact // if (time_to_impact > 0.5) { return (FALSE); } if (get_local_entity_int_value (target, INT_TYPE_COLLISION_TEST_MOBILE)) { //////////////////////////////////////// // // MOBILE TARGET // //////////////////////////////////////// target_motion_vector = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_MOTION_VECTOR); sqr_velocity = ( target_motion_vector->x * target_motion_vector->x + target_motion_vector->y * target_motion_vector->y + target_motion_vector->z * target_motion_vector->z ); if (sqr_velocity > 1.0) { // // moving mobile // if (get_local_entity_int_value (target, INT_TYPE_UPDATED)) { get_local_entity_target_point (target, &target_new_position); target_old_position.x = target_new_position.x - target_motion_vector->x * get_delta_time (); target_old_position.y = target_new_position.y - target_motion_vector->y * get_delta_time (); target_old_position.z = target_new_position.z - target_motion_vector->z * get_delta_time (); } else { get_local_entity_target_point (target, &target_old_position); target_new_position.x = target_old_position.x + target_motion_vector->x * get_delta_time (); target_new_position.y = target_old_position.y + target_motion_vector->y * get_delta_time (); target_new_position.z = target_old_position.z + target_motion_vector->z * get_delta_time (); } if (get_3d_vector_cube_cube_intersect (weapon_old_position, weapon_new_position, &target_old_position, &target_new_position)) { line_line_3d_intercept ( weapon_old_position, weapon_new_position, &target_old_position, &target_new_position, &weapon_intercept_point, &target_intercept_point ); range = get_3d_range (&weapon_intercept_point, &target_intercept_point); if (range < COLLISION_THRESHOLD) { *weapon_new_position = weapon_intercept_point; return (TRUE); } } } else { // // stationary mobile // get_local_entity_target_point (target, &target_new_position); range = get_3d_perp_dist_of_point_from_line (weapon_old_position, weapon_new_position, &target_new_position, &weapon_intercept_point); if (range < COLLISION_THRESHOLD) { *weapon_new_position = weapon_intercept_point; return (TRUE); } } } else if (get_local_entity_int_value (target, INT_TYPE_COLLISION_TEST_FIXED)) { //////////////////////////////////////// // // FIXED TARGET // //////////////////////////////////////// get_local_entity_target_point (target, &target_new_position); range = get_3d_perp_dist_of_point_from_line (weapon_old_position, weapon_new_position, &target_new_position, &weapon_intercept_point); if (range < COLLISION_THRESHOLD) { *weapon_new_position = weapon_intercept_point; return (TRUE); } } return (FALSE); }
void reset_satellite_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max, length; ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); //ASSERT (z_min < z_max); heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); v.x = 0.0; v.y = 0.0; v.z = 0.0; multiply_matrix3x3_vec3d (&v, m, &v); get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } raw->motion_vector.y = raw->position.y; raw->position.y += 5000; // // attitude // v.x = pos.x - raw->position.x; v.y = pos.y - raw->position.y; v.z = pos.z - raw->position.z; length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&v, length); get_matrix3x3_from_unit_vec3d (raw->attitude, &v); } else { get_identity_matrix3x3 (raw->attitude); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.z = 0.0; raw->fly_by_camera_timer = frand1() * 150 + 80; // parasiting on the struct, can't get my own data... }