Exemple #1
0
entity *get_closest_mobile_entity (vec3d *pos)
{

	entity
		*closest_en = NULL,
		*en;

	int
		range,
		best_range = INT_MAX;

	vec3d
		pos2,
		test_pos;

	en = get_local_entity_list ();

	while (en)
	{

		if (get_local_entity_int_value (en, INT_TYPE_IDENTIFY_MOBILE))
		{
	
			get_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &pos2);
	
			test_pos.x = pos->x - pos2.x;
	
			test_pos.y = 0.0;
	
			test_pos.z = pos->z - pos2.z;
	
			range = get_3d_vector_magnitude (&test_pos);
	
			if (range < best_range)
			{
	
				best_range = range;
	
				closest_en = en;
	
				if (range < 1.0)
				{
				
					return closest_en;
				}
			}
		}

		en = get_local_entity_succ (en);
	}
	
	return closest_en;
}
Exemple #2
0
void update_drop_camera (camera *raw)
{
	entity
		*en;

	vec3d
		pos,
		v;

	//
	// pre-amble
	//

	ASSERT (raw);

	ASSERT (raw->external_view_entity);

	en = raw->external_view_entity;

	//
	// get camera to entity vector
	//

	get_local_entity_target_point (en, &pos);

	v.x = pos.x - raw->position.x;
	v.y = pos.y - raw->position.y;
	v.z = pos.z - raw->position.z;

	//
	// prevent divide by zero
	//

	if (get_3d_vector_magnitude (&v) < 0.001)
	{
		v.x = 0.0;
		v.y = 0.0;
		v.z = 1.0;
	}

	//
	// get camera attitude
	//

	normalise_3d_vector (&v);

	get_matrix3x3_from_unit_vec3d (raw->attitude, &v);
}
Exemple #3
0
float get_formation_member_radius (formation_types form, int member_count)
{

	formation_type
		*formation_data;

	int
		loop,
		biggest_radius_index;

	float
		radius,
		sqr_radius,
		biggest_sqr_radius;

	formation_data = get_formation (form);

	biggest_sqr_radius = 0.0;

	biggest_radius_index = 0;

	for (loop = 0; loop < member_count; loop ++)
	{

		sqr_radius = (formation_data->sites [loop].x * formation_data->sites [loop].x) + (formation_data->sites [loop].z * formation_data->sites [loop].z);

		if (sqr_radius > biggest_sqr_radius)
		{

			biggest_sqr_radius = sqr_radius;

			biggest_radius_index = loop;
		}
	}

	radius = get_3d_vector_magnitude (&formation_data->sites [biggest_radius_index]);

	return radius;
}
Exemple #4
0
void insert_zbiased_smoke_trail_into_3d_scene ( int number_of_points, float zbias, int additive, screen *texture, float texture_distance, float texture_size, smoke_trail_data *points )
{

	smoke_trail_data
		*rotated_points;

	int
		count,
		visible;

	//
	// First, copy the ROTATED point data over to an internal 3d visual buffer ( checking for visibility )
	//

	visible = FALSE;

	rotated_points = get_smoke_trail_point_data ( number_of_points );

	if ( rotated_points )
	{
	
		for ( count = 0; count < number_of_points; count++ )
		{
	
			get_position_3d_relative_position ( &points[count].point1, &rotated_points[count].point1 );
	
			if ( rotated_points[count].point1.z > clip_hither )
			{
	
				visible = TRUE;
			}
	
			get_position_3d_relative_position ( &points[count].point2, &rotated_points[count].point2 );
	
			if ( rotated_points[count].point2.z > clip_hither )
			{
	
				visible = TRUE;
			}

			rotated_points[count].centre.x = ( rotated_points[count].point1.x + rotated_points[count].point2.x ) / 2;
			rotated_points[count].centre.y = ( rotated_points[count].point1.y + rotated_points[count].point2.y ) / 2;
			rotated_points[count].centre.z = ( rotated_points[count].point1.z + rotated_points[count].point2.z ) / 2;
		}
	
		if ( visible )
		{
	
			smoke_trail_information
				*smoke_trail;
	
			float
				texture_u;
	
			//
			// Some part ( or all ) of the smoke trail is visible - generate a smoke trail header.
			//
	
			smoke_trail = get_smoke_trail_header ();

			if ( smoke_trail )
			{

				smoke_trail->additive = additive;

				smoke_trail->texture = texture;
		
				smoke_trail->texture_size = texture_size;
		
				smoke_trail->number_of_points = number_of_points;
		
				smoke_trail->points = rotated_points;
		
				//
				// Go calculate the u texture coordinates
				//
		
				texture_u = texture_distance / texture_size;
		
				rotated_points[0].texture_u = texture_u;

				rotated_points[0].colour = light_smoke_colour ( points[0].colour, additive );
		
				for ( count = 0; count < ( number_of_points - 1 ); count++ )
				{
		
					vec3d
						centre_point1,
						centre_point2,
						length_vector;
		
					float
						texture_temp_distance;
		
					centre_point1.x = ( points[count].point1.x + points[count].point2.x ) / 2;
					centre_point1.y = ( points[count].point1.y + points[count].point2.y ) / 2;
					centre_point1.z = ( points[count].point1.z + points[count].point2.z ) / 2;
		
					centre_point2.x = ( points[count+1].point1.x + points[count+1].point2.x ) / 2;
					centre_point2.y = ( points[count+1].point1.y + points[count+1].point2.y ) / 2;
					centre_point2.z = ( points[count+1].point1.z + points[count+1].point2.z ) / 2;
		
					length_vector.x = centre_point2.x - centre_point1.x;
					length_vector.y = centre_point2.y - centre_point1.y;
					length_vector.z = centre_point2.z - centre_point1.z;
		
					//
					// Calculate the length of line connecting the two centre points
					//
		
					texture_temp_distance = ( get_3d_vector_magnitude ( &length_vector ) / texture_size );
		
					texture_u += texture_temp_distance;
		
					rotated_points[count+1].texture_u = texture_u;
					rotated_points[count+1].colour = light_smoke_colour ( points[count+1].colour, additive );
				}
		
				//
				// Now insert each segment dependant on it being visible or not.
				//
		
				for ( count = 0; count < ( number_of_points - 1 ); count++ )
				{
		
					if (	( rotated_points[count].point1.z > clip_hither ) || ( rotated_points[count].point2.z > clip_hither ) ||
							( rotated_points[count+1].point1.z > clip_hither ) || ( rotated_points[count+1].point1.z > clip_hither ) )
					{
		
						scene_slot_drawing_list
							*buffer;
		
						float
							average_z;
		
						average_z = (	( rotated_points[count].point1.z + rotated_points[count].point2.z ) +
											( rotated_points[count+1].point1.z + rotated_points[count+1].point2.z ) );
		
						average_z /= 4;

						average_z += zbias;
		
						buffer = get_3d_scene_slot ();
			
						if ( buffer )
						{
		
							buffer->type = OBJECT_3D_DRAW_TYPE_SMOKE_TRAIL;
			
							buffer->z = *( ( int * ) &average_z );
			
							buffer->smoke_trail.trail = smoke_trail;
		
							buffer->smoke_trail.segment = count;
		
							if ( points[count].point1.y > middle_scene_slot_height )
							{
			
								insert_high_nonzbuffered_scene_slot_into_3d_scene ( buffer );
							}
							else
							{
		
								insert_low_nonzbuffered_scene_slot_into_3d_scene ( buffer );
							}
						}
						else
						{

							debug_log ( "SMOKE TRAIL OVERFLOWED OBJECT BUFFER" );
						}
					}
				}
			}
			else
			{

				//
				// No point in freeing up the smoke trail point data, as all the headers are used up!
				//
			}
		}
		else
		{
	
			//
			// Free up the reserved smoke trail point data slots
			//
	
			remove_smoke_trail_point_data ( number_of_points );
		}
	}
}
Exemple #5
0
void draw_3d_cloud_sector ( scene_slot_drawing_list *slot )
{

	int
		count;

	float
		current_sector_x_offset,
		current_sector_z_offset;

	double
		tempx,
		tempz;

	vec3d
		sector_centre,
		sector_relative_centre;

	cloud_3d_point
		cloud_points[256];

	float
		cloud_polygon_alphas[256];

	cloud_3d_textured_reference
		point_references[4];

	//
	// Set the fog intensity for clouds ( NO FOG )
	//

	current_sector_x_offset = slot->cloud_sector.x * CLOUD_3D_SECTOR_SIDE_LENGTH;
	current_sector_z_offset = slot->cloud_sector.z * CLOUD_3D_SECTOR_SIDE_LENGTH;

	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_centre.x -= visual_3d_vp->x;
	sector_centre.y -= visual_3d_vp->y;
	sector_centre.z -= visual_3d_vp->z;

	sector_relative_centre.x = (	( sector_centre.x ) * visual_3d_vp->xv.x +
											( sector_centre.y ) * visual_3d_vp->xv.y +
											( sector_centre.z ) * visual_3d_vp->xv.z );

	sector_relative_centre.y = (	( sector_centre.x ) * visual_3d_vp->yv.x +
											( sector_centre.y ) * visual_3d_vp->yv.y +
											( sector_centre.z ) * visual_3d_vp->yv.z );

	sector_relative_centre.z = (	( sector_centre.x ) * visual_3d_vp->zv.x +
											( sector_centre.y ) * visual_3d_vp->zv.y +
											( sector_centre.z ) * visual_3d_vp->zv.z );

	set_d3d_fog_face_intensity ( 0 );

	if ( d3d_flat_only_alpha )
	{

		int
			number_of_sub_sectors,
			number_of_points,
			x,
			z;

		float
			x_offset,
			z_offset,
			alpha;

		number_of_sub_sectors = 1;

		number_of_points = ( number_of_sub_sectors + 1 ) * ( number_of_sub_sectors + 1 );

		count = 0;

		for ( z = 0; z <= number_of_sub_sectors; z++ )
		{

			for ( x = 0; x <= number_of_sub_sectors; x++ )
			{

				vec3d
					point_vector;

				float
					angle,
					distance,
					colour_t,
					dr,
					dg,
					db,
					r,
					g,
					b;

				int
					ir,
					ig,
					ib;

				x_offset = ( -CLOUD_3D_SECTOR_SIDE_LENGTH/2 ) + ( ( ( float ) x / ( float ) number_of_sub_sectors ) * CLOUD_3D_SECTOR_SIDE_LENGTH );
				z_offset = ( -CLOUD_3D_SECTOR_SIDE_LENGTH/2 ) + ( ( ( float ) z / ( float ) number_of_sub_sectors ) * CLOUD_3D_SECTOR_SIDE_LENGTH );

				cloud_points[count].x = x_offset;
				cloud_points[count].y = 0;
				cloud_points[count].z = z_offset;

				point_vector.x = sector_centre.x + x_offset;
				point_vector.y = 0;
				point_vector.z = sector_centre.z + z_offset;

				distance = get_3d_vector_magnitude ( &point_vector );

				if ( distance > 1 )
				{

					normalise_3d_vector_given_magnitude ( &point_vector, distance );

					angle = ( ( point_vector.x * cloud_colour_blend_vector.x ) + ( point_vector.z * cloud_colour_blend_vector.z ) );
					angle = bound ( angle, 0, 1 );
					angle *= angle;
					angle *= angle;

					colour_t = ( distance / CLOUD_MAXIMUM_COLOUR_BLEND_DISTANCE );
					colour_t = bound ( colour_t, 0, 1 );
					colour_t *= angle;
				}
				else
				{

					colour_t = 0;
				}

				dr = active_3d_environment->cloud_light.object_colour.red - active_3d_environment->cloud_light.light_colour.red;
				dg = active_3d_environment->cloud_light.object_colour.green - active_3d_environment->cloud_light.light_colour.green;
				db = active_3d_environment->cloud_light.object_colour.blue - active_3d_environment->cloud_light.light_colour.blue;

				r = active_3d_environment->cloud_light.light_colour.red + ( colour_t * dr );
				g = active_3d_environment->cloud_light.light_colour.green + ( colour_t * dg );
				b = active_3d_environment->cloud_light.light_colour.blue + ( colour_t * db );

				convert_float_to_int ( r * 255.0, &ir );
				convert_float_to_int ( g * 255.0, &ig );
				convert_float_to_int ( b * 255.0, &ib );

				cloud_points[count].red = ir;
				cloud_points[count].green = ig;
				cloud_points[count].blue = ib;

				count++;
			}
		}

		count = 0;

		z_offset = -CLOUD_3D_SECTOR_SIDE_LENGTH/2 + ( CLOUD_3D_SECTOR_SIDE_LENGTH / ( number_of_sub_sectors * 2 ) );

		for ( z = 0; z < number_of_sub_sectors; z++ )
		{

			x_offset = -CLOUD_3D_SECTOR_SIDE_LENGTH/2 + ( CLOUD_3D_SECTOR_SIDE_LENGTH / ( number_of_sub_sectors * 2 ) );

			for ( x = 0; x < number_of_sub_sectors; x++ )
			{

				tempx = sector_centre.x + x_offset;
				tempz = sector_centre.z + z_offset;

				tempx *= tempx;
				tempz *= tempz;

				alpha = ( ( cloud_3d_blend_constant - ( tempx + tempz ) ) * cloud_3d_adjusted_blend_factor );
				alpha = bound ( alpha, 0, 1 );

				cloud_polygon_alphas[count] = alpha;

				x_offset += CLOUD_3D_SECTOR_SIDE_LENGTH / ( number_of_sub_sectors * 1 );

				count++;
			}

			z_offset += CLOUD_3D_SECTOR_SIDE_LENGTH / ( number_of_sub_sectors * 1 );
		}

		transform_cloud_points ( number_of_points, cloud_points, cloud_transformed_3d_points, &sector_relative_centre );

		//
		// Render a quad twice, for the blending between cloud textures
		//

		count = 0;

		z_offset = 0;

		for ( z = 0; z < number_of_sub_sectors; z++ )
		{

			x_offset = 0;

			for ( x = 0; x < number_of_sub_sectors; x++ )
			{

				int
					tmp,
					z_bottom_point_offset,
					z_top_point_offset;

				z_bottom_point_offset = z * ( number_of_sub_sectors + 1 );

				z_top_point_offset = z_bottom_point_offset +  ( number_of_sub_sectors + 1 );

				if ( cloud_3d_base_height < visual_3d_vp->y )
				{

					point_references[3].point = x + z_bottom_point_offset;
					point_references[3].u = x_offset;
					point_references[3].v = z_offset;

					point_references[2].point = x + z_bottom_point_offset + 1;
					point_references[2].u = x_offset + ( 1.0 / number_of_sub_sectors );
					point_references[2].v = z_offset;

					point_references[1].point = x + z_top_point_offset + 1;
					point_references[1].u = x_offset + ( 1.0 / number_of_sub_sectors );
					point_references[1].v = z_offset + ( 1.0 / number_of_sub_sectors );

					point_references[0].point = x + z_top_point_offset;
					point_references[0].u = x_offset;
					point_references[0].v = z_offset + ( 1.0 / number_of_sub_sectors );
				}
				else
				{

					point_references[0].point = x + z_bottom_point_offset;
					point_references[0].u = x_offset;
					point_references[0].v = z_offset;

					point_references[1].point = x + z_bottom_point_offset + 1;
					point_references[1].u = x_offset + ( 1.0 / number_of_sub_sectors );
					point_references[1].v = z_offset;

					point_references[2].point = x + z_top_point_offset + 1;
					point_references[2].u = x_offset + ( 1.0 / number_of_sub_sectors );
					point_references[2].v = z_offset + ( 1.0 / number_of_sub_sectors );

					point_references[3].point = x + z_top_point_offset;
					point_references[3].u = x_offset;
					point_references[3].v = z_offset + ( 1.0 / number_of_sub_sectors );
				}

				for ( tmp = 0; tmp < 4; tmp++ )
				{

					cloud_points[ point_references[tmp].point ].a = cloud_polygon_alphas[count];
				}

				if ( current_weather_texture )
				{

					render_cloud_polygon ( 4, point_references, cloud_transformed_3d_points, cloud_points, cloud_weather_one_minus_blend_factor, current_weather_texture );
				}

				if ( target_weather_texture )
				{

					render_cloud_polygon ( 4, point_references, cloud_transformed_3d_points, cloud_points, cloud_weather_blend_factor, target_weather_texture );
				}

				x_offset += ( 1.0 / number_of_sub_sectors );

				count++;
			}

			z_offset += ( 1.0 / number_of_sub_sectors );
		}
	}
	else
	{

		cloud_points[0].x = -CLOUD_3D_SECTOR_SIDE_LENGTH/2;
		cloud_points[0].y = 0;
		cloud_points[0].z = -CLOUD_3D_SECTOR_SIDE_LENGTH/2;

		cloud_points[1].x = +CLOUD_3D_SECTOR_SIDE_LENGTH/2;
		cloud_points[1].y = 0;
		cloud_points[1].z = -CLOUD_3D_SECTOR_SIDE_LENGTH/2;

		cloud_points[2].x = +CLOUD_3D_SECTOR_SIDE_LENGTH/2;
		cloud_points[2].y = 0;
		cloud_points[2].z = +CLOUD_3D_SECTOR_SIDE_LENGTH/2;

		cloud_points[3].x = -CLOUD_3D_SECTOR_SIDE_LENGTH/2;
		cloud_points[3].y = 0;
		cloud_points[3].z = +CLOUD_3D_SECTOR_SIDE_LENGTH/2;

		for ( count = 0; count < 4; count++ )
		{

			vec3d
				point_vector;

			int
				ir,
				ig,
				ib;

			float
				colour_t,
				alpha,
				distance,
				angle,
				dr,
				dg,
				db,
				r,
				g,
				b;

			tempx = sector_centre.x + cloud_points[count].x;
			tempz = sector_centre.z + cloud_points[count].z;

			point_vector.x = tempx;
			point_vector.y = 0;
			point_vector.z = tempz;

			distance = get_3d_vector_magnitude ( &point_vector );

			if ( distance > 1 )
			{

				normalise_3d_vector_given_magnitude ( &point_vector, distance );

				angle = ( ( point_vector.x * cloud_colour_blend_vector.x ) + ( point_vector.z * cloud_colour_blend_vector.z ) );
				angle = bound ( angle, 0, 1 );
				angle *= angle;
				angle *= angle;

				colour_t = ( distance / CLOUD_MAXIMUM_COLOUR_BLEND_DISTANCE );
				colour_t = bound ( colour_t, 0, 1 );
				colour_t *= angle;
			}
			else
			{

				colour_t = 0;
			}

			alpha = ( ( cloud_3d_blend_constant - ( distance * distance ) ) * cloud_3d_adjusted_blend_factor );

			cloud_points[count].a = bound ( alpha, 0, 1 );

			dr = active_3d_environment->cloud_light.object_colour.red - active_3d_environment->cloud_light.light_colour.red;
			dg = active_3d_environment->cloud_light.object_colour.green - active_3d_environment->cloud_light.light_colour.green;
			db = active_3d_environment->cloud_light.object_colour.blue - active_3d_environment->cloud_light.light_colour.blue;

			r = active_3d_environment->cloud_light.light_colour.red + ( colour_t * dr );
			g = active_3d_environment->cloud_light.light_colour.green + ( colour_t * dg );
			b = active_3d_environment->cloud_light.light_colour.blue + ( colour_t * db );

			convert_float_to_int ( r * 255.0, &ir );
			convert_float_to_int ( g * 255.0, &ig );
			convert_float_to_int ( b * 255.0, &ib );

			cloud_points[count].red = ir;
			cloud_points[count].green = ig;
			cloud_points[count].blue = ib;
/*
			debug_log ( "( %d, %d, %d ) -> ( %d, %d, %d ) d( %d, %d, %d ) blend = %f = %d, %d, %d",
									active_3d_environment->cloud_light.light_colour.red * 255,
									active_3d_environment->cloud_light.light_colour.green * 255,
									active_3d_environment->cloud_light.light_colour.blue * 255,
									active_3d_environment->cloud_light.object_colour.red * 255,
									active_3d_environment->cloud_light.object_colour.green * 255,
									active_3d_environment->cloud_light.object_colour.blue * 255,
									dr * 255,
									dg * 255,
									db * 255,
									colour_t,
									ir, ig, ib );
*/
		}

		transform_cloud_points ( 4, cloud_points, cloud_transformed_3d_points, &sector_relative_centre );

		//
		// Render a quad twice, for the blending between cloud textures
		//

		if ( cloud_3d_base_height < visual_3d_vp->y )
		{

			point_references[3].point = 0; point_references[3].u = 0; point_references[3].v = 0;
			point_references[2].point = 1; point_references[2].u = 1; point_references[2].v = 0;
			point_references[1].point = 2; point_references[1].u = 1; point_references[1].v = 1;
			point_references[0].point = 3; point_references[0].u = 0; point_references[0].v = 1;
		}
		else
		{

			point_references[0].point = 0; point_references[0].u = 0; point_references[0].v = 0;
			point_references[1].point = 1; point_references[1].u = 1; point_references[1].v = 0;
			point_references[2].point = 2; point_references[2].u = 1; point_references[2].v = 1;
			point_references[3].point = 3; point_references[3].u = 0; point_references[3].v = 1;
		}

		if ( current_weather_texture )
		{

			render_cloud_polygon ( 4, point_references, cloud_transformed_3d_points, cloud_points, cloud_weather_one_minus_blend_factor, current_weather_texture );
		}

		if ( target_weather_texture )
		{

			render_cloud_polygon ( 4, point_references, cloud_transformed_3d_points, cloud_points, cloud_weather_blend_factor, target_weather_texture );
		}
	}
}
Exemple #6
0
static void update_threat_warning_display (void)
{
	entity
		*source,
		*threat;

	int
		above = FALSE,
		overshot,
		threat_active;

	float
		dx,
		dy,
		dz,
		theta,
		threat_bearing,
		threat_range,
		threat_velocity,
		time_to_impact,
		source_heading,
		length,
		cos_error;

	threat_types
		threat_type;

	vec3d
		*source_position,
		*threat_position,
		uvec_threat_to_target;

	matrix3x3
		*attitude;

	clear_threat_warning_display_lamps ();

	if (hind_damage.threat_warning_display || hind_damage.radar_warning_system)
	{
		return;
	}

	threat = get_local_entity_first_child (get_gunship_entity (), LIST_TYPE_TARGET);

	if (threat)
	{
		source = get_gunship_entity ();

		source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);

		source_heading = get_local_entity_float_value (source, FLOAT_TYPE_HEADING);

		while (threat)
		{
			entity_sub_types sub_type = get_local_entity_int_value(threat, INT_TYPE_ENTITY_SUB_TYPE);
			float max_range = 10.0;

			threat_type = (threat_types) get_local_entity_int_value (threat, INT_TYPE_THREAT_TYPE);

			//
			// check threat is active
			//

			if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_VEHICLE))
			{
				max_range = vehicle_database[sub_type].air_scan_range;
				threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
			}
			else if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_AIRCRAFT))
			{
				max_range = aircraft_database[sub_type].air_scan_range;
				threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
			}
			else if (get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_WEAPON))
			{
				weapon_guidance_types guidance = weapon_database[sub_type].guidance_type;

				threat_active = guidance == WEAPON_GUIDANCE_TYPE_ACTIVE_RADAR;
				if (guidance == WEAPON_GUIDANCE_TYPE_ACTIVE_RADAR || guidance == WEAPON_GUIDANCE_TYPE_SEMI_ACTIVE_RADAR)
				{
					hind_lamps.threat_warning_missile_lh_lock = 1;
					hind_lamps.threat_warning_missile_rh_lock = 1;
				}

				max_range = weapon_database[sub_type].max_range;
			}

#if 0
			switch (threat_type)
			{
				////////////////////////////////////////
				case THREAT_TYPE_INVALID:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_RF_MISSILE:
				////////////////////////////////////////
				{
					ASSERT(get_local_entity_int_value (threat, INT_TYPE_IDENTIFY_WEAPON));

					if (!hind_damage.radar_warning_system)
					{
						threat_active = TRUE;
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_IR_MISSILE:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_LASER_MISSILE:
				////////////////////////////////////////
				{
					threat_active = FALSE;

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_AIRBORNE_RADAR:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_SAM:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_AAA:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				case THREAT_TYPE_EARLY_WARNING_RADAR:
				////////////////////////////////////////
				{
					if (!hind_damage.radar_warning_system)
					{
						threat_active = get_local_entity_int_value (threat, INT_TYPE_RADAR_ON);
					}
					else
					{
						threat_active = FALSE;
					}

					break;
				}
				////////////////////////////////////////
				default:
				////////////////////////////////////////
				{
					debug_fatal ("Invalid threat type = %d", threat_type);

					break;
				}
			}
#endif

			if (threat_active)
			{
				//
				// get threat direction wrt aircraft datum
				//

				threat_position = get_local_entity_vec3d_ptr (threat, VEC3D_TYPE_POSITION);

				dx = threat_position->x - source_position->x;
				dy = threat_position->y - source_position->y;
				dz = threat_position->z - source_position->z;

				threat_range = sqrt ((dx * dx) + (dy * dy) + (dz * dz));
				above = dy > 0.0;
				threat_bearing = atan2 (dx, dz);
				theta = threat_bearing - source_heading;

				if (theta > rad (180.0))
				{
					theta -= rad (360.0);
				}
				else if (theta < rad (-180.0))
				{
					theta += rad (360.0);
				}

				//
				// if missile threat then guard against 'overshot target' to prevent spurious indications
				//

				if ((threat_type == THREAT_TYPE_RF_MISSILE) || (threat_type == THREAT_TYPE_IR_MISSILE) || (threat_type == THREAT_TYPE_LASER_MISSILE))
				{
					threat_velocity = get_local_entity_float_value (threat, FLOAT_TYPE_VELOCITY);

					time_to_impact = threat_range / max (threat_velocity, 1.0f);

					overshot = FALSE;

					if (time_to_impact < 1.0)
					{
						uvec_threat_to_target.x = source_position->x - threat_position->x;
						uvec_threat_to_target.y = source_position->y - threat_position->y;
						uvec_threat_to_target.z = source_position->z - threat_position->z;

						length = get_3d_vector_magnitude (&uvec_threat_to_target);

						if (length > 1.0)
						{
							normalise_3d_vector_given_magnitude (&uvec_threat_to_target, length);

							attitude = get_local_entity_attitude_matrix_ptr (threat);

							cos_error = get_3d_unit_vector_dot_product ((vec3d *) &((*attitude) [2][0]), &uvec_threat_to_target);

							if (cos_error < 0.0)
							{
								overshot = TRUE;
							}
						}
						else
						{
							overshot = TRUE;
						}
					}

					if (!overshot)
					{
						light_threat_bearing_lamp (theta);
						light_signal_strength_lamps(threat_range, max_range);

						hind_lamps.threat_warning_radar_type_1 = 1;

						if (above)
							hind_lamps.threat_warning_missile_above = 1;
						else
							hind_lamps.threat_warning_missile_below = 1;
					}
				}
				else
				{
					light_threat_bearing_lamp (theta);
					light_signal_strength_lamps(threat_range, max_range);

					if (above)
						hind_lamps.threat_warning_missile_above = 1;
					else
						hind_lamps.threat_warning_missile_below = 1;

					if (threat_type == THREAT_TYPE_AIRBORNE_RADAR)
						hind_lamps.threat_warning_radar_type_1 = 1;
					else
					{
						if (max_range <= 4000.0)  // short range
							hind_lamps.threat_warning_radar_type_4 = 1;
						else if (max_range <= 10000.0)   // medium range
							hind_lamps.threat_warning_radar_type_3 = 1;
						else  // long range
							hind_lamps.threat_warning_radar_type_2 = 1;
					}

				}
			}

			threat = get_local_entity_child_succ (threat, LIST_TYPE_TARGET);
		}
	}
}
Exemple #7
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;
		}
	}
}
Exemple #8
0
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);
		}
	}
}