void update_overview_camera (camera *raw) { entity *en; vec3d rel_camera_position; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera attitude // get_3d_transformation_matrix (raw->attitude, get_local_entity_float_value (en, FLOAT_TYPE_HEADING) + rad (180.0), rad (-15.0), 0.0); // // get camera position // rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5f); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void reset_static_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max, radius, length; int fast_airborne; ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); radius = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min); fast_airborne = FALSE; if (get_local_entity_int_value (en, INT_TYPE_AIRBORNE_AIRCRAFT)) { if (get_local_entity_vec3d_magnitude (en, VEC3D_TYPE_MOTION_VECTOR) >= knots_to_metres_per_second (10.0)) { fast_airborne = TRUE; } } if (fast_airborne) { get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &v); normalise_3d_vector (&v); v.x *= radius; v.y *= radius; v.z *= radius; } else { heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); v.x = 0.0; v.y = 0.0; v.z = radius; multiply_matrix3x3_vec3d (&v, m, &v); } get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // attitude // v.x = pos.x - raw->position.x; v.y = pos.y - raw->position.y; v.z = pos.z - raw->position.z; length = (v.x * v.x) + (v.y * v.y) + (v.z * v.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&v, length); get_matrix3x3_from_unit_vec3d (raw->attitude, &v); } else { get_identity_matrix3x3 (raw->attitude); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.y = 0.0; raw->motion_vector.z = 0.0; }
void update_vector_attitude_dynamics (void) { matrix3x3 delta_attitude, attitude; float heading, pitch, roll; vec3d result, test_point; get_local_entity_attitude_matrix (get_gunship_entity (), attitude); // get heading, pitch, and roll heading = atan2 (attitude [2][0], attitude [2][2]); pitch = asin (attitude [2][1]); roll = atan2 (-attitude [0][1], attitude [1][1]); current_flight_dynamics->heading.value = heading; current_flight_dynamics->pitch.value = pitch; current_flight_dynamics->roll.value = roll; // // roll // current_flight_dynamics->roll.delta = 30 * current_flight_dynamics->main_rotor_roll_angle.value * get_delta_time (); // // pitch // current_flight_dynamics->pitch.delta = 30 * current_flight_dynamics->main_rotor_pitch_angle.value * get_delta_time (); // // heading // current_flight_dynamics->heading.delta = 15 * (-(current_flight_dynamics->tail_rotor_thrust.value * current_flight_dynamics->tail_boom_length.value * current_flight_dynamics->tail_rotor_diameter.value) * get_delta_time () / current_flight_dynamics->mass.value); get_3d_transformation_matrix (delta_attitude, -current_flight_dynamics->heading.delta, current_flight_dynamics->pitch.delta, current_flight_dynamics->roll.delta); multiply_matrix3x3_vec3d (&test_point, current_flight_dynamics->attitude, ¤t_flight_dynamics->rotation_origin); multiply_matrix3x3_matrix3x3 (current_flight_dynamics->attitude, delta_attitude, attitude); multiply_matrix3x3_vec3d (&result, current_flight_dynamics->attitude, ¤t_flight_dynamics->rotation_origin); result.x -= test_point.x; result.y -= test_point.y; result.z -= test_point.z; current_flight_dynamics->position.x -= result.x; current_flight_dynamics->position.y -= result.y; current_flight_dynamics->position.z -= result.z; }
void update_cinematic_camera_continued (camera *raw) { entity *en; object_3d_instance *inst3d; viewpoint vp; float normalised_timer; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera position and attitude // switch (raw->cinematic_camera_index) { //////////////////////////////////////// case OBJECT_3D_INVALID_CAMERA_INDEX: //////////////////////////////////////// { float combined_heading, z_min, z_max; vec3d rel_camera_position; combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); combined_heading += raw->cinematic_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->cinematic_camera_pitch, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * 0.1) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_MOVING: //////////////////////////////////////// { normalised_timer = raw->cinematic_camera_timer / raw->cinematic_camera_lifetime; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_STATIC: //////////////////////////////////////// { normalised_timer = 0.0; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } } // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void reset_drop_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // place camera behind object to prevent going inside object (especially when the object is stationary) // heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); v.x = 0.0; v.y = 0.0; v.z = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min); multiply_matrix3x3_vec3d (&v, m, &v); get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.y = 0.0; raw->motion_vector.z = 0.0; }
void update_chase_camera (camera *raw) { entity *en; float combined_heading, z_min, z_max; vec3d rel_camera_position; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // adjust camera heading // if (adjust_view_left_key || joystick_pov_left) { raw->chase_camera_heading += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } else if (adjust_view_right_key || joystick_pov_right) { raw->chase_camera_heading -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading); // // adjust camera pitch // if (adjust_view_up_key || joystick_pov_up) { raw->chase_camera_pitch -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = max (CHASE_CAMERA_ROTATE_DOWN_LIMIT, raw->chase_camera_pitch); } else if (adjust_view_down_key || joystick_pov_down) { raw->chase_camera_pitch += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = min (CHASE_CAMERA_ROTATE_UP_LIMIT, raw->chase_camera_pitch); } if (adjust_view_zoom_in_key) { raw->chase_camera_zoom -= CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = max (CHASE_CAMERA_ZOOM_IN_LIMIT, raw->chase_camera_zoom); } else if (adjust_view_zoom_out_key) { raw->chase_camera_zoom += CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = min (CHASE_CAMERA_ZOOM_OUT_LIMIT, raw->chase_camera_zoom); } // // get camera attitude // if (get_local_entity_int_value (en, INT_TYPE_ALIVE) && raw->chase_camera_lock_rotate) { combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); } else { combined_heading = 0.0; } combined_heading += raw->chase_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->chase_camera_pitch, 0.0); // // get camera position // if (in_flight_zoom_test) { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE_TEST); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE_TEST); } else { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); } ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * raw->chase_camera_zoom * raw->chase_camera_zoom) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void 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... }