コード例 #1
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;
	}
}
コード例 #2
0
ファイル: 3dstrail.c プロジェクト: Comanche93/eech
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 );
		}
	}
}
コード例 #3
0
ファイル: 3dline.c プロジェクト: Comanche93/eech
int insert_zbiased_polyline_into_3d_scene ( int number_of_points, float zbias, int lit, rgb_colour colour, vec3d *points )
{

	polyline_point
		*rotated_points;

	int
		count,
		visible;

	real_colour
		polyline_colour;

	if ( exclusive_3d_instance )
	{

		return ( FALSE );
	}

	//
	// First, ensure we have enough memory
	//

	if ( number_of_3d_polyline_points + number_of_points > MAX_POLYLINE_POINTS )
	{

		return ( FALSE );
	}

	if ( number_of_3d_polylines + 1 > MAX_POLYLINES )
	{

		return ( FALSE );
	}

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

	visible = FALSE;

	rotated_points = &polyline_points[number_of_3d_polyline_points];

	//
	// Copy the colour value
	//

	polyline_colour.red = colour.r;
	polyline_colour.green = colour.g;
	polyline_colour.blue = colour.b;
	polyline_colour.alpha = 0;

	if ( rotated_points )
	{

		visible = transform_3d_polyline_points ( number_of_points, points, rotated_points );

		if ( visible )
		{

			polyline_header
				*polyline;
	
			//
			// Some part ( or all ) of the polyline is visible
			//

			polyline = &polyline_headers[number_of_3d_polylines];

			number_of_3d_polylines++;

			number_of_3d_polyline_points += number_of_points;

			polyline->number_of_points = number_of_points;
	
			polyline->points = rotated_points;

			polyline->colour = polyline_colour;

			polyline->lit = lit;
	
			//
			// Now insert each segment dependant on it being visible or not.
			//
	
			for ( count = 0; count < ( number_of_points - 1 ); count++ )
			{
	
				if ( ( rotated_points[count].transformed_point.z > clip_hither ) || ( rotated_points[count+1].transformed_point.z > clip_hither ) )
				{
	
					scene_slot_drawing_list
						*buffer;
	
					float
						average_z;
	
					average_z = ( rotated_points[count].transformed_point.z + rotated_points[count+1].transformed_point.z ) / 2.0;
	
					average_z += zbias;
	
					buffer = get_3d_scene_slot ();
		
					if ( buffer )
					{
	
						buffer->type = OBJECT_3D_DRAW_TYPE_POLYLINE;
		
						buffer->z = *( ( int * ) &average_z );
		
						buffer->polyline.polyline = polyline;
	
						buffer->polyline.segment = count;
	
						if ( points[count].y > middle_scene_slot_height )
						{
		
							insert_high_zbuffered_scene_slot_into_3d_scene ( buffer );
						}
						else
						{
	
							insert_low_zbuffered_scene_slot_into_3d_scene ( buffer );
						}
					}
				}
			}
		}
	}

	return ( TRUE );
}