void update_session_sound_effects (entity *en) { session *raw; entity *spec; vec3d *camera_pos; weathermodes current_weather_mode, target_weather_mode; float alt, trans, value, light_wind_sound_level, heavy_wind_sound_level, rain_sound_levels [WEATHERMODE_LAST]; ASSERT (en); raw = (session *) get_local_entity_data (en); if (in_cockpit) { camera_pos = get_local_entity_vec3d_ptr (get_gunship_entity (), VEC3D_TYPE_POSITION); alt = get_local_entity_float_value (get_gunship_entity (), FLOAT_TYPE_RADAR_ALTITUDE); } else { camera_pos = get_local_entity_vec3d_ptr (get_camera_entity (), VEC3D_TYPE_POSITION); alt = get_local_entity_float_value (get_camera_entity (), FLOAT_TYPE_RADAR_ALTITUDE); } // // rain // memset (rain_sound_levels, 0, sizeof (float) * WEATHERMODE_LAST); if (camera_pos->y < get_cloud_3d_base_height ()) { if ((!in_cockpit) && (alt >= SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)) { // // rain should only make a sound when it hits either the cockpit, or the ground // } else { get_session_weather_at_point (camera_pos, ¤t_weather_mode, &target_weather_mode, &trans); if (target_weather_mode == current_weather_mode) { rain_sound_levels [target_weather_mode] = 1.0; rain_sound_levels [current_weather_mode] = 1.0; } else { rain_sound_levels [target_weather_mode] = trans; rain_sound_levels [current_weather_mode] = (1.0 - trans); } if (!in_cockpit) { rain_sound_levels [target_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)); rain_sound_levels [current_weather_mode] *= (1.0 - (alt / SESSION_RAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE)); } } } // // wind // { float r, wind_speed; wind_speed = get_session_wind_velocity_at_point (camera_pos, NULL); if (wind_speed <= raw->wind_minimum_speed) { r = 0.0; } else if (wind_speed >= raw->wind_maximum_speed) { r = 1.0; } else { r = (wind_speed - raw->wind_minimum_speed) / (raw->wind_maximum_speed - raw->wind_minimum_speed); } ASSERT ((r >= 0.0) && (r <= 1.0)); if (r == 0.0) { light_wind_sound_level = 0.0; heavy_wind_sound_level = 0.0; } else if (r < 0.5) { light_wind_sound_level = r * 2.0; heavy_wind_sound_level = 0.0; } else { light_wind_sound_level = 1.0 - ((r - 0.5) * 2.0); heavy_wind_sound_level = (r - 0.5) * 2.0; } } // // terrain // { float xpos, zpos; xpos = bound (camera_pos->x, MIN_MAP_X, MAX_MAP_X); zpos = bound (camera_pos->z, MIN_MAP_Z, MAX_MAP_Z); get_terrain_3d_types_in_sector (xpos, zpos); } // // set new values // spec = get_local_entity_first_child (en, LIST_TYPE_SPECIAL_EFFECT); while (spec) { switch (get_local_entity_int_value (spec, INT_TYPE_ENTITY_SUB_TYPE)) { case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_RAIN: { set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_LIGHT_RAIN]); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_RAIN: { set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, rain_sound_levels [WEATHERMODE_HEAVY_RAIN]); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_LIGHT_WIND: { set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, light_wind_sound_level); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_HEAVY_WIND: { set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, heavy_wind_sound_level); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_SEA: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_SEA]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMBIENT_JUNGLE: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_FOREST_TOP]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB1: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_RIVER]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB2: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_RESERVOIR]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB3: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND1]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } case ENTITY_SUB_TYPE_EFFECT_SOUND_AMB4: { if (alt >= SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE) { value = 0.0; } else { value = get_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION); if (terrain_types_in_sector [TERRAIN_TYPE_ALTERED_LAND2]) { value += (0.5 * get_delta_time ()); } else { value -= (0.5 * get_delta_time ()); } value = bound (value, 0.0, 0.3); value *= bound(1.0 - (alt / SESSION_TERRAIN_SOUND_EFFECT_ZERO_VOLUME_ALTITUDE), 0.0, 1.0); if (in_cockpit) { value *= 0.75; } } set_local_entity_float_value (spec, FLOAT_TYPE_AMPLIFICATION, value); break; } } spec = get_local_entity_child_succ (spec, LIST_TYPE_SPECIAL_EFFECT); } }
void update_3d_rain ( env_3d *env, float time, matrix3x3 view_attitude ) { int start_raindrop_number, end_raindrop_number, total_raindrop_number, start_snowdrop_number, end_snowdrop_number, total_snowdrop_number, creation_allowed, count; float displacement_magnitude, snow_displacement_magnitude, snow_fall_displacement, weather_t; vec3d distance_moved, rain_displacement, snow_drift_displacement, rain_streak_displacement, creation_vector; // // Calculate how many rain drops we should have. This is a linear scale, from 0, to TOTAL_3D_RAINDROPS. // DRY = 0 // LIGHT_RAIN = TOTAL_3D_RAINDROPS / 2 // HEAVY_RAIN = TOTAL_3D_RAINDROPS // if ( visual_3d_vp ) { if ( visual_3d_vp->position.y > get_cloud_3d_base_height () ) { creation_allowed = FALSE; } else { creation_allowed = TRUE; } } else { creation_allowed = FALSE; } start_raindrop_number = number_of_weather_particles_allowed[env->weathermode].number_of_raindrops; start_snowdrop_number = number_of_weather_particles_allowed[env->weathermode].number_of_snowdrops; end_raindrop_number = number_of_weather_particles_allowed[env->target_weathermode].number_of_raindrops; end_snowdrop_number = number_of_weather_particles_allowed[env->target_weathermode].number_of_snowdrops; weather_t = env->weather_targetdistance; if ( weather_t == 0 ) { total_raindrop_number = start_raindrop_number; total_snowdrop_number = start_snowdrop_number; } else if ( weather_t == 1 ) { total_raindrop_number = end_raindrop_number; total_snowdrop_number = end_snowdrop_number; } else { total_raindrop_number = start_raindrop_number + ( ( ( float ) ( end_raindrop_number - start_raindrop_number ) ) * weather_t ); total_snowdrop_number = start_snowdrop_number + ( ( ( float ) ( end_snowdrop_number - start_snowdrop_number ) ) * weather_t ); } // // Special snow flag stuff // if ( special_snow_flag ) { /* if ( visual_3d_vp ) { int x, z; int near_snow; float old_rain_total; near_snow = FALSE; for ( z = -1; z <= 1; z++ ) { for ( x = -1; x <= 1; x++ ) { float x_pos, z_pos; x_pos = visual_3d_vp->x + x * TERRAIN_3D_SECTOR_SIDE_LENGTH; z_pos = visual_3d_vp->z + z * TERRAIN_3D_SECTOR_SIDE_LENGTH; x_pos = bound ( x_pos, terrain_3d_min_map_x, terrain_3d_max_map_x ); z_pos = bound ( z_pos, terrain_3d_min_map_z, terrain_3d_max_map_z ); get_terrain_3d_types_in_sector ( x_pos, z_pos ); if ( terrain_types_in_sector[TERRAIN_TYPE_ALTERED_LAND3] ) { near_snow = TRUE; } } } if ( near_snow ) { old_rain_total = total_raindrop_number; total_raindrop_number = old_rain_total * 0.0; total_snowdrop_number = old_rain_total * 1.0; } } */ } // // // rain_3d_delta_time = time - time_rain_last_updated; time_rain_last_updated = time; // // Calculate the distance moved by each raindrop. // distance_moved.x = rain_3d_wind_direction.x * rain_3d_wind_speed * rain_3d_delta_time; distance_moved.y = rain_3d_wind_direction.y * rain_3d_wind_speed * rain_3d_delta_time; distance_moved.z = rain_3d_wind_direction.z * rain_3d_wind_speed * rain_3d_delta_time; rain_displacement.x = distance_moved.x; rain_displacement.y = distance_moved.y + ( rain_3d_speed * rain_3d_delta_time ); rain_displacement.z = distance_moved.z; // // Calculate the distance moved by each snowdrop. // snow_drift_displacement.x = distance_moved.x; snow_drift_displacement.y = distance_moved.y; snow_drift_displacement.z = distance_moved.z; snow_fall_displacement = ( rain_3d_speed / 4 ) * rain_3d_delta_time; snow_displacement_magnitude = get_3d_vector_magnitude ( &snow_drift_displacement ); // // Calculate the 'streak' effect - this is now NOT framerate related // rain_streak_displacement = rain_displacement; displacement_magnitude = get_3d_vector_magnitude ( &rain_streak_displacement ); if ( displacement_magnitude != 0 ) { displacement_magnitude = 1.5 / displacement_magnitude; rain_streak_displacement.x *= displacement_magnitude; rain_streak_displacement.y *= displacement_magnitude; rain_streak_displacement.z *= displacement_magnitude; } else { // // Put artificial streaking in there ( game paused ) // rain_streak_displacement.x = rain_3d_wind_direction.x * rain_3d_wind_speed * 0.05; rain_streak_displacement.y = rain_3d_wind_direction.y * rain_3d_wind_speed * 0.05 + ( rain_3d_speed * 0.05 ); rain_streak_displacement.z = rain_3d_wind_direction.z * rain_3d_wind_speed * 0.05; displacement_magnitude = get_3d_vector_magnitude ( &rain_streak_displacement ); if ( displacement_magnitude != 0 ) { displacement_magnitude = 1.5 / displacement_magnitude; rain_streak_displacement.x *= displacement_magnitude; rain_streak_displacement.y *= displacement_magnitude; rain_streak_displacement.z *= displacement_magnitude; } } // // Remove any raindrops that have strayed out of the area of effect // creation_vector.x = rain_3d_wind_direction.x * rain_3d_wind_speed * 0.5; creation_vector.y = rain_3d_wind_direction.y * rain_3d_wind_speed * 0.5 + ( rain_3d_speed * 0.5 ); creation_vector.z = rain_3d_wind_direction.z * rain_3d_wind_speed * 0.5; normalise_any_3d_vector ( &creation_vector ); for ( count = 0; count < TOTAL_3D_RAINDROPS; count++ ) { switch ( rain_3d_drops[count].type ) { case RAINDROP_RAIN: { vec3d rel; // // Update the rain position // rain_3d_drops[count].current_position.x -= rain_displacement.x; rain_3d_drops[count].current_position.y -= rain_displacement.y; rain_3d_drops[count].current_position.z -= rain_displacement.z; rel.x = rain_3d_drops[count].current_position.x - visual_3d_vp->x; rel.y = rain_3d_drops[count].current_position.y - visual_3d_vp->y; rel.z = rain_3d_drops[count].current_position.z - visual_3d_vp->z; if ( ( rel.x > RAINDROPS_AREA_WIDTH ) || ( rel.x < ( -RAINDROPS_AREA_WIDTH ) ) || ( rel.y > RAINDROPS_AREA_HEIGHT ) || ( rel.y < ( -RAINDROPS_AREA_HEIGHT ) ) || ( rel.z > RAINDROPS_AREA_DEPTH ) || ( rel.z < ( -RAINDROPS_AREA_DEPTH ) ) ) { rain_3d_raindrops_valid--; rain_3d_drops[count].type = RAINDROP_INVALID; } break; } case RAINDROP_SNOW: { vec3d snow_noise, rel; float relative_speed; // // Update the rain position // snow_noise.x = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; snow_noise.y = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; snow_noise.z = sfrand1 () * rain_3d_delta_time; //0.1 ;//snow_displacement_magnitude; relative_speed = rain_3d_drops[count].relative_speed; rain_3d_drops[count].current_position.x -= ( snow_drift_displacement.x + snow_noise.x ); rain_3d_drops[count].current_position.y -= ( snow_drift_displacement.y ); rain_3d_drops[count].current_position.z -= ( snow_drift_displacement.z + snow_noise.x ); rain_3d_drops[count].current_position.y -= ( snow_fall_displacement * relative_speed ); rel.x = rain_3d_drops[count].current_position.x - visual_3d_vp->x; rel.y = rain_3d_drops[count].current_position.y - visual_3d_vp->y; rel.z = rain_3d_drops[count].current_position.z - visual_3d_vp->z; if ( ( rel.x > SNOWDROPS_AREA_WIDTH ) || ( rel.x < ( -SNOWDROPS_AREA_WIDTH ) ) || ( rel.y > SNOWDROPS_AREA_HEIGHT ) || ( rel.y < ( -SNOWDROPS_AREA_HEIGHT ) ) || ( rel.z > SNOWDROPS_AREA_DEPTH ) || ( rel.z < ( -SNOWDROPS_AREA_DEPTH ) ) ) { rain_3d_snowdrops_valid--; rain_3d_drops[count].type = RAINDROP_INVALID; } break; } } if ( ( rain_3d_drops[count].type == RAINDROP_INVALID ) && ( creation_allowed ) ) { if ( rain_3d_raindrops_valid < total_raindrop_number ) { float x, y, z, creation_distance; // // Generate a new rain drop randomly // z = ( ( frand1 () * 0.8 ) + 0.2 ) * ( RAINDROPS_AREA_DEPTH / 5 ); x = sfrand1 () * ( RAINDROPS_AREA_WIDTH / 5 ); y = sfrand1 () * ( RAINDROPS_AREA_HEIGHT / 5 ); x *= z / 50; y *= z / 50; // // Now project along the motion vector // creation_distance = frand1 () * 8; x += creation_vector.x * creation_distance; y += creation_vector.y * creation_distance; z += creation_vector.z * creation_distance; // // Rotate this back into the view coordinate system // rain_3d_drops[count].current_position.x = x * view_attitude[0][0] + y * view_attitude[1][0] + z * view_attitude[2][0]; rain_3d_drops[count].current_position.y = x * view_attitude[0][1] + y * view_attitude[1][1] + z * view_attitude[2][1]; rain_3d_drops[count].current_position.z = x * view_attitude[0][2] + y * view_attitude[1][2] + z * view_attitude[2][2]; rain_3d_drops[count].current_position.x += visual_3d_vp->x; rain_3d_drops[count].current_position.y += visual_3d_vp->y; rain_3d_drops[count].current_position.z += visual_3d_vp->z; rain_3d_drops[count].type = RAINDROP_RAIN; rain_3d_raindrops_valid++; } else if ( rain_3d_snowdrops_valid < total_snowdrop_number ) { float x, y, z, creation_distance; // // Generate a new snowdrop // z = ( ( frand1 () * 0.8 ) + 0.2 ) * ( SNOWDROPS_AREA_DEPTH / 5 ); x = sfrand1 () * ( SNOWDROPS_AREA_WIDTH / 5 ); y = sfrand1 () * ( SNOWDROPS_AREA_HEIGHT / 5 ); x *= z / 50; y *= z / 50; // // Now project along the motion vector // creation_distance = frand1 () * 8; x += creation_vector.x * creation_distance; y += creation_vector.y * creation_distance; z += creation_vector.z * creation_distance; // // Rotate this back into the view coordinate system // rain_3d_drops[count].current_position.x = x * view_attitude[0][0] + y * view_attitude[1][0] + z * view_attitude[2][0]; rain_3d_drops[count].current_position.y = x * view_attitude[0][1] + y * view_attitude[1][1] + z * view_attitude[2][1]; rain_3d_drops[count].current_position.z = x * view_attitude[0][2] + y * view_attitude[1][2] + z * view_attitude[2][2]; rain_3d_drops[count].current_position.x += visual_3d_vp->x; rain_3d_drops[count].current_position.y += visual_3d_vp->y; rain_3d_drops[count].current_position.z += visual_3d_vp->z; rain_3d_drops[count].relative_speed = ( frand1() * 0.5 ) + 0.5; rain_3d_drops[count].type = RAINDROP_SNOW; rain_3d_snowdrops_valid++; } } } // // Now calculate the predicted positions for rendering // for ( count = 0; count < TOTAL_3D_RAINDROPS; count++ ) { if ( rain_3d_drops[count].type == RAINDROP_RAIN ) { rain_3d_drops[count].predicted_position.x = rain_3d_drops[count].current_position.x - rain_streak_displacement.x; rain_3d_drops[count].predicted_position.y = rain_3d_drops[count].current_position.y - rain_streak_displacement.y; rain_3d_drops[count].predicted_position.z = rain_3d_drops[count].current_position.z - rain_streak_displacement.z; } } }