UE5 Runtime 加载obj模型

文章详细描述了如何使用FMeshUtils中的GetStaticMeshFromObjPath函数,从OBJ文件路径中解析几何数据并创建静态网格,包括面片、纹理坐标、法线等,并设置材质和SDF信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UStaticMesh* FMeshUtils::GetStaticMeshFromObjPath(const FString ObjPath, const FString MeshId, const FString ComponentId)
{
	if (ObjPath.IsEmpty() || !FPaths::FileExists(ObjPath))
	{
		UE_LOG( LogTemp, Error, TEXT("FMeshUtils::GetStaticMeshFromObjPath: %s is empty"), *ObjPath);
		return nullptr;
	}

	TPimplPtr<FObjData> ObjDataPtr = MakePimpl<FObjData>();
	ObjDataPtr->ObjFilename = ObjPath;
	static UE::MeshUtils::ObjParserUtils::FKeywordMap ObjKeywordMap =
	{
		{ TEXT("o"),      UE::MeshUtils::ObjParserUtils::ParseObjectName },
		{ TEXT("v"),      UE::MeshUtils::ObjParserUtils::ParseVertexPosition },
		{ TEXT("vt"),     UE::MeshUtils::ObjParserUtils::ParseTextureCoordinate },
		{ TEXT("vn"),     UE::MeshUtils::ObjParserUtils::ParseNormalVector },
		{ TEXT("f"),      UE::MeshUtils::ObjParserUtils::ParseFace },
		{ TEXT("g"),      UE::MeshUtils::ObjParserUtils::ParseGroup },
		{ TEXT("mtllib"), UE::MeshUtils::ObjParserUtils::ParseMaterialLib },
		{ TEXT("usemtl"), UE::MeshUtils::ObjParserUtils::ParseUseMaterial }
	};

	bool bSuccess = UE::MeshUtils::ObjParserUtils::ParseFile(*ObjDataPtr.Get(), *ObjPath, ObjKeywordMap);

	TArray<const FMeshDescription*> MeshDescriptionPointers;
	MeshDescriptionPointers.Reserve(ObjDataPtr->Groups.Num());
	TArray<FMeshDescription> LodMeshDescriptions;
	for (auto It = ObjDataPtr->Groups.CreateIterator(); It; ++It)
	{
		const FMeshDescription MeshDesc = ObjDataPtr->MakeMeshDescriptionForGroup(It->Key, FTransform::Identity);
		LodMeshDescriptions.Add(MeshDesc);
	}
	for (const FMeshDescription& MeshDescription : LodMeshDescriptions)
	{
		MeshDescriptionPointers.Add(&MeshDescription);
	}

	FString SMName = MeshId + "_" + ComponentId;
	UStaticMesh* StaticMesh = NewObject<UStaticMesh>(GetTransientPackage(), FName(SMName), RF_Transient);

	//-----------Deal Static Mesh Description----------------
	UStaticMesh::FBuildMeshDescriptionsParams Params1 = UStaticMesh::FBuildMeshDescriptionsParams();
	Params1.bFastBuild = true;
	Params1.bBuildSimpleCollision = true;
	const UStaticMesh::FBuildMeshDescriptionsParams Params = Params1;
	StaticMesh->BuildFromMeshDescriptions(MeshDescriptionPointers,Params);

	// -----------Deal Static Material Slot----------------
	TArray<FStaticMaterial> InStaticMaterials;
	for (int i = 0; i< StaticMesh->GetRenderData()->LODResources[0].Sections.Num(); i++)
	{
		FStaticMaterial CurrentMaterial = FStaticMaterial();
		CurrentMaterial.MaterialInterface = UMaterial::GetDefaultMaterial(MD_Surface);
		CurrentMaterial.MaterialSlotName = FName(TEXT("MaterialSlot")+FString::FromInt(i));
		CurrentMaterial.UVChannelData.bInitialized = true;
		InStaticMaterials.Add(CurrentMaterial);
	}
	StaticMesh->SetStaticMaterials(InStaticMaterials);
	
	const FSourceMeshDataForDerivedDataTask SourceMeshDataForDerivedDataTask;
	FQueuedThreadPool* ThreadPool = FQueuedThreadPool::Allocate();
	TArray<FSignedDistanceFieldBuildMaterialData> MaterialBlendModes;
	MaterialBlendModes.SetNum(StaticMesh->GetRenderData()->LODResources[0].Sections.Num());
	const FBoxSphereBounds Bounds = StaticMesh->GetRenderData()->Bounds;
	
	// //----------Deal SDF----------------------
	FDistanceFieldVolumeData* GenDistanceFieldVolumeData = new FDistanceFieldVolumeData();
	// MeshUtilities->GenerateSignedDistanceFieldVolumeData(StaticMesh->GetName(), SourceMeshDataForDerivedDataTask, StaticMesh->GetRenderData()->LODResources[0], *ThreadPool, MaterialBlendModes, Bounds, 1.0, true, *GenDistanceFieldVolumeData);
	// StaticMesh->GetRenderData()->LODResources[0].DistanceFieldData = GenDistanceFieldVolumeData;
	
	//----------Deal Mesh Cards---------------
	FCardRepresentationData* GeneratedCardRepresentation = new FCardRepresentationData();
	const FDistanceFieldVolumeData* DistanceFieldVolumeData = GenDistanceFieldVolumeData;
	int MaxLumenMeshCards = 12;
	MeshUtilities->GenerateCardRepresentationData(StaticMesh->GetName(), SourceMeshDataForDerivedDataTask, StaticMesh->GetRenderData()->LODResources[0], *ThreadPool, MaterialBlendModes, Bounds, DistanceFieldVolumeData, MaxLumenMeshCards,true,*GeneratedCardRepresentation);
	StaticMesh->GetRenderData()->LODResources[0].CardRepresentationData = GeneratedCardRepresentation;

	return StaticMesh;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值