Exemple #1
0
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, &current_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);
	}
}
Exemple #2
0
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;
		}
	}
}