// Pre-UE4.23 code public void SerializeBuffersLegacy(FAssetArchive Ar, FStripDataFlags stripDataFlags) { PositionVertexBuffer = new FPositionVertexBuffer(Ar); VertexBuffer = new FStaticMeshVertexBuffer(Ar); if (Ar.Game == EGame.GAME_BORDERLANDS3) { var numColorStreams = Ar.Read <int>(); ColorVertexBuffer = new FColorVertexBuffer(Ar); for (var i = 0; i < numColorStreams - 1; i++) { var _ = new FColorVertexBuffer(Ar); } } else { ColorVertexBuffer = new FColorVertexBuffer(Ar); } IndexBuffer = new FRawStaticIndexBuffer(Ar); if (Ar.Ver >= UE4Version.VER_UE4_SOUND_CONCURRENCY_PACKAGE && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_ReversedIndexBuffer)) { ReversedIndexBuffer = new FRawStaticIndexBuffer(Ar); DepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); ReversedDepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); } else { // UE4.8 or older, or when has CDSF_ReversedIndexBuffer DepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (Ar.Ver is >= UE4Version.VER_UE4_FTEXT_HISTORY and < UE4Version.VER_UE4_RENAME_CROUCHMOVESCHARACTERDOWN) { new FDistanceFieldVolumeData(Ar); // distanceFieldData } if (!stripDataFlags.IsEditorDataStripped()) { WireframeIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (!stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { AdjacencyIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (Ar.Game >= EGame.GAME_UE4_16) { for (var i = 0; i < Sections.Length; i++) { new FWeightedRandomSampler(Ar); } new FWeightedRandomSampler(Ar); } }
public void SerializeBuffers(FArchive Ar) { var stripDataFlags = Ar.Read <FStripDataFlags>(); PositionVertexBuffer = new FPositionVertexBuffer(Ar); VertexBuffer = new FStaticMeshVertexBuffer(Ar); ColorVertexBuffer = new FColorVertexBuffer(Ar); if (Ar.Game == EGame.GAME_RogueCompany) { var _ = new FColorVertexBuffer(Ar); } IndexBuffer = new FRawStaticIndexBuffer(Ar); if (!stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_ReversedIndexBuffer)) { ReversedIndexBuffer = new FRawStaticIndexBuffer(Ar); } DepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); if (!stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_ReversedIndexBuffer)) { ReversedDepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (!stripDataFlags.IsEditorDataStripped()) { WireframeIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (FUE5ReleaseStreamObjectVersion.Get(Ar) < FUE5ReleaseStreamObjectVersion.Type.RemovingTessellation && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { AdjacencyIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (Ar.Versions["StaticMesh.HasRayTracingGeometry"] && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_RayTracingResources)) { var _ = Ar.ReadBulkArray <byte>(); // rayTracingGeometry } // https://github.com/EpicGames/UnrealEngine/blob/4.27/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp#L547 var areaWeightedSectionSamplers = new FWeightedRandomSampler[Sections.Length]; for (var i = 0; i < Sections.Length; i++) { areaWeightedSectionSamplers[i] = new FWeightedRandomSampler(Ar); } _ = new FWeightedRandomSampler(Ar); // areaWeightedSampler }
private void SerializeStreamedData(FArchive Ar, bool bHasVertexColors) { var stripDataFlags = Ar.Read <FStripDataFlags>(); Indices = new FMultisizeIndexContainer(Ar); VertexBufferGPUSkin = new FSkeletalMeshVertexBuffer { bUseFullPrecisionUVs = true }; var positionVertexBuffer = new FPositionVertexBuffer(Ar); var staticMeshVertexBuffer = new FStaticMeshVertexBuffer(Ar); var skinWeightVertexBuffer = new FSkinWeightVertexBuffer(Ar, VertexBufferGPUSkin.bExtraBoneInfluences); if (bHasVertexColors) { var newColorVertexBuffer = new FColorVertexBuffer(Ar); ColorVertexBuffer = new FSkeletalMeshVertexColorBuffer(newColorVertexBuffer.Data); } if (FUE5ReleaseStreamObjectVersion.Get(Ar) < FUE5ReleaseStreamObjectVersion.Type.RemovingTessellation && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { AdjacencyIndexBuffer = new FMultisizeIndexContainer(Ar); } if (HasClothData()) { ClothVertexBuffer = new FSkeletalMeshVertexClothBuffer(Ar); } var skinWeightProfilesData = new FSkinWeightProfilesData(Ar); if (Ar.Game >= EGame.GAME_UE5_0) // Note: This was added in UE4.27, but we're only reading it on UE5 for compatibility with Fortnite { var rayTracingData = Ar.ReadArray <byte>(); } NumVertices = positionVertexBuffer.NumVertices; NumTexCoords = staticMeshVertexBuffer.NumTexCoords; VertexBufferGPUSkin.VertsFloat = new FGPUVertFloat[NumVertices]; for (var i = 0; i < VertexBufferGPUSkin.VertsFloat.Length; i++) { VertexBufferGPUSkin.VertsFloat[i] = new FGPUVertFloat { Pos = positionVertexBuffer.Verts[i], Infs = skinWeightVertexBuffer.Weights[i], Normal = staticMeshVertexBuffer.UV[i].Normal, UV = staticMeshVertexBuffer.UV[i].UV }; } }
private void SerializeRenderItem_Legacy(FAssetArchive Ar, bool bHasVertexColors, byte numVertexColorChannels) { var stripDataFlags = Ar.Read <FStripDataFlags>(); Sections = new FSkelMeshSection[Ar.Read <int>()]; for (var i = 0; i < Sections.Length; i++) { Sections[i] = new FSkelMeshSection(); Sections[i].SerializeRenderItem(Ar); } Indices = new FMultisizeIndexContainer(Ar); VertexBufferGPUSkin = new FSkeletalMeshVertexBuffer { bUseFullPrecisionUVs = true }; ActiveBoneIndices = Ar.ReadArray <short>(); RequiredBones = Ar.ReadArray <short>(); if (!stripDataFlags.IsDataStrippedForServer() && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_MinLodData)) { var positionVertexBuffer = new FPositionVertexBuffer(Ar); var staticMeshVertexBuffer = new FStaticMeshVertexBuffer(Ar); var skinWeightVertexBuffer = new FSkinWeightVertexBuffer(Ar, VertexBufferGPUSkin.bExtraBoneInfluences); if (!bHasVertexColors && Ar.Game == EGame.GAME_BORDERLANDS3) { for (var i = 0; i < numVertexColorChannels; i++) { var newColorVertexBuffer = new FColorVertexBuffer(Ar); ColorVertexBuffer = new FSkeletalMeshVertexColorBuffer(newColorVertexBuffer.Data); } } else if (bHasVertexColors) { var newColorVertexBuffer = new FColorVertexBuffer(Ar); ColorVertexBuffer = new FSkeletalMeshVertexColorBuffer(newColorVertexBuffer.Data); } if (!stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { AdjacencyIndexBuffer = new FMultisizeIndexContainer(Ar); } if (HasClothData()) { ClothVertexBuffer = new FSkeletalMeshVertexClothBuffer(Ar); } NumVertices = positionVertexBuffer.NumVertices; NumTexCoords = staticMeshVertexBuffer.NumTexCoords; VertexBufferGPUSkin.VertsFloat = new FGPUVertFloat[NumVertices]; for (var i = 0; i < VertexBufferGPUSkin.VertsFloat.Length; i++) { VertexBufferGPUSkin.VertsFloat[i] = new FGPUVertFloat { Pos = positionVertexBuffer.Verts[i], Infs = skinWeightVertexBuffer.Weights[i], Normal = staticMeshVertexBuffer.UV[i].Normal, UV = staticMeshVertexBuffer.UV[i].UV }; } } if (Ar.Game >= EGame.GAME_UE4_23) { var skinWeightProfilesData = new FSkinWeightProfilesData(Ar); } }
// Pre-UE4.23 code public void SerializeBuffersLegacy(FAssetArchive Ar, FStripDataFlags stripDataFlags) { PositionVertexBuffer = new FPositionVertexBuffer(Ar); VertexBuffer = new FStaticMeshVertexBuffer(Ar); if (Ar.Game == EGame.GAME_Borderlands3) { var numColorStreams = Ar.Read <int>(); if (numColorStreams != 0) { ColorVertexBuffer = new FColorVertexBuffer(Ar); for (var i = 0; i < numColorStreams - 1; i++) { var _ = new FColorVertexBuffer(Ar); } } } else { ColorVertexBuffer = new FColorVertexBuffer(Ar); } IndexBuffer = new FRawStaticIndexBuffer(Ar); if (Ar.Game != EGame.GAME_PlayerUnknownsBattlegrounds || !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_StripIndexBuffers)) { if (Ar.Ver >= EUnrealEngineObjectUE4Version.SOUND_CONCURRENCY_PACKAGE && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_ReversedIndexBuffer)) { ReversedIndexBuffer = new FRawStaticIndexBuffer(Ar); DepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); ReversedDepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); } else { // UE4.8 or older, or when has CDSF_ReversedIndexBuffer DepthOnlyIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (Ar.Ver >= EUnrealEngineObjectUE4Version.FTEXT_HISTORY && Ar.Ver < EUnrealEngineObjectUE4Version.RENAME_CROUCHMOVESCHARACTERDOWN) { var _ = new FDistanceFieldVolumeData(Ar); // distanceFieldData } if (!stripDataFlags.IsEditorDataStripped()) { WireframeIndexBuffer = new FRawStaticIndexBuffer(Ar); } if (!stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { AdjacencyIndexBuffer = new FRawStaticIndexBuffer(Ar); } } if (Ar.Game > EGame.GAME_UE4_16) { for (var i = 0; i < Sections.Length; i++) { var _ = new FWeightedRandomSampler(Ar); } _ = new FWeightedRandomSampler(Ar); } }