Exemple #1
0
bool FDerivedDataPhysXCooker::Build( TArray<uint8>& OutData )
{
	SCOPE_CYCLE_COUNTER(STAT_PhysXCooking);

	check(Cooker != NULL);

	FMemoryWriter Ar( OutData );
	uint8 bLittleEndian = PLATFORM_LITTLE_ENDIAN;	//TODO: We should pass the target platform into this function and write it. Then swap the endian on the writer so the reader doesn't have to do it at runtime
	int32 NumConvexElementsCooked = 0;
	int32 NumMirroredElementsCooked = 0;
	uint8 bTriMeshCooked = false;
	uint8 bMirroredTriMeshCooked = false;
	Ar << bLittleEndian;
	int64 CookedMeshInfoOffset = Ar.Tell();
	Ar << NumConvexElementsCooked;	
	Ar << NumMirroredElementsCooked;
	Ar << bTriMeshCooked;
	Ar << bMirroredTriMeshCooked;

	//TODO: we must save an id with convex and tri meshes for serialization. We must save this here and patch it up at runtime somehow

	// Cook convex meshes, but only if we are not forcing complex collision to be used as simple collision as well
	if( BodySetup && BodySetup->CollisionTraceFlag != CTF_UseComplexAsSimple && BodySetup->AggGeom.ConvexElems.Num() > 0 )
	{
		if( bGenerateNormalMesh )
		{
			NumConvexElementsCooked = BuildConvex( OutData, false );
		}
		if ( bGenerateMirroredMesh )
		{
			NumMirroredElementsCooked = BuildConvex( OutData, true );
		}
	}

	// Cook trimeshes, but only if we do not frce simple collision to be used as complex collision as well
	bool bUsingAllTriData = BodySetup != NULL ? BodySetup->bMeshCollideAll : false;
	if( (BodySetup == NULL || BodySetup->CollisionTraceFlag != CTF_UseSimpleAsComplex) && ShouldGenerateTriMeshData(bUsingAllTriData) )
	{
		if( bGenerateNormalMesh )
		{
			bTriMeshCooked = (uint8)BuildTriMesh( OutData, false, bUsingAllTriData );
		}
		if( bGenerateMirroredMesh && ShouldGenerateNegXTriMeshData() )
		{
			bMirroredTriMeshCooked = (uint8)BuildTriMesh( OutData, true, bUsingAllTriData );
		}
	}

	// Update info on what actually got cooked
	Ar.Seek( CookedMeshInfoOffset );
	Ar << NumConvexElementsCooked;	
	Ar << NumMirroredElementsCooked;
	Ar << bTriMeshCooked;
	Ar << bMirroredTriMeshCooked;

	// Whatever got cached return true. We want to cache 'failure' too.
	return true;
}
Exemple #2
0
int main( int argc, char *argv[] )
{
	char		*in_brush_name;
	char		*out_shape_name;
	char		*out_glmesh_name;
	char		*in_plane_name;
	char		*in_texdef_name;
	char		*in_texture_name;
	char		*in_tm_name;
	char		*path_name;
	
	hobj_t		*brush_root;	
	hmanager_t	*plane_hm;
	hmanager_t	*texdef_hm;
	hmanager_t	*texture_hm;
	hobj_t		*tm_root;
	hobj_t		*meshtile_root;

	hobj_search_iterator_t	brush_iter;
	hobj_search_iterator_t	surf_iter;
	hobj_search_iterator_t	surf2_iter;
	hobj_t		*brush;
	hobj_t		*surf;
	hobj_t		*surf2;
	
	hobj_t		*shape_root;
	hobj_t		*shape;
	FILE		*h;

	int		num_total_tris;

	char		tt[256];


	gld = GLD_BeginSession( "xxx" );
	GLD_StartRecord( gld );
	GLD_BeginList( gld, "polys", "line" );

	puts( "===== meshtile1 - create meshtiles from surfaces =====" );
	SetCmdArgs( argc, argv );

	if ( argc == 1 )
	{
		puts( "usage:" );
		puts( " -i	: input bspbrush class" );
		puts( " -o	: output shape class" );
		puts( " -obin	: output glmesh binary" );
		puts( " -pl	: input plane class" );
		puts( " -td	: input texdef class" );
		puts( " -tx	: input texture class" );
		puts( " -tm	: input texture material class" );
		puts( " -path	: config path to ./shape_config and ./meshtiles" );

		exit(-1);
	}

	in_brush_name = GetCmdOpt2( "-i" );
	out_shape_name = GetCmdOpt2( "-o" );
	out_glmesh_name = GetCmdOpt2( "-obin" );
	in_plane_name = GetCmdOpt2( "-pl" );
	in_texdef_name = GetCmdOpt2( "-td" );
	in_texture_name = GetCmdOpt2( "-tx" );
	in_tm_name = GetCmdOpt2( "-tm" );
	path_name = GetCmdOpt2( "-path" );

	if ( !in_brush_name )
		Error( "no input bspbrush class\n" );
	if ( !out_shape_name )
		Error( "no output shape class\n" );
	if ( !out_glmesh_name )
		Error( "no output glmesh binary\n" );
	if ( !in_plane_name )
		Error( "no input plane class\n" );
	if ( !in_texdef_name )
		Error( "no input texdef class\n" );
	if ( !in_texture_name )
		Error( "no input texture class\n" );
	if ( !in_tm_name )
		Error( "no input texture material class\n" );
	if ( !path_name )
		Error( "no config path\n" );

	brush_root = ReadClassFile( in_brush_name );
	if ( !brush_root )
		Error( "can't read bspbrush class\n" );

	texdef_hm = NewHManagerLoadClass( in_texdef_name );
	if ( !texdef_hm )
		Error( "can't read texdef class\n" );

	plane_hm = ReadPlaneClass( in_plane_name );

	texture_hm = NewHManagerLoadClass( in_texture_name );
	if ( !texture_hm )
		Error( "can't read texture class\n" );

	tm_root = ReadClassFile( in_tm_name );
	if ( !tm_root )
		Error( "can't read texture material class" );

	sprintf( tt, "%s/shape_config/meshtile.hobj", path_name );
	meshtile_root = ReadClassFile( tt );
	if ( !meshtile_root )
		Error( "can't read meshtile class ( %s )\n", tt );


	shape_root = NewClass( "shapes", "meshtiles0" );
	
	//
	// for all c5 brushes
	//

	num_total_tris = 0;

	InitClassSearchIterator( &brush_iter, brush_root, "bspbrush" );
	for ( ; ( brush = SearchGetNextClass( &brush_iter ) ) ; )
	{
		int		b_contents;
		int		num_surf;

		vec3d_t		v;
		hobj_t		*surf_poly_obj;
		polygon_t	*surf_poly;
		

		EasyFindInt( &b_contents, brush, "content" );
		if ( b_contents != 5 )
		{
			continue;
		}


		//
		// for all surfaces
		//
		InitClassSearchIterator( &surf_iter, brush, "surface" );
		for ( num_surf = 0; ( surf = SearchGetNextClass( &surf_iter ) ) ; num_surf++ )
		{
			int	s_contents;

			hobj_t	*plane;
			hobj_t	*texdef;
			hobj_t	*texture;
			hobj_t	*meshtile;
			hpair_t	*pair;
			hpair_t	*mat_pair;
#if 1
			EasyFindInt( &s_contents, surf, "content" );

			if ( !(s_contents & 32) )
			{				
				// no substructur flag
				continue;
			}
#endif
//			GenerateMeshtile( surf, plane_hm, texdef_hm, 

			plane = EasyLookupClsref( surf, "plane", plane_hm );
			texdef = EasyLookupClsref( surf, "texdef", texdef_hm );
			texture = EasyLookupClsref( texdef, "texture", texture_hm );

			pair = FindHPair( texture, "ident" );
			if ( !pair )
				Error( "missing key 'ident'\n" );

			meshtile = FindClass( meshtile_root, pair->value );
			if ( !meshtile )
			{
				Error( "no meshtile defs for ident '%s'\n", pair->value );
			}

			mat_pair = FindHPair( tm_root, pair->value );
			
			{
				int		i, j;
				vec3d_t		norm;
				fp_t		dist;

				hobj_t		*plane2;
				vec3d_t		norm2;
				fp_t		dist2;				

				fp_t		rotate;
				vec2d_t		shift;
				vec2d_t		scale;
				vec2d_t		vec0, vec1;

				fp_t		u_size, v_size, height;
				u_list_t	*raw_poly_list;


				u_list_t		*base_tile_mesh;
				

				surf_poly_obj = FindClassType( surf, "polygon" );
				surf_poly = CreatePolygonFromClass( surf_poly_obj );

				EasyFindVec3d( norm, plane, "norm" );
				EasyFindFloat( &dist, plane, "dist" );
				EasyFindVec2d( shift, texdef, "shift" );
				EasyFindVec2d( vec0, texdef, "vec0" );
				EasyFindVec2d( vec1, texdef, "vec1" );
			     

				if ( vec0[0] == 0.0 && vec0[1] == 0.0 )
				{
					vec0[0] = 1.0;
				}
				if ( vec1[0] == 0.0 && vec1[1] == 0.0 )
				{
					vec1[1] = 1.0;
				}

				EasyFindVec2d( scale, texdef, "scale" );
				EasyFindFloat( &rotate, texdef, "rotate" );
				
				EasyFindFloat( &u_size, meshtile, "u_size" );
				EasyFindFloat( &v_size, meshtile, "v_size" );
				EasyFindFloat( &height, meshtile, "height" );
				
				pair = FindHPair( meshtile, "raw_path" );
				if ( !pair )
					Error( "missing key 'raw_path'\n" );
				sprintf( tt, "%s/%s", path_name, pair->value );
				raw_poly_list = ReadPolygonList( tt );
				if ( !raw_poly_list )
					Error( "can't load raw polygons\n" );

				printf( "%s: %d raw polygons/tile \n", pair->value, U_ListLength( raw_poly_list ) );
				NormalizePolygonList( raw_poly_list );
				{
					vec3d_t		scl;
					scl[0] = u_size;
					scl[1] = v_size;
					scl[2] = height;
					ScalePolygonList( raw_poly_list, scl );
				}

				{
					vec3d_t		shf;
					shf[0] = 0.0;
					shf[1] = 0.0;
					shf[2] = -height;
					ShiftPolygonList( raw_poly_list, shf );
				}
				
				base_tile_mesh = GenBaseTileMesh( surf_poly, norm, dist, vec0, vec1, shift, raw_poly_list, u_size, v_size, rotate, scale );

				//
				// clip base by all surface planes
				//

				InitClassSearchIterator( &surf2_iter, brush, "surface" );
				for ( ; ( surf2 = SearchGetNextClass( &surf2_iter ) ) ; )
				{
					if ( surf2 == surf )
						continue;
					
					EasyFindInt( &s_contents, surf2, "content" );
					
					if ( !(s_contents & 32) )
					{				
						// no substructur flag
						continue;
					}

					plane2 = EasyLookupClsref( surf2, "plane", plane_hm );
					EasyFindVec3d( norm2, plane2, "norm" );
					EasyFindFloat( &dist2, plane2, "dist" );
					
					ClipPolygonList( base_tile_mesh, norm2, dist2 );
				}


				for ( i = 0; i < surf_poly->pointnum; i++ )
				{
					j = (i+1==surf_poly->pointnum)?0:(i+1);
					
					// search surf, which the edge is on
					InitClassSearchIterator( &surf2_iter, brush, "surface" );
					for ( ; ( surf2 = SearchGetNextClass( &surf2_iter ) ) ; )
					{
						if ( surf2 == surf )
							continue;

						plane2 = EasyLookupClsref( surf2, "plane", plane_hm );
						EasyFindVec3d( norm2, plane2, "norm" );
						EasyFindFloat( &dist2, plane2, "dist" );

						if ( fabs(Vec3dDotProduct( surf_poly->p[i], norm2 )-dist2 ) < 0.1 &&
						     fabs(Vec3dDotProduct( surf_poly->p[j], norm2 )-dist2 ) < 0.1 )
						{
							// that's the surf

							vec3d_t		delta1, delta2;
							vec3d_t		cross;
							
							Vec3dSub( delta1, surf_poly->p[j], surf_poly->p[i] );
							Vec3dAdd( delta2, norm, norm2 );
							Vec3dUnify( delta1 );
							Vec3dUnify( delta2 );
							
							Vec3dCrossProduct( cross, delta1, delta2 );
							Vec3dUnify( cross );

							dist2 = Vec3dInitPlane2( cross, surf_poly->p[i] );
							ClipPolygonList( base_tile_mesh, cross, dist2 );
							break;							
						}
					}					
				}

//				DrawPolygonList( base_tile_mesh );

				//
				// build meshtile shape
				//
				plane = EasyLookupClsref( surf, "plane", plane_hm );
				shape = BuildMeshTileShape( surf_poly_obj, plane, texdef, mat_pair, base_tile_mesh );
				BuildTriMesh( shape, base_tile_mesh );
				InsertClass( shape_root, shape );

				num_total_tris += U_ListLength( base_tile_mesh );
			}
			
			
		}
	}

	printf( " generated %d triangles\n", num_total_tris );

	GLD_EndList( gld );       
	GLD_Update( gld );
	GLD_Pause( gld );
	GLD_EndSession( gld );
	

	h = fopen( out_shape_name, "w" );
	if ( !h )
		Error( "can't write shape class\n" );
	WriteClass( shape_root, h );
	fclose( h );

	h = fopen( out_glmesh_name, "w" );
	if ( !h )
		Error( "can't write glmesh binary\n" );
	fwrite( glmesh_base, glmesh_ofs, 1, h );
	fclose( h );

	HManagerSaveID();

	exit(0);
}