Пример #1
0
void UStaticMesh::SerializeLegacySouceData(FArchive& Ar, const FBoxSphereBounds& LegacyBounds)
{
	int32 InternalVersion = 0;
	bool bHaveSourceData = false;
	TArray<FStaticMeshOptimizationSettings> OptimizationSettings;
	bool bHasBeenSimplified = false;

	Ar << InternalVersion;
	Ar << bHaveSourceData;
	if (bHaveSourceData)
	{
		FStaticMeshSourceModel& SrcModel = *new(SourceModels) FStaticMeshSourceModel();

		// Serialize in the old source render data.
		FLegacyStaticMeshRenderData TempRenderData;
		TempRenderData.Serialize(Ar, this, INDEX_NONE);

		// Convert it to a raw mesh.
		FRawMesh RawMesh;
		BuildRawMeshFromRenderData(RawMesh, SrcModel.BuildSettings, TempRenderData, *GetPathName());

		// Store the raw mesh as our source model.
		SrcModel.RawMeshBulkData->SaveRawMesh(RawMesh);
	}
	Ar << OptimizationSettings;
	Ar << bHasBeenSimplified;

	// Convert any old optimization settings to the source model's reduction settings.
	for (int32 i = 0; i < OptimizationSettings.Num(); ++i)
	{
		if (!SourceModels.IsValidIndex(i))
		{
			new(SourceModels) FStaticMeshSourceModel();
		}
		FStaticMeshSourceModel& SrcModel = SourceModels[i];

		FMeshReductionSettings& NewSettings = SrcModel.ReductionSettings;
		switch (OptimizationSettings[i].ReductionMethod)
		{
		case OT_NumOfTriangles:
			NewSettings.PercentTriangles = FMath::Clamp(OptimizationSettings[i].NumOfTrianglesPercentage / 100.0f, 0.0f, 1.0f);
			NewSettings.MaxDeviation = 0.0f;
			break;
		case OT_MaxDeviation:
			NewSettings.PercentTriangles = 1.0f;
			NewSettings.MaxDeviation = OptimizationSettings[i].MaxDeviationPercentage * LegacyBounds.SphereRadius;
			break;
		default:
			NewSettings.PercentTriangles = 1.0f;
			NewSettings.MaxDeviation = 0.0f;
			break;
		}
		NewSettings.WeldingThreshold = OptimizationSettings[i].WeldingThreshold;
		NewSettings.HardAngleThreshold = OptimizationSettings[i].NormalsThreshold;
		NewSettings.SilhouetteImportance = (EMeshFeatureImportance::Type)OptimizationSettings[i].SilhouetteImportance;
		NewSettings.TextureImportance = (EMeshFeatureImportance::Type)OptimizationSettings[i].TextureImportance;
		NewSettings.ShadingImportance = (EMeshFeatureImportance::Type)OptimizationSettings[i].ShadingImportance;
	}

	// Serialize in any legacy LOD models.
	TIndirectArray<FLegacyStaticMeshRenderData> LegacyLODModels;
	LegacyLODModels.Serialize(Ar, this);

	TArray<FLegacyStaticMeshLODInfo> LegacyLODInfo;
	Ar << LegacyLODInfo;

	for (int32 LODIndex = 0; LODIndex < LegacyLODModels.Num(); ++LODIndex)
	{
		if (!SourceModels.IsValidIndex(LODIndex))
		{
			new(SourceModels) FStaticMeshSourceModel();
		}
		FStaticMeshSourceModel& SrcModel = SourceModels[LODIndex];

		// Really we want to use LOD0 only if the mesh has /not/ been simplified.
		// Unfortunately some data seems to be corrupted in source meshes but not LOD0, so just use LOD0.
		//if (SrcModel.RawMeshBulkData->IsEmpty() && (!bHasBeenSimplified || LODIndex == 0))
		{
			// Store the raw mesh for this LOD.
			FRawMesh RawMesh;
			BuildRawMeshFromRenderData(RawMesh, SrcModel.BuildSettings, LegacyLODModels[LODIndex], *GetPathName());
			SrcModel.RawMeshBulkData->SaveRawMesh(RawMesh);
		}

		// And make sure to clear reduction settings for LOD0.
		if (LODIndex == 0)
		{
			FMeshReductionSettings DefaultSettings;
			SrcModel.ReductionSettings = DefaultSettings;
		}

		// Always use a hash as the guid for legacy models.
		SrcModel.RawMeshBulkData->UseHashAsGuid(this);

		// Setup the material map for this LOD model.
		if (LODIndex == 0)
		{
			for (int32 SectionIndex = 0; SectionIndex < LegacyLODModels[LODIndex].Elements.Num(); ++SectionIndex)
			{
				FMeshSectionInfo Info;
				Info.MaterialIndex = Materials.Add(LegacyLODModels[LODIndex].Elements[SectionIndex].Material);
				Info.bEnableCollision = LegacyLODModels[LODIndex].Elements[SectionIndex].EnableCollision;
				Info.bCastShadow = LegacyLODModels[LODIndex].Elements[SectionIndex].bEnableShadowCasting;
				SectionInfoMap.Set(LODIndex, SectionIndex, Info);
			}
		}
		else
		{
			for (int32 SectionIndex = 0; SectionIndex < LegacyLODModels[LODIndex].Elements.Num(); ++SectionIndex)
			{
				FMeshSectionInfo Info;
				Info.MaterialIndex = Materials.AddUnique(LegacyLODModels[LODIndex].Elements[SectionIndex].Material);
				Info.bEnableCollision = LegacyLODModels[LODIndex].Elements[SectionIndex].EnableCollision;
				Info.bCastShadow = LegacyLODModels[LODIndex].Elements[SectionIndex].bEnableShadowCasting;
				SectionInfoMap.Set(LODIndex, SectionIndex, Info);
			}
		}
	}
}