void get_default_virtual_cockpit_adi_angles (matrix3x3 attitude, float *heading, float *pitch, float *roll) { matrix3x3 inverse_attitude, heading_rotation, result; // // get inverse attitude (attiude * inverse attitude = identity) which aligns the ADI with the world axis // inverse_attitude[0][0] = attitude[0][0]; inverse_attitude[1][0] = attitude[0][1]; inverse_attitude[2][0] = attitude[0][2]; inverse_attitude[0][1] = attitude[1][0]; inverse_attitude[1][1] = attitude[1][1]; inverse_attitude[2][1] = attitude[1][2]; inverse_attitude[0][2] = attitude[2][0]; inverse_attitude[1][2] = attitude[2][1]; inverse_attitude[2][2] = attitude[2][2]; // // rotate heading so that the ADI pitch markings face the pilot // get_3d_transformation_matrix (heading_rotation, get_heading_from_attitude_matrix (attitude), 0.0, 0.0); multiply_matrix3x3_matrix3x3 (result, heading_rotation, inverse_attitude); *heading = get_heading_from_attitude_matrix (result); *pitch = get_pitch_from_attitude_matrix (result); *roll = get_roll_from_attitude_matrix (result); }
static void set_local_float_value (entity *en, float_types type, float value) { mobile *raw; #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_FLOAT_VALUE, en, type, value); #endif raw = (mobile *) get_local_entity_data (en); switch (type) { //////////////////////////////////////// case FLOAT_TYPE_HEADING: //////////////////////////////////////// { matrix3x3 attitude; float pitch, roll; pitch = get_pitch_from_attitude_matrix (raw->attitude); roll = get_roll_from_attitude_matrix (raw->attitude); get_3d_transformation_matrix (attitude, value, pitch, roll); set_local_entity_attitude_matrix (en, attitude); break; } //////////////////////////////////////// case FLOAT_TYPE_HIGH_VELOCITY: case FLOAT_TYPE_LOW_VELOCITY: case FLOAT_TYPE_MEDIUM_VELOCITY: case FLOAT_TYPE_VELOCITY: case FLOAT_TYPE_VERY_HIGH_VELOCITY: //////////////////////////////////////// { raw->velocity = value; break; } //////////////////////////////////////// default: //////////////////////////////////////// { debug_fatal_invalid_float_type (en, type); break; } } }
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); }
static void draw_local_3d_object (entity *en, float range) { site_updatable *raw; object_3d_instance *inst3d; vec3d face_normal; day_segment_types day_segment_type; raw = (site_updatable *) get_local_entity_data (en); inst3d = construct_temporary_3d_object (raw->fix.object_3d_shape, raw->fix.alive); if (inst3d) { if (raw->fix.alive) { animate_site_radar (en, inst3d); animate_site_loading_doors (en, inst3d); } memcpy (&inst3d->vp.position, &raw->fix.position, sizeof (vec3d)); if (fixed_database[raw->fix.sub_type].align_with_terrain) { get_3d_terrain_face_normal (&face_normal, raw->fix.position.x, raw->fix.position.z); get_3d_transformation_matrix_from_face_normal_and_heading (inst3d->vp.attitude, &face_normal, raw->fix.heading); } else { get_3d_transformation_matrix (inst3d->vp.attitude, raw->fix.heading, 0.0, 0.0); } day_segment_type = (day_segment_types) get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE); inst3d->object_sprite_lights = ((day_segment_type == DAY_SEGMENT_TYPE_NIGHT) || (day_segment_type == DAY_SEGMENT_TYPE_DUSK)); inst3d->object_has_shadow = FALSE; insert_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_OBJECT, inst3d); } }
static void set_local_attitude_angles (entity *en, float heading, float pitch, float roll) { camera *raw; #if DEBUG_MODULE debug_log_entity_args (ENTITY_DEBUG_LOCAL, ENTITY_DEBUG_ATTITUDE_ANGLES, en, heading, pitch, roll); #endif raw = get_local_entity_data (en); get_3d_transformation_matrix (raw->attitude, heading, pitch, roll); }
void update_static_camera (camera *raw) { float heading, pitch; ASSERT (raw); heading = get_heading_from_attitude_matrix (raw->attitude); pitch = get_pitch_from_attitude_matrix (raw->attitude); // // adjust camera heading // if (adjust_view_left_key || joystick_pov_left) { heading -= STATIC_CAMERA_ROTATE_RATE * get_delta_time (); } else if (adjust_view_right_key || joystick_pov_right) { heading += STATIC_CAMERA_ROTATE_RATE * get_delta_time (); } heading = wrap_angle (heading); // // adjust camera pitch // if (adjust_view_up_key || joystick_pov_up) { pitch += STATIC_CAMERA_ROTATE_RATE * get_delta_time (); pitch = min (STATIC_CAMERA_ROTATE_UP_LIMIT, pitch); } else if (adjust_view_down_key || joystick_pov_down) { pitch -= STATIC_CAMERA_ROTATE_RATE * get_delta_time (); pitch = max (STATIC_CAMERA_ROTATE_DOWN_LIMIT, pitch); } get_3d_transformation_matrix (raw->attitude, heading, pitch, 0.0); }
static void set_cockpit_white_lighting (matrix3x3 attitude) { matrix3x3 directional_light_rotation, result; vec3d directional_light_direction; light_colour ambient_light_colour, directional_light_colour; float directional_light_heading, directional_light_pitch, directional_light_roll; ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 1.0; directional_light_colour.blue = 1.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-40.0); directional_light_roll = rad (0.0); set_3d_ambient_light (main_3d_single_light_env, &ambient_light_colour); get_3d_transformation_matrix (directional_light_rotation, directional_light_heading, directional_light_pitch, directional_light_roll); multiply_matrix3x3_matrix3x3 (result, directional_light_rotation, attitude); directional_light_direction.x = -result[2][0]; directional_light_direction.y = -result[2][1]; directional_light_direction.z = -result[2][2]; set_3d_main_light_source (main_3d_single_light_env, &directional_light_colour, &directional_light_direction, FALSE); }
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 initialise_scene_bounding_sub_objects ( int scene_index ) { int index, count; memset ( &scene_bounds, 0, sizeof ( object_3d_bounds ) ); memset ( &scene_bounds2, 0, sizeof ( object_3d_bounds ) ); index = objects_3d_scene_database[scene_index].index; scene_position.x = 0; scene_position.y = 0; scene_position.z = 0; get_3d_transformation_matrix ( scene_rotation, 0, 0, 0 ); if ( index != 0 ) { rotate_sub_scene_boundaries ( &rotated_bounds, &objects_3d_data[index].bounding_box ); rotate_sub_scene_boundaries ( &rotated_bounds2, &objects_3d_data[index].bounding_box2 ); scene_bounds.xmin = min ( scene_bounds.xmin, rotated_bounds.xmin ); scene_bounds.ymin = min ( scene_bounds.ymin, rotated_bounds.ymin ); scene_bounds.zmin = min ( scene_bounds.zmin, rotated_bounds.zmin ); scene_bounds.xmax = max ( scene_bounds.xmax, rotated_bounds.xmax ); scene_bounds.ymax = max ( scene_bounds.ymax, rotated_bounds.ymax ); scene_bounds.zmax = max ( scene_bounds.zmax, rotated_bounds.zmax ); scene_bounds2.xmin = min ( scene_bounds2.xmin, rotated_bounds2.xmin ); scene_bounds2.ymin = min ( scene_bounds2.ymin, rotated_bounds2.ymin ); scene_bounds2.zmin = min ( scene_bounds2.zmin, rotated_bounds2.zmin ); scene_bounds2.xmax = max ( scene_bounds2.xmax, rotated_bounds2.xmax ); scene_bounds2.ymax = max ( scene_bounds2.ymax, rotated_bounds2.ymax ); scene_bounds2.zmax = max ( scene_bounds2.zmax, rotated_bounds2.zmax ); } contributes_to_collision = TRUE; for ( count = 0; count < objects_3d_scene_database[scene_index].number_of_sub_objects; count++ ) { recurse_initialise_sub_scene_bounding_box ( &objects_3d_scene_database[scene_index].sub_objects[count] ); } objects_3d_scene_database[scene_index].bounding_box = scene_bounds; objects_3d_scene_database[scene_index].bounding_box2 = scene_bounds2; // // Calculate the radius based on the bounding_box values // { double dxmin, dxmax, dymin, dymax, dzmin, dzmax, radius; dxmax = ( (double) scene_bounds.xmax * (double) scene_bounds.xmax ); dxmin = ( (double) scene_bounds.xmin * (double) scene_bounds.xmin ); dymax = ( (double) scene_bounds.ymax * (double) scene_bounds.ymax ); dymin = ( (double) scene_bounds.ymin * (double) scene_bounds.ymin ); dzmax = ( (double) scene_bounds.zmax * (double) scene_bounds.zmax ); dzmin = ( (double) scene_bounds.zmin * (double) scene_bounds.zmin ); radius = 0; radius = max ( radius, ( dxmax + dymax + dzmax ) ); radius = max ( radius, ( dxmax + dymax + dzmin ) ); radius = max ( radius, ( dxmax + dymin + dzmax ) ); radius = max ( radius, ( dxmax + dymin + dzmin ) ); radius = max ( radius, ( dxmin + dymax + dzmax ) ); radius = max ( radius, ( dxmin + dymax + dzmin ) ); radius = max ( radius, ( dxmin + dymin + dzmax ) ); radius = max ( radius, ( dxmin + dymin + dzmin ) ); radius = sqrt ( radius ); objects_3d_scene_database[scene_index].radius = radius; } }
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 draw_hokum_virtual_cockpit (void) { int draw_main_rotors; float theta; object_3d_instance *inst3d; object_3d_sub_object_search_data search; switch (get_view_mode ()) { case VIEW_MODE_VIRTUAL_COCKPIT_CREW: case VIEW_MODE_VIRTUAL_COCKPIT_HUD: case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY: { break; } default: { if (!get_global_draw_cockpit_graphics ()) { draw_external_hokum_hud (); return; } break; } } // // lamps and instruments // draw_hokum_virtual_cockpit_lamps (); draw_hokum_virtual_cockpit_instruments (); // // crew animation // set_hokum_crew_head_positions (); // // animate main rotors // if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED)) { animate_damaged_helicopter_main_rotors (get_gunship_entity (), TRUE); } else { animate_helicopter_main_rotors (get_gunship_entity (), TRUE, FALSE); } inst3d = get_local_entity_ptr_value (get_gunship_entity (), PTR_TYPE_INSTANCE_3D_OBJECT); theta = get_rotation_angle_of_helicopter_main_rotors (inst3d); set_rotation_angle_of_helicopter_main_rotors (virtual_cockpit_inst3d, theta); animate_helicopter_virtual_cockpit_main_rotors (get_gunship_entity (), virtual_cockpit_inst3d); draw_main_rotors = TRUE; if (get_global_glass_cockpit ()) { draw_main_rotors = FALSE; } else { if (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW) { if (get_helicopter_main_rotors_blurred (get_gunship_entity ())) { if (!get_global_blurred_main_rotors_visible_from_cockpit ()) { draw_main_rotors = FALSE; } } } } search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_MAIN_ROTOR_SHAFT; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->visible_object = draw_main_rotors; } search.search_depth = 1; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_MAIN_ROTOR_SHAFT; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->visible_object = draw_main_rotors; } // // animate electro-optics // animate_hokum_virtual_cockpit_eo (virtual_cockpit_inst3d); // // animate wipers // animate_hokum_wipers (virtual_cockpit_inst3d); // // draw 3D scene // set_3d_view_distances (main_3d_env, 10.0, 0.1, 1.0, 0.0); realise_3d_clip_extents (main_3d_env); recalculate_3d_environment_settings (main_3d_env); clear_zbuffer_screen (); if (begin_3d_scene ()) { // // light direction is in world coordinates // light_3d_source *display_backlight, *cockpit_light; vec3d direction; matrix3x3 m1, m2; if (get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE) == DAY_SEGMENT_TYPE_DAY) { //////////////////////////////////////// // // DAY LIGHTING // //////////////////////////////////////// if (night_vision_system_active && (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW)) { // // active night vision system // get_3d_transformation_matrix (m1, rad (0.0), rad (135.0), rad (0.0)); multiply_matrix3x3_matrix3x3 (m2, m1, virtual_cockpit_inst3d->vp.attitude); direction.x = m2[2][0]; direction.y = m2[2][1]; direction.z = m2[2][2]; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.5000, 0.4000, 0.0000); insert_light_3d_source_into_3d_scene (cockpit_light); insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); end_3d_scene (); remove_light_3d_source_from_3d_scene (cockpit_light); destroy_light_3d_source (cockpit_light); } else { // // inactive night vision system // insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); end_3d_scene (); } } else { //////////////////////////////////////// // // NIGHT LIGHTING // //////////////////////////////////////// direction.x = virtual_cockpit_inst3d->vp.zv.x; direction.y = virtual_cockpit_inst3d->vp.zv.y; direction.z = virtual_cockpit_inst3d->vp.zv.z; display_backlight = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.2500, 0.0980, 0.0000); if (night_vision_system_active && (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW)) { // // active night vision system // get_3d_transformation_matrix (m1, rad (0.0), rad (135.0), rad (0.0)); multiply_matrix3x3_matrix3x3 (m2, m1, virtual_cockpit_inst3d->vp.attitude); direction.x = m2[2][0]; direction.y = m2[2][1]; direction.z = m2[2][2]; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.5000, 0.4000, 0.0000); } else { // // inactive night vision system // direction.x = virtual_cockpit_inst3d->vp.yv.x; direction.y = virtual_cockpit_inst3d->vp.yv.y; direction.z = virtual_cockpit_inst3d->vp.yv.z; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.0666, 0.1098, 0.6431); } insert_light_3d_source_into_3d_scene (display_backlight); insert_light_3d_source_into_3d_scene (cockpit_light); insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); end_3d_scene (); remove_light_3d_source_from_3d_scene (display_backlight); remove_light_3d_source_from_3d_scene (cockpit_light); destroy_light_3d_source (display_backlight); destroy_light_3d_source (cockpit_light); } } #if RECOGNITION_GUIDE set_3d_view_distances (main_3d_env, 10000.0, 100.0, 1.0, 0.0); #else set_3d_view_distances (main_3d_env, 10000.0, 1.0, 1.0, 0.0); #endif realise_3d_clip_extents (main_3d_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... }
void draw_3d_moon ( void ) { vertex *moon_polygon, *vert, moon_quad[4]; int outcode, outcode2, count; float moon_width, moon_height, moon_depth; matrix3x3 moon_matrix; int moon_red, moon_green, moon_blue; real_colour colour, specular; moon_polygon = moon_quad; moon_width = 12000; moon_height = 12000; moon_depth = 100000; moon_quad[0].next_vertex = &moon_quad[1]; moon_quad[1].next_vertex = &moon_quad[2]; moon_quad[2].next_vertex = &moon_quad[3]; moon_quad[3].next_vertex = NULL; moon_quad[0].x = -moon_width/2; moon_quad[0].y = moon_height/2; moon_quad[0].z = moon_depth; moon_quad[0].u = 0; moon_quad[0].v = 0; moon_quad[1].x = moon_width/2; moon_quad[1].y = moon_height/2; moon_quad[1].z = moon_depth; moon_quad[1].u = 1; moon_quad[1].v = 0; moon_quad[2].x = moon_width/2; moon_quad[2].y = -moon_height/2; moon_quad[2].z = moon_depth; moon_quad[2].u = 1; moon_quad[2].v = 1; moon_quad[3].x = -moon_width/2; moon_quad[3].y = -moon_height/2; moon_quad[3].z = moon_depth; moon_quad[3].u = 0; moon_quad[3].v = 1; // // Rotate the moon into position // get_3d_transformation_matrix ( moon_matrix, moon_3d_heading, moon_3d_pitch, 0 ); for ( count = 0; count < 4; count++ ) { float x, y, z; x = moon_quad[count].x * moon_matrix[0][0] + moon_quad[count].y * moon_matrix[1][0] + moon_quad[count].z * moon_matrix[2][0]; y = moon_quad[count].x * moon_matrix[0][1] + moon_quad[count].y * moon_matrix[1][1] + moon_quad[count].z * moon_matrix[2][1]; z = moon_quad[count].x * moon_matrix[0][2] + moon_quad[count].y * moon_matrix[1][2] + moon_quad[count].z * moon_matrix[2][2]; moon_quad[count].x = x; moon_quad[count].y = y; moon_quad[count].z = z; } // // Clip the moon to the horizon // clip_3d_coord = 0; moon_polygon = horizon_clip_3d_polygon ( moon_quad ); if ( moon_polygon ) { // // Rotate the polygon around to the users viewpoint // vert = moon_polygon; rotation_3d[0][0] = ( visual_3d_vp->xv.x ); rotation_3d[0][1] = ( visual_3d_vp->yv.x ); rotation_3d[0][2] = ( visual_3d_vp->zv.x ); rotation_3d[1][0] = ( visual_3d_vp->xv.y ); rotation_3d[1][1] = ( visual_3d_vp->yv.y ); rotation_3d[1][2] = ( visual_3d_vp->zv.y ); rotation_3d[2][0] = ( visual_3d_vp->xv.z ); rotation_3d[2][1] = ( visual_3d_vp->yv.z ); rotation_3d[2][2] = ( visual_3d_vp->zv.z ); outcode = 0; outcode2 = CLIP_LEFT | CLIP_RIGHT | CLIP_TOP | CLIP_BOTTOM | CLIP_HITHER | CLIP_YONDER; while ( vert ) { float x, y, z; x = vert->x * rotation_3d[0][0] + vert->y * rotation_3d[1][0] + vert->z * rotation_3d[2][0]; y = vert->x * rotation_3d[0][1] + vert->y * rotation_3d[1][1] + vert->z * rotation_3d[2][1]; z = vert->x * rotation_3d[0][2] + vert->y * rotation_3d[1][2] + vert->z * rotation_3d[2][2]; x *= active_3d_environment->screen_i_scale; y *= active_3d_environment->screen_j_scale; if ( *( ( int * ) &z ) >= *( ( int * ) &clip_hither ) ) { float q, i, j; float oxmax, oxmin, oymax, oymin; int ixmax, ixmin, iymax, iymin; q = 1.0 / z; vert->x = x; vert->y = y; vert->z = z; vert->q = q; i = ( x * q ); j = ( y * q ); vert->j = active_3d_environment->y_origin - j; vert->i = active_3d_environment->x_origin + i; oxmax = active_viewport.x_max - vert->i; oxmin = vert->i - active_viewport.x_min; oymax = active_viewport.y_max - vert->j; oymin = vert->j - active_viewport.y_min; ixmax = *( ( int * ) &oxmax ); ixmin = *( ( int * ) &oxmin ); iymax = *( ( int * ) &oymax ); iymin = *( ( int * ) &oymin ); vert->outcode = generate_lookup_outcode ( ixmin, iymin, ixmax, iymax ); outcode |= vert->outcode; outcode2 &= vert->outcode; } else { vert->outcode = CLIP_HITHER; vert->z = z; vert->x = x; vert->y = y; outcode |= vert->outcode; outcode2 &= vert->outcode; } vert = vert->next_vertex; } if ( outcode2 ) { return; } if ( outcode & CLIP_HITHER ) { moon_polygon = hither_clip_3d_polygon ( moon_polygon, &outcode ); if ( !moon_polygon ) { return; } } if ( outcode ) { apply_perspective_to_polygon_texture ( moon_polygon ); moon_polygon = clip_3d_polygon ( moon_polygon, outcode ); if ( !moon_polygon ) { return; } remove_perspective_from_polygon_texture ( moon_polygon ); } asm_convert_float_to_int ( ( moon_colour.red * 255 ), &moon_red ); asm_convert_float_to_int ( ( moon_colour.green * 255 ), &moon_green ); asm_convert_float_to_int ( ( moon_colour.blue * 255 ), &moon_blue ); colour.red = moon_red; colour.green = moon_green; colour.blue = moon_blue; specular.colour = 0; set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS ); set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE ); suspend_d3d_fog (); set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD ); set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); set_d3d_texture ( 0, load_hardware_texture_map ( moon_texture ) ); draw_wbuffered_flat_shaded_textured_polygon ( moon_polygon, colour, specular ); set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_DISABLE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); set_d3d_texture ( 0, NULL ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); reinstate_d3d_fog (); set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, zbuffer_default_comparison ); set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, TRUE ); } }
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 ship_vehicle_movement (entity *en) { ship_vehicle *raw; entity *guide, *current_waypoint; vec3d wp_pos, wp_vec, new_pos; float roll, pitch, heading, sqr_range, turn_rate, required_heading, delta_heading, current_velocity, new_velocity; raw = get_local_entity_data (en); // // abort if mobile is not moving (i.e. landed, or dead) // if (!get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING)) { return; } // // abort if the mobile has no PRIMARY guide (also stops ships from moving if just engaging) // guide = get_local_entity_primary_guide (en); if (!guide) { return; } current_waypoint = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT); ASSERT (current_waypoint); current_velocity = raw->vh.mob.velocity; // // GET WAYPOINT POSITION // ship_movement_get_waypoint_position (en, &wp_pos); wp_vec.x = wp_pos.x - raw->vh.mob.position.x; wp_vec.y = 0; wp_vec.z = wp_pos.z - raw->vh.mob.position.z; sqr_range = ((wp_vec.x * wp_vec.x) + (wp_vec.z * wp_vec.z)); #if DEBUG_MODULE create_vectored_debug_3d_object (&wp_pos, (vec3d *) &raw->vh.mob.attitude [1], OBJECT_3D_RED_ARROW, 0, 0.20); #endif // ???? if (fabs (sqr_range) < 1 * CENTIMETRE) { wp_vec.z = 0; wp_vec.y = 0; wp_vec.z = 1; } //////////////////////////////////////// // // angles // //////////////////////////////////////// // heading normalise_3d_vector (&wp_vec); heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude); required_heading = atan2 (wp_vec.x, wp_vec.z); { float angle, range, v; range = sqrt (sqr_range); v = sqrt (0.5 * range * vehicle_database [raw->vh.mob.sub_type].g_max); angle = ((raw->vh.mob.attitude [2][0] * wp_vec.x) + (raw->vh.mob.attitude [2][2] * wp_vec.z)); if (angle < 0.707) // 45 degs. { // wp behind ship #if DEBUG_MODULE debug_log ("SH_MOVE: ship cannot reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max); #endif new_velocity = bound (v, 0.0, get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY)); } else { #if DEBUG_MODULE debug_log ("SH_MOVE: ship can reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max); #endif new_velocity = get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY); } } turn_rate = 0.0; if (raw->vh.mob.velocity != 0.0) { turn_rate = fabs (vehicle_database [raw->vh.mob.sub_type].g_max / raw->vh.mob.velocity); } delta_heading = required_heading - heading; if (delta_heading <= -PI) { delta_heading += PI2; } if (delta_heading >= PI) { delta_heading -= PI2; } delta_heading = bound (delta_heading, -turn_rate, turn_rate); heading += delta_heading * get_entity_movement_delta_time (); pitch = 0.0; roll = 0.0; //////////////////////////////////////// // // attitude // //////////////////////////////////////// get_3d_transformation_matrix (raw->vh.mob.attitude, heading, rad (pitch), rad (roll)); //////////////////////////////////////// // // velocity // //////////////////////////////////////// { float maximum_acceleration, required_acceleration; required_acceleration = (new_velocity - raw->vh.mob.velocity); maximum_acceleration = get_local_entity_float_value (en, FLOAT_TYPE_MAX_ACCELERATION); raw->vh.mob.velocity += min (required_acceleration, maximum_acceleration) * get_entity_movement_delta_time (); } //////////////////////////////////////// // // position // //////////////////////////////////////// new_pos.x = raw->vh.mob.position.x + (raw->vh.mob.velocity * raw->vh.mob.zv.x * get_entity_movement_delta_time ()); new_pos.y = 0.0; new_pos.z = raw->vh.mob.position.z + (raw->vh.mob.velocity * raw->vh.mob.zv.z * get_entity_movement_delta_time ()); bound_position_to_map_volume (&new_pos); // // Calculate motion vector for view system // raw->vh.mob.motion_vector.x = (new_pos.x - raw->vh.mob.position.x) * get_one_over_delta_time (); raw->vh.mob.motion_vector.y = 0.0; raw->vh.mob.motion_vector.z = (new_pos.z - raw->vh.mob.position.z) * get_one_over_delta_time (); new_pos.y = 0.0; set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos); }
void draw_buffered_sorted_terrain_trees ( void ) { buffered_tree *tree; tree = buffered_sorted_tree_tail; while ( tree ) { // // Draw a tree object at ( x, y, z ) // terrain_3d_tree_object->vp.x = tree->position.x; terrain_3d_tree_object->vp.y = tree->position.y; terrain_3d_tree_object->vp.z = tree->position.z; terrain_3d_tree_object->relative_scale.x = tree->scale.x; terrain_3d_tree_object->relative_scale.y = tree->scale.y; terrain_3d_tree_object->relative_scale.z = tree->scale.z; get_3d_transformation_matrix ( terrain_3d_tree_object->vp.attitude, 0, 0, 0 ); set_object_3d_instance_relative_position ( terrain_3d_tree_object ); if ( get_object_3d_instance_visibility ( terrain_3d_tree_object ) != OBJECT_3D_NOT_VISIBLE ) { if ( terrain_3d_tree_object->rel_vp.z < 1024.0 ) { float alpha; int ialpha; current_tree_colour_red = tree->colour.red; current_tree_colour_green = tree->colour.green; current_tree_colour_blue = tree->colour.blue; current_tree_colour_red /= 255.0; current_tree_colour_green /= 255.0; current_tree_colour_blue /= 255.0; // // Set the alpha value here // if ( terrain_3d_tree_object->rel_vp.z > 512.0 ) { alpha = 1024.0 - terrain_3d_tree_object->rel_vp.z; alpha /= 512.0; convert_float_to_int ( ( alpha * 255 ), &ialpha ); current_tree_colour_alpha = ialpha; } else { current_tree_colour_alpha = 255; } current_tree_colour_alpha = 255; draw_3d_terrain_tree ( terrain_3d_tree_object ); } } tree = tree->pred; } }
void draw_kiowa_virtual_cockpit (void) { int draw_main_rotors; float theta; object_3d_instance *inst3d; object_3d_sub_object_search_data search; switch (get_view_mode ()) { case VIEW_MODE_VIRTUAL_COCKPIT_CREW: case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY: case VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY: { break; } default: { if (!get_global_draw_cockpit_graphics ()) { return; } break; } } // // lamps // draw_kiowa_virtual_cockpit_lamps (); // // crew animation // set_kiowa_crew_head_positions (); // // animate main rotors // if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_MAIN_ROTOR_DAMAGED)) { animate_damaged_helicopter_main_rotors (get_gunship_entity (), TRUE); } else { animate_helicopter_main_rotors (get_gunship_entity (), TRUE, FALSE); } inst3d = (object_3d_instance *) get_local_entity_ptr_value (get_gunship_entity (), PTR_TYPE_INSTANCE_3D_OBJECT); theta = get_rotation_angle_of_helicopter_main_rotors (inst3d); set_rotation_angle_of_helicopter_main_rotors (virtual_cockpit_inst3d, theta); animate_helicopter_virtual_cockpit_main_rotors (get_gunship_entity (), virtual_cockpit_inst3d); draw_main_rotors = TRUE; if (get_global_glass_cockpit ()) { draw_main_rotors = FALSE; } else { if (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW) { if (get_helicopter_main_rotors_blurred (get_gunship_entity ())) { if (!get_global_blurred_main_rotors_visible_from_cockpit ()) { draw_main_rotors = FALSE; } } } } search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_MAIN_ROTOR_SHAFT; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->visible_object = draw_main_rotors; } // // draw 3D scene // set_3d_view_distances (main_3d_env, 10.0, 0.1, 1.0, 0.0); realise_3d_clip_extents (main_3d_env); recalculate_3d_environment_settings (main_3d_env); clear_zbuffer_screen (); if (begin_3d_scene ()) { // // light direction is in world coordinates // light_3d_source *display_backlight, *cockpit_light; vec3d direction; matrix3x3 m1, m2; //VJ 050131 update on wideview mod, much better movement if (get_global_wide_cockpit () && ( get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY ) ) { get_kiowa_crew_viewpoint (); virtual_cockpit_inst3d->vp.x += wide_cockpit_position[wide_cockpit_nr].c.x; virtual_cockpit_inst3d->vp.y += wide_cockpit_position[wide_cockpit_nr].c.y; virtual_cockpit_inst3d->vp.z += wide_cockpit_position[wide_cockpit_nr].c.z; //ataribaby 27/12/2008 //virtual_cockpit_inst3d->vp.x += bound(current_flight_dynamics->model_acceleration_vector.x * ONE_OVER_G, -3.0, 3.0) * 0.025 * command_line_g_force_head_movment_modifier; //virtual_cockpit_inst3d->vp.y += bound(current_flight_dynamics->g_force.value - 1.0, -1.5, 5.0) * 0.025 * command_line_g_force_head_movment_modifier; if (wide_cockpit_nr == WIDEVIEW_KIOWA_PILOT) pilot_head_pitch_datum = rad ( wide_cockpit_position[wide_cockpit_nr].c.p ); if (wide_cockpit_nr == WIDEVIEW_KIOWA_COPILOT) co_pilot_head_pitch_datum = rad ( wide_cockpit_position[wide_cockpit_nr].c.p ); set_3d_view_distances (main_3d_env, 10.0, 0.1, 1.0, 0.0); } //ataribaby 27/12/2008 new head g-force movement and vibration from main rotor if (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_PILOT_LHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_PILOT_RHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_LHS_DISPLAY && get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CO_PILOT_RHS_DISPLAY) { if (get_time_acceleration() != TIME_ACCELERATION_PAUSE) { random_vibration_x = (frand1() * (current_flight_dynamics->main_rotor_rpm.value * 0.00002)) * command_line_g_force_head_movment_modifier; random_vibration_y = (frand1() * (current_flight_dynamics->main_rotor_rpm.value * 0.00002)) * command_line_g_force_head_movment_modifier; } x_head_g_movement = move_by_rate(x_head_g_movement, random_vibration_x + (bound(current_flight_dynamics->model_acceleration_vector.x * ONE_OVER_G, -3.0, 3.0) * 0.025 * command_line_g_force_head_movment_modifier), 0.05); y_head_g_movement = move_by_rate(y_head_g_movement, random_vibration_y + (bound(current_flight_dynamics->g_force.value - 1.0, -1.5, 5.0) * 0.025 * command_line_g_force_head_movment_modifier), 0.05); virtual_cockpit_inst3d->vp.x -= x_head_g_movement; //if (!current_flight_dynamics->auto_hover) // arneh - auto hover has some weird dynamics which cause lots of g-forces, so disable head movement when auto hover is enabled virtual_cockpit_inst3d->vp.y -= y_head_g_movement; } { // // ADI // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_ADI; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { float heading, pitch, roll; get_kiowa_virtual_cockpit_adi_angles (virtual_cockpit_inst3d->vp.attitude, &heading, &pitch, &roll); search.result_sub_object->relative_heading = -heading; search.result_sub_object->relative_pitch = pitch; search.result_sub_object->relative_roll = -roll; } // // ADI slip // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_ADI_SIDE_SLIP; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = get_kiowa_virtual_cockpit_adi_slip_indicator_needle_value (); } // // airspeed // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_AIRSPEED; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = get_kiowa_virtual_cockpit_airspeed_indicator_needle_value (); } // // altimeter // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_ALTIMETER; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = get_kiowa_virtual_cockpit_barometric_altimeter_needle_value (); } search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_COMPASS_HEADING_NULL; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_heading = -current_flight_dynamics->heading.value; } // // clock // { float hours, minutes, seconds; // // only read clock values if drawing virtual cockpit needles to prevent speeding up clock debug values // get_kiowa_virtual_cockpit_clock_hand_values (&hours, &minutes, &seconds); // // hour hand // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_CLOCK_HOUR_HAND; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = hours; } // // minute hand // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_CLOCK_MINUTE_HAND; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = minutes; } // // second hand // search.search_depth = 0; search.search_object = virtual_cockpit_inst3d; search.sub_object_index = OBJECT_3D_SUB_OBJECT_APACHE_VIRTUAL_COCKPIT_CLOCK_SECOND_HAND; if (find_object_3d_sub_object (&search) == SUB_OBJECT_SEARCH_RESULT_OBJECT_FOUND) { search.result_sub_object->relative_roll = seconds; } } } if (get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE) == DAY_SEGMENT_TYPE_DAY) { //////////////////////////////////////// // // DAY LIGHTING // //////////////////////////////////////// if (night_vision_system_active && (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW)) { // // active night vision system // get_3d_transformation_matrix (m1, rad (0.0), rad (135.0), rad (0.0)); multiply_matrix3x3_matrix3x3 (m2, m1, virtual_cockpit_inst3d->vp.attitude); direction.x = m2[2][0]; direction.y = m2[2][1]; direction.z = m2[2][2]; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.0000, 0.5000, 0.0000); insert_light_3d_source_into_3d_scene (cockpit_light); insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); end_3d_scene (); remove_light_3d_source_from_3d_scene (cockpit_light); destroy_light_3d_source (cockpit_light); } else { // // inactive night vision system // insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); print_edit_wide_cockpit (); end_3d_scene (); } } else { //////////////////////////////////////// // // NIGHT LIGHTING // //////////////////////////////////////// direction.x = virtual_cockpit_inst3d->vp.zv.x; direction.y = virtual_cockpit_inst3d->vp.zv.y; direction.z = virtual_cockpit_inst3d->vp.zv.z; display_backlight = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.0627, 0.2039, 0.0392); if (night_vision_system_active && (get_view_mode () != VIEW_MODE_VIRTUAL_COCKPIT_CREW)) { // // active night vision system // get_3d_transformation_matrix (m1, rad (0.0), rad (135.0), rad (0.0)); multiply_matrix3x3_matrix3x3 (m2, m1, virtual_cockpit_inst3d->vp.attitude); direction.x = m2[2][0]; direction.y = m2[2][1]; direction.z = m2[2][2]; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.0000, 0.5000, 0.0000); } else { // // inactive night vision system // direction.x = virtual_cockpit_inst3d->vp.yv.x; direction.y = virtual_cockpit_inst3d->vp.yv.y; direction.z = virtual_cockpit_inst3d->vp.yv.z; cockpit_light = create_light_3d_source (LIGHT_3D_TYPE_DIRECTIONAL, FALSE, &direction, 0, 0.0666, 0.1098, 0.6431); } insert_light_3d_source_into_3d_scene (display_backlight); insert_light_3d_source_into_3d_scene (cockpit_light); insert_relative_object_into_3d_scene (OBJECT_3D_DRAW_TYPE_ZBUFFERED_OBJECT, &virtual_cockpit_inst3d->vp.position, virtual_cockpit_inst3d); draw_3d_scene (); print_edit_wide_cockpit (); end_3d_scene (); remove_light_3d_source_from_3d_scene (display_backlight); remove_light_3d_source_from_3d_scene (cockpit_light); destroy_light_3d_source (display_backlight); destroy_light_3d_source (cockpit_light); } } move_edit_wide_cockpit (); #if RECOGNITION_GUIDE set_3d_view_distances (main_3d_env, 10000.0, 100.0, 1.0, 0.0); #else set_3d_view_distances (main_3d_env, 10000.0, 1.0, 1.0, 0.0); #endif realise_3d_clip_extents (main_3d_env); }
static void set_cockpit_lighting (matrix3x3 attitude) { matrix3x3 directional_light_rotation, result; vec3d directional_light_direction; light_colour ambient_light_colour, directional_light_colour; float directional_light_heading, directional_light_pitch, directional_light_roll; switch (get_local_entity_int_value (get_session_entity (), INT_TYPE_DAY_SEGMENT_TYPE)) { //////////////////////////////////////// case DAY_SEGMENT_TYPE_DAWN: //////////////////////////////////////// { ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 0.0; directional_light_colour.blue = 0.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-15.0); directional_light_roll = rad (0.0); break; } //////////////////////////////////////// case DAY_SEGMENT_TYPE_DAY: //////////////////////////////////////// { ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 1.0; directional_light_colour.blue = 1.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-40.0); directional_light_roll = rad (0.0); break; } //////////////////////////////////////// case DAY_SEGMENT_TYPE_DUSK: //////////////////////////////////////// { ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 0.0; directional_light_colour.blue = 0.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-15.0); directional_light_roll = rad (0.0); break; } //////////////////////////////////////// case DAY_SEGMENT_TYPE_NIGHT: //////////////////////////////////////// { ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 0.0; directional_light_colour.blue = 0.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-15.0); directional_light_roll = rad (0.0); break; } } #if DEMO_VERSION ambient_light_colour.red = 0.0; ambient_light_colour.green = 0.0; ambient_light_colour.blue = 0.0; directional_light_colour.red = 1.0; directional_light_colour.green = 1.0; directional_light_colour.blue = 1.0; directional_light_heading = rad (0.0); directional_light_pitch = rad (-40.0); directional_light_roll = rad (0.0); #endif set_3d_ambient_light (main_3d_single_light_env, &ambient_light_colour); get_3d_transformation_matrix (directional_light_rotation, directional_light_heading, directional_light_pitch, directional_light_roll); multiply_matrix3x3_matrix3x3 (result, directional_light_rotation, attitude); directional_light_direction.x = -result[2][0]; directional_light_direction.y = -result[2][1]; directional_light_direction.z = -result[2][2]; set_3d_main_light_source (main_3d_single_light_env, &directional_light_colour, &directional_light_direction, FALSE); }
void ship_vehicle_death_movement (entity *en) { ship_vehicle *raw; float speed, heading, pitch, roll; vec3d *pos, *velocity, new_pos; raw = get_local_entity_data (en); // // work out new position // velocity = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_MOTION_VECTOR); pos = get_local_entity_vec3d_ptr (en, VEC3D_TYPE_POSITION); new_pos.x = pos->x + (velocity->x * get_entity_movement_delta_time()); new_pos.y = pos->y + (velocity->y * get_entity_movement_delta_time()); new_pos.z = pos->z + (velocity->z * get_entity_movement_delta_time()); // // update velocity // velocity->x -= (velocity->x * 0.2 * get_entity_movement_delta_time ()); velocity->z -= (velocity->z * 0.2 * get_entity_movement_delta_time ()); velocity->y -= (SHIP_SINK_RATE * get_entity_movement_delta_time ()); speed = get_3d_vector_magnitude (velocity); set_local_entity_float_value (en, FLOAT_TYPE_VELOCITY, speed); // // update attitude // heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude); pitch = get_pitch_from_attitude_matrix (raw->vh.mob.attitude); pitch += (SHIP_SINK_DELTA_PITCH_RATE * get_entity_movement_delta_time()); roll = get_roll_from_attitude_matrix (raw->vh.mob.attitude); roll += (SHIP_SINK_DELTA_ROLL_RATE * get_entity_movement_delta_time()); get_3d_transformation_matrix (raw->vh.mob.attitude, heading, pitch, roll); // // set new position // set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos); clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_FIRE); clear_ship_fires (en, ENTITY_SUB_TYPE_EFFECT_SMOKE_LIST_EXPLOSION_TRAIL); // // remove ship if totally obscured (i.e. sunk) // if (get_comms_model () == COMMS_MODEL_SERVER) { struct OBJECT_3D_BOUNDS *bounding_box; vec3d d; float obscured_altitude; bounding_box = get_object_3d_bounding_box (get_local_entity_int_value (en, INT_TYPE_OBJECT_3D_SHAPE)); d.x = bounding_box->xmax - bounding_box->xmin; d.y = bounding_box->ymax - bounding_box->ymin; d.z = bounding_box->zmax - bounding_box->zmin; obscured_altitude = -(0.5 * get_3d_vector_magnitude (&d)); if (new_pos.y < obscured_altitude) { // // ship is no longer visible // destroy_client_server_entity_family (en); } } }
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); }
void draw_z_sorted_sub_object ( object_3d_sub_instance *obj, object_3d_database_entry *scene, viewpoint *parent_viewpoint, light_3d_source *parent_lights, vec3d *position ) { int count, num_faces, object_number, temp; object_3d_face *faces; vec3d *pos; matrix3x3 temp_matrix; vec3d scaled_relative_position, temp_scale, object_pos, object_unit_pos, sub_pos, *rel; light_3d_source *this_light, *prev_light, *light_ptr, *light; viewpoint vp; pos = &parent_viewpoint->position; rel = &obj->relative_position; object_number = scene->index; // // Calculate the object's position relative to the viewer. // // NOTE: // BECAUSE THIS USES THE ROTATION_3D MATRIX, IT TAKES INTO ACCOUNT THE PARENT'S SCALE // sub_pos.x = ( ( obj->relative_position.x * rotation_3d[0][0] ) + ( obj->relative_position.y * rotation_3d[1][0] ) + ( obj->relative_position.z * rotation_3d[2][0] ) ); sub_pos.y = ( ( obj->relative_position.x * rotation_3d[0][1] ) + ( obj->relative_position.y * rotation_3d[1][1] ) + ( obj->relative_position.z * rotation_3d[2][1] ) ); sub_pos.z = ( ( obj->relative_position.x * rotation_3d[0][2] ) + ( obj->relative_position.y * rotation_3d[1][2] ) + ( obj->relative_position.z * rotation_3d[2][2] ) ); sub_pos.x += position->x; sub_pos.y += position->y; sub_pos.z += position->z; // // Calculate the object's real world position // scaled_relative_position.x = rel->x * object_3d_scale.x; scaled_relative_position.y = rel->y * object_3d_scale.y; scaled_relative_position.z = rel->z * object_3d_scale.z; vp.x = ( ( scaled_relative_position.x * parent_viewpoint->xv.x ) + ( scaled_relative_position.y * parent_viewpoint->yv.x ) + ( scaled_relative_position.z * parent_viewpoint->zv.x ) ); vp.y = ( ( scaled_relative_position.x * parent_viewpoint->xv.y ) + ( scaled_relative_position.y * parent_viewpoint->yv.y ) + ( scaled_relative_position.z * parent_viewpoint->zv.y ) ); vp.z = ( ( scaled_relative_position.x * parent_viewpoint->xv.z ) + ( scaled_relative_position.y * parent_viewpoint->yv.z ) + ( scaled_relative_position.z * parent_viewpoint->zv.z ) ); vp.x += parent_viewpoint->x; vp.y += parent_viewpoint->y; vp.z += parent_viewpoint->z; // // From now on all sub objects are considered to be non-static - so the whole matrix has to be calculated. // { matrix3x3 relative_attitude; // // Store the rotation matrix, so when we go back to the parent, other sub objects can inherit the matrix safely // memcpy ( temp_matrix, rotation_3d, sizeof ( matrix3x3 ) ); // // Store the scaling before we trash it // memcpy ( &temp_scale, &object_3d_scale, sizeof ( vec3d ) ); // // Alter the scaling according to this object's scale // object_3d_scale.x *= obj->relative_scale.x; object_3d_scale.y *= obj->relative_scale.y; object_3d_scale.z *= obj->relative_scale.z; // // Compute the sub object's relative attitude matrix // get_3d_transformation_matrix ( relative_attitude, obj->relative_heading, -obj->relative_pitch, -obj->relative_roll ); // // Calculate the sub object's rotation matrix, to transform its 3d points relative to the parent object. // vp.xv.x = ( ( relative_attitude[0][0] * parent_viewpoint->xv.x ) + ( relative_attitude[0][1] * parent_viewpoint->yv.x ) + ( relative_attitude[0][2] * parent_viewpoint->zv.x ) ); vp.xv.y = ( ( relative_attitude[0][0] * parent_viewpoint->xv.y ) + ( relative_attitude[0][1] * parent_viewpoint->yv.y ) + ( relative_attitude[0][2] * parent_viewpoint->zv.y ) ); vp.xv.z = ( ( relative_attitude[0][0] * parent_viewpoint->xv.z ) + ( relative_attitude[0][1] * parent_viewpoint->yv.z ) + ( relative_attitude[0][2] * parent_viewpoint->zv.z ) ); vp.yv.x = ( ( relative_attitude[1][0] * parent_viewpoint->xv.x ) + ( relative_attitude[1][1] * parent_viewpoint->yv.x ) + ( relative_attitude[1][2] * parent_viewpoint->zv.x ) ); vp.yv.y = ( ( relative_attitude[1][0] * parent_viewpoint->xv.y ) + ( relative_attitude[1][1] * parent_viewpoint->yv.y ) + ( relative_attitude[1][2] * parent_viewpoint->zv.y ) ); vp.yv.z = ( ( relative_attitude[1][0] * parent_viewpoint->xv.z ) + ( relative_attitude[1][1] * parent_viewpoint->yv.z ) + ( relative_attitude[1][2] * parent_viewpoint->zv.z ) ); vp.zv.x = ( ( relative_attitude[2][0] * parent_viewpoint->xv.x ) + ( relative_attitude[2][1] * parent_viewpoint->yv.x ) + ( relative_attitude[2][2] * parent_viewpoint->zv.x ) ); vp.zv.y = ( ( relative_attitude[2][0] * parent_viewpoint->xv.y ) + ( relative_attitude[2][1] * parent_viewpoint->yv.y ) + ( relative_attitude[2][2] * parent_viewpoint->zv.y ) ); vp.zv.z = ( ( relative_attitude[2][0] * parent_viewpoint->xv.z ) + ( relative_attitude[2][1] * parent_viewpoint->yv.z ) + ( relative_attitude[2][2] * parent_viewpoint->zv.z ) ); // // Calculate the main matrix to transform the points to the screen // rotation_3d[0][0] = ( ( vp.xv.x * visual_3d_vp->xv.x ) + ( vp.xv.y * visual_3d_vp->xv.y ) + ( vp.xv.z * visual_3d_vp->xv.z ) ); rotation_3d[0][1] = ( ( vp.xv.x * visual_3d_vp->yv.x ) + ( vp.xv.y * visual_3d_vp->yv.y ) + ( vp.xv.z * visual_3d_vp->yv.z ) ); rotation_3d[0][2] = ( ( vp.xv.x * visual_3d_vp->zv.x ) + ( vp.xv.y * visual_3d_vp->zv.y ) + ( vp.xv.z * visual_3d_vp->zv.z ) ); rotation_3d[1][0] = ( ( vp.yv.x * visual_3d_vp->xv.x ) + ( vp.yv.y * visual_3d_vp->xv.y ) + ( vp.yv.z * visual_3d_vp->xv.z ) ); rotation_3d[1][1] = ( ( vp.yv.x * visual_3d_vp->yv.x ) + ( vp.yv.y * visual_3d_vp->yv.y ) + ( vp.yv.z * visual_3d_vp->yv.z ) ); rotation_3d[1][2] = ( ( vp.yv.x * visual_3d_vp->zv.x ) + ( vp.yv.y * visual_3d_vp->zv.y ) + ( vp.yv.z * visual_3d_vp->zv.z ) ); rotation_3d[2][0] = ( ( vp.zv.x * visual_3d_vp->xv.x ) + ( vp.zv.y * visual_3d_vp->xv.y ) + ( vp.zv.z * visual_3d_vp->xv.z ) ); rotation_3d[2][1] = ( ( vp.zv.x * visual_3d_vp->yv.x ) + ( vp.zv.y * visual_3d_vp->yv.y ) + ( vp.zv.z * visual_3d_vp->yv.z ) ); rotation_3d[2][2] = ( ( vp.zv.x * visual_3d_vp->zv.x ) + ( vp.zv.y * visual_3d_vp->zv.y ) + ( vp.zv.z * visual_3d_vp->zv.z ) ); // // Scale the rotation matrix // rotation_3d[0][0] *= object_3d_scale.x; rotation_3d[1][0] *= object_3d_scale.y; rotation_3d[2][0] *= object_3d_scale.z; rotation_3d[0][1] *= object_3d_scale.x; rotation_3d[1][1] *= object_3d_scale.y; rotation_3d[2][1] *= object_3d_scale.z; rotation_3d[0][2] *= object_3d_scale.x; rotation_3d[1][2] *= object_3d_scale.y; rotation_3d[2][2] *= object_3d_scale.z; // // Calculate the vector from the object to the viewpoint, in the object's view system // { float x, y, z; x = ( ( visual_3d_vp->x - vp.x ) * vp.xv.x ); x += ( ( visual_3d_vp->y - vp.y ) * vp.xv.y ); x += ( ( visual_3d_vp->z - vp.z ) * vp.xv.z ); y = ( ( visual_3d_vp->x - vp.x ) * vp.yv.x ); y += ( ( visual_3d_vp->y - vp.y ) * vp.yv.y ); y += ( ( visual_3d_vp->z - vp.z ) * vp.yv.z ); z = ( ( visual_3d_vp->x - vp.x ) * vp.zv.x ); z += ( ( visual_3d_vp->y - vp.y ) * vp.zv.y ); z += ( ( visual_3d_vp->z - vp.z ) * vp.zv.z ); object_pos.x = x; object_pos.y = y; object_pos.z = z; object_unit_pos.x = -object_pos.x; object_unit_pos.y = -object_pos.y; object_unit_pos.z = -object_pos.z; normalise_any_3d_vector ( &object_unit_pos ); } // // Rotate the light source vector to be relative to the object. // light_ptr = current_3d_lights; prev_light = NULL; light = NULL; if ( light_ptr ) { light = &light_3d_array[object_3d_light_3d_current_base]; while ( light_ptr ) { float lx, ly, lz; this_light = &light_3d_array[object_3d_light_3d_current_base]; object_3d_light_3d_current_base++; if ( prev_light ) { prev_light->succ = this_light; } this_light->pred = prev_light; this_light->succ = NULL; this_light->colour.red = light_ptr->colour.red; this_light->colour.green = light_ptr->colour.green; this_light->colour.blue = light_ptr->colour.blue; lx = ( light_ptr->lx * vp.attitude[0][0] ); lx += ( light_ptr->ly * vp.attitude[0][1] ); lx += ( light_ptr->lz * vp.attitude[0][2] ); ly = ( light_ptr->lx * vp.attitude[1][0] ); ly += ( light_ptr->ly * vp.attitude[1][1] ); ly += ( light_ptr->lz * vp.attitude[1][2] ); lz = ( light_ptr->lx * vp.attitude[2][0] ); lz += ( light_ptr->ly * vp.attitude[2][1] ); lz += ( light_ptr->lz * vp.attitude[2][2] ); this_light->lx = lx; this_light->ly = ly; this_light->lz = lz; // // Generate a highlight vector // this_light->highlight_vector.x = ( lx - object_unit_pos.x ); this_light->highlight_vector.y = ( ly - object_unit_pos.y ); this_light->highlight_vector.z = ( lz - object_unit_pos.z ); normalise_any_3d_vector ( &this_light->highlight_vector ); prev_light = this_light; light_ptr = light_ptr->succ; } } object_3d_object_base[object_3d_object_current_base].lights = light; } // // Set up this objects' object info structure // object_3d_object_base[object_3d_object_current_base].points_base = object_3d_points_current_base; object_3d_object_base[object_3d_object_current_base].object_number = object_number; current_object_3d_object_base = &object_3d_object_base[object_3d_object_current_base]; if ( objects_3d_data[object_number].number_of_points ) { // // Set up the face sorting variables // num_faces = objects_3d_data[object_number].number_of_faces; faces = objects_3d_data[object_number].faces; // // Insert this objects' faces into the sorted list. // { object_short_3d_point *object_points; point_3d_plain_reference *plain_point_list; face_surface_description *surfaces; int surface, surface_face_count, gouraud_point_index, texture_point_index, face_normal_index, point_reference_index; surface = 0; gouraud_point_index = 0; face_normal_index = 0; texture_point_index = 0; point_reference_index = 0; object_points = objects_3d_data[object_number].points; plain_point_list = NULL; //objects_3d_data[object_number].object_faces_point_plain_list; surfaces = objects_3d_data[object_number].surfaces; surface_face_count = surfaces[surface].number_of_faces; for ( count = num_faces; count > 0; count-- ) { if ( surface_face_count == 0 ) { surface++; surface_face_count = surfaces[surface].number_of_faces; } if ( faces->number_of_points > 2 ) { float tmp; vec3d true_depth_point; { point_3d_plain_reference *point_list; point_list = &plain_point_list[point_reference_index]; true_depth_point.x = object_points[point_list[0].point].x; true_depth_point.y = object_points[point_list[0].point].y; true_depth_point.z = object_points[point_list[0].point].z; true_depth_point.x += object_points[point_list[1].point].x; true_depth_point.y += object_points[point_list[1].point].y; true_depth_point.z += object_points[point_list[1].point].z; true_depth_point.x += object_points[point_list[2].point].x; true_depth_point.y += object_points[point_list[2].point].y; true_depth_point.z += object_points[point_list[2].point].z; point_list += 3; for ( temp = faces->number_of_points; temp > 3; temp-- ) { true_depth_point.x += object_points[point_list->point].x; true_depth_point.y += object_points[point_list->point].y; true_depth_point.z += object_points[point_list->point].z; point_list++; } tmp = true_depth_point.x * rotation_3d[0][2]; tmp += true_depth_point.y * rotation_3d[1][2]; tmp += true_depth_point.z * rotation_3d[2][2]; tmp *= one_over_table[faces->number_of_points]; tmp += position->z; // // Just use the binary representation of the float z value for z-sorting // insert_z_sorted_3d_face ( faces, *( ( int * ) &tmp ), surface, point_reference_index, gouraud_point_index, face_normal_index, texture_point_index, current_object_3d_object_base ); // insert_z_sorted_3d_face ( faces, *( ( int * ) &tmp ), surface, point_reference_index, gouraud_point_index, 0, texture_point_index, current_object_3d_object_base ); } } else { /* float tmp; point_3d_plain_reference *point_list; point_list = &plain_point_list[faces->point_reference_index]; depth_point = &object_points[point_list->point]; tmp = pos->z; point_list++; tmp += depth_point->x * rotation_3d[0][2]; tmp += depth_point->y * rotation_3d[1][2]; tmp += depth_point->z * rotation_3d[2][2]; // // Just use the binary representation of the float z value for z-sorting // insert_z_sorted_3d_face ( faces, * ( ( int * ) &tmp ), this_object_3d_info ); */ } point_reference_index += faces->number_of_points; if ( surfaces[surface].textured ) { texture_point_index += faces->number_of_points; } if ( surfaces[surface].smoothed ) { gouraud_point_index += faces->number_of_points; } if ( faces->number_of_points >= 3 ) { face_normal_index++; } faces++; surface_face_count--; } } // // Transform the object's shape data // illuminate_3d_object ( &objects_3d_data[object_number], &sub_pos, object_3d_object_base[object_3d_object_current_base].lights, NULL, object_3d_points_current_base ); transform_3d_object ( &objects_3d_data[object_number], &sub_pos, object_3d_object_base[object_3d_object_current_base].lights, NULL, object_3d_points_current_base ); } // // Set the points base index to after the end of the object. // object_3d_object_current_base ++; object_3d_points_current_base += objects_3d_data[object_number].number_of_points; // // Recurse down any sub objects // if ( scene->number_of_sub_objects != 0 ) { for ( count = ( scene->number_of_sub_objects -1 ); count >= 0; count-- ) { if ( obj->sub_objects[count].visible_object ) { draw_z_sorted_sub_object ( &obj->sub_objects[count], &scene->sub_objects[count], &vp, current_object_3d_object_base->lights, &sub_pos ); } } } // // Restore the object rotation matrix // memcpy ( rotation_3d, temp_matrix, sizeof ( matrix3x3 ) ); memcpy ( &object_3d_scale, &temp_scale, sizeof ( vec3d ) ); }
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 recurse_initialise_sub_scene_bounding_box ( object_3d_database_entry *sub_object ) { vec3d old_scene_position, relative_position; matrix3x3 matrix, new_rotation, old_scene_rotation; int old_contributes_to_collision, count; // // Save state variables // old_scene_position = scene_position; old_contributes_to_collision = contributes_to_collision; memcpy ( old_scene_rotation, scene_rotation, sizeof ( matrix3x3 ) ); // // Set the collision flag // if ( !sub_object->collision_contribution ) { contributes_to_collision = FALSE; } // // Figure out new position // relative_position.x = ( ( sub_object->keyframes[0].x * scene_rotation[0][0] ) + ( sub_object->keyframes[0].y * scene_rotation[1][0] ) + ( sub_object->keyframes[0].z * scene_rotation[2][0] ) ); relative_position.y = ( ( sub_object->keyframes[0].x * scene_rotation[0][1] ) + ( sub_object->keyframes[0].y * scene_rotation[1][1] ) + ( sub_object->keyframes[0].z * scene_rotation[2][1] ) ); relative_position.z = ( ( sub_object->keyframes[0].x * scene_rotation[0][2] ) + ( sub_object->keyframes[0].y * scene_rotation[1][2] ) + ( sub_object->keyframes[0].z * scene_rotation[2][2] ) ); scene_position.x += relative_position.x; scene_position.y += relative_position.y; scene_position.z += relative_position.z; get_3d_transformation_matrix ( matrix, sub_object->keyframes[0].heading, -sub_object->keyframes[0].pitch, -sub_object->keyframes[0].roll ); new_rotation[0][0] = ( ( matrix[0][0] * scene_rotation[0][0] ) + ( matrix[0][1] * scene_rotation[1][0] ) + ( matrix[0][2] * scene_rotation[2][0] ) ); new_rotation[0][1] = ( ( matrix[0][0] * scene_rotation[0][1] ) + ( matrix[0][1] * scene_rotation[1][1] ) + ( matrix[0][2] * scene_rotation[2][1] ) ); new_rotation[0][2] = ( ( matrix[0][0] * scene_rotation[0][2] ) + ( matrix[0][1] * scene_rotation[1][2] ) + ( matrix[0][2] * scene_rotation[2][2] ) ); new_rotation[1][0] = ( ( matrix[1][0] * scene_rotation[0][0] ) + ( matrix[1][1] * scene_rotation[1][0] ) + ( matrix[1][2] * scene_rotation[2][0] ) ); new_rotation[1][1] = ( ( matrix[1][0] * scene_rotation[0][1] ) + ( matrix[1][1] * scene_rotation[1][1] ) + ( matrix[1][2] * scene_rotation[2][1] ) ); new_rotation[1][2] = ( ( matrix[1][0] * scene_rotation[0][2] ) + ( matrix[1][1] * scene_rotation[1][2] ) + ( matrix[1][2] * scene_rotation[2][2] ) ); new_rotation[2][0] = ( ( matrix[2][0] * scene_rotation[0][0] ) + ( matrix[2][1] * scene_rotation[1][0] ) + ( matrix[2][2] * scene_rotation[2][0] ) ); new_rotation[2][1] = ( ( matrix[2][0] * scene_rotation[0][1] ) + ( matrix[2][1] * scene_rotation[1][1] ) + ( matrix[2][2] * scene_rotation[2][1] ) ); new_rotation[2][2] = ( ( matrix[2][0] * scene_rotation[0][2] ) + ( matrix[2][1] * scene_rotation[1][2] ) + ( matrix[2][2] * scene_rotation[2][2] ) ); memcpy ( scene_rotation, new_rotation, sizeof ( matrix3x3 ) ); scene_rotation[0][0] *= sub_object->keyframes[0].scale_x; scene_rotation[1][0] *= sub_object->keyframes[0].scale_y; scene_rotation[2][0] *= sub_object->keyframes[0].scale_z; scene_rotation[0][1] *= sub_object->keyframes[0].scale_x; scene_rotation[1][1] *= sub_object->keyframes[0].scale_y; scene_rotation[2][1] *= sub_object->keyframes[0].scale_z; scene_rotation[0][2] *= sub_object->keyframes[0].scale_x; scene_rotation[1][2] *= sub_object->keyframes[0].scale_y; scene_rotation[2][2] *= sub_object->keyframes[0].scale_z; // // Compute the bounding boxes // rotate_sub_scene_boundaries ( &rotated_bounds, &objects_3d_data[ sub_object->index ].bounding_box ); rotate_sub_scene_boundaries ( &rotated_bounds2, &objects_3d_data[ sub_object->index ].bounding_box2 ); rotated_bounds.xmin += scene_position.x; rotated_bounds.ymin += scene_position.y; rotated_bounds.zmin += scene_position.z; rotated_bounds.xmax += scene_position.x; rotated_bounds.ymax += scene_position.y; rotated_bounds.zmax += scene_position.z; scene_bounds.xmin = min ( scene_bounds.xmin, rotated_bounds.xmin ); scene_bounds.ymin = min ( scene_bounds.ymin, rotated_bounds.ymin ); scene_bounds.zmin = min ( scene_bounds.zmin, rotated_bounds.zmin ); scene_bounds.xmax = max ( scene_bounds.xmax, rotated_bounds.xmax ); scene_bounds.ymax = max ( scene_bounds.ymax, rotated_bounds.ymax ); scene_bounds.zmax = max ( scene_bounds.zmax, rotated_bounds.zmax ); if ( ( ( rotated_bounds2.xmax - rotated_bounds2.xmin ) != 0 ) || ( ( rotated_bounds2.ymax - rotated_bounds2.ymin ) != 0 ) || ( ( rotated_bounds2.zmax - rotated_bounds2.zmin ) != 0 ) ) { rotated_bounds2.xmin += scene_position.x; rotated_bounds2.ymin += scene_position.y; rotated_bounds2.zmin += scene_position.z; rotated_bounds2.xmax += scene_position.x; rotated_bounds2.ymax += scene_position.y; rotated_bounds2.zmax += scene_position.z; if ( contributes_to_collision ) { scene_bounds2.xmin = min ( scene_bounds2.xmin, rotated_bounds2.xmin ); scene_bounds2.ymin = min ( scene_bounds2.ymin, rotated_bounds2.ymin ); scene_bounds2.zmin = min ( scene_bounds2.zmin, rotated_bounds2.zmin ); scene_bounds2.xmax = max ( scene_bounds2.xmax, rotated_bounds2.xmax ); scene_bounds2.ymax = max ( scene_bounds2.ymax, rotated_bounds2.ymax ); scene_bounds2.zmax = max ( scene_bounds2.zmax, rotated_bounds2.zmax ); } } // // Calculate sub objects // for ( count = 0; count < sub_object->number_of_sub_objects; count++ ) { recurse_initialise_sub_scene_bounding_box ( &sub_object->sub_objects[count] ); } // // Restore the original position & rotation // scene_position = old_scene_position; memcpy ( scene_rotation, old_scene_rotation, sizeof ( matrix3x3 ) ); contributes_to_collision = old_contributes_to_collision; }
void draw_3d_sun ( void ) { vertex *sun_polygon, sun_quad[4]; matrix3x3 sun_matrix; float flare_intensity; int sun_red, sun_green, sun_blue; real_colour colour, specular; // // Draw the main sun object // get_3d_transformation_matrix ( sun_matrix, sun_3d_heading, sun_3d_pitch, 0 ); sun_polygon = construct_sun_polygon ( sun_matrix, sun_quad, 32000 * sun_3d_scale, 32000 * sun_3d_scale, 100000 ); specular.colour = 0; if ( sun_polygon ) { asm_convert_float_to_int ( ( sun_3d_colour.red * 255 ), &sun_red ); asm_convert_float_to_int ( ( sun_3d_colour.green * 255 ), &sun_green ); asm_convert_float_to_int ( ( sun_3d_colour.blue * 255 ), &sun_blue ); colour.red = sun_red; colour.green = sun_green; colour.blue = sun_blue; set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS ); set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE ); suspend_d3d_fog (); set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT ); set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); set_d3d_texture ( 0, load_hardware_texture_map ( sun_texture ) ); draw_wbuffered_flat_shaded_textured_polygon ( sun_polygon, colour, specular ); } // // Now render the flare around the sun, if it is indeed there. // // // Calculate the intensity of the sun flare // flare_intensity = ( ( sun_matrix[2][0] * visual_3d_vp->zv.x ) + ( sun_matrix[2][1] * visual_3d_vp->zv.y ) + ( sun_matrix[2][2] * visual_3d_vp->zv.z ) ); flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= flare_intensity; flare_intensity *= sun_3d_intensity; flare_intensity *= sun_3d_intensity; flare_intensity *= sun_3d_intensity; flare_intensity *= 255; sun_polygon = construct_sun_polygon ( sun_matrix, sun_quad, 144000, 69750, 100000 ); if ( sun_polygon ) { asm_convert_float_to_int ( ( ( 74.0 / 255.0 ) * flare_intensity ), &sun_red ); asm_convert_float_to_int ( ( ( 177.0 / 255.0 ) * flare_intensity ), &sun_green ); asm_convert_float_to_int ( ( ( 248.0 / 255.0 ) * flare_intensity ), &sun_blue ); // asm_convert_float_to_int ( ( sun_3d_colour.red * flare_intensity ), &sun_red ); // asm_convert_float_to_int ( ( sun_3d_colour.green * flare_intensity ), &sun_green ); // asm_convert_float_to_int ( ( sun_3d_colour.blue * flare_intensity ), &sun_blue ); colour.red = sun_red; colour.green = sun_green; colour.blue = sun_blue; set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS ); set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE ); suspend_d3d_fog (); set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT ); set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP ); set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); set_d3d_texture ( 0, load_hardware_texture_map ( sun_flare_texture ) ); draw_wbuffered_flat_shaded_textured_polygon ( sun_polygon, colour, specular ); } set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_DISABLE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); set_d3d_texture ( 0, NULL ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); reinstate_d3d_fog (); set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, zbuffer_default_comparison ); set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, TRUE ); }
void update_vector_altitude_dynamics (void) { static float last_ground_height = 0; matrix3x3 attitude; float heading, pitch, roll, ground_height, centre_of_gravity_to_ground_distance; vec3d position, *face_normal; centre_of_gravity_to_ground_distance = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_CENTRE_OF_GRAVITY_TO_GROUND_DISTANCE); get_local_entity_attitude_matrix (get_gunship_entity (), attitude); ground_height = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_TERRAIN_ELEVATION); // // debug // if ((ground_height < -1000) || (ground_height > 32000)) { debug_log ("!!!!!!!!!!!!!! GROUND HEIGHT %f", ground_height); ground_height = last_ground_height; } // // end // last_ground_height = ground_height; current_flight_dynamics->altitude.value = current_flight_dynamics->position.y; current_flight_dynamics->altitude.min = ground_height; switch (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE)) { case OPERATIONAL_STATE_LANDED: { if (current_flight_dynamics->world_velocity_y.value > 0.0) { #if DEBUG_DYNAMICS debug_log ("VECTOR DYN: takeoff !"); #endif set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_NAVIGATING); delete_local_entity_from_parents_child_list (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT); transmit_entity_comms_message (ENTITY_COMMS_MOBILE_TAKEOFF, get_gunship_entity ()); } else { entity *wp; vec3d wp_pos; wp = get_local_entity_parent (get_gunship_entity (), LIST_TYPE_CURRENT_WAYPOINT); if (wp) { get_local_waypoint_formation_position (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_FORMATION_POSITION), wp, &wp_pos); ground_height = wp_pos.y; } current_flight_dynamics->world_velocity_y.value = max (current_flight_dynamics->world_velocity_y.value, 0.0); current_flight_dynamics->velocity_y.value = max (current_flight_dynamics->velocity_y.value, 0.0); memset (¤t_flight_dynamics->world_motion_vector, 0, sizeof (vec3d)); current_flight_dynamics->velocity_x.value = bound (current_flight_dynamics->velocity_x.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50)); current_flight_dynamics->velocity_y.value = 0; current_flight_dynamics->velocity_z.value = bound (current_flight_dynamics->velocity_z.value, knots_to_metres_per_second (-10), knots_to_metres_per_second (50)); current_flight_dynamics->position.y = ground_height + centre_of_gravity_to_ground_distance; current_flight_dynamics->altitude.value = ground_height + centre_of_gravity_to_ground_distance; heading = get_heading_from_attitude_matrix (attitude); //get_3d_terrain_face_normal (&n, current_flight_dynamics->position.x, current_flight_dynamics->position.z); face_normal = get_local_entity_ptr_value (get_gunship_entity (), PTR_TYPE_TERRAIN_FACE_NORMAL); get_3d_transformation_matrix_from_face_normal_and_heading (attitude, face_normal, heading); pitch = get_pitch_from_attitude_matrix (attitude); pitch += rad (aircraft_database [ENTITY_SUB_TYPE_AIRCRAFT_AH64D_APACHE_LONGBOW].fuselage_angle); roll = get_roll_from_attitude_matrix (attitude); get_3d_transformation_matrix (attitude, heading, pitch, roll); 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); set_local_entity_attitude_matrix (get_gunship_entity (), attitude); } break; } default: { if (current_flight_dynamics->world_velocity_y.value < 0.0) { if (current_flight_dynamics->altitude.value < current_flight_dynamics->altitude.min + centre_of_gravity_to_ground_distance) { if (get_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE) != OPERATIONAL_STATE_LANDED) { // // need to find what wp the user is trying to land on .... // //entity //*wp; #if DEBUG_DYNAMICS debug_log ("VECTOR DYN: landed !"); #endif set_local_entity_int_value (get_gunship_entity (), INT_TYPE_OPERATIONAL_STATE, OPERATIONAL_STATE_LANDED); //transmit_entity_comms_message (ENTITY_COMMS_MOBILE_LAND, get_gunship_entity (), wp); } } } break; } } current_flight_dynamics->altitude.value = bound ( current_flight_dynamics->altitude.value, current_flight_dynamics->altitude.min, current_flight_dynamics->altitude.max); }
void scan_3d_clouds ( void ) { int visual_sector_x, visual_sector_z, current_sector_x, current_sector_z, minimum_sector_x, minimum_sector_z, maximum_sector_x, maximum_sector_z; float initial_sector_x_offset, initial_sector_z_offset, current_sector_x_offset, current_sector_z_offset; weathermodes current_weathermode, target_weathermode; matrix3x3 cloud_matrix; // // Get the vector pointing to the colour blend // get_3d_transformation_matrix ( cloud_matrix, active_3d_environment->cloud_light.heading, active_3d_environment->cloud_light.pitch, 0 ); cloud_colour_blend_vector.x = cloud_matrix[2][0]; cloud_colour_blend_vector.y = 0; cloud_colour_blend_vector.z = cloud_matrix[2][2]; normalise_3d_vector ( &cloud_colour_blend_vector ); // // Adjust the cloud blend factor // if ( ( visual_3d_vp->y > ( cloud_3d_base_height - 100 ) ) && ( visual_3d_vp->y < ( cloud_3d_base_height + 100 ) ) ) { float blend; blend = ( ( fabs ( visual_3d_vp->y - cloud_3d_base_height ) ) / 100 ); if ( blend > 1 ) { blend = 1; } cloud_3d_adjusted_blend_factor = cloud_3d_blend_factor * blend; } else { cloud_3d_adjusted_blend_factor = cloud_3d_blend_factor; } // // Choose the two textures to be blending inbetween // current_weathermode = get_3d_weathermode ( active_3d_environment ); target_weathermode = get_3d_target_weathermode ( active_3d_environment ); if ( !cloud_textures[current_weathermode].valid ) { debug_fatal ( "Unable to draw clouds - no texture set for current weathermode: %d", current_weathermode ); } if ( !cloud_textures[target_weathermode].texture_index ) { debug_fatal ( "Unable to draw clouds - no texture set for target weathermode: %d", target_weathermode ); } cloud_weather_blend_factor = get_3d_target_weathermode_transitional_status ( active_3d_environment ); cloud_weather_one_minus_blend_factor = 1.0 - cloud_weather_blend_factor; if ( current_weathermode != target_weathermode ) { if ( cloud_weather_blend_factor == 1 ) { current_weather_texture = system_textures[ cloud_textures[target_weathermode].texture_index ]; target_weather_texture = NULL; cloud_weather_blend_factor = 0; cloud_weather_one_minus_blend_factor = 1.0; } else if ( cloud_weather_blend_factor == 0 ) { current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ]; target_weather_texture = NULL; cloud_weather_blend_factor = 0; cloud_weather_one_minus_blend_factor = 1.0; } else { current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ]; target_weather_texture = system_textures[ cloud_textures[target_weathermode].texture_index ]; } } else { current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ]; target_weather_texture = NULL; cloud_weather_blend_factor = 0; cloud_weather_one_minus_blend_factor = 1.0; } // // Now bias the blend factors, to take into account the transparency of each texture // cloud_weather_one_minus_blend_factor *= active_3d_environment->cloud_light.light_colour.alpha; cloud_weather_blend_factor *= active_3d_environment->cloud_light.light_colour.alpha; // // Get the sector the visual_3d_vp is currently in // get_cloud_3d_sector ( visual_3d_vp->x, visual_3d_vp->z, &visual_sector_x, &visual_sector_z ); minimum_sector_x = visual_sector_x - cloud_3d_sector_scan_radius; minimum_sector_z = visual_sector_z - cloud_3d_sector_scan_radius; maximum_sector_x = visual_sector_x + cloud_3d_sector_scan_radius; maximum_sector_z = visual_sector_z + cloud_3d_sector_scan_radius; initial_sector_x_offset = minimum_sector_x * CLOUD_3D_SECTOR_SIDE_LENGTH; initial_sector_z_offset = minimum_sector_z * CLOUD_3D_SECTOR_SIDE_LENGTH; current_sector_z_offset = initial_sector_z_offset; for ( current_sector_z = minimum_sector_z; current_sector_z < maximum_sector_z; current_sector_z++ ) { current_sector_x_offset = initial_sector_x_offset; for ( current_sector_x = minimum_sector_x; current_sector_x < maximum_sector_x; current_sector_x++ ) { vec3d sector_centre, sector_relative_centre; scene_slot_drawing_list *sorting_slot; sector_centre.x = current_sector_x_offset + ( CLOUD_3D_SECTOR_SIDE_LENGTH / 2 ); sector_centre.y = cloud_3d_base_height; sector_centre.z = current_sector_z_offset + ( CLOUD_3D_SECTOR_SIDE_LENGTH / 2 ); sector_relative_centre.z = ( ( sector_centre.x - visual_3d_vp->x ) * visual_3d_vp->zv.x + ( sector_centre.y - visual_3d_vp->y ) * visual_3d_vp->zv.y + ( sector_centre.z - visual_3d_vp->z ) * visual_3d_vp->zv.z ); if ( ( sector_relative_centre.z + ( CLOUD_3D_SECTOR_SIDE_LENGTH * 1.4142 ) ) < clip_hither ) { // // Cloud sector is totally behind the view // } else { unsigned int outcode, outcode1, outcode2; float x_minimum_offset, x_maximum_offset, z_minimum_offset, z_maximum_offset; x_minimum_offset = current_sector_x_offset; x_maximum_offset = current_sector_x_offset + CLOUD_3D_SECTOR_SIDE_LENGTH; z_minimum_offset = current_sector_z_offset; z_maximum_offset = current_sector_z_offset + CLOUD_3D_SECTOR_SIDE_LENGTH; outcode = get_3d_point_outcodes ( x_minimum_offset, cloud_3d_base_height, z_minimum_offset ); outcode1 = outcode; outcode2 = outcode; outcode = get_3d_point_outcodes ( x_minimum_offset, cloud_3d_base_height, z_maximum_offset ); outcode1 |= outcode; outcode2 &= outcode; outcode = get_3d_point_outcodes ( x_maximum_offset, cloud_3d_base_height, z_minimum_offset ); outcode1 |= outcode; outcode2 &= outcode; outcode = get_3d_point_outcodes ( x_maximum_offset, cloud_3d_base_height, z_maximum_offset ); outcode1 |= outcode; outcode2 &= outcode; // if ( outcode2 == 0 ) { sorting_slot = get_3d_scene_slot (); if ( sorting_slot ) { sorting_slot->type = OBJECT_3D_DRAW_TYPE_CLOUD_SECTOR; // // Use the integer representation of the float value // sector_relative_centre.z += 32768; sorting_slot->z = *( ( int * ) §or_relative_centre.z ); sorting_slot->cloud_sector.x = current_sector_x; sorting_slot->cloud_sector.z = current_sector_z; insert_middle_scene_slot_into_3d_scene ( sorting_slot ); } else { debug_log ( "Run out of object slots!" ); } } } current_sector_x_offset += CLOUD_3D_SECTOR_SIDE_LENGTH; } current_sector_z_offset += CLOUD_3D_SECTOR_SIDE_LENGTH; } }
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_satellite_camera (camera *raw) { float heading, pitch; /*vec3d pos;*/ entity *en; ASSERT (raw); en = raw->external_view_entity; if (adjust_view_left_key || joystick_pov_left) { raw->position.x -= 1; } else if (adjust_view_right_key || joystick_pov_right) { raw->position.x += 1; } if (adjust_view_up_key || joystick_pov_up) { raw->position.z += 1; } else if (adjust_view_down_key || joystick_pov_down) { raw->position.z -= 1; } if (adjust_view_zoom_out_key) { raw->position.y += 1000; raw->position.y = min (5000 + raw->motion_vector.y, raw->position.y); adjust_view_zoom_out_key = FALSE; } else if (adjust_view_zoom_in_key) { raw->position.y -= 1000; raw->position.y = max (1000 + raw->motion_vector.y, raw->position.y); adjust_view_zoom_in_key = FALSE; } heading = 0.1; pitch = -1.5; /*switch (get_local_entity_type (en)) { case ENTITY_TYPE_HELICOPTER: case ENTITY_TYPE_FIXED_WING: case ENTITY_TYPE_ROUTED_VEHICLE: case ENTITY_TYPE_SHIP_VEHICLE: case ENTITY_TYPE_ANTI_AIRCRAFT: case ENTITY_TYPE_GROUP: { get_local_entity_target_point (en, &pos); raw->position.x = pos.x + v.x; raw->position.z = pos.z + v.z; break; } }*/ get_3d_transformation_matrix (raw->attitude, heading, pitch, 0.0); }