コード例 #1
0
ファイル: cm_drop.c プロジェクト: DexterWard/comanche
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);
}
コード例 #2
0
ファイル: cm_stat.c プロジェクト: Comanche93/eech
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;
}
コード例 #3
0
ファイル: clouds.c プロジェクト: DexterWard/comanche
void scan_3d_clouds ( void )
{

	int
		visual_sector_x,
		visual_sector_z,
		current_sector_x,
		current_sector_z,
		minimum_sector_x,
		minimum_sector_z,
		maximum_sector_x,
		maximum_sector_z;

	float
		initial_sector_x_offset,
		initial_sector_z_offset,
		current_sector_x_offset,
		current_sector_z_offset;

	weathermodes
		current_weathermode,
		target_weathermode;

	matrix3x3
		cloud_matrix;

	//
	// Get the vector pointing to the colour blend
	//

	get_3d_transformation_matrix ( cloud_matrix, active_3d_environment->cloud_light.heading, active_3d_environment->cloud_light.pitch, 0 );

	cloud_colour_blend_vector.x = cloud_matrix[2][0];
	cloud_colour_blend_vector.y = 0;
	cloud_colour_blend_vector.z = cloud_matrix[2][2];

	normalise_3d_vector ( &cloud_colour_blend_vector );

	//
	// Adjust the cloud blend factor
	//

	if ( ( visual_3d_vp->y > ( cloud_3d_base_height - 100 ) ) && ( visual_3d_vp->y < ( cloud_3d_base_height + 100 ) ) )
	{

		float
			blend;

		blend = ( ( fabs ( visual_3d_vp->y - cloud_3d_base_height ) ) / 100 );

		if ( blend > 1 )
		{

			blend = 1;
		}

		cloud_3d_adjusted_blend_factor = cloud_3d_blend_factor * blend;
	}
	else
	{

		cloud_3d_adjusted_blend_factor = cloud_3d_blend_factor;
	}

	//
	// Choose the two textures to be blending inbetween
	//

	current_weathermode = get_3d_weathermode ( active_3d_environment );

	target_weathermode = get_3d_target_weathermode ( active_3d_environment );

	if ( !cloud_textures[current_weathermode].valid )
	{

		debug_fatal ( "Unable to draw clouds - no texture set for current weathermode: %d", current_weathermode );
	}

	if ( !cloud_textures[target_weathermode].texture_index )
	{

		debug_fatal ( "Unable to draw clouds - no texture set for target weathermode: %d", target_weathermode );
	}

	cloud_weather_blend_factor = get_3d_target_weathermode_transitional_status ( active_3d_environment );

	cloud_weather_one_minus_blend_factor = 1.0 - cloud_weather_blend_factor;

	if ( current_weathermode != target_weathermode )
	{

		if ( cloud_weather_blend_factor == 1 )
		{

			current_weather_texture = system_textures[ cloud_textures[target_weathermode].texture_index ];

			target_weather_texture = NULL;

			cloud_weather_blend_factor = 0;

			cloud_weather_one_minus_blend_factor = 1.0;
		}
		else if ( cloud_weather_blend_factor == 0 )
		{

			current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ];

			target_weather_texture = NULL;

			cloud_weather_blend_factor = 0;

			cloud_weather_one_minus_blend_factor = 1.0;
		}
		else
		{

			current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ];

			target_weather_texture = system_textures[ cloud_textures[target_weathermode].texture_index ];
		}
	}
	else
	{

		current_weather_texture = system_textures[ cloud_textures[current_weathermode].texture_index ];

		target_weather_texture = NULL;

		cloud_weather_blend_factor = 0;

		cloud_weather_one_minus_blend_factor = 1.0;
	}

	//
	// Now bias the blend factors, to take into account the transparency of each texture
	//

	cloud_weather_one_minus_blend_factor *= active_3d_environment->cloud_light.light_colour.alpha;

	cloud_weather_blend_factor *= active_3d_environment->cloud_light.light_colour.alpha;

	//
	// Get the sector the visual_3d_vp is currently in
	//

	get_cloud_3d_sector ( visual_3d_vp->x, visual_3d_vp->z, &visual_sector_x, &visual_sector_z );

	minimum_sector_x = visual_sector_x - cloud_3d_sector_scan_radius;
	minimum_sector_z = visual_sector_z - cloud_3d_sector_scan_radius;

	maximum_sector_x = visual_sector_x + cloud_3d_sector_scan_radius;
	maximum_sector_z = visual_sector_z + cloud_3d_sector_scan_radius;

	initial_sector_x_offset = minimum_sector_x * CLOUD_3D_SECTOR_SIDE_LENGTH;
	initial_sector_z_offset = minimum_sector_z * CLOUD_3D_SECTOR_SIDE_LENGTH;

	current_sector_z_offset = initial_sector_z_offset;

	for ( current_sector_z = minimum_sector_z; current_sector_z < maximum_sector_z; current_sector_z++ )
	{

		current_sector_x_offset = initial_sector_x_offset;

		for ( current_sector_x = minimum_sector_x; current_sector_x < maximum_sector_x; current_sector_x++ )
		{

			vec3d
				sector_centre,
				sector_relative_centre;

			scene_slot_drawing_list
				*sorting_slot;

			sector_centre.x = current_sector_x_offset + ( CLOUD_3D_SECTOR_SIDE_LENGTH / 2 );
			sector_centre.y = cloud_3d_base_height;
			sector_centre.z = current_sector_z_offset + ( CLOUD_3D_SECTOR_SIDE_LENGTH / 2 );

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

			if ( ( sector_relative_centre.z + ( CLOUD_3D_SECTOR_SIDE_LENGTH * 1.4142 ) ) < clip_hither )
			{

				//
				// Cloud sector is totally behind the view
				//
			}
			else
			{

				unsigned int
					outcode,
					outcode1,
					outcode2;

				float
					x_minimum_offset,
					x_maximum_offset,
					z_minimum_offset,
					z_maximum_offset;

				x_minimum_offset = current_sector_x_offset;
				x_maximum_offset = current_sector_x_offset + CLOUD_3D_SECTOR_SIDE_LENGTH;

				z_minimum_offset = current_sector_z_offset;
				z_maximum_offset = current_sector_z_offset + CLOUD_3D_SECTOR_SIDE_LENGTH;

				outcode = get_3d_point_outcodes ( x_minimum_offset, cloud_3d_base_height, z_minimum_offset );
				outcode1 = outcode;
				outcode2 = outcode;

				outcode = get_3d_point_outcodes ( x_minimum_offset, cloud_3d_base_height, z_maximum_offset );
				outcode1 |= outcode;
				outcode2 &= outcode;

				outcode = get_3d_point_outcodes ( x_maximum_offset, cloud_3d_base_height, z_minimum_offset );
				outcode1 |= outcode;
				outcode2 &= outcode;

				outcode = get_3d_point_outcodes ( x_maximum_offset, cloud_3d_base_height, z_maximum_offset );
				outcode1 |= outcode;
				outcode2 &= outcode;

//				if ( outcode2 == 0 )
				{

					sorting_slot = get_3d_scene_slot ();

					if ( sorting_slot )
					{

						sorting_slot->type = OBJECT_3D_DRAW_TYPE_CLOUD_SECTOR;

						//
						// Use the integer representation of the float value
						//

						sector_relative_centre.z += 32768;

						sorting_slot->z = *( ( int * ) &sector_relative_centre.z );

						sorting_slot->cloud_sector.x = current_sector_x;

						sorting_slot->cloud_sector.z = current_sector_z;

						insert_middle_scene_slot_into_3d_scene ( sorting_slot );
					}
					else
					{

						debug_log ( "Run out of object slots!" );
					}
				}
			}

			current_sector_x_offset += CLOUD_3D_SECTOR_SIDE_LENGTH;
		}

		current_sector_z_offset += CLOUD_3D_SECTOR_SIDE_LENGTH;
	}
}
コード例 #4
0
ファイル: mb_tgt.c プロジェクト: Comanche93/eech
int check_position_line_of_sight (entity *source, entity *target, vec3d *source_position, vec3d *target_position, mobile_los_check_criteria criteria)
{

	entity
		*collision_en;

	vec3d
		increment,
		collision_point,
		normal,
		#if LINE_DEBUG_MODULE
		old_position,
		#endif
		check_position,
		direction;

	float
		target_range,
		collision_distance,
		number_of_terrain_checks,
		terrain_elevation;

	terrain_3d_point_data
		terrain_info;

	ASSERT (source);

	ASSERT (target);

	ASSERT (source_position);

	ASSERT (target_position);

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

	target_range = sqrt ((direction.x * direction.x) + (direction.z * direction.z));

	normalise_3d_vector (&direction);
	
	////////////////////////////////////////////////////////////////
	// COARSE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_COURSE_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_COARSE_CHECK_DISTANCE;
	
		increment.x = direction.x * LOS_COARSE_CHECK_DISTANCE;
		increment.y = direction.y * LOS_COARSE_CHECK_DISTANCE;
		increment.z = direction.z * LOS_COARSE_CHECK_DISTANCE;
	
		check_position = *source_position;
	
		memset (&terrain_info, 0, sizeof (terrain_3d_point_data));
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x += increment.x;
			check_position.y += increment.y;
			check_position.z += increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed COURSE terrain LOS", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// SOURCE END FINE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_SOURCE_END_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_SOURCE_END;
	
		number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_SOURCE_END);
	
		increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
		increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
		increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_SOURCE_END;
	
		check_position = *source_position;
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x += increment.x;
			check_position.y += increment.y;
			check_position.z += increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// TARGET END FINE line of sight check with terrain
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_TARGET_END_TERRAIN)
	{
		number_of_terrain_checks = target_range / LOS_FINE_CHECK_DISTANCE_TARGET_END;
	
		number_of_terrain_checks = min (number_of_terrain_checks, LOS_NUMBER_OF_FINE_CHECKS_TARGET_END);
	
		increment.x = direction.x * LOS_FINE_CHECK_DISTANCE_TARGET_END;
		increment.y = direction.y * LOS_FINE_CHECK_DISTANCE_TARGET_END;
		increment.z = direction.z * LOS_FINE_CHECK_DISTANCE_TARGET_END;
	
		check_position = *target_position;
	
		while (number_of_terrain_checks > 1.0)
		{
			#if LINE_DEBUG_MODULE
	
			old_position = check_position;
	
			#endif
	
			check_position.x -= increment.x;
			check_position.y -= increment.y;
			check_position.z -= increment.z;
	
			get_3d_terrain_point_data (check_position.x, check_position.z, &terrain_info);
	
			terrain_elevation = get_3d_terrain_point_data_elevation (&terrain_info);
	
			if (terrain_elevation > check_position.y)
			{
	
				#if TEXT_DEBUG_MODULE
	
				debug_log ("MB_TGT: (%s -> %s) failed FINE terrain LOS (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME));
	
				#endif
	
				return FALSE;
			}
	
			#if LINE_DEBUG_MODULE
	
			create_debug_3d_line (&old_position, &check_position, sys_col_yellow, 10.0);
	
			#endif
	
			number_of_terrain_checks --;
		}
	}

	////////////////////////////////////////////////////////////////
	// SOURCE END line of sight check with objects
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_SOURCE_END_OBJECTS)
	{
		check_position.x = source_position->x + (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.y = source_position->y + (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.z = source_position->z + (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);

		collision_en = get_line_of_sight_collision_entity
							(
								source,
								target,
								source_position,
								&check_position,
								&collision_point,
								&normal
							);
	
		if (collision_en)
		{
	
			#if TEXT_DEBUG_MODULE

			debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (source end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en));
			
			#endif
	
			return FALSE;
		}
	}
	
	////////////////////////////////////////////////////////////////
	// TARGET END line of sight check with objects
	////////////////////////////////////////////////////////////////

	if (criteria &	MOBILE_LOS_CHECK_TARGET_END_OBJECTS)
	{	
		check_position.x = target_position->x - (direction.x * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.y = target_position->y - (direction.y * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);
		check_position.z = target_position->z - (direction.z * LOS_OBJECT_CHECK_DISTANCE_TARGET_END);

		collision_en = get_line_of_sight_collision_entity
							(
								source,
								target,
								target_position,
								&check_position,
								&collision_point,
								&normal
							);
	
		if (collision_en)
		{
			collision_distance = get_sqr_3d_range (&collision_point, target_position);

			if (collision_distance > (LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END * LOS_OBJECT_EXCLUDE_DISTANCE_TARGET_END))
			{
				#if TEXT_DEBUG_MODULE
			
				debug_log ("MB_TGT: (%s -> %s) failed OBJECT LOS with %s (target end)", get_local_entity_string (source, STRING_TYPE_FULL_NAME), get_local_entity_string (target, STRING_TYPE_FULL_NAME), get_local_entity_type_name (collision_en));
			
				#endif
	
				return FALSE;
			}
		}
	}

	return TRUE;
}
コード例 #5
0
ファイル: cm_rvrs.c プロジェクト: DexterWard/comanche
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);
}
コード例 #6
0
ファイル: sh_move.c プロジェクト: DexterWard/comanche
void ship_vehicle_movement (entity *en)
{
	ship_vehicle
		*raw;

	entity
		*guide,
		*current_waypoint;

	vec3d
		wp_pos,
		wp_vec,
		new_pos;

	float
		roll,
		pitch,
		heading,
		sqr_range,
		turn_rate,
		required_heading,
		delta_heading,
		current_velocity,
		new_velocity;

	raw = get_local_entity_data (en);

	//
	// abort if mobile is not moving (i.e. landed, or dead)
	//

	if (!get_local_entity_int_value (en, INT_TYPE_MOBILE_MOVING))
	{

		return;
	}

	//
	// abort if the mobile has no PRIMARY guide (also stops ships from moving if just engaging)
	//

	guide = get_local_entity_primary_guide (en);

	if (!guide)
	{
		return;
	}

	current_waypoint = get_local_entity_parent (guide, LIST_TYPE_CURRENT_WAYPOINT);

	ASSERT (current_waypoint);

	current_velocity = raw->vh.mob.velocity;

	//
	// GET WAYPOINT POSITION
	//

	ship_movement_get_waypoint_position (en, &wp_pos);

	wp_vec.x = wp_pos.x - raw->vh.mob.position.x;
	wp_vec.y = 0;
	wp_vec.z = wp_pos.z - raw->vh.mob.position.z;

	sqr_range = ((wp_vec.x * wp_vec.x) + (wp_vec.z * wp_vec.z));

	#if DEBUG_MODULE

	create_vectored_debug_3d_object (&wp_pos, (vec3d *) &raw->vh.mob.attitude [1], OBJECT_3D_RED_ARROW, 0, 0.20);

	#endif
	
	// ????
	if (fabs (sqr_range) < 1 * CENTIMETRE)
	{
		wp_vec.z = 0;
		wp_vec.y = 0;
		wp_vec.z = 1;
	}

	////////////////////////////////////////
	//
	// angles
	//
	////////////////////////////////////////

	// heading

	normalise_3d_vector (&wp_vec);

	heading = get_heading_from_attitude_matrix (raw->vh.mob.attitude);

	required_heading = atan2 (wp_vec.x, wp_vec.z);

	{

		float
			angle,
			range,
			v;

		range = sqrt (sqr_range);
	
		v = sqrt (0.5 * range * vehicle_database [raw->vh.mob.sub_type].g_max);

		angle = ((raw->vh.mob.attitude [2][0] * wp_vec.x) + (raw->vh.mob.attitude [2][2] * wp_vec.z));

		if (angle < 0.707) // 45 degs.
		{

			// wp behind ship
	
			#if DEBUG_MODULE
		
			debug_log ("SH_MOVE: ship cannot reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max);

			#endif

			new_velocity = bound (v, 0.0, get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY));
		}
		else
		{
	
			#if DEBUG_MODULE
		
			debug_log ("SH_MOVE: ship can reach wp at vel %f m/s (max v %f), range %f, g %f", raw->vh.mob.velocity, v, range, vehicle_database [raw->vh.mob.sub_type].g_max);

			#endif

			new_velocity = get_local_entity_float_value (guide, FLOAT_TYPE_VELOCITY);
		}
	}

	turn_rate = 0.0;

	if (raw->vh.mob.velocity != 0.0)
	{

		turn_rate = fabs (vehicle_database [raw->vh.mob.sub_type].g_max / raw->vh.mob.velocity);
	}

	delta_heading = required_heading - heading;

	if (delta_heading <= -PI)
	{

		delta_heading += PI2;
	}

	if (delta_heading >= PI)
	{

		delta_heading -= PI2;
	}

	delta_heading = bound (delta_heading, -turn_rate, turn_rate);

	heading += delta_heading * get_entity_movement_delta_time ();

	pitch = 0.0;

	roll = 0.0;

	////////////////////////////////////////
	//
	// attitude
	//
	////////////////////////////////////////

	get_3d_transformation_matrix (raw->vh.mob.attitude, heading, rad (pitch), rad (roll));

	////////////////////////////////////////
	//
	// velocity
	//
	////////////////////////////////////////

	{
		float
			maximum_acceleration,
			required_acceleration;

		required_acceleration = (new_velocity - raw->vh.mob.velocity);

		maximum_acceleration = get_local_entity_float_value (en, FLOAT_TYPE_MAX_ACCELERATION);
		
		raw->vh.mob.velocity += min (required_acceleration, maximum_acceleration) * get_entity_movement_delta_time ();
	}

	////////////////////////////////////////
	//
	// position
	//
	////////////////////////////////////////

	new_pos.x = raw->vh.mob.position.x + (raw->vh.mob.velocity * raw->vh.mob.zv.x * get_entity_movement_delta_time ());
	new_pos.y = 0.0;
	new_pos.z = raw->vh.mob.position.z + (raw->vh.mob.velocity * raw->vh.mob.zv.z * get_entity_movement_delta_time ());

	bound_position_to_map_volume (&new_pos);

	//
	// Calculate motion vector for view system
	//

	raw->vh.mob.motion_vector.x = (new_pos.x - raw->vh.mob.position.x) * get_one_over_delta_time ();
	raw->vh.mob.motion_vector.y = 0.0;
	raw->vh.mob.motion_vector.z = (new_pos.z - raw->vh.mob.position.z) * get_one_over_delta_time ();

	new_pos.y = 0.0;

	set_local_entity_vec3d (en, VEC3D_TYPE_POSITION, &new_pos);
}
コード例 #7
0
ファイル: terrtree.c プロジェクト: Comanche93/eech
void draw_3d_terrain_tree ( object_3d_instance *obj )
{

	int
		object_number;

	object_3d_info
		*this_object_3d_info;

	light_3d_source
		*this_light,
		*prev_light,
		*light_ptr,
		*light;

	vec3d
		*pos;
	
	vec3d
		object_camera_position,
		object_pos;

	//
	// Set up the object drawing global variables
	//

	object_3d_points_current_base = 0;

	object_3d_object_current_base = 0;

	object_3d_light_3d_current_base = 0;

	//
	// Calculate the object's position relative to the view.
	//

	pos = &obj->rel_vp.position;

	{

		float
			fog_intensity;

		int
			ifog_intensity;

		fog_intensity = get_fog_distance_value ( pos->z );

		convert_float_to_int ( fog_intensity, &ifog_intensity );

		set_d3d_fog_face_intensity ( ifog_intensity );
	}

	//
	// Set the main objects' scaling values
	//

	object_3d_scale.x = obj->relative_scale.x;
	object_3d_scale.y = obj->relative_scale.y;
	object_3d_scale.z = obj->relative_scale.z;

	//
	// Calculate the object's rotation matrix, to transform its 3d points relative to the view.
	//

	rotation_3d[0][0] = ( obj->vp.xv.x * visual_3d_vp->xv.x + obj->vp.xv.y * visual_3d_vp->xv.y + obj->vp.xv.z * visual_3d_vp->xv.z );
	rotation_3d[0][1] = ( obj->vp.xv.x * visual_3d_vp->yv.x + obj->vp.xv.y * visual_3d_vp->yv.y + obj->vp.xv.z * visual_3d_vp->yv.z );
	rotation_3d[0][2] = ( obj->vp.xv.x * visual_3d_vp->zv.x + obj->vp.xv.y * visual_3d_vp->zv.y + obj->vp.xv.z * visual_3d_vp->zv.z );

	rotation_3d[1][0] = ( obj->vp.yv.x * visual_3d_vp->xv.x + obj->vp.yv.y * visual_3d_vp->xv.y + obj->vp.yv.z * visual_3d_vp->xv.z );
	rotation_3d[1][1] = ( obj->vp.yv.x * visual_3d_vp->yv.x + obj->vp.yv.y * visual_3d_vp->yv.y + obj->vp.yv.z * visual_3d_vp->yv.z );
	rotation_3d[1][2] = ( obj->vp.yv.x * visual_3d_vp->zv.x + obj->vp.yv.y * visual_3d_vp->zv.y + obj->vp.yv.z * visual_3d_vp->zv.z );

	rotation_3d[2][0] = ( obj->vp.zv.x * visual_3d_vp->xv.x + obj->vp.zv.y * visual_3d_vp->xv.y + obj->vp.zv.z * visual_3d_vp->xv.z );
	rotation_3d[2][1] = ( obj->vp.zv.x * visual_3d_vp->yv.x + obj->vp.zv.y * visual_3d_vp->yv.y + obj->vp.zv.z * visual_3d_vp->yv.z );
	rotation_3d[2][2] = ( obj->vp.zv.x * visual_3d_vp->zv.x + obj->vp.zv.y * visual_3d_vp->zv.y + obj->vp.zv.z * visual_3d_vp->zv.z );

	rotation_3d[0][0] *= object_3d_scale.x;
	rotation_3d[1][0] *= object_3d_scale.y;
	rotation_3d[2][0] *= object_3d_scale.z;

	rotation_3d[0][1] *= object_3d_scale.x;
	rotation_3d[1][1] *= object_3d_scale.y;
	rotation_3d[2][1] *= object_3d_scale.z;

	rotation_3d[0][2] *= object_3d_scale.x;
	rotation_3d[1][2] *= object_3d_scale.y;
	rotation_3d[2][2] *= object_3d_scale.z;

	//
	// Calculate the vector from the object to the viewpoint, in the object's view system
	//

	{

		float
			x,
			y,
			z;

		x = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.xv.x );
		x += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.xv.y );
		x += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.xv.z );

		y = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.yv.x );
		y += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.yv.y );
		y += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.yv.z );

		z = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.zv.x );
		z += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.zv.y );
		z += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.zv.z );

		object_pos.x = x;
		object_pos.y = y;
		object_pos.z = z;
	}

	//
	// Get the object number
	//

	object_number = get_object_approximation_number ( obj->object_number, pos->z, &object_3d_approximation_level );

	//
	// Rotate the light source vector to be relative to the object.
	//

	light_ptr = current_3d_lights;

	prev_light = NULL;

	light = NULL;

	if ( light_ptr )
	{

		light = &light_3d_array[object_3d_light_3d_current_base];

		while ( light_ptr )
		{

			float
				lx,
				ly,
				lz;

			if ( light_ptr->type == LIGHT_3D_TYPE_POINT )
			{

				vec3d
					vector;

				float
					distance;

				//
				// Work out the distance from object to light source
				//

				vector.x = - light_ptr->light_position.x + obj->vp.x;
				vector.y = - light_ptr->light_position.y + obj->vp.y;
				vector.z = - light_ptr->light_position.z + obj->vp.z;

				lx = vector.x * vector.x;
				ly = vector.y * vector.y;
				lz = vector.z * vector.z;

				distance = ( lx + ly + lz );

				if ( distance < light_ptr->radius )
				{

					distance = 1 - ( distance / light_ptr->radius );

					this_light = &light_3d_array[object_3d_light_3d_current_base];
			
					object_3d_light_3d_current_base++;
		
					if ( prev_light )
					{
		
						prev_light->succ = this_light;
					}
		
					this_light->pred = prev_light;
					this_light->succ = NULL;
		
					this_light->type = light_ptr->type;

					this_light->colour.red = light_ptr->colour.red * distance;
					this_light->colour.green = light_ptr->colour.green * distance;
					this_light->colour.blue = light_ptr->colour.blue * distance;
//					this_light->colour.intensity = light_ptr->colour.intensity * distance;

					normalise_3d_vector ( &vector );

					lx = ( vector.x * obj->vp.attitude[0][0] );
					lx += ( vector.y * obj->vp.attitude[0][1] );
					lx += ( vector.z * obj->vp.attitude[0][2] );
		
					ly = ( vector.x * obj->vp.attitude[1][0] );
					ly += ( vector.y * obj->vp.attitude[1][1] );
					ly += ( vector.z * obj->vp.attitude[1][2] );
		
					lz = ( vector.x * obj->vp.attitude[2][0] );
					lz += ( vector.y * obj->vp.attitude[2][1] );
					lz += ( vector.z * obj->vp.attitude[2][2] );
		
					this_light->lx = lx;
					this_light->ly = ly;
					this_light->lz = lz;
		
					prev_light = this_light;
				}
			}
			else
			{
	
				this_light = &light_3d_array[object_3d_light_3d_current_base];
		
				object_3d_light_3d_current_base++;
	
				if ( prev_light )
				{
	
					prev_light->succ = this_light;
				}
	
				this_light->pred = prev_light;
				this_light->succ = NULL;
	
				this_light->type = light_ptr->type;

				this_light->colour.red = light_ptr->colour.red;
				this_light->colour.green = light_ptr->colour.green;
				this_light->colour.blue = light_ptr->colour.blue;
//				this_light->colour.intensity = light_ptr->colour.intensity;
	
				lx = ( light_ptr->lx * obj->vp.attitude[0][0] );
				lx +=  ( light_ptr->ly * obj->vp.attitude[0][1] );
				lx += ( light_ptr->lz * obj->vp.attitude[0][2] );
	
				ly = ( light_ptr->lx * obj->vp.attitude[1][0] );
				ly += ( light_ptr->ly * obj->vp.attitude[1][1] );
				ly += ( light_ptr->lz * obj->vp.attitude[1][2] );
	
	
				lz = ( light_ptr->lx * obj->vp.attitude[2][0] );
				lz += ( light_ptr->ly * obj->vp.attitude[2][1] );
				lz += ( light_ptr->lz * obj->vp.attitude[2][2] );
	
				this_light->lx = lx;
				this_light->ly = ly;
				this_light->lz = lz;
	
				prev_light = this_light;
			}
	
			light_ptr = light_ptr->succ;
		}
	}

	{

		vec3d
			rel_pos;

		//
		// Calculate the relative camera position in the object viewspace
		//

		rel_pos.x = visual_3d_vp->x - obj->vp.x;
		rel_pos.y = visual_3d_vp->y - obj->vp.y;
		rel_pos.z = visual_3d_vp->z - obj->vp.z;

		object_camera_position.x = ( rel_pos.x * obj->vp.attitude[0][0] + rel_pos.y * obj->vp.attitude[1][0] + rel_pos.z * obj->vp.attitude[2][0] );
		object_camera_position.y = ( rel_pos.x * obj->vp.attitude[0][1] + rel_pos.y * obj->vp.attitude[1][1] + rel_pos.z * obj->vp.attitude[2][1] );
		object_camera_position.z = ( rel_pos.x * obj->vp.attitude[0][2] + rel_pos.y * obj->vp.attitude[1][2] + rel_pos.z * obj->vp.attitude[2][2] );
	}

	//
	//	Set up this objects' object info structure
	//

	object_3d_object_base[object_3d_object_current_base].lights = light;

	object_3d_object_base[object_3d_object_current_base].camera_position = object_camera_position;

	object_3d_object_base[object_3d_object_current_base].points_base = object_3d_points_current_base;

	object_3d_object_base[object_3d_object_current_base].object_number = object_number;

	this_object_3d_info = &object_3d_object_base[object_3d_object_current_base];

	global_object_3d_info = this_object_3d_info;

	//
	// Transform the object's shape data
	//

	//
	// Setup the objects scaling information
	//

	{

		float
			xdistance,
			ydistance,
			zdistance;

		xdistance = ( objects_3d_data[object_number].bounding_box.xmax - objects_3d_data[object_number].bounding_box.xmin ) / 2;
		ydistance = ( objects_3d_data[object_number].bounding_box.ymax - objects_3d_data[object_number].bounding_box.ymin ) / 2;
		zdistance = ( objects_3d_data[object_number].bounding_box.zmax - objects_3d_data[object_number].bounding_box.zmin ) / 2;

		object_3d_x_middle = objects_3d_data[object_number].bounding_box.xmin + xdistance;
		object_3d_y_middle = objects_3d_data[object_number].bounding_box.ymin + ydistance;
		object_3d_z_middle = objects_3d_data[object_number].bounding_box.zmin + zdistance;

		object_3d_x_scale = xdistance / 32767.0;
		object_3d_y_scale = ydistance / 32767.0;
		object_3d_z_scale = zdistance / 32767.0;
	}
/*
	if ( objects_3d_data[object_number].number_of_points )
	{

		int
			object_outcode;

		object_outcode = get_object_3d_outcode ( object_number, pos );

		if ( object_outcode )
		{

			transform_3d_object ( &objects_3d_data[object_number], pos, light, object_3d_points_current_base);
		}
		else
		{

			transform_unclipped_3d_object ( &objects_3d_data[object_number], pos, light, object_3d_points_current_base);
		}


		polygon_zdistance_bias = POLYGON_ZDISTANCE_NORMAL_BIAS;

		set_d3d_int_state ( D3DRENDERSTATE_CULLMODE, D3DCULL_CW );

		if ( object_outcode )
		{

			draw_3d_terrain_tree_clipped_faces ( object_number, this_object_3d_info );
		}
		else
		{

			draw_3d_terrain_tree_unclipped_faces ( object_number, this_object_3d_info );
		}

		set_d3d_int_state ( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW );

		if ( object_outcode )
		{

			draw_3d_terrain_tree_clipped_faces ( object_number, this_object_3d_info );
		}
		else
		{

			draw_3d_terrain_tree_unclipped_faces ( object_number, this_object_3d_info );
		}
	}
	*/
}