static void update_recognition_guide_camera (camera *raw, object_3d_camera_index_numbers index) { entity *en; object_3d_instance *inst3d; viewpoint vp; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera position and attitude // inst3d = (object_3d_instance *) get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); ASSERT (inst3d); set_3d_exclusive_instance ( inst3d ); 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, index, 0, 0.0, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); // // 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 set_hud_bob_up_overlay (void) { hud_bob_up_overlay = TRUE; hud_bob_up_heading = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_HEADING); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &hud_bob_up_position); }
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); }
entity *get_closest_mobile_entity (vec3d *pos) { entity *closest_en = NULL, *en; int range, best_range = INT_MAX; vec3d pos2, test_pos; en = get_local_entity_list (); while (en) { if (get_local_entity_int_value (en, INT_TYPE_IDENTIFY_MOBILE)) { get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos2); test_pos.x = pos->x - pos2.x; test_pos.y = 0.0; test_pos.z = pos->z - pos2.z; range = get_3d_vector_magnitude (&test_pos); if (range < best_range) { best_range = range; closest_en = en; if (range < 1.0) { return closest_en; } } } en = get_local_entity_succ (en); } return closest_en; }
void reset_chase_camera (camera *raw) { ASSERT (raw); ASSERT (raw->external_view_entity); // // motion vector // get_local_entity_vec3d (raw->external_view_entity, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void get_comanche_eo_relative_centred_viewpoint (viewpoint *vp) { entity *source; object_3d_instance *inst3d; object_3d_sub_object_search_data search; ASSERT (vp); source = get_gunship_entity (); inst3d = (object_3d_instance *) get_local_entity_ptr_value (source, PTR_TYPE_INSTANCE_3D_OBJECT); ASSERT (inst3d); inst3d->vp.x = 0.0; inst3d->vp.y = 0.0; inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (source, inst3d->vp.attitude); search.search_depth = 0; search.search_object = inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_COMANCHE_EO_CAMERA; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { get_3d_sub_object_world_viewpoint (search.result_sub_object, vp); } else { // // can happpen if the object is being destroyed // memcpy (&vp->position, &inst3d->vp.position, sizeof (vec3d)); debug_log ("OBJECT_3D_SUB_OBJECT_COMANCHE_EO_CAMERA missing from Comanche"); } memcpy (&vp->attitude, &inst3d->vp.attitude, sizeof (matrix3x3)); // // fix up the instance position (just in case) // get_local_entity_vec3d (source, VEC3D_TYPE_POSITION, &inst3d->vp.position); }
void update_vector_acceleration_dynamics (void) { vec3d position; get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); current_flight_dynamics->position.x = position.x; current_flight_dynamics->position.y = position.y; current_flight_dynamics->position.z = position.z; // convert to world axis and // move the object current_flight_dynamics->world_velocity_x.value = (current_flight_dynamics->velocity_x.value * cos (current_flight_dynamics->heading.value)) + (current_flight_dynamics->velocity_z.value * sin (current_flight_dynamics->heading.value)) + (current_flight_dynamics->velocity_y.value * sin (current_flight_dynamics->pitch.value) * sin (current_flight_dynamics->heading.value)); current_flight_dynamics->world_velocity_y.value = (current_flight_dynamics->velocity_y.value) + (current_flight_dynamics->velocity_z.value * sin (current_flight_dynamics->pitch.value)) + (current_flight_dynamics->velocity_x.value * sin (current_flight_dynamics->roll.value)); current_flight_dynamics->world_velocity_z.value = (current_flight_dynamics->velocity_z.value * cos (current_flight_dynamics->heading.value)) + (current_flight_dynamics->velocity_x.value * sin (current_flight_dynamics->heading.value)) + (current_flight_dynamics->velocity_y.value * sin (current_flight_dynamics->pitch.value) * cos (current_flight_dynamics->heading.value)); current_flight_dynamics->position.x += current_flight_dynamics->world_velocity_x.value * get_delta_time (); current_flight_dynamics->position.y += current_flight_dynamics->world_velocity_y.value * get_delta_time (); current_flight_dynamics->position.z += current_flight_dynamics->world_velocity_z.value * get_delta_time (); // maintain motion vector for outputed variables. current_flight_dynamics->model_motion_vector.x = current_flight_dynamics->velocity_x.value; current_flight_dynamics->model_motion_vector.y = current_flight_dynamics->velocity_y.value; current_flight_dynamics->model_motion_vector.z = current_flight_dynamics->velocity_z.value; current_flight_dynamics->world_motion_vector.x = current_flight_dynamics->world_velocity_x.value; current_flight_dynamics->world_motion_vector.y = current_flight_dynamics->world_velocity_y.value; current_flight_dynamics->world_motion_vector.z = current_flight_dynamics->world_velocity_z.value; position.x = current_flight_dynamics->position.x; position.y = current_flight_dynamics->position.y; position.z = current_flight_dynamics->position.z; set_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); }
void get_default_crew_viewpoint (int index, object_3d_instance *virtual_cockpit_inst3d) { viewpoint vp; float head_pitch_datum; head_pitch_datum = pilot_head_pitch_datum; // // rotate head // virtual_cockpit_inst3d->sub_objects[index].relative_heading = -pilot_head_heading; virtual_cockpit_inst3d->sub_objects[index].relative_pitch = head_pitch_datum - pilot_head_pitch; virtual_cockpit_inst3d->sub_objects[index].relative_roll = 0.0; // // get viewpoint (avoid jitter) // virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); get_3d_sub_object_world_viewpoint (&virtual_cockpit_inst3d->sub_objects[index], &vp); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pilot_head_vp.position); // x,y,z is here north south east west! //inserting fixed values here does not work because of head movement pilot_head_vp.x += vp.x; pilot_head_vp.y += vp.y; pilot_head_vp.z += vp.z; memcpy (pilot_head_vp.attitude, vp.attitude, sizeof (matrix3x3)); vp.x = -vp.x; vp.y = -vp.y; vp.z = -vp.z; multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, pilot_head_vp.attitude, &vp.position); }
void get_ah64a_eo_centred_viewpoint (viewpoint *vp) { entity *source; object_3d_instance *inst3d; object_3d_sub_object_search_data search; ASSERT (vp); source = get_gunship_entity (); inst3d = (object_3d_instance *) get_local_entity_ptr_value (source, PTR_TYPE_INSTANCE_3D_OBJECT); ASSERT (inst3d); get_local_entity_vec3d (source, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (source, inst3d->vp.attitude); search.search_depth = 0; search.search_object = inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_AH64D_TADS_HEADING; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { get_3d_sub_object_world_viewpoint (search.result_sub_object, vp); } else { // // can happpen if the object is being destroyed // memcpy (&vp->position, &inst3d->vp.position, sizeof (vec3d)); debug_log ("OBJECT_3D_SUB_OBJECT_AH64D_TADS_HEADING missing from Apache"); } memcpy (&vp->attitude, &inst3d->vp.attitude, sizeof (matrix3x3)); }
static void reset_recognition_guide_camera (camera *raw) { entity *en; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void set_vector_dynamics_defaults (void) { vec3d position; get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); current_flight_dynamics->position.x = position.x; current_flight_dynamics->position.y = position.y; current_flight_dynamics->position.z = position.z; get_identity_matrix3x3 (current_flight_dynamics->attitude); current_flight_dynamics->air_density.value = 2.3; current_flight_dynamics->air_density.max = 2.3; current_flight_dynamics->air_density.min = 1.5; current_flight_dynamics->altitude.min = 0.0; current_flight_dynamics->altitude.max = MAX_MAP_Y; current_flight_dynamics->input_data.cyclic_x.min = -100.0; current_flight_dynamics->input_data.cyclic_x.max = 100.0; current_flight_dynamics->input_data.cyclic_y.min = -100.0; current_flight_dynamics->input_data.cyclic_y.max = 100.0; current_flight_dynamics->input_data.cyclic_horizontal_pressure.min = -100.0; current_flight_dynamics->input_data.cyclic_horizontal_pressure.max = 100.0; current_flight_dynamics->input_data.cyclic_vertical_pressure.min = -100.0; current_flight_dynamics->input_data.cyclic_vertical_pressure.max = 100.0; current_flight_dynamics->input_data.collective_pressure.min = -10.0; current_flight_dynamics->input_data.collective_pressure.max = 10.0; current_flight_dynamics->input_data.pedal.min = -100.0; current_flight_dynamics->input_data.pedal.max = 100.0; current_flight_dynamics->input_data.pedal_pressure.min = -10.0; current_flight_dynamics->input_data.pedal_pressure.max = 10.0; // main rotor characteristics current_flight_dynamics->main_rotor_diameter.value = 14.63; current_flight_dynamics->main_rotor_area.value = PI * pow ((current_flight_dynamics->main_rotor_diameter.value / 2.0), 2); current_flight_dynamics->main_rotor_induced_air.value = 4.63; current_flight_dynamics->main_rotor_induced_air.min = 2.5; current_flight_dynamics->main_rotor_induced_air.max = 6.5; current_flight_dynamics->main_rotor_roll_angle.min = rad (-5.0); current_flight_dynamics->main_rotor_roll_angle.max = rad (5.0); current_flight_dynamics->main_rotor_pitch_angle.min = rad (-5.0); current_flight_dynamics->main_rotor_pitch_angle.max = rad (5.0); current_flight_dynamics->main_rotor_thrust.min = 0.0; current_flight_dynamics->main_rotor_thrust.max = 100.0; current_flight_dynamics->main_rotor_rpm.value = 80.0; current_flight_dynamics->main_rotor_rpm.min = 80.0; current_flight_dynamics->main_rotor_rpm.max = 100.0; current_flight_dynamics->main_rotor_coning_angle.min = rad (-3.0); current_flight_dynamics->main_rotor_coning_angle.max = rad (10.0); current_flight_dynamics->main_blade_pitch.value = 2.5; current_flight_dynamics->main_blade_pitch.min = rad (2.5); current_flight_dynamics->main_blade_pitch.max = rad (6.0); // tail rotor characteristics current_flight_dynamics->tail_rotor_diameter.value = 2.79; current_flight_dynamics->tail_rotor_rpm.value = 80.0; current_flight_dynamics->tail_rotor_rpm.min = 80.0; current_flight_dynamics->tail_rotor_rpm.max = 100.0; current_flight_dynamics->tail_rotor_thrust.min = 0.0; current_flight_dynamics->tail_rotor_thrust.max = 100.0; current_flight_dynamics->tail_blade_pitch.value = 0.0; current_flight_dynamics->tail_blade_pitch.min = rad (-5.0); current_flight_dynamics->tail_blade_pitch.max = rad (5.0); current_flight_dynamics->tail_boom_length.value = 10.59; // actually the wheelbase (but close enough) current_flight_dynamics->cross_coupling_effect.value = 0.0; // other current_flight_dynamics->velocity_x.min = -11.1; current_flight_dynamics->velocity_x.max = 11.1; current_flight_dynamics->acceleration_x.min = -10.0; current_flight_dynamics->acceleration_x.max = 10.0; current_flight_dynamics->velocity_y.value = 0.0; current_flight_dynamics->velocity_y.min = -1000.0; current_flight_dynamics->velocity_y.max = 15.7; current_flight_dynamics->acceleration_y.min = -1000.0; current_flight_dynamics->acceleration_y.max = 15.7; current_flight_dynamics->velocity_z.min = -8.33; current_flight_dynamics->velocity_z.max = knots_to_metres_per_second (250); //(197); // never exceed current_flight_dynamics->acceleration_z.value = 0.0; current_flight_dynamics->acceleration_z.min = -10.0; current_flight_dynamics->acceleration_z.max = 10.0; current_flight_dynamics->power_avaliable.min = 0.0; current_flight_dynamics->power_avaliable.max = 2530.0; current_flight_dynamics->lift.min = -10.0; current_flight_dynamics->lift.max = 40.0; current_flight_dynamics->drag_x.min = 0.90; current_flight_dynamics->drag_x.max = 0.98; current_flight_dynamics->drag_y.min = 0.80; current_flight_dynamics->drag_y.max = 0.97; current_flight_dynamics->drag_z.min = 0.9999; current_flight_dynamics->drag_z.max = 1.0; current_flight_dynamics->heading_inertia.value = 2000; current_flight_dynamics->pitch_inertia.value = 1200; current_flight_dynamics->roll_inertia.value = 1200; current_flight_dynamics->mass.value = 7480.0; current_flight_dynamics->mass.min = 5000.0; current_flight_dynamics->mass.max = 10000.0; current_flight_dynamics->centre_of_gravity.x = 0.00; current_flight_dynamics->centre_of_gravity.y = 2.475; current_flight_dynamics->centre_of_gravity.z = 0.00; }
void get_kiowa_crew_viewpoint (void) { object_3d_sub_object_search_data search_head, search_viewpoint; viewpoint vp; float head_pitch_datum; // // select head // if (get_local_entity_int_value (get_pilot_entity (), INT_TYPE_CREW_ROLE) == CREW_ROLE_PILOT) { search_head.sub_object_index = OBJECT_3D_SUB_OBJECT_PILOT_HEAD; search_viewpoint.sub_object_index = OBJECT_3D_SUB_OBJECT_PILOT_VIEWPOINT; head_pitch_datum = pilot_head_pitch_datum; } else { search_head.sub_object_index = OBJECT_3D_SUB_OBJECT_WSO_HEAD; search_viewpoint.sub_object_index = OBJECT_3D_SUB_OBJECT_WSO_VIEWPOINT; head_pitch_datum = co_pilot_head_pitch_datum; } // // rotate head // search_head.search_depth = 0; search_head.search_object = virtual_cockpit_inst3d; if (find_object_3d_sub_object (&search_head) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search_head.result_sub_object->relative_heading = -pilot_head_heading; search_head.result_sub_object->relative_pitch = head_pitch_datum - pilot_head_pitch; if ((command_line_TIR_6DOF == TRUE)&&(query_TIR_active() == TRUE)) // Retro 6Feb2005 search_head.result_sub_object->relative_roll = TIR_GetRoll() / 16383. * PI / 2.; // Retro 6Feb2005 else search_head.result_sub_object->relative_roll = 0.0; } else { debug_fatal ("Failed to locate crew's head in virtual cockpit"); } // // get viewpoint (avoid jitter) // search_viewpoint.search_object = virtual_cockpit_inst3d; search_viewpoint.search_depth = 0; if (find_object_3d_sub_object (&search_viewpoint) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); get_3d_sub_object_world_viewpoint (search_viewpoint.result_sub_object, &vp); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pilot_head_vp.position); pilot_head_vp.x += vp.x; pilot_head_vp.y += vp.y; pilot_head_vp.z += vp.z; if ((command_line_TIR_6DOF == TRUE)&&(query_TIR_active() == TRUE)) // Retro 6Feb2005 (whole block) { matrix3x3 invAttitude; vec3d shiftVP, shiftWorld; // First lets find out the displacement the user wants.. this is in the user's viewsystem coords !! // Now store this info in a temp vect3d.. shiftVP.x = current_custom_cockpit_viewpoint.x; shiftVP.y = current_custom_cockpit_viewpoint.y; shiftVP.z = current_custom_cockpit_viewpoint.z; // Now we need to convert our vec3d into world coords.. for this we need the inverse of the viewpoint attitude matrix.. get_inverse_matrix (invAttitude, vp.attitude); // And rotate ! Voila, the result vec3d is now in world coords.. multiply_transpose_matrix3x3_vec3d (&shiftWorld, invAttitude, &shiftVP); // Now apply that displacement.. BUT ONLY TO THE HEAD !! pilot_head_vp.x -= shiftWorld.x; pilot_head_vp.y -= shiftWorld.y; pilot_head_vp.z -= shiftWorld.z; } memcpy (pilot_head_vp.attitude, vp.attitude, sizeof (matrix3x3)); vp.x = -vp.x; vp.y = -vp.y; vp.z = -vp.z; multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, pilot_head_vp.attitude, &vp.position); if ((command_line_TIR_6DOF == TRUE)&&(query_TIR_active() == TRUE)) // Retro 6Feb2005 (whole block) { // Now shift the viewpoint (AND the model) by the positive displacement.. puts the cockpit back were it belongs.. // but the viewpoint (the head) is in another place.. fini virtual_cockpit_inst3d->vp.x += current_custom_cockpit_viewpoint.x; virtual_cockpit_inst3d->vp.y += current_custom_cockpit_viewpoint.y; virtual_cockpit_inst3d->vp.z += current_custom_cockpit_viewpoint.z; } } else { debug_fatal ("Failed to locate crew's viewpoint in virtual cockpit"); } }
void get_kiowa_display_viewpoint (view_modes mode) { object_3d_sub_object_index_numbers index; object_3d_sub_object_search_data search; vec3d position; ASSERT (get_gunship_entity ()); ASSERT (virtual_cockpit_inst3d); switch (mode) { //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_FL; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_FR; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_RL; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_RR; break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal ("Invalid view mode = %d", mode); break; } } virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; //////////////////////////////////////// // #if DEBUG_MODULE_FINE_DISPLAY_CAMERA_POSITION_ADJUSTMENT get_identity_matrix3x3 (virtual_cockpit_inst3d->vp.attitude); #else get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); #endif // //////////////////////////////////////// search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = index; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { get_3d_sub_object_world_viewpoint (search.result_sub_object, &main_vp); } else { debug_fatal ("Failed to locate display viewpoint in virtual cockpit"); } position.x = -main_vp.x; position.y = -main_vp.y; position.z = -main_vp.z; //////////////////////////////////////// // #if DEBUG_MODULE_FINE_DISPLAY_CAMERA_POSITION_ADJUSTMENT { static float z_offset = 0.0; float dx, dy, dz; if (check_key (DIK_Q)) { z_offset -= 0.0001; } if (check_key (DIK_A)) { z_offset += 0.0001; } dx = main_vp.zv.x * z_offset; dy = main_vp.zv.y * z_offset; dz = main_vp.zv.z * z_offset; position.x += dx; position.y += dy; position.z += dz; debug_filtered_log ("offset=%.6f x=%.6f y=%.6f z=%.6f", z_offset, position.x, position.y, position.z); } #endif // //////////////////////////////////////// multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, main_vp.attitude, &position); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); main_vp.x += position.x; main_vp.y += position.y; main_vp.z += position.z; }
void reset_cinematic_camera (camera *raw) { entity *en; object_3d_instance *inst3d; int num_moving_cameras, num_static_cameras, attempts; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); // // select 3D camera // raw->cinematic_camera_index = OBJECT_3D_INVALID_CAMERA_INDEX; if (inst3d) { num_moving_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_MOVING); num_static_cameras = get_number_of_3d_object_cameras (inst3d, OBJECT_3D_CAMERA_SCENIC_STATIC); if ((num_moving_cameras > 0) && (num_static_cameras > 0)) { if (frand1 () < 0.333) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING; } else { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC; } } else if (num_moving_cameras > 0) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_MOVING; } else if (num_static_cameras > 0) { raw->cinematic_camera_index = OBJECT_3D_CAMERA_SCENIC_STATIC; } } switch (raw->cinematic_camera_index) { //////////////////////////////////////// case OBJECT_3D_INVALID_CAMERA_INDEX: //////////////////////////////////////// { raw->cinematic_camera_depth = 0; raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0; raw->cinematic_camera_heading = rad (45.0) * ((float) (rand16 () % 8)); raw->cinematic_camera_pitch = rad (-45.0) * ((float) (rand16 () % 2)); #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is INVALID (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f, heading = %.2f, pitch = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime, deg (raw->cinematic_camera_heading), deg (raw->cinematic_camera_pitch) ); #endif break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_MOVING: //////////////////////////////////////// { // // try and prevent using the same moving camera twice in succession // if (num_moving_cameras > 1) { attempts = 10; while (attempts--) { raw->cinematic_camera_depth = rand16 () % num_moving_cameras; if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_moving_depth) { break; } } } else { raw->cinematic_camera_depth = 0; } raw->cinematic_camera_previous_moving_depth = raw->cinematic_camera_depth; raw->cinematic_camera_lifetime = get_object_3d_camera_lifetime (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth); #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is MOVING (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime ); #endif ASSERT (raw->cinematic_camera_lifetime > 0.0); break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_STATIC: //////////////////////////////////////// { // // try and prevent using the same static camera twice in succession // if (num_static_cameras > 1) { attempts = 10; while (attempts--) { raw->cinematic_camera_depth = rand16 () % num_static_cameras; if (raw->cinematic_camera_depth != raw->cinematic_camera_previous_static_depth) { break; } } } else { raw->cinematic_camera_depth = 0; } raw->cinematic_camera_previous_static_depth = raw->cinematic_camera_depth; raw->cinematic_camera_lifetime = (frand1 () * 2.0) + 2.0; #if DEBUG_MODULE debug_log ( "CINEMATIC CAMERA is STATIC (object = %s, moving cameras = %d, static cameras = %d, depth = %d, lifetime = %.2f)", get_local_entity_string (en, STRING_TYPE_FULL_NAME), num_moving_cameras, num_static_cameras, raw->cinematic_camera_depth, raw->cinematic_camera_lifetime ); #endif } } raw->cinematic_camera_timer = 0.0; // // 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); }
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags) { entity *target; aircraft *raw; vec3d *target_pos, en_pos; ASSERT (en); raw = get_local_entity_data (en); // // Fire suppressed // if (check_flags & AIRCRAFT_FIRE_SUPPRESSED) { if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return AIRCRAFT_FIRE_SUPPRESSED; } } // // check weapon // if (check_flags & AIRCRAFT_FIRE_NO_WEAPON) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON"); return AIRCRAFT_FIRE_NO_WEAPON; } } // // weapon system_ready // if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY) { if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY)) { debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY"); return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY; } } // // find target // if (check_flags & AIRCRAFT_FIRE_NO_TARGET) { target = get_local_entity_parent (en, LIST_TYPE_TARGET); if (!target) { debug_log ("AC_WPN: Fire Weapon Error - NO TARGET"); return AIRCRAFT_FIRE_NO_TARGET; } } // // line of sight checks // if (check_flags & AIRCRAFT_FIRE_NO_LOS) { int criteria; if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { criteria = MOBILE_LOS_CHECK_ALL; } else { criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN; } get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos); target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0); if (!check_position_line_of_sight (en, target, &en_pos, target_pos, criteria)) { debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); return AIRCRAFT_FIRE_NO_LOS; } } // // Play Speech // play_aircraft_weapon_launched_speech (en, raw->selected_weapon); // // Fire weapon // launch_client_server_weapon (en, raw->selected_weapon); return AIRCRAFT_FIRE_OK; }
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 draw_debug_guide_entity (entity *en) { waypoint *raw; entity *member, *this_waypoint; vec3d direction, guide_pos, *member_pos, *this_waypoint_position; float length; ASSERT (en); raw = (waypoint *) get_local_entity_data (en); // // get guide position // get_local_entity_vec3d (en, VEC3D_TYPE_GUIDE_POSITION, &guide_pos); // // get waypoint position // this_waypoint_position = NULL; this_waypoint = get_local_entity_parent (en, LIST_TYPE_CURRENT_WAYPOINT); ASSERT (this_waypoint); // // draw guide position // direction.x = 0.0; direction.y = 1.0; direction.z = 0.0; create_vectored_debug_3d_object (&guide_pos, &direction, OBJECT_3D_SPHERICAL_TEST, 0.0, 1.0); if (get_local_entity_int_value (this_waypoint, INT_TYPE_POSITION_TYPE) != POSITION_TYPE_VIRTUAL) { this_waypoint_position = get_local_entity_vec3d_ptr (this_waypoint, VEC3D_TYPE_POSITION); length = get_3d_range (&guide_pos, this_waypoint_position); if (length > 0.0) { create_debug_3d_line (&guide_pos, this_waypoint_position, sys_col_yellow, 0.0); } } // // draw vector to group position // member = get_local_entity_first_child (en, LIST_TYPE_FOLLOWER); while (member) { member_pos = get_local_entity_vec3d_ptr (member, VEC3D_TYPE_POSITION); length = get_3d_range (&guide_pos, member_pos); if (length > 0.0) { create_debug_3d_line (&guide_pos, member_pos, sys_col_light_red, 0.0); } member = get_local_entity_child_succ (member, LIST_TYPE_FOLLOWER); } }
static void get_display_viewpoint (view_modes mode, viewpoint *display_viewpoint) { object_3d_sub_object_index_numbers index; object_3d_sub_object_search_data search; viewpoint vp; ASSERT (display_viewpoint); if ((!full_screen_hi_res) && (application_video_colourdepth == 16)) { display_viewpoint->x = 0.0; display_viewpoint->y = 0.0; display_viewpoint->z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), display_viewpoint->attitude); return; } if (mode == VIEW_MODE_COCKPIT_PANEL_SPECIAL_APACHE_LHS_MFD) { index = OBJECT_3D_SUB_OBJECT_APACHE_COCKPIT_LHS_MFD_CAMERA; } else if (mode == VIEW_MODE_COCKPIT_PANEL_SPECIAL_APACHE_RHS_MFD) { index = OBJECT_3D_SUB_OBJECT_APACHE_COCKPIT_RHS_MFD_CAMERA; } else { debug_fatal ("Invalid view mode = %d", mode); } virtual_cockpit_inst3d = virtual_cockpit_level1_inst3d; search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = index; if (find_object_3d_sub_object (&search) != SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { debug_fatal ("Failed to locate display viewpoint in virtual cockpit"); } virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); get_3d_sub_object_world_viewpoint (search.result_sub_object, &vp); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &main_vp.position); main_vp.x += vp.x; main_vp.y += vp.y; main_vp.z += vp.z; memcpy (main_vp.attitude, vp.attitude, sizeof (matrix3x3)); vp.x = -vp.x; vp.y = -vp.y; vp.z = -vp.z; multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, vp.attitude, &vp.position); memcpy (display_viewpoint, &virtual_cockpit_inst3d->vp, sizeof (viewpoint)); }
static void kill_local (entity *en) { object *raw; vec3d pos; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif raw = (object *) get_local_entity_data (en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// // // fixed // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_TARGET); // gunship_target_link // sector_link // // object // //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos); pos.y = get_3d_terrain_elevation (pos.x, pos.z); create_client_server_crater (CRATER_TYPE_LARGE_EXPLOSION, &pos); } // // must be done AFTER object explosion // raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape); }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; waypoint *raw; vec3d v; //////////////////////////////////////// // // VALIDATE // //////////////////////////////////////// validate_local_create_entity_index (index); #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_CREATE, NULL, type, index); #endif en = get_free_entity (index); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = malloc_fast_mem (sizeof (waypoint)); set_local_entity_data (en, raw); //////////////////////////////////////// // // INITIALISE ALL ENTITY DATA TO 'WORKING' DEFAULT VALUES // // DO NOT USE ACCESS FUNCTIONS // // DO NOT USE RANDOM VALUES // //////////////////////////////////////// memset (raw, 0, sizeof (waypoint)); raw->position.x = MID_MAP_X; raw->position.z = MID_MAP_Z; raw->position.y = MID_MAP_Y; raw->sub_type = ENTITY_SUB_TYPE_WAYPOINT_NAVIGATION; raw->waypoint_formation = FORMATION_ROW_LEFT; raw->position_type = POSITION_TYPE_ABSOLUTE; raw->heading = 0.0; //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->waypoint_link.parent); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &v); ASSERT (point_inside_map_volume (&v)); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// if (raw->task_dependent_link.parent) { insert_local_entity_into_parents_child_list (en, LIST_TYPE_TASK_DEPENDENT, raw->task_dependent_link.parent, NULL); } insert_local_entity_into_parents_child_list (en, LIST_TYPE_WAYPOINT, raw->waypoint_link.parent, raw->waypoint_link.child_pred); #if DEBUG_MODULE insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->position), NULL); #endif } return (en); }
void vector_dynamics_velocity (event *ev) { if (ev->modifier == MODIFIER_RIGHT_SHIFT) { switch (ev->key) { case DIK_Q: { current_flight_dynamics->velocity_z.value = 1000; break; } case DIK_A: { current_flight_dynamics->velocity_z.value = 0.0; break; } } } else if (ev->modifier == MODIFIER_RIGHT_ALT) { switch (ev->key) { case DIK_Q: { vec3d pos; get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pos); pos.y += 10; set_client_server_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pos); break; } case DIK_A: { vec3d pos; get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pos); pos.y -= 10; set_client_server_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pos); break; } } } else { switch (ev->key) { case DIK_Q: { current_flight_dynamics->velocity_z.value += 20; break; } case DIK_A: { current_flight_dynamics->velocity_z.value -= 20; break; } } } current_flight_dynamics->velocity_z.value = bound (current_flight_dynamics->velocity_z.value, -1000, 1000); }
aircraft_fire_result aircraft_fire_weapon (entity *en, unsigned int check_flags) { entity *target; aircraft *raw; vec3d *target_pos, en_pos; int loal_mode = FALSE; ASSERT (en); raw = (aircraft *) get_local_entity_data (en); // // Fire suppressed // if (check_flags & AIRCRAFT_FIRE_SUPPRESSED) { if (get_local_entity_int_value (get_session_entity (), INT_TYPE_SUPPRESS_AI_FIRE)) { return AIRCRAFT_FIRE_SUPPRESSED; } } // // check weapon // if (check_flags & AIRCRAFT_FIRE_NO_WEAPON) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_NO_WEAPON) { debug_log ("AC_WPN: Fire Weapon Error - NO WEAPON"); return AIRCRAFT_FIRE_NO_WEAPON; } } // // weapon system_ready // if (check_flags & AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY) { if (!get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON_SYSTEM_READY)) { debug_log ("AC_WPN: Fire Weapon Error - WEAPON SYSTEM NOT READY"); return AIRCRAFT_FIRE_WEAPON_SYSTEM_NOT_READY; } } // debug_log("%s: %d", get_sub_type_name(en), get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON)); // // find target // if (check_flags & AIRCRAFT_FIRE_NO_TARGET) { target = get_local_entity_parent (en, LIST_TYPE_TARGET); if (!target) { debug_log ("AC_WPN: Fire Weapon Error - NO TARGET"); return AIRCRAFT_FIRE_NO_TARGET; } } // // line of sight checks // if (check_flags & AIRCRAFT_FIRE_NO_LOS) { int criteria; if (get_local_entity_int_value (target, INT_TYPE_PLAYER) != ENTITY_PLAYER_AI) { criteria = MOBILE_LOS_CHECK_ALL; } else { criteria = MOBILE_LOS_CHECK_COURSE_TERRAIN; } get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &en_pos); target_pos = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION); en_pos.y -= (get_local_entity_float_value (en, FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE) + 2.0); if (!check_position_line_of_sight (en, target, &en_pos, target_pos, (mobile_los_check_criteria) criteria)) { if (get_local_entity_int_value (en, INT_TYPE_SELECTED_WEAPON) == ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE && get_2d_range(&en_pos, target_pos) > weapon_database[ENTITY_SUB_TYPE_WEAPON_AGM114L_LONGBOW_HELLFIRE].min_range_loal) { debug_log("AC_WPN: Switching to LOAL mode to fire at target without LOS ((Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); loal_mode = TRUE; } else { debug_log ("AC_WPN: Fire Weapon Error - NO LOS (Aircraft %s (%d), Target %s (%d))", get_local_entity_string (en, STRING_TYPE_FULL_NAME), get_local_entity_index (en), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_index (target)); return AIRCRAFT_FIRE_NO_LOS; } } } // // Play Speech // play_aircraft_weapon_launched_speech (en, raw->selected_weapon); // // Fire weapon // set_local_entity_int_value(en, INT_TYPE_LOCK_ON_AFTER_LAUNCH, loal_mode); launch_client_server_weapon (en, raw->selected_weapon); return AIRCRAFT_FIRE_OK; }
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 get_hokum_display_viewpoint (view_modes mode) { object_3d_sub_object_index_numbers index; object_3d_sub_object_search_data search; vec3d position; ASSERT (get_gunship_entity ()); ASSERT (virtual_cockpit_inst3d); switch (mode) { //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_LHS_2; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_LHS_1; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_RHS_1; break; } //////////////////////////////////////// case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY: //////////////////////////////////////// { index = OBJECT_3D_SUB_OBJECT_COCKPIT_VIEW_MFD_RHS_2; break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal ("Invalid view mode = %d", mode); break; } } virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = index; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { get_3d_sub_object_world_viewpoint (search.result_sub_object, &main_vp); } else { debug_fatal ("Failed to locate display viewpoint in virtual cockpit"); } position.x = -main_vp.x; position.y = -main_vp.y; position.z = -main_vp.z; multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, main_vp.attitude, &position); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &position); main_vp.x += position.x; main_vp.y += position.y; main_vp.z += position.z; }
static void kill_local (entity *en) { site *raw; vec3d pos; entity *task, *destroy_task; //////////////////////////////////////// // // PRE-AMBLE // //////////////////////////////////////// #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_KILL, en); #endif raw = get_local_entity_data (en); //////////////////////////////////////// // // UNLINK FROM SYSTEM // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { task = get_local_entity_first_child (en, LIST_TYPE_TASK_DEPENDENT); while (task) { destroy_task = task; task = get_local_entity_child_succ (task, LIST_TYPE_TASK_DEPENDENT); if (destroy_task->type == ENTITY_TYPE_TASK) { #if DEBUG_MODULE debug_log ("ST_DSTRY: killing site, notifying task %s complete", entity_sub_type_task_names [get_local_entity_int_value (destroy_task, INT_TYPE_ENTITY_SUB_TYPE)]); #endif notify_local_entity (ENTITY_MESSAGE_TASK_COMPLETED, destroy_task, en, TASK_TERMINATED_OBJECTIVE_MESSAGE); } } } // // fixed // unlink_local_entity_children (en, LIST_TYPE_TASK_DEPENDENT); unlink_local_entity_children (en, LIST_TYPE_TARGET); // gunship_target_link // sector_link // // site // //////////////////////////////////////// // // KILL // //////////////////////////////////////// // must be done BEFORE alive flag set subtract_local_entity_importance_from_keysite (en); set_local_entity_int_value (en, INT_TYPE_ALIVE, FALSE); //////////////////////////////////////// // // SPECIAL EFFECTS // //////////////////////////////////////// if (get_comms_model () == COMMS_MODEL_SERVER) { create_client_server_object_killed_explosion_effect (en); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos); pos.y = get_3d_terrain_elevation (pos.x, pos.z); create_client_server_crater (CRATER_TYPE_LARGE_EXPLOSION, &pos); } // // must be done AFTER object explosion // raw->fix.object_3d_shape = get_3d_object_destroyed_object_index (raw->fix.object_3d_shape); }
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 get_hokum_crew_viewpoint (void) { object_3d_sub_object_search_data search_head, search_viewpoint; viewpoint vp; float head_pitch_datum; // // select head // if (get_local_entity_int_value (get_pilot_entity (), INT_TYPE_CREW_ROLE) == CREW_ROLE_PILOT) { search_head.sub_object_index = OBJECT_3D_SUB_OBJECT_PILOT_HEAD; search_viewpoint.sub_object_index = OBJECT_3D_SUB_OBJECT_PILOT_VIEWPOINT; head_pitch_datum = pilot_head_pitch_datum; } else { search_head.sub_object_index = OBJECT_3D_SUB_OBJECT_WSO_HEAD; search_viewpoint.sub_object_index = OBJECT_3D_SUB_OBJECT_WSO_VIEWPOINT; head_pitch_datum = co_pilot_head_pitch_datum; } // // rotate head // search_head.search_depth = 0; search_head.search_object = virtual_cockpit_inst3d; if (find_object_3d_sub_object (&search_head) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search_head.result_sub_object->relative_heading = -pilot_head_heading; search_head.result_sub_object->relative_pitch = head_pitch_datum - pilot_head_pitch; search_head.result_sub_object->relative_roll = 0.0; } else { debug_fatal ("Failed to locate crew's head in virtual cockpit"); } // // get viewpoint (avoid jitter) // search_viewpoint.search_object = virtual_cockpit_inst3d; search_viewpoint.search_depth = 0; if (find_object_3d_sub_object (&search_viewpoint) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { virtual_cockpit_inst3d->vp.x = 0.0; virtual_cockpit_inst3d->vp.y = 0.0; virtual_cockpit_inst3d->vp.z = 0.0; get_local_entity_attitude_matrix (get_gunship_entity (), virtual_cockpit_inst3d->vp.attitude); get_3d_sub_object_world_viewpoint (search_viewpoint.result_sub_object, &vp); get_local_entity_vec3d (get_gunship_entity (), VEC3D_TYPE_POSITION, &pilot_head_vp.position); pilot_head_vp.x += vp.x; pilot_head_vp.y += vp.y; pilot_head_vp.z += vp.z; memcpy (pilot_head_vp.attitude, vp.attitude, sizeof (matrix3x3)); vp.x = -vp.x; vp.y = -vp.y; vp.z = -vp.z; multiply_transpose_matrix3x3_vec3d (&virtual_cockpit_inst3d->vp.position, pilot_head_vp.attitude, &vp.position); } else { debug_fatal ("Failed to locate crew's viewpoint in virtual cockpit"); } }
static void ship_movement_get_waypoint_position (entity *en, vec3d *wp_pos) { entity *wp, *group, *guide; float distance; vec3d *pos; ASSERT (en); ASSERT (wp_pos); group = get_local_entity_parent (en, LIST_TYPE_MEMBER); ASSERT (group); guide = get_local_entity_parent (en, LIST_TYPE_FOLLOWER); ASSERT (guide); wp = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT); ASSERT (wp); // // Should vehicle follow leader, or follow guide in set waypoint formation? // if (get_local_entity_int_value (wp, INT_TYPE_MOBILE_FOLLOW_WAYPOINT_OFFSET)) { vec3d offset; get_local_entity_vec3d (guide, VEC3D_TYPE_GUIDE_POSITION, wp_pos); get_local_entity_formation_position_offset (en, wp, &offset); wp_pos->x += offset.x; wp_pos->y += offset.y; wp_pos->z += offset.z; } else { // // Task leader follows guide,.... other members follow task leader // if (get_local_entity_int_value (en, INT_TYPE_TASK_LEADER)) { get_local_entity_vec3d (guide, VEC3D_TYPE_GUIDE_POSITION, wp_pos); } else { // // set wp pos to offset from task leader // entity *task_leader; vec3d *xv, *leader_pos; formation_type *formation; int type, formation_count, formation_index, leader_formation_index; // // find task leader // task_leader = get_local_entity_ptr_value (guide, PTR_TYPE_TASK_LEADER); ASSERT (task_leader); // // get formation // type = get_local_entity_int_value (group, INT_TYPE_GROUP_FORMATION); formation = get_formation (type); formation_count = formation->number_in_formation; formation_index = get_local_entity_int_value (en, INT_TYPE_GROUP_MEMBER_NUMBER); leader_formation_index = get_local_entity_int_value (task_leader, INT_TYPE_GROUP_MEMBER_NUMBER); ASSERT (formation_index < formation_count); ASSERT (leader_formation_index < formation_count); // // calculate position // leader_pos = get_local_entity_vec3d_ptr (task_leader, VEC3D_TYPE_POSITION); xv = get_local_entity_vec3d_ptr (task_leader, VEC3D_TYPE_XV); // // take leader position and SUBTRACT leaders formation position (coz leader is not necessarily formation pos 0) // wp_pos->x = leader_pos->x - ((xv->x * formation->sites [leader_formation_index].x) + (xv->z * formation->sites [leader_formation_index].z)); wp_pos->y = 0; wp_pos->z = leader_pos->z - ((xv->z * formation->sites [leader_formation_index].x) + (xv->x * formation->sites [leader_formation_index].z)); // // then ADD members formation position // wp_pos->x += ((xv->x * formation->sites [formation_index].x) + (xv->z * formation->sites [formation_index].z)); wp_pos->z += ((xv->z * formation->sites [formation_index].x) + (xv->x * formation->sites [formation_index].z)); } } // // calculate distance of entity to desired position // pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); distance = get_2d_range (pos, wp_pos); #if DEBUG_WAYPOINT_VECTOR if (distance > 0.0) { create_debug_3d_line (pos, wp_pos, sys_col_black, 0.0); } #endif set_local_entity_float_value (en, FLOAT_TYPE_DISTANCE, distance); }