public FRawAnimSequenceTrack(FArchive Ar) { PosKeys = Ar.ReadBulkArray <FVector>(); RotKeys = Ar.ReadBulkArray <FQuat>(); if (Ar.Ver >= EUnrealEngineObjectUE4Version.ANIM_SUPPORT_NONUNIFORM_SCALE_ANIMATION) { ScaleKeys = Ar.ReadBulkArray <FVector>(); } }
public FMeshMapBuildData(FArchive Ar) { LightMap = new FLightMap(Ar); ShadowMap = new FLightMap(Ar); IrrelevantLights = Ar.ReadArray <FGuid>(); PerInstanceLightmapData = Ar.ReadBulkArray <FPerInstanceLightmapData>(); }
public FMultisizeIndexContainer(FArchive Ar) : this() { if (Ar.Ver < EUnrealEngineObjectUE4Version.KEEP_SKEL_MESH_INDEX_DATA) { Ar.Position += 4; //var bOldNeedsCPUAccess = Ar.ReadBoolean(); } var dataSize = Ar.Read <byte>(); if (dataSize == 0x02) { Indices16 = Ar.ReadBulkArray <ushort>(); } else { Indices32 = Ar.ReadBulkArray <uint>(); } }
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 }
public FRawStaticIndexBuffer(FArchive Ar) : this() { if (Ar.Ver < EUnrealEngineObjectUE4Version.SUPPORT_32BIT_STATIC_MESH_INDICES) { Indices16 = Ar.ReadBulkArray <ushort>(); } else { var is32bit = Ar.ReadBoolean(); var data = Ar.ReadBulkArray <byte>(); var tempAr = new FByteArchive("IndicesReader", data, Ar.Versions); if (Ar.Versions["RawIndexBuffer.HasShouldExpandTo32Bit"]) { var bShouldExpandTo32Bit = Ar.ReadBoolean(); } if (tempAr.Length == 0) { tempAr.Dispose(); return; } if (is32bit) { var count = (int)tempAr.Length / 4; Indices32 = tempAr.ReadArray <uint>(count); } else { var count = (int)tempAr.Length / 2; Indices16 = tempAr.ReadArray <ushort>(count); } tempAr.Dispose(); } }
public FRawStaticIndexBuffer(FArchive Ar) : this() { if (Ar.Ver < UE4Version.VER_UE4_SUPPORT_32BIT_STATIC_MESH_INDICES) { Indices16 = Ar.ReadBulkArray <ushort>(); } else { var is32bit = Ar.ReadBoolean(); var data = Ar.ReadBulkArray <byte>(); var tempAr = new FByteArchive("IndicesReader", data, Ar.Versions); if (Ar.Game >= EGame.GAME_UE4_25) { Ar.Position += 4; } if (tempAr.Length == 0) { tempAr.Dispose(); return; } if (is32bit) { var count = (int)tempAr.Length / 4; Indices32 = tempAr.ReadArray <uint>(count); } else { var count = (int)tempAr.Length / 2; Indices16 = tempAr.ReadArray <ushort>(count); } tempAr.Dispose(); } }
public FColorVertexBuffer(FArchive Ar) { var stripDataFlags = new FStripDataFlags(Ar, (int)UE4Version.VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX); Stride = Ar.Read <int>(); NumVertices = Ar.Read <int>(); if (!stripDataFlags.IsDataStrippedForServer() & NumVertices > 0) { Data = Ar.ReadBulkArray <FColor>(); } else { Data = new FColor[0]; } }
public FModelVertexBuffer(FArchive Ar) { if (FRenderingObjectVersion.Get(Ar) < FRenderingObjectVersion.Type.IncreaseNormalPrecision) { var deprecatedVertices = Ar.ReadBulkArray <FDeprecatedModelVertex>(); Vertices = new FModelVertex[deprecatedVertices.Length]; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = deprecatedVertices[i]; } } else { Vertices = Ar.ReadArray(() => new FModelVertex(Ar)); } }
public FColorVertexBuffer(FArchive Ar) { var stripDataFlags = new FStripDataFlags(Ar, FPackageFileVersion.CreateUE4Version(EUnrealEngineObjectUE4Version.STATIC_SKELETAL_MESH_SERIALIZATION_FIX)); Stride = Ar.Read <int>(); NumVertices = Ar.Read <int>(); if (!stripDataFlags.IsDataStrippedForServer() & NumVertices > 0) { Data = Ar.ReadBulkArray <FColor>(); } else { Data = Array.Empty <FColor>(); } }
public FSkinWeightVertexBuffer(FArchive Ar, bool numSkelCondition) { var bNewWeightFormat = FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.UnlimitedBoneInfluences; #region FSkinWeightDataVertexBuffer var dataStripFlags = Ar.Read <FStripDataFlags>(); #region FSkinWeightDataVertexBuffer::SerializeMetaData bool bVariableBonesPerVertex; bool bExtraBoneInfluences; uint maxBoneInfluences; bool bUse16BitBoneIndex; uint numVertices; uint numBones; if (Ar.Game < EGame.GAME_UE4_24) { bExtraBoneInfluences = Ar.ReadBoolean(); numVertices = Ar.Read <uint>(); maxBoneInfluences = bExtraBoneInfluences ? 8u : 4u; } else if (!bNewWeightFormat) { bExtraBoneInfluences = Ar.ReadBoolean(); if (FSkeletalMeshCustomVersion.Get(Ar) >= FSkeletalMeshCustomVersion.Type.SplitModelAndRenderData) { Ar.Position += 4; // var stride = Ar.Read<uint>(); } numVertices = Ar.Read <uint>(); maxBoneInfluences = bExtraBoneInfluences ? 8u : 4u; numBones = maxBoneInfluences * numVertices; bVariableBonesPerVertex = false; } else { bVariableBonesPerVertex = Ar.ReadBoolean(); maxBoneInfluences = Ar.Read <uint>(); numBones = Ar.Read <uint>(); numVertices = Ar.Read <uint>(); bExtraBoneInfluences = maxBoneInfluences > _NUM_INFLUENCES_UE4; // bUse16BitBoneIndex doesn't exist before version IncreaseBoneIndexLimitPerChunk if (FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.IncreaseBoneIndexLimitPerChunk) { bUse16BitBoneIndex = Ar.ReadBoolean(); } } #endregion byte[] newData = Array.Empty <byte>(); if (!dataStripFlags.IsDataStrippedForServer()) { if (!bNewWeightFormat) { Weights = Ar.ReadBulkArray(() => new FSkinWeightInfo(Ar, bExtraBoneInfluences)); } else { newData = Ar.ReadBulkArray <byte>(); } } else { bExtraBoneInfluences = numSkelCondition; } #endregion if (bNewWeightFormat) { #region FSkinWeightLookupVertexBuffer var lookupStripFlags = Ar.Read <FStripDataFlags>(); #region FSkinWeightLookupVertexBuffer::SerializeMetaData //if (bNewWeightFormat) //{ var numLookupVertices = Ar.Read <int>(); //} #endregion if (!lookupStripFlags.IsDataStrippedForServer()) { Ar.ReadBulkArray <uint>(); // LookupData } #endregion // Convert influence data if (newData.Length > 0) { using var tempAr = new FByteArchive("WeightsReader", newData, Ar.Versions); Weights = new FSkinWeightInfo[numVertices]; for (var i = 0; i < Weights.Length; i++) { Weights[i] = new FSkinWeightInfo(tempAr, bExtraBoneInfluences); } } } }
public FPositionVertexBuffer(FArchive Ar) { Stride = Ar.Read <int>(); NumVertices = Ar.Read <int>(); Verts = Ar.ReadBulkArray <FVector>(); }
public readonly FStaticMeshUVItem[] UV; // TangentsData ? public FStaticMeshVertexBuffer(FArchive Ar) { var stripDataFlags = new FStripDataFlags(Ar, (int)UE4Version.VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX); // SerializeMetaData NumTexCoords = Ar.Read <int>(); Strides = Ar.Game < EGame.GAME_UE4_19 ? Ar.Read <int>() : -1; NumVertices = Ar.Read <int>(); UseFullPrecisionUVs = Ar.ReadBoolean(); UseHighPrecisionTangentBasis = Ar.Game >= EGame.GAME_UE4_12 && Ar.ReadBoolean(); if (!stripDataFlags.IsDataStrippedForServer()) { if (Ar.Game < EGame.GAME_UE4_19) { UV = Ar.ReadBulkArray(() => new FStaticMeshUVItem(Ar, UseHighPrecisionTangentBasis, NumTexCoords, UseFullPrecisionUVs)); } else { // BulkSerialize var itemSize = Ar.Read <int>(); var itemCount = Ar.Read <int>(); var position = Ar.Position; if (itemCount != NumVertices) { throw new ParserException($"NumVertices={itemCount} != NumVertices={NumVertices}"); } var tempTangents = Ar.ReadArray(NumVertices, () => FStaticMeshUVItem.SerializeTangents(Ar, UseHighPrecisionTangentBasis)); if (Ar.Position - position != itemCount * itemSize) { throw new ParserException($"Read incorrect amount of tangent bytes, at {Ar.Position}, should be: {position + itemSize * itemCount} behind: {position + (itemSize * itemCount) - Ar.Position}"); } itemSize = Ar.Read <int>(); itemCount = Ar.Read <int>(); position = Ar.Position; if (itemCount != NumVertices * NumTexCoords) { throw new ParserException($"NumVertices={itemCount} != {NumVertices * NumTexCoords}"); } var uv = Ar.ReadArray(NumVertices, () => FStaticMeshUVItem.SerializeTexcoords(Ar, NumTexCoords, UseFullPrecisionUVs)); if (Ar.Position - position != itemCount * itemSize) { throw new ParserException($"Read incorrect amount of Texture Coordinate bytes, at {Ar.Position}, should be: {position + itemSize * itemCount} behind: {position + (itemSize * itemCount) - Ar.Position}"); } UV = new FStaticMeshUVItem[NumVertices]; for (var i = 0; i < NumVertices; i++) { UV[i] = new FStaticMeshUVItem(tempTangents[i], uv[i]); } } } else { UV = new FStaticMeshUVItem[0]; } }
public readonly FStaticMeshUVItem[] UV; // TangentsData ? public FStaticMeshVertexBuffer(FArchive Ar) { var stripDataFlags = new FStripDataFlags(Ar, FPackageFileVersion.CreateUE4Version(EUnrealEngineObjectUE4Version.STATIC_SKELETAL_MESH_SERIALIZATION_FIX)); // SerializeMetaData NumTexCoords = Ar.Read <int>(); Strides = Ar.Game < EGame.GAME_UE4_19 ? Ar.Read <int>() : -1; NumVertices = Ar.Read <int>(); UseFullPrecisionUVs = Ar.ReadBoolean(); UseHighPrecisionTangentBasis = Ar.Game >= EGame.GAME_UE4_12 && Ar.ReadBoolean(); if (!stripDataFlags.IsDataStrippedForServer()) { if (Ar.Game < EGame.GAME_UE4_19) { UV = Ar.ReadBulkArray(() => new FStaticMeshUVItem(Ar, UseHighPrecisionTangentBasis, NumTexCoords, UseFullPrecisionUVs)); } else { var tempTangents = Array.Empty <FPackedNormal[]>(); if (Ar.Game == EGame.GAME_StarWarsJediFallenOrder && Ar.ReadBoolean()) // bDropNormals { goto texture_coordinates; } // BulkSerialize var itemSize = Ar.Read <int>(); var itemCount = Ar.Read <int>(); var position = Ar.Position; if (itemCount != NumVertices) { throw new ParserException($"NumVertices={itemCount} != NumVertices={NumVertices}"); } tempTangents = Ar.ReadArray(NumVertices, () => FStaticMeshUVItem.SerializeTangents(Ar, UseHighPrecisionTangentBasis)); if (Ar.Position - position != itemCount * itemSize) { throw new ParserException($"Read incorrect amount of tangent bytes, at {Ar.Position}, should be: {position + itemSize * itemCount} behind: {position + (itemSize * itemCount) - Ar.Position}"); } texture_coordinates: itemSize = Ar.Read <int>(); itemCount = Ar.Read <int>(); position = Ar.Position; if (itemCount != NumVertices * NumTexCoords) { throw new ParserException($"NumVertices={itemCount} != {NumVertices * NumTexCoords}"); } var uv = Ar.ReadArray(NumVertices, () => FStaticMeshUVItem.SerializeTexcoords(Ar, NumTexCoords, UseFullPrecisionUVs)); if (Ar.Position - position != itemCount * itemSize) { throw new ParserException($"Read incorrect amount of Texture Coordinate bytes, at {Ar.Position}, should be: {position + itemSize * itemCount} behind: {position + (itemSize * itemCount) - Ar.Position}"); } UV = new FStaticMeshUVItem[NumVertices]; for (var i = 0; i < NumVertices; i++) { if (Ar.Game == EGame.GAME_StarWarsJediFallenOrder && tempTangents.Length == 0) { UV[i] = new FStaticMeshUVItem(new [] { new FPackedNormal(0), new FPackedNormal(0), new FPackedNormal(0) }, uv[i]); } else { UV[i] = new FStaticMeshUVItem(tempTangents[i], uv[i]); } } } } else { UV = Array.Empty <FStaticMeshUVItem>(); } }