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 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_cinematic_camera_continued (camera *raw) { entity *en; object_3d_instance *inst3d; viewpoint vp; float normalised_timer; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // get camera position and attitude // switch (raw->cinematic_camera_index) { //////////////////////////////////////// case OBJECT_3D_INVALID_CAMERA_INDEX: //////////////////////////////////////// { float combined_heading, z_min, z_max; vec3d rel_camera_position; combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); combined_heading += raw->cinematic_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->cinematic_camera_pitch, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * 0.1) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_MOVING: //////////////////////////////////////// { normalised_timer = raw->cinematic_camera_timer / raw->cinematic_camera_lifetime; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } //////////////////////////////////////// case OBJECT_3D_CAMERA_SCENIC_STATIC: //////////////////////////////////////// { normalised_timer = 0.0; inst3d = get_local_entity_ptr_value (en, PTR_TYPE_INSTANCE_3D_OBJECT); get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &inst3d->vp.position); get_local_entity_attitude_matrix (en, inst3d->vp.attitude); get_object_3d_camera_position (inst3d, raw->cinematic_camera_index, raw->cinematic_camera_depth, normalised_timer, &vp); raw->position = vp.position; memcpy (raw->attitude, vp.attitude, sizeof (matrix3x3)); break; } } // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + 0.5); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void reset_drop_camera (camera *raw) { entity *en; vec3d pos, v; matrix3x3 m; float heading, z_min, z_max; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // place camera behind object to prevent going inside object (especially when the object is stationary) // heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); get_3d_transformation_matrix (m, heading, CHASE_CAMERA_RESET_PITCH, 0.0); z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); v.x = 0.0; v.y = 0.0; v.z = -(((z_max - z_min) * CHASE_CAMERA_RESET_ZOOM * CHASE_CAMERA_RESET_ZOOM) + z_min); multiply_matrix3x3_vec3d (&v, m, &v); get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.y = pos.y + v.y; raw->position.z = pos.z + v.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // raw->motion_vector.x = 0.0; raw->motion_vector.y = 0.0; raw->motion_vector.z = 0.0; }
void update_chase_camera (camera *raw) { entity *en; float combined_heading, z_min, z_max; vec3d rel_camera_position; // // pre-amble // ASSERT (raw); ASSERT (raw->external_view_entity); en = raw->external_view_entity; // // adjust camera heading // if (adjust_view_left_key || joystick_pov_left) { raw->chase_camera_heading += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } else if (adjust_view_right_key || joystick_pov_right) { raw->chase_camera_heading -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); } raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading); // // adjust camera pitch // if (adjust_view_up_key || joystick_pov_up) { raw->chase_camera_pitch -= CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = max (CHASE_CAMERA_ROTATE_DOWN_LIMIT, raw->chase_camera_pitch); } else if (adjust_view_down_key || joystick_pov_down) { raw->chase_camera_pitch += CHASE_CAMERA_ROTATE_RATE * get_delta_time (); raw->chase_camera_pitch = min (CHASE_CAMERA_ROTATE_UP_LIMIT, raw->chase_camera_pitch); } if (adjust_view_zoom_in_key) { raw->chase_camera_zoom -= CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = max (CHASE_CAMERA_ZOOM_IN_LIMIT, raw->chase_camera_zoom); } else if (adjust_view_zoom_out_key) { raw->chase_camera_zoom += CHASE_CAMERA_ZOOM_RATE * get_delta_time (); raw->chase_camera_zoom = min (CHASE_CAMERA_ZOOM_OUT_LIMIT, raw->chase_camera_zoom); } // // get camera attitude // if (get_local_entity_int_value (en, INT_TYPE_ALIVE) && raw->chase_camera_lock_rotate) { combined_heading = get_local_entity_float_value (en, FLOAT_TYPE_HEADING); } else { combined_heading = 0.0; } combined_heading += raw->chase_camera_heading; get_3d_transformation_matrix (raw->attitude, combined_heading, raw->chase_camera_pitch, 0.0); // // get camera position // if (in_flight_zoom_test) { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE_TEST); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE_TEST); } else { z_min = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (en, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); } ASSERT (z_min < z_max); rel_camera_position.x = 0.0; rel_camera_position.y = 0.0; rel_camera_position.z = -(((z_max - z_min) * raw->chase_camera_zoom * raw->chase_camera_zoom) + z_min); multiply_matrix3x3_vec3d (&rel_camera_position, raw->attitude, &rel_camera_position); get_local_entity_target_point (en, &raw->position); raw->position.x += rel_camera_position.x; raw->position.y += rel_camera_position.y; raw->position.z += rel_camera_position.z; // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // motion vector // get_local_entity_vec3d (en, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
void set_reverse_tactical_camera_values (entity *source, entity *target) { camera *raw; int airborne; object_3d_index_numbers object_3d_index; object_3d_bounds *bounding_box; float length, radius, z_min, z_max, rad_alt, dx, dy, dz; vec3d source_position, target_position, direction; ASSERT (source); ASSERT (target); ASSERT (get_camera_entity ()); raw = get_local_entity_data (get_camera_entity ()); // // get camera position // if (get_local_entity_int_value (target, INT_TYPE_IDENTIFY_FIXED)) { object_3d_index = get_local_entity_int_value (target, INT_TYPE_OBJECT_3D_SHAPE); bounding_box = get_object_3d_bounding_box (object_3d_index); dx = bounding_box->xmax - bounding_box->xmin; dy = bounding_box->ymax; dz = bounding_box->zmax - bounding_box->zmin; radius = sqrt ((dx * dx) + (dy * dy) + (dz * dz)) * 2.0; } else { z_min = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE); z_max = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE); ASSERT (z_min < z_max); radius = ((z_max - z_min) * 0.05) + z_min; } get_local_entity_target_point (source, &source_position); get_local_entity_target_point (target, &target_position); airborne = FALSE; if (get_local_entity_int_value (target, INT_TYPE_AIRBORNE_AIRCRAFT)) { if (point_inside_map_area (&target_position)) { rad_alt = max (target_position.y - get_3d_terrain_elevation (target_position.x, target_position.z), 0.0); if (rad_alt > z_min) { airborne = TRUE; } } } if (airborne) { direction.x = target_position.x - source_position.x; direction.y = target_position.y - source_position.y; direction.z = target_position.z - source_position.z; length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); } else { direction.x = 0.0; direction.y = 0.0; direction.z = -1.0; } } else { direction.x = target_position.x - source_position.x; direction.y = 0.0; direction.z = target_position.z - source_position.z; length = (direction.x * direction.x) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); } else { direction.x = 0.0; direction.z = -1.0; } direction.y = 0.5; normalise_3d_vector (&direction); } raw->position.x = target_position.x + (direction.x * radius); raw->position.y = target_position.y + (direction.y * radius); raw->position.z = target_position.z + (direction.z * radius); // // keep point above ground (unless point off map) // if (point_inside_map_area (&raw->position)) { raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND); } // // get camera attitude // direction.x = target_position.x - raw->position.x; direction.y = target_position.y - raw->position.y; direction.z = target_position.z - raw->position.z; length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z); if (length > 1.0) { length = sqrt (length); normalise_3d_vector_given_magnitude (&direction, length); get_matrix3x3_from_unit_vec3d (raw->attitude, &direction); } else { get_identity_matrix3x3 (raw->attitude); } // // motion vector // get_local_entity_vec3d (target, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector); }
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... }