OpenCTM Mesh 转换为UE4 静态资源Asset

OpenCTM Mesh 转换为UE4 静态资源

CTMMesh顶点数据转换为UE4编辑器中的StaticMesh

RawMesh

生成UE4 静态资源使用的重要类FRawMesh
Raw mesh data used to construct optimized runtime rendering streams.

用于构建优化的运行时渲染流的原始网格数据。

生成 StaticMesh 本地资源文件

void DesBlockToMesh(const FString& blockId, BYTE* blockContent)
{
	//二进制ctm解析顶点、索引等信息
	CTMGeometry* geometry = new CTMGeometry(CTMGeometry::ECTMMode::IMPORT);
	if (geometry->LoadStream(blockContent))
	{
		auto vertices = geometry->GetVertices();
		auto indices = geometry->GetIndices();
		auto uv0s = geometry->GetUVs(CTMGeometry::UV0);
		auto normals = geometry->CalculateNormals(vertices, indices);
		auto tangents = geometry->CalculateTangents(vertices, indices, uv0s);

		FString PathName = FString(TEXT("/Game/Mesh/"));
		FString PackageName = PathName+blockId;

		//Raw mesh data we are filling in
		FRawMesh RawMesh;
		// Materials to apply to new mesh


		TArray<UMaterialInterface*> MeshMaterials;
		MeshMaterials.Add(UMaterial::GetDefaultMaterial(MD_Surface));
		//Material'/Game/mat/red.red'
		//UMaterial* Material1 = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("Material'/Game/Materials/M_BaseMaterial.M_BaseMaterial'"));
		//MeshMaterials.Add(Material1);
		
		// Copy verts
		for (FVector& Vert : vertices)
		{
			RawMesh.VertexPositions.Add(Vert);
		}
		// Copy 'wedge' info
		for (uint32& Idx : indices)
		{
			RawMesh.WedgeIndices.Add(Idx);

			FVector TangentX = tangents[Idx];
			FVector TangentZ = normals[Idx];
			FVector TangentY = (TangentX ^ TangentZ).GetSafeNormal();

			RawMesh.WedgeTangentX.Add(TangentX);
			RawMesh.WedgeTangentY.Add(TangentY);
			RawMesh.WedgeTangentZ.Add(TangentZ);

			RawMesh.WedgeTexCoords[0].Add(uv0s[Idx]);
			RawMesh.WedgeColors.Add(FColor());
		}

		// copy face info
		int32 NumTris = indices.Num() / 3;
		for (int32 TriIdx = 0; TriIdx < NumTris; TriIdx++)
		{
			RawMesh.FaceMaterialIndices.Add(0);
			RawMesh.FaceSmoothingMasks.Add(0); // Assume this is ignored as bRecomputeNormals is false
		}

		// If we got some valid data.
		if (RawMesh.VertexPositions.Num() > 3 && RawMesh.WedgeIndices.Num() > 3)
		{
			// Then find/create it.
			UPackage* Package = CreatePackage(NULL, *PackageName);
			// Create StaticMesh object
			UStaticMesh* StaticMesh = NewObject<UStaticMesh>(Package, FName(*blockId), RF_Public | RF_Standalone);
			StaticMesh->PreEditChange(nullptr);
			// Add source to new StaticMesh
			FStaticMeshSourceModel& SrcModel = StaticMesh->AddSourceModel();
			SrcModel.SaveRawMesh(RawMesh);

			// Copy materials to new mesh
			for (UMaterialInterface* Material : MeshMaterials)
			{
				StaticMesh->StaticMaterials.Add(FStaticMaterial(Material));
			}

			// Build mesh from source
			TArray< FText > BuildErrors;
			StaticMesh->Build(true, &BuildErrors);
			StaticMesh->PostEditChange();

			// Notify asset registry of new asset
			FAssetRegistryModule::AssetCreated(StaticMesh);
		}
	}
	delete geometry;
	geometry = nullptr;
}


Result

1

2

参考

  1. UE4尝试用C++生成一个最简单的StaticMesh
  2. UE4实验观察FRawMesh的数据结构
  3. 批量绘制ProceduralMesh并转化为StaticMesh资产
  4. OpenCTM
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值