Exemplo n.º 1
0
void set_chase_camera_view_target_to_source (entity *source, entity *target)
{
	camera
		*raw;

	float
		length;

	vec3d
		*source_position,
		*target_position,
		direction;

	ASSERT (source);

	ASSERT (target);

	ASSERT (get_camera_entity ());

	raw = get_local_entity_data (get_camera_entity ());

	source_position = get_local_entity_vec3d_ptr (source, VEC3D_TYPE_POSITION);

	target_position = get_local_entity_vec3d_ptr (target, VEC3D_TYPE_POSITION);

	direction.x = source_position->x - target_position->x;
	direction.y = source_position->y - target_position->y;
	direction.z = source_position->z - target_position->z;

	length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z);

	if (length > 1.0)
	{
		length = sqrt (length);

		normalise_3d_vector_given_magnitude (&direction, length);

		raw->chase_camera_heading = atan2 (direction.x, direction.z);

		if (raw->chase_camera_lock_rotate)
		{
			raw->chase_camera_heading -= get_local_entity_float_value (target, FLOAT_TYPE_HEADING);

			raw->chase_camera_heading = wrap_angle (raw->chase_camera_heading);
		}

		raw->chase_camera_pitch = asin (direction.y);
	}
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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 );
		}
	}
}
Exemplo n.º 4
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);
		}
	}
}
Exemplo n.º 5
0
void set_reverse_tactical_camera_values (entity *source, entity *target)
{
	camera
		*raw;

	int
		airborne;

	object_3d_index_numbers
		object_3d_index;

	object_3d_bounds
		*bounding_box;

	float
		length,
		radius,
		z_min,
		z_max,
		rad_alt,
		dx,
		dy,
		dz;

	vec3d
		source_position,
		target_position,
		direction;

	ASSERT (source);

	ASSERT (target);

	ASSERT (get_camera_entity ());

	raw = get_local_entity_data (get_camera_entity ());

	//
	// get camera position
	//

	if (get_local_entity_int_value (target, INT_TYPE_IDENTIFY_FIXED))
	{
		object_3d_index = get_local_entity_int_value (target, INT_TYPE_OBJECT_3D_SHAPE);

		bounding_box = get_object_3d_bounding_box (object_3d_index);

		dx = bounding_box->xmax - bounding_box->xmin;
		dy = bounding_box->ymax;
		dz = bounding_box->zmax - bounding_box->zmin;

		radius = sqrt ((dx * dx) + (dy * dy) + (dz * dz)) * 2.0;
	}
	else
	{
		z_min = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MIN_DISTANCE);
		z_max = get_local_entity_float_value (target, FLOAT_TYPE_CHASE_VIEW_MAX_DISTANCE);

		ASSERT (z_min < z_max);

		radius = ((z_max - z_min) * 0.05) + z_min;
	}

	get_local_entity_target_point (source, &source_position);

	get_local_entity_target_point (target, &target_position);

	airborne = FALSE;

	if (get_local_entity_int_value (target, INT_TYPE_AIRBORNE_AIRCRAFT))
	{
		if (point_inside_map_area (&target_position))
		{
			rad_alt = max (target_position.y - get_3d_terrain_elevation (target_position.x, target_position.z), 0.0);

			if (rad_alt > z_min)
			{
				airborne = TRUE;
			}
		}
	}

	if (airborne)
	{
		direction.x = target_position.x - source_position.x;
		direction.y = target_position.y - source_position.y;
		direction.z = target_position.z - source_position.z;

		length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z);

		if (length > 1.0)
		{
			length = sqrt (length);

			normalise_3d_vector_given_magnitude (&direction, length);
		}
		else
		{
			direction.x = 0.0;
			direction.y = 0.0;
			direction.z = -1.0;
		}
	}
	else
	{
		direction.x = target_position.x - source_position.x;
		direction.y = 0.0;
		direction.z = target_position.z - source_position.z;

		length = (direction.x * direction.x) + (direction.z * direction.z);

		if (length > 1.0)
		{
			length = sqrt (length);

			normalise_3d_vector_given_magnitude (&direction, length);
		}
		else
		{
			direction.x = 0.0;
			direction.z = -1.0;
		}

		direction.y = 0.5;

		normalise_3d_vector (&direction);
	}

	raw->position.x = target_position.x + (direction.x * radius);
	raw->position.y = target_position.y + (direction.y * radius);
	raw->position.z = target_position.z + (direction.z * radius);

	//
	// keep point above ground (unless point off map)
	//

	if (point_inside_map_area (&raw->position))
	{
		raw->position.y = max (raw->position.y, get_3d_terrain_point_data (raw->position.x, raw->position.z, &raw->terrain_info) + CAMERA_MIN_HEIGHT_ABOVE_GROUND);
	}

	//
	// get camera attitude
	//

	direction.x = target_position.x - raw->position.x;
	direction.y = target_position.y - raw->position.y;
	direction.z = target_position.z - raw->position.z;

	length = (direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z);

	if (length > 1.0)
	{
		length = sqrt (length);

		normalise_3d_vector_given_magnitude (&direction, length);

		get_matrix3x3_from_unit_vec3d (raw->attitude, &direction);
	}
	else
	{
		get_identity_matrix3x3 (raw->attitude);
	}

	//
	// motion vector
	//

	get_local_entity_vec3d (target, VEC3D_TYPE_MOTION_VECTOR, &raw->motion_vector);
}
Exemplo n.º 6
0
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...

}