public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); bStreaming = Ar.Game >= EGame.GAME_UE4_25; if (TryGetValue(out bool s, nameof(bStreaming))) // will return false if not found { bStreaming = s; } else if (TryGetValue(out FName loadingBehavior, "LoadingBehavior")) { bStreaming = !loadingBehavior.IsNone && loadingBehavior.Text != "ESoundWaveLoadingBehavior::ForceInline"; } bCooked = Ar.ReadBoolean(); if (!bStreaming) { if (bCooked) { CompressedFormatData = new FFormatContainer(Ar); } else { RawData = new FByteBulkData(Ar); } CompressedDataGuid = Ar.Read <FGuid>(); } else { CompressedDataGuid = Ar.Read <FGuid>(); RunningPlatformData = new FStreamedAudioPlatformData(Ar); } }
public FTexture2DMipMap(FAssetArchive Ar) { SizeZ = 1; var cooked = Ar.Ver >= UE4Version.VER_UE4_TEXTURE_SOURCE_ART_REFACTOR && Ar.ReadBoolean(); Data = new FByteBulkData(Ar); if (Ar.Game == EGame.GAME_BORDERLANDS3) { SizeX = Ar.Read <ushort>(); SizeY = Ar.Read <ushort>(); SizeZ = Ar.Read <ushort>(); } else { SizeX = Ar.Read <int>(); SizeY = Ar.Read <int>(); if (Ar.Game >= EGame.GAME_UE4_20) { SizeZ = Ar.Read <int>(); } } if (Ar.Ver >= UE4Version.VER_UE4_TEXTURE_DERIVED_DATA2 && !cooked) { var derivedDataKey = Ar.ReadFString(); } }
public FDistanceFieldVolumeData5(FAssetArchive Ar) { LocalSpaceMeshBounds = Ar.Read <FBox>(); bMostlyTwoSided = Ar.ReadBoolean(); Mips = Ar.ReadArray <FSparseDistanceFieldMip>(DistanceField.NumMips); AlwaysLoadedMip = Ar.ReadArray <byte>(); StreamableMips = new FByteBulkData(Ar); }
public FStreamedAudioChunk(FAssetArchive Ar) { if (Ar.ReadBoolean()) // bCooked { BulkData = new FByteBulkData(Ar); DataSize = Ar.Read <int>(); AudioDataSize = Ar.Read <int>(); } else { Ar.Position -= sizeof(int); throw new ParserException(Ar, "StreamedAudioChunks must be cooked"); } }
public FVirtualTextureDataChunk(FAssetArchive Ar, uint numLayers) { CodecType = new EVirtualTextureCodec[numLayers]; CodecPayloadOffset = new ushort[numLayers]; SizeInBytes = Ar.Read <uint>(); CodecPayloadSize = Ar.Read <uint>(); for (uint layerIndex = 0u; layerIndex < numLayers; ++layerIndex) { CodecType[layerIndex] = Ar.Read <EVirtualTextureCodec>(); CodecPayloadOffset[layerIndex] = Ar.Read <ushort>(); } BulkData = new FByteBulkData(Ar); }
public FNaniteResources(FAssetArchive Ar) { var stripFlags = new FStripDataFlags(Ar); if (!stripFlags.IsDataStrippedForServer()) { ResourceFlags = Ar.Read <uint>(); RootClusterPage = Ar.ReadArray <byte>(); StreamableClusterPages = new FByteBulkData(Ar); PageStreamingStates = Ar.ReadArray <FPageStreamingState>(); HierarchyNodes = Ar.ReadArray(() => new FPackedHierarchyNode(Ar)); HierarchyRootOffsets = Ar.ReadArray <uint>(); PageDependencies = Ar.ReadArray <uint>(); ImposterAtlas = Ar.ReadArray <ushort>(); PositionPrecision = Ar.Read <int>(); NumInputTriangles = Ar.Read <uint>(); NumInputVertices = Ar.Read <uint>(); NumInputMeshes = Ar.Read <ushort>(); NumInputTexCoords = Ar.Read <ushort>(); } }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); bStreaming = Ar.Game >= EGame.GAME_UE4_25 && Ar.Game != EGame.GAME_GTATheTrilogyDefinitiveEdition && Ar.Game != EGame.GAME_ReadyOrNot; if (TryGetValue(out bool s, nameof(bStreaming))) // will return false if not found { bStreaming = s; } else if (TryGetValue(out FName loadingBehavior, "LoadingBehavior")) { bStreaming = !loadingBehavior.IsNone && loadingBehavior.Text != "ESoundWaveLoadingBehavior::ForceInline"; } bCooked = Ar.ReadBoolean(); if (Ar.Ver >= EUnrealEngineObjectUE4Version.SOUND_COMPRESSION_TYPE_ADDED && FFrameworkObjectVersion.Get(Ar) < FFrameworkObjectVersion.Type.RemoveSoundWaveCompressionName) { Ar.ReadFName(); // DummyCompressionName } if (!bStreaming) { if (bCooked) { CompressedFormatData = new FFormatContainer(Ar); } else { RawData = new FByteBulkData(Ar); } CompressedDataGuid = Ar.Read <FGuid>(); } else { CompressedDataGuid = Ar.Read <FGuid>(); RunningPlatformData = new FStreamedAudioPlatformData(Ar); } }
public FTexture2DMipMap(FAssetArchive Ar) { var cooked = Ar.Ver >= EUnrealEngineObjectUE4Version.TEXTURE_SOURCE_ART_REFACTOR && Ar.Game < EGame.GAME_UE5_0 ? Ar.ReadBoolean() : Ar.IsFilterEditorOnly; Data = new FByteBulkData(Ar); if (Ar.Game == EGame.GAME_Borderlands3) { SizeX = Ar.Read <ushort>(); SizeY = Ar.Read <ushort>(); SizeZ = Ar.Read <ushort>(); } else { SizeX = Ar.Read <int>(); SizeY = Ar.Read <int>(); SizeZ = Ar.Game >= EGame.GAME_UE4_20 ? Ar.Read <int>() : 1; } if (Ar.Ver >= EUnrealEngineObjectUE4Version.TEXTURE_DERIVED_DATA2 && !cooked) { var derivedDataKey = Ar.ReadFString(); } }
public FAkMediaDataChunk(FAssetArchive Ar) { IsPrefetch = Ar.ReadBoolean(); Data = new FByteBulkData(Ar); }
public void SerializeRenderItem(FAssetArchive Ar, bool bHasVertexColors, byte numVertexColorChannels) { if (Ar.Game < EGame.GAME_UE4_24) { SerializeRenderItem_Legacy(Ar, bHasVertexColors, numVertexColorChannels); return; } var stripDataFlags = Ar.Read <FStripDataFlags>(); var bIsLODCookedOut = Ar.ReadBoolean(); var bInlined = Ar.ReadBoolean(); RequiredBones = Ar.ReadArray <short>(); if (!stripDataFlags.IsDataStrippedForServer() && !bIsLODCookedOut) { Sections = new FSkelMeshSection[Ar.Read <int>()]; for (var i = 0; i < Sections.Length; i++) { Sections[i] = new FSkelMeshSection(); Sections[i].SerializeRenderItem(Ar); } ActiveBoneIndices = Ar.ReadArray <short>(); Ar.Position += 4; //var buffersSize = Ar.Read<uint>(); if (bInlined) { SerializeStreamedData(Ar, bHasVertexColors); if (Ar.Game == EGame.GAME_ROGUECOMPANY) { Ar.Position += 10; // FStripDataFlags, ElementSize, ElementCount Ar.SkipBulkArrayData(); Ar.Position += 10; } } else { var bulk = new FByteBulkData(Ar); if (bulk.Header.ElementCount > 0) { using (var tempAr = new FByteArchive("LodReader", bulk.Data, Ar.Versions)) { SerializeStreamedData(tempAr, bHasVertexColors); } var skipBytes = 5; if (FUE5ReleaseStreamObjectVersion.Get(Ar) < FUE5ReleaseStreamObjectVersion.Type.RemovingTessellation && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { skipBytes += 5; } skipBytes += 4 * 4 + 2 * 4 + 2 * 4; skipBytes += FSkinWeightVertexBuffer.MetadataSize(Ar); Ar.Position += skipBytes; if (HasClothData()) { var clothIndexMapping = Ar.ReadArray <long>(); Ar.Position += 2 * 4; } var profileNames = Ar.ReadArray(Ar.ReadFName); } } } }
public FStaticMeshLODResources(FAssetArchive Ar) { var stripDataFlags = Ar.Read <FStripDataFlags>(); Sections = Ar.ReadArray(() => new FStaticMeshSection(Ar)); MaxDeviation = Ar.Read <float>(); if (Ar.Game < EGame.GAME_UE4_23) { if (!stripDataFlags.IsDataStrippedForServer() && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_MinLodData)) { SerializeBuffersLegacy(Ar, stripDataFlags); } return; } var bIsLODCookedOut = Ar.ReadBoolean(); var bInlined = Ar.ReadBoolean(); if (Ar.Game == EGame.GAME_ROGUECOMPANY) { bInlined = true; } if (!stripDataFlags.IsDataStrippedForServer() && !bIsLODCookedOut) { if (bInlined) { SerializeBuffers(Ar); if (Ar.Game == EGame.GAME_ROGUECOMPANY) { Ar.Position += 10; } } else { var bulkData = new FByteBulkData(Ar); if (bulkData.Header.ElementCount > 0) { var tempAr = new FByteArchive("StaticMeshBufferReader", bulkData.Data, Ar.Versions); SerializeBuffers(tempAr); tempAr.Dispose(); } // https://github.com/EpicGames/UnrealEngine/blob/4.27/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp#L560 Ar.Position += 8; // DepthOnlyNumTriangles + Packed Ar.Position += 4 * 4 + 2 * 4 + 2 * 4 + 5 * 2 * 4; // StaticMeshVertexBuffer = 2x int32, 2x bool // PositionVertexBuffer = 2x int32 // ColorVertexBuffer = 2x int32 // IndexBuffer = int32 + bool // ReversedIndexBuffer // DepthOnlyIndexBuffer // ReversedDepthOnlyIndexBuffer // WireframeIndexBuffer if (FUE5ReleaseStreamObjectVersion.Get(Ar) < FUE5ReleaseStreamObjectVersion.Type.RemovingTessellation) { Ar.Position += 2 * 4; // AdjacencyIndexBuffer } } } // FStaticMeshBuffersSize // uint32 SerializedBuffersSize = 0; // uint32 DepthOnlyIBSize = 0; // uint32 ReversedIBsSize = 0; Ar.Position += 12; }
// UE ref https://github.com/EpicGames/UnrealEngine/blob/26450a5a59ef65d212cf9ce525615c8bd673f42a/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp#L710 public void SerializeRenderItem(FAssetArchive Ar, bool bHasVertexColors, byte numVertexColorChannels) { var stripDataFlags = Ar.Read <FStripDataFlags>(); var bIsLODCookedOut = false; if (Ar.Game != EGame.GAME_Splitgate) { bIsLODCookedOut = Ar.ReadBoolean(); } var bInlined = Ar.ReadBoolean(); RequiredBones = Ar.ReadArray <short>(); if (!stripDataFlags.IsDataStrippedForServer() && !bIsLODCookedOut) { Sections = new FSkelMeshSection[Ar.Read <int>()]; for (var i = 0; i < Sections.Length; i++) { Sections[i] = new FSkelMeshSection(); Sections[i].SerializeRenderItem(Ar); } ActiveBoneIndices = Ar.ReadArray <short>(); if (Ar.Game == EGame.GAME_KenaBridgeofSpirits) { Ar.ReadArray <byte>(); // EAssetType_array1 } Ar.Position += 4; //var buffersSize = Ar.Read<uint>(); if (bInlined) { SerializeStreamedData(Ar, bHasVertexColors); if (Ar.Game == EGame.GAME_RogueCompany) { Ar.Position += 12; // 1 (Long) + 2^16 (Int) var elementSize = Ar.Read <int>(); var elementCount = Ar.Read <int>(); if (elementSize > 0 && elementCount > 0) { Ar.SkipBulkArrayData(); } } } else { var bulk = new FByteBulkData(Ar); if (bulk.Header.ElementCount > 0) { using (var tempAr = new FByteArchive("LodReader", bulk.Data, Ar.Versions)) { SerializeStreamedData(tempAr, bHasVertexColors); } var skipBytes = 5; if (FUE5ReleaseStreamObjectVersion.Get(Ar) < FUE5ReleaseStreamObjectVersion.Type.RemovingTessellation && !stripDataFlags.IsClassDataStripped((byte)EClassDataStripFlag.CDSF_AdjacencyData)) { skipBytes += 5; } skipBytes += 4 * 4 + 2 * 4 + 2 * 4; skipBytes += FSkinWeightVertexBuffer.MetadataSize(Ar); Ar.Position += skipBytes; if (HasClothData()) { var clothIndexMapping = Ar.ReadArray <long>(); Ar.Position += 2 * 4; } var profileNames = Ar.ReadArray(Ar.ReadFName); } } } if (Ar.Game == EGame.GAME_ReadyOrNot) { Ar.Position += 4; } }