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; }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; routed_vehicle *raw; entity_sub_types group_sub_type; float heading; vec3d *face_normal; //////////////////////////////////////// // // 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 (routed_vehicle)); 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 (routed_vehicle)); // // mobile // raw->vh.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->vh.mob.position.x = MID_MAP_X; raw->vh.mob.position.y = MID_MAP_Y; raw->vh.mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->vh.mob.attitude); raw->vh.mob.alive = TRUE; raw->vh.mob.side = ENTITY_SIDE_UNINITIALISED; raw->vh.operational_state = OPERATIONAL_STATE_UNKNOWN; // // vehicle // raw->vh.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX; raw->vh.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED; raw->vh.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; raw->vh.weapon_vector.x = 0.0; raw->vh.weapon_vector.y = 0.0; raw->vh.weapon_vector.z = 1.0; raw->vh.weapon_to_target_vector.x = 0.0; raw->vh.weapon_to_target_vector.y = 0.0; raw->vh.weapon_to_target_vector.z = -1.0; raw->vh.loading_door_state = VEHICLE_LOADING_DOORS_OPEN_FLOAT_VALUE; // // routed // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->vh.member_link.parent); ASSERT (get_local_entity_type (raw->vh.member_link.parent) == ENTITY_TYPE_GROUP); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// raw->sub_route = NULL; // // side // if (raw->vh.mob.side == ENTITY_SIDE_UNINITIALISED) { raw->vh.mob.side = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_SIDE); } ASSERT (raw->vh.mob.side != ENTITY_SIDE_NEUTRAL); // // sub_type // if (raw->vh.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED) { group_sub_type = get_local_entity_int_value (raw->vh.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE); if (raw->vh.mob.side == ENTITY_SIDE_BLUE_FORCE) { raw->vh.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type; } else { raw->vh.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type; } } ASSERT (entity_sub_type_vehicle_valid (raw->vh.mob.sub_type)); // // 3D shape // if (raw->vh.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX) { raw->vh.object_3d_shape = vehicle_database[raw->vh.mob.sub_type].default_3d_shape; } // // weapon config // if (raw->vh.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED) { raw->vh.weapon_config_type = vehicle_database[raw->vh.mob.sub_type].default_weapon_config_type; } ASSERT (weapon_config_type_valid (raw->vh.weapon_config_type)); // // damage levels // raw->vh.damage_level = vehicle_database[raw->vh.mob.sub_type].initial_damage_level; // // radar dish rotation (ok to use a random number as this is for visual effect only) // raw->vh.radar_rotation_state = frand1 (); //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// // // 3D object // raw->vh.inst3d = construct_3d_object (raw->vh.object_3d_shape); set_routed_vehicle_id_number (en); set_initial_rotation_angle_of_routed_vehicle_wheels (raw->vh.inst3d); // // align with terrain // get_3d_terrain_point_data (raw->vh.mob.position.x, raw->vh.mob.position.z, &raw->vh.terrain_info); heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude); face_normal = get_3d_terrain_point_data_normal (&raw->vh.terrain_info); get_3d_transformation_matrix_from_face_normal_and_heading (raw->vh.mob.attitude, face_normal, heading); // // weapon config // raw->vh.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY); memset (raw->vh.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY); load_local_entity_weapon_config (en); // // update force info // add_to_force_info (get_local_force_entity (raw->vh.mob.side), en); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->vh.member_link.parent, raw->vh.member_link.child_pred); // // insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en)); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->vh.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; camera *raw; //////////////////////////////////////// // // 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); ASSERT (!get_camera_entity ()); if (en) { //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = (camera *) malloc_fast_mem (sizeof (camera)); 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 (camera)); raw->position.x = MID_MAP_X; raw->position.y = MID_MAP_Y; raw->position.z = MID_MAP_Z; raw->offset.x = 0; raw->offset.y = 0; raw->offset.z = 0; raw->offset_movement.x = 0; raw->offset_movement.y = 0; raw->offset_movement.z = 0; raw->turbulence_offset.x = 0.0; raw->turbulence_offset.y = 0.0; raw->turbulence_offset.z = 0.0; raw->turbulence_movement.x = 0.0; raw->turbulence_movement.y = 0.0; raw->turbulence_movement.z = 0.0; get_identity_matrix3x3 (raw->attitude); raw->camera_mode = CAMERA_MODE_CHASE; raw->chase_camera_lock_rotate = TRUE; reset_chase_camera_position (raw); reset_cinematic_camera_for_new_view_entity (raw); //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); set_camera_entity (en); } return (en); }
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; }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; cargo *raw; //////////////////////////////////////// // // 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 = (cargo *) malloc_fast_mem (sizeof (cargo)); 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 (cargo)); // // mobile // raw->mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->mob.position.x = MID_MAP_X; raw->mob.position.y = MID_MAP_Y; raw->mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->mob.attitude); raw->mob.alive = TRUE; raw->mob.side = ENTITY_SIDE_UNINITIALISED; // // cargo // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// if (raw->cargo_link.parent) { insert_local_entity_into_parents_child_list (en, LIST_TYPE_CARGO, raw->cargo_link.parent, NULL); } insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->mob.position), NULL); //insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
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 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 entity *create_local (entity_types type, int index, char *pargs) { entity *en; weapon *raw; int seed; viewpoint vp; //////////////////////////////////////// // // 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) { float dispersion; //////////////////////////////////////// // // MALLOC ENTITY DATA // //////////////////////////////////////// set_local_entity_type (en, type); raw = (weapon *) malloc_fast_mem (sizeof (weapon)); 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 (weapon)); // // mobile // raw->mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->mob.position.x = MID_MAP_X; raw->mob.position.y = MID_MAP_Y; raw->mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->mob.attitude); raw->mob.alive = TRUE; // // weapon // raw->kill_code = WEAPON_KILL_CODE_OK; //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (entity_sub_type_weapon_valid (raw->mob.sub_type)); ASSERT (raw->launched_weapon_link.parent); ASSERT (raw->burst_size > 0); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// if (weapon_database[raw->mob.sub_type].acquire_parent_forward_velocity) { raw->mob.velocity = get_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VELOCITY); } else { // // overwrite attribute // raw->mob.velocity = 0.0; } raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity; seed = get_client_server_entity_random_number_seed (en); raw->mob.velocity += weapon_database[raw->mob.sub_type].muzzle_velocity_max_error * frand1x (&seed); raw->weapon_lifetime = weapon_database[raw->mob.sub_type].burn_time; raw->decoy_timer = get_decoy_timer_start_value (weapon_database[raw->mob.sub_type].decoy_type); // // detach weapon from launcher (get position and attitude) // detach_local_entity_weapon (raw->launched_weapon_link.parent, raw->mob.sub_type, raw->burst_size, &vp); raw->mob.position = vp.position; // arneh - add dispersion as random rotation in heading and pitch up to max error angle dispersion = weapon_database[raw->mob.sub_type].max_range_error_ratio; if (dispersion > 0.0) { matrix3x3 m; float heading = dispersion * sfrand1norm(), pitch = dispersion * sfrand1norm(); get_3d_transformation_matrix(m, heading, pitch, 0.0); multiply_matrix3x3_matrix3x3(raw->mob.attitude, vp.attitude, m); } else memcpy (raw->mob.attitude, vp.attitude, sizeof (matrix3x3)); // // interest level // set_local_entity_float_value (raw->launched_weapon_link.parent, FLOAT_TYPE_VIEW_INTEREST_LEVEL, DEFAULT_VIEW_INTEREST_LEVEL); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_LAUNCHED_WEAPON, raw->launched_weapon_link.parent, NULL); if (raw->mob.target_link.parent) { insert_local_entity_into_parents_child_list (en, LIST_TYPE_TARGET, raw->mob.target_link.parent, NULL); } insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); if (tacview_is_logging()) write_tacview_new_unit(en); // // check if the weapon camera is primed and this weapon has been launched by the external view entity // if (get_camera_entity ()) { if (get_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED)) { if (raw->launched_weapon_link.parent == get_external_view_entity ()) { if (get_local_entity_int_value (en, INT_TYPE_VIEWABLE_WEAPON)) { notify_local_entity (ENTITY_MESSAGE_SET_CAMERA_ACTION, get_camera_entity (), NULL, CAMERA_ACTION_WEAPON); set_local_entity_int_value (get_camera_entity (), INT_TYPE_WEAPON_CAMERA_PRIMED, FALSE); } } } } } return (en); }
static entity *create_local (entity_types type, int index, char *pargs) { entity *en; fixed_wing *raw; entity_sub_types group_sub_type; //////////////////////////////////////// // // 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 (fixed_wing)); 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 (fixed_wing)); // // mobile // raw->ac.mob.sub_type = ENTITY_SUB_TYPE_UNINITIALISED; raw->ac.mob.position.x = MID_MAP_X; raw->ac.mob.position.y = MID_MAP_Y; raw->ac.mob.position.z = MID_MAP_Z; get_identity_matrix3x3 (raw->ac.mob.attitude); raw->ac.mob.alive = TRUE; raw->ac.mob.side = ENTITY_SIDE_UNINITIALISED; raw->ac.operational_state = OPERATIONAL_STATE_UNKNOWN; // // aircraft // raw->ac.object_3d_shape = OBJECT_3D_INVALID_OBJECT_INDEX; raw->ac.weapon_config_type = WEAPON_CONFIG_TYPE_UNINITIALISED; raw->ac.selected_weapon = ENTITY_SUB_TYPE_WEAPON_NO_WEAPON; raw->ac.weapon_vector.x = 0.0; raw->ac.weapon_vector.y = 0.0; raw->ac.weapon_vector.z = 1.0; raw->ac.weapon_to_target_vector.x = 0.0; raw->ac.weapon_to_target_vector.y = 0.0; raw->ac.weapon_to_target_vector.z = -1.0; raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_OPEN_FLOAT_VALUE; raw->ac.undercarriage_state = AIRCRAFT_UNDERCARRIAGE_DOWN_FLOAT_VALUE; raw->ac.air_radar_contact_timeout = AIR_RADAR_CONTACT_TIMEOUT_INVALID; // // fixed_wing // //////////////////////////////////////// // // OVERWRITE DEFAULT VALUES WITH GIVEN ATTRIBUTES // //////////////////////////////////////// set_local_entity_attributes (en, pargs); //////////////////////////////////////// // // CHECK MANDATORY ATTRIBUTES HAVE BEEN GIVEN // //////////////////////////////////////// ASSERT (raw->ac.member_link.parent); ASSERT (get_local_entity_type (raw->ac.member_link.parent) == ENTITY_TYPE_GROUP); //////////////////////////////////////// // // RESOLVE DEFAULT VALUES // //////////////////////////////////////// // // side // if (raw->ac.mob.side == ENTITY_SIDE_UNINITIALISED) { raw->ac.mob.side = get_local_entity_int_value (raw->ac.member_link.parent, INT_TYPE_SIDE); } ASSERT (raw->ac.mob.side != ENTITY_SIDE_NEUTRAL); // // sub_type // if (raw->ac.mob.sub_type == ENTITY_SUB_TYPE_UNINITIALISED) { group_sub_type = get_local_entity_int_value (raw->ac.member_link.parent, INT_TYPE_ENTITY_SUB_TYPE); if (raw->ac.mob.side == ENTITY_SIDE_BLUE_FORCE) { raw->ac.mob.sub_type = group_database[group_sub_type].default_blue_force_sub_type; } else { raw->ac.mob.sub_type = group_database[group_sub_type].default_red_force_sub_type; } } ASSERT (entity_sub_type_aircraft_valid (raw->ac.mob.sub_type)); // // 3D shape // if (raw->ac.object_3d_shape == OBJECT_3D_INVALID_OBJECT_INDEX) { raw->ac.object_3d_shape = aircraft_database[raw->ac.mob.sub_type].default_3d_shape; } // // weapon config // if (raw->ac.weapon_config_type == WEAPON_CONFIG_TYPE_UNINITIALISED) { raw->ac.weapon_config_type = aircraft_database[raw->ac.mob.sub_type].default_weapon_config_type; } ASSERT (weapon_config_type_valid (raw->ac.weapon_config_type)); // // damage levels // raw->ac.damage_level = aircraft_database[raw->ac.mob.sub_type].initial_damage_level; //////////////////////////////////////// // // BUILD COMPONENTS // //////////////////////////////////////// // // 3D object // raw->ac.inst3d = construct_3d_object (raw->ac.object_3d_shape); set_fixed_wing_id_number (en); initialise_fixed_wing_propellors (en); #if RECOGNITION_GUIDE raw->ac.loading_door_state = AIRCRAFT_LOADING_DOORS_CLOSED_FLOAT_VALUE; #endif // // weapon config // raw->ac.weapon_package_status_array = malloc_fast_mem (SIZE_WEAPON_PACKAGE_STATUS_ARRAY); memset (raw->ac.weapon_package_status_array, 0, SIZE_WEAPON_PACKAGE_STATUS_ARRAY); load_local_entity_weapon_config (en); // // update force info // add_to_force_info (get_local_force_entity (raw->ac.mob.side), en); //////////////////////////////////////// // // LINK INTO SYSTEM // //////////////////////////////////////// insert_local_entity_into_parents_child_list (en, LIST_TYPE_MEMBER, raw->ac.member_link.parent, raw->ac.member_link.child_pred); // // insert into LIST_TYPE_MEMBER before LIST_TYPE_VIEW // insert_local_entity_into_parents_child_list (en, LIST_TYPE_VIEW, get_camera_entity (), get_local_entity_view_list_pred (en)); insert_local_entity_into_parents_child_list (en, LIST_TYPE_SECTOR, get_local_sector_entity (&raw->ac.mob.position), NULL); insert_local_entity_into_parents_child_list (en, LIST_TYPE_UPDATE, get_update_entity (), NULL); } return (en); }
env_2d *create_2d_environment (void) { env_2d *env; env = (env_2d *) safe_malloc (sizeof (env_2d)); // // initialise 'safe' values // env->vp.x_min = 0.0; env->vp.y_min = 0.0; env->vp.x_max = 639.999; env->vp.y_max = 479.999; env->window_x_min = -1.0; env->window_y_min = -1.0; env->window_x_max = 1.0; env->window_y_max = 1.0; env->offset_x = env->offset_y = 0.0; get_identity_matrix3x3 (env->instance_scaling); get_identity_matrix3x3 (env->instance_rotation); get_identity_matrix3x3 (env->instance_translation); get_identity_matrix3x3 (env->instance_transformation); get_identity_matrix3x3 (env->window_translation); get_identity_matrix3x3 (env->window_scaling); get_identity_matrix3x3 (env->window_rotation); get_identity_matrix3x3 (env->viewport_translation); get_identity_matrix3x3 (env->composite_transformation); get_identity_matrix3x3 (env->inverse_viewport_translation); get_identity_matrix3x3 (env->inverse_window_rotation); get_identity_matrix3x3 (env->inverse_window_scaling); get_identity_matrix3x3 (env->inverse_window_translation); get_identity_matrix3x3 (env->inverse_composite_transformation); env->instance_transformation_matrix_valid = TRUE; env->composite_transformation_matrix_valid = TRUE; env->inverse_composite_transformation_matrix_valid = TRUE; return (env); }
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... }