예제 #1
0
 public FConnectivityCube(FArchive Ar)
 {
     for (int i = 0; i < Faces.Length; i++)
     {
         // Reference: FArchive& operator<<(FArchive&, TBitArray&)
         var numBits  = Ar.Read <int>();
         var numWords = numBits.DivideAndRoundUp(32);
         var data     = Ar.ReadArray <int>(numWords);
         Faces[i] = new BitArray(data)
         {
             Length = numBits
         };
     }
 }
        // public readonly FHashTable ShaderMapHashTable;
        // public readonly FHashTable ShaderHashTable;

        public FSerializedShaderArchive(FArchive Ar)
        {
            ShaderMapHashes  = Ar.ReadArray(() => new FSHAHash(Ar));
            ShaderHashes     = Ar.ReadArray(() => new FSHAHash(Ar));
            ShaderMapEntries = Ar.ReadArray <FShaderMapEntry>();
            ShaderEntries    = Ar.ReadArray <FShaderCodeEntry>();
            PreloadEntries   = Ar.ReadArray <FFileCachePreloadEntry>();
            ShaderIndices    = Ar.ReadArray <uint>();
        }
        public FSkeletalMeshVertexClothBuffer(FArchive Ar)
        {
            var stripDataFlags = new FStripDataFlags(Ar, (int)UE4Version.VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX);

            if (stripDataFlags.IsDataStrippedForServer())
            {
                return;
            }

            Ar.SkipBulkArrayData();
            if (FSkeletalMeshCustomVersion.Get(Ar) >= FSkeletalMeshCustomVersion.Type.CompactClothVertexBuffer)
            {
                ClothIndexMapping = Ar.ReadArray <ulong>();
            }
        }
예제 #4
0
        public FSkeletalMeshVertexClothBuffer(FArchive Ar)
        {
            var stripDataFlags = new FStripDataFlags(Ar, FPackageFileVersion.CreateUE4Version(EUnrealEngineObjectUE4Version.STATIC_SKELETAL_MESH_SERIALIZATION_FIX));

            if (stripDataFlags.IsDataStrippedForServer())
            {
                return;
            }

            Ar.SkipBulkArrayData();
            if (FSkeletalMeshCustomVersion.Get(Ar) >= FSkeletalMeshCustomVersion.Type.CompactClothVertexBuffer)
            {
                ClothIndexMapping = Ar.ReadArray <ulong>();
            }
        }
예제 #5
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));
     }
 }
예제 #6
0
        private static T[] ReadCArrayView <T>(FArchive Ar, Func <T> getter)
        {
            var initialPos           = Ar.Position;
            var arrayNum             = Ar.Read <int>();
            var offsetToDataFromThis = Ar.Read <int>();

            if (arrayNum == 0)
            {
                return(Array.Empty <T>());
            }

            var continuePos = Ar.Position;

            Ar.Position = initialPos + offsetToDataFromThis;
            var result = Ar.ReadArray(arrayNum, getter);

            Ar.Position = continuePos;
            return(result);
        }
예제 #7
0
        public FMeshToMeshVertData(FArchive Ar)
        {
            PositionBaryCoordsAndDist = Ar.Read <FVector4>();
            NormalBaryCoordsAndDist   = Ar.Read <FVector4>();
            TangentBaryCoordsAndDist  = Ar.Read <FVector4>();
            SourceMeshVertIndices     = Ar.ReadArray <short>(4);

            if (FReleaseObjectVersion.Get(Ar) < FReleaseObjectVersion.Type.WeightFMeshToMeshVertData)
            {
                // Old version had "uint32 Padding[2]"
                var discard = Ar.Read <uint>();
                Padding = Ar.Read <uint>();
            }
            else
            {
                // New version has "float Weight and "uint32 Padding"
                Weight  = Ar.Read <float>();
                Padding = Ar.Read <uint>();
            }
        }
예제 #8
0
        public FStaticMeshComponentLODInfo(FArchive Ar)
        {
            var stripFlags = new FStripDataFlags(Ar);

            if (!stripFlags.IsDataStrippedForServer())
            {
                MapBuildDataId = Ar.Read <FGuid>();
            }

            if (!stripFlags.IsClassDataStripped(OverrideColorsStripFlag))
            {
                var bLoadVertexColorData = Ar.Read <byte>();

                if (bLoadVertexColorData == 1)
                {
                    OverrideVertexColors = new FColorVertexBuffer(Ar);
                }
            }

            if (!stripFlags.IsEditorDataStripped())
            {
                PaintedVertices = Ar.ReadArray(() => new FPaintedVertex(Ar));
            }
        }
 public FWeightedRandomSampler(FArchive Ar)
 {
     Prob        = Ar.ReadArray <float>();
     Alias       = Ar.ReadArray <int>();
     TotalWeight = Ar.Read <float>();
 }
예제 #10
0
 public FCompressedOffsetDataBase(FArchive Ar)
 {
     OffsetData = Ar.ReadArray <T>();
     StripSize  = Ar.Read <int>();
 }
 public TEvaluationTreeEntryContainer(FArchive Ar)
 {
     Entries = Ar.ReadArray <FEntry>();
     Items   = Ar.ReadArray <T>();
 }
예제 #12
0
        public WwiseReader(FArchive Ar)
        {
            IdToString         = new Dictionary <uint, string>();
            WwiseEncodedMedias = new Dictionary <string, byte[]>();
            while (Ar.Position < Ar.Length)
            {
                var sectionIdentifier = Ar.Read <ESectionIdentifier>();
                var sectionLength     = Ar.Read <int>();
                var position          = Ar.Position;

                switch (sectionIdentifier)
                {
                case ESectionIdentifier.AKPK:
                    if (!Ar.ReadBoolean())
                    {
                        throw new ParserException(Ar, $"'{Ar.Name}' has unsupported endianness.");
                    }

                    Ar.Position += 16;
                    Folders      = Ar.ReadArray(() => new AkFolder(Ar));
                    foreach (var folder in Folders)
                    {
                        folder.PopulateName(Ar);
                    }
                    foreach (var folder in Folders)
                    {
                        folder.Entries = new AkEntry[Ar.Read <uint>()];
                        for (var i = 0; i < folder.Entries.Length; i++)
                        {
                            var entry = new AkEntry(Ar);
                            entry.Path = Folders[entry.FolderId].Name;

                            var savePos = Ar.Position;
                            Ar.Position       = entry.Offset;
                            entry.IsSoundBank = Ar.Read <ESectionIdentifier>() == ESectionIdentifier.BKHD;
                            Ar.Position      -= 4;
                            entry.Data        = Ar.ReadBytes(entry.Size);
                            Ar.Position       = savePos;

                            folder.Entries[i] = entry;
                        }
                    }
                    break;

                case ESectionIdentifier.BKHD:
                    Header = Ar.Read <BankHeader>();
                    break;

                case ESectionIdentifier.INIT:
                    Initialization = Ar.ReadArray(() =>
                    {
                        Ar.Position += 4;
                        return(Ar.ReadFString());
                    });
                    break;

                case ESectionIdentifier.DIDX:
                    WemIndexes = Ar.ReadArray(sectionLength / 12, Ar.Read <DataIndex>);
                    break;

                case ESectionIdentifier.DATA:
                    if (WemIndexes == null)
                    {
                        break;
                    }
                    WemSounds = new byte[WemIndexes.Length][];
                    for (var i = 0; i < WemSounds.Length; i++)
                    {
                        Ar.Position  = position + WemIndexes[i].Offset;
                        WemSounds[i] = Ar.ReadBytes(WemIndexes[i].Length);
                        WwiseEncodedMedias[WemIndexes[i].Id.ToString()] = WemSounds[i];
                    }
                    break;

                case ESectionIdentifier.HIRC:
                    Hierarchy = Ar.ReadArray(() => new Hierarchy(Ar));
                    break;

                case ESectionIdentifier.RIFF:
                    // read byte[sectionLength] it's simply a wem file
                    break;

                case ESectionIdentifier.STID:
                    Ar.Position += 4;
                    var count = Ar.Read <int>();
                    for (var i = 0; i < count; i++)
                    {
                        IdToString[Ar.Read <uint>()] = Ar.ReadString();
                    }
                    break;

                case ESectionIdentifier.STMG:
                    break;

                case ESectionIdentifier.ENVS:
                    break;

                case ESectionIdentifier.FXPR:
                    break;

                case ESectionIdentifier.PLAT:
                    Platform = Ar.ReadFString();
                    break;

                default:
#if DEBUG
                    Log.Warning($"Unknown section {sectionIdentifier:X} at {position - sizeof(uint) - sizeof(uint)}");
#endif
                    break;
                }

                if (Ar.Position != position + sectionLength)
                {
                    var shouldBe = position + sectionLength;
#if DEBUG
                    Log.Warning($"Didn't read 0x{sectionIdentifier:X} correctly (at {Ar.Position}, should be {shouldBe})");
#endif
                    Ar.Position = shouldBe;
                }
            }


            if (Folders != null)
            {
                foreach (var folder in Folders)
                {
                    foreach (var entry in folder.Entries)
                    {
                        if (entry.IsSoundBank || entry.Data == null)
                        {
                            continue;
                        }
                        WwiseEncodedMedias[IdToString.TryGetValue(entry.NameHash, out var k) ? k : $"{entry.Path.ToUpper()}_{entry.NameHash}"] = entry.Data;
예제 #13
0
        public FPakEntry(PakFileReader reader, string path, FArchive Ar) : base(reader)
        {
            Path = path;
            // FPakEntry is duplicated before each stored file, without a filename. So,
            // remember the serialized size of this structure to avoid recomputation later.
            var startOffset = Ar.Position;

            Offset           = Ar.Read <long>();
            CompressedSize   = Ar.Read <long>();
            UncompressedSize = Ar.Read <long>();
            Size             = UncompressedSize;

            if (reader.Info.Version < EPakFileVersion.PakFile_Version_FNameBasedCompressionMethod)
            {
                var LegacyCompressionMethod = Ar.Read <ECompressionFlags>();
                int CompressionMethodIndex;

                if (LegacyCompressionMethod == ECompressionFlags.COMPRESS_None)
                {
                    CompressionMethodIndex = 0;
                }
                else if (LegacyCompressionMethod == ECompressionFlags.COMPRESS_LZ4)
                {
                    CompressionMethodIndex = 4;
                }
                else if (LegacyCompressionMethod.HasFlag(ECompressionFlags.COMPRESS_ZLIB))
                {
                    CompressionMethodIndex = 1;
                }
                else if (LegacyCompressionMethod.HasFlag(ECompressionFlags.COMPRESS_GZIP))
                {
                    CompressionMethodIndex = 2;
                }
                else if (LegacyCompressionMethod.HasFlag(ECompressionFlags.COMPRESS_Custom))
                {
                    CompressionMethodIndex = 3;
                }
                else
                {
                    CompressionMethodIndex = -1;
                    //throw new ParserException("Found an unknown compression type in pak file, will need to be supported for legacy files");
                }

                CompressionMethod = CompressionMethodIndex == -1 ? CompressionMethod.Unknown : reader.Info.CompressionMethods[CompressionMethodIndex];
            }
            else if (reader.Info.Version == EPakFileVersion.PakFile_Version_FNameBasedCompressionMethod && !reader.Info.IsSubVersion)
            {
                CompressionMethod = reader.Info.CompressionMethods[Ar.Read <byte>()];
            }
            else
            {
                CompressionMethod = reader.Info.CompressionMethods[Ar.Read <int>()];
            }

            if (reader.Info.Version < EPakFileVersion.PakFile_Version_NoTimestamps)
            {
                Ar.Position += 8; // Timestamp
            }
            Ar.Position += 20;    // Hash
            if (reader.Info.Version >= EPakFileVersion.PakFile_Version_CompressionEncryption)
            {
                if (CompressionMethod != CompressionMethod.None)
                {
                    CompressionBlocks = Ar.ReadArray <FPakCompressedBlock>();
                }
                IsEncrypted          = Ar.ReadFlag();
                CompressionBlockSize = Ar.Read <uint>();
            }

            if (reader.Info.Version >= EPakFileVersion.PakFile_Version_RelativeChunkOffsets)
            {
                // Convert relative compressed offsets to absolute
                for (var i = 0; i < CompressionBlocks.Length; i++)
                {
                    CompressionBlocks[i].CompressedStart += Offset;
                    CompressionBlocks[i].CompressedEnd   += Offset;
                }
            }

            StructSize = (int)(Ar.Position - startOffset);
        }
예제 #14
0
        internal FPackageFileSummary(FArchive Ar)
        {
            Tag = Ar.Read <uint>();

            /*
             * The package file version number when this package was saved.
             *
             * Lower 16 bits stores the UE3 engine version
             * Upper 16 bits stores the UE4/licensee version
             * For newer packages this is -7
             *		-2 indicates presence of enum-based custom versions
             *		-3 indicates guid-based custom versions
             *		-4 indicates removal of the UE3 version. Packages saved with this ID cannot be loaded in older engine versions
             *		-5 indicates the replacement of writing out the "UE3 version" so older versions of engine can gracefully fail to open newer packages
             *		-6 indicates optimizations to how custom versions are being serialized
             *		-7 indicates the texture allocation info has been removed from the summary
             *		-8 indicates that the UE5 version has been added to the summary
             */
            const int CurrentLegacyFileVersion = -8;
            var       legacyFileVersion        = CurrentLegacyFileVersion;

            if (Tag == PACKAGE_FILE_TAG_ONE) // SOD2, "one"
            {
                Ar.Game                = EGame.GAME_StateOfDecay2;
                Ar.Ver                 = Ar.Game.GetVersion();
                legacyFileVersion      = Ar.Read <int>(); // seems to be always int.MinValue
                bUnversioned           = true;
                FileVersionUE          = Ar.Ver;
                CustomVersionContainer = Array.Empty <FCustomVersion>();
                FolderName             = "None";
                PackageFlags           = EPackageFlags.PKG_FilterEditorOnly;
                goto afterPackageFlags;
            }

            if (Tag != PACKAGE_FILE_TAG && Tag != PACKAGE_FILE_TAG_SWAPPED)
            {
                throw new ParserException($"Invalid uasset magic: 0x{Tag:X8} != 0x{PACKAGE_FILE_TAG:X8}");
            }

            // The package has been stored in a separate endianness than the linker expected so we need to force
            // endian conversion. Latent handling allows the PC version to retrieve information about cooked packages.
            if (Tag == PACKAGE_FILE_TAG_SWAPPED)
            {
                // Set proper tag.
                //Tag = PACKAGE_FILE_TAG;
                // Toggle forced byte swapping.
                throw new ParserException("Byte swapping for packages not supported");
            }

            legacyFileVersion = Ar.Read <int>();

            if (legacyFileVersion < 0) // means we have modern version numbers
            {
                if (legacyFileVersion < CurrentLegacyFileVersion)
                {
                    // we can't safely load more than this because the legacy version code differs in ways we can not predict.
                    // Make sure that the linker will fail to load with it.
                    FileVersionUE.Reset();
                    FileVersionLicenseeUE = 0;
                    throw new ParserException("Can't load legacy UE3 file");
                }

                if (legacyFileVersion != -4)
                {
                    var legacyUE3Version = Ar.Read <int>();
                }

                FileVersionUE.FileVersionUE4 = Ar.Read <int>();

                if (legacyFileVersion <= -8)
                {
                    FileVersionUE.FileVersionUE5 = Ar.Read <int>();
                }

                FileVersionLicenseeUE  = Ar.Read <EUnrealEngineObjectLicenseeUEVersion>();
                CustomVersionContainer = legacyFileVersion <= -2 ? Ar.ReadArray <FCustomVersion>() : Array.Empty <FCustomVersion>();

                if (Ar.Versions.CustomVersions == null && CustomVersionContainer.Length > 0)
                {
                    Ar.Versions.CustomVersions = CustomVersionContainer.ToList();
                }

                if (FileVersionUE.FileVersionUE4 == 0 && FileVersionUE.FileVersionUE5 == 0 && FileVersionLicenseeUE == 0)
                {
                    // this file is unversioned, remember that, then use current versions
                    bUnversioned          = true;
                    FileVersionUE         = Ar.Ver;
                    FileVersionLicenseeUE = EUnrealEngineObjectLicenseeUEVersion.VER_LIC_AUTOMATIC_VERSION;
                }
                else
                {
                    bUnversioned = false;
                    // Only apply the version if an explicit version is not set
                    if (!Ar.Versions.bExplicitVer)
                    {
                        Ar.Ver = FileVersionUE;
                    }
                }
            }
            else
            {
                // This is probably an old UE3 file, make sure that the linker will fail to load with it.
                throw new ParserException("Can't load legacy UE3 file");
            }

            TotalHeaderSize = Ar.Read <int>();
            FolderName      = Ar.ReadFString();
            PackageFlags    = Ar.Read <EPackageFlags>();

            /*if (PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
             * {
             *  TODO Ar.SetFilterEditorOnly(true);
             * }*/

afterPackageFlags:
            NameCount  = Ar.Read <int>();
            NameOffset = Ar.Read <int>();

            if (!PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
            {
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_SUMMARY_LOCALIZATION_ID)
                {
                    LocalizationId = Ar.ReadFString();
                }
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.SERIALIZE_TEXT_IN_PACKAGES)
            {
                GatherableTextDataCount  = Ar.Read <int>();
                GatherableTextDataOffset = Ar.Read <int>();
            }

            ExportCount   = Ar.Read <int>();
            ExportOffset  = Ar.Read <int>();
            ImportCount   = Ar.Read <int>();
            ImportOffset  = Ar.Read <int>();
            DependsOffset = Ar.Read <int>();

            if (FileVersionUE < EUnrealEngineObjectUE4Version.OLDEST_LOADABLE_PACKAGE || FileVersionUE > EUnrealEngineObjectUE4Version.AUTOMATIC_VERSION)
            {
                Generations = Array.Empty <FGenerationInfo>();
                ChunkIds    = Array.Empty <int>();
                return; // we can't safely load more than this because the below was different in older files.
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADD_STRING_ASSET_REFERENCES_MAP)
            {
                SoftPackageReferencesCount  = Ar.Read <int>();
                SoftPackageReferencesOffset = Ar.Read <int>();
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_SEARCHABLE_NAMES)
            {
                SearchableNamesOffset = Ar.Read <int>();
            }

            ThumbnailTableOffset = Ar.Read <int>();

            if (Ar.Game == EGame.GAME_Valorant)
            {
                Ar.Position += 8;
            }

            Guid = Ar.Read <FGuid>();

            if (!PackageFlags.HasFlag(EPackageFlags.PKG_FilterEditorOnly))
            {
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_OWNER)
                {
                    PersistentGuid = Ar.Read <FGuid>();
                }
                else
                {
                    // By assigning the current package guid, we maintain a stable persistent guid, so we can reference this package even if it wasn't resaved.
                    PersistentGuid = Guid;
                }

                // The owner persistent guid was added in VER_UE4_ADDED_PACKAGE_OWNER but removed in the next version VER_UE4_NON_OUTER_PACKAGE_IMPORT
                if (FileVersionUE >= EUnrealEngineObjectUE4Version.ADDED_PACKAGE_OWNER && FileVersionUE < EUnrealEngineObjectUE4Version.NON_OUTER_PACKAGE_IMPORT)
                {
                    var ownerPersistentGuid = Ar.Read <FGuid>();
                }
            }

            Generations = Ar.ReadArray <FGenerationInfo>();

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.ENGINE_VERSION_OBJECT)
            {
                SavedByEngineVersion = new FEngineVersion(Ar);
                FixCorruptEngineVersion(FileVersionUE, SavedByEngineVersion);
            }
            else
            {
                var engineChangelist = Ar.Read <int>();

                if (engineChangelist != 0)
                {
                    SavedByEngineVersion = new FEngineVersion(4, 0, 0, (uint)engineChangelist, string.Empty);
                }
            }

            if (FileVersionUE >= EUnrealEngineObjectUE4Version.PACKAGE_SUMMARY_HAS_COMPATIBLE_ENGINE_VERSION)
            {
                CompatibleWithEngineVersion = new FEngineVersion(Ar);
                FixCorruptEngineVersion(FileVersionUE, CompatibleWithEngineVersion);
            }
            else
            {
                CompatibleWithEngineVersion = SavedByEngineVersion;
            }
예제 #15
0
 public FCardRepresentationData(FArchive Ar)
 {
     Bounds        = Ar.Read <FBox>();
     MaxLodLevel   = Ar.Read <int>();
     CardBuildData = Ar.ReadArray <FLumenCardBuildData>();
 }
예제 #16
0
 public FVolumetricLightmapDataLayer(FArchive Ar)
 {
     Data = Ar.ReadArray <byte>();
 }
예제 #17
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>();
            }
        }
예제 #18
0
        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];
            }
        }
예제 #19
0
        public byte Frequency; // Enum

        public FShaderEntry(FArchive Ar)
        {
            Code             = Ar.ReadArray <byte>();
            UncompressedSize = Ar.Read <int>();
            Frequency        = Ar.Read <byte>();
        }
예제 #20
0
 public FShaderMapResourceCode(FArchive Ar)
 {
     ResourceHash  = new FSHAHash(Ar);
     ShaderHashes  = Ar.ReadArray(() => new FSHAHash(Ar));
     ShaderEntries = Ar.ReadArray(() => new FShaderEntry(Ar));
 }
예제 #21
0
 public FFontFaceData(FArchive Ar)
 {
     Data = Ar.ReadArray <byte>();
 }
예제 #22
0
 public FLightMap(FArchive Ar)
 {
     LightGuids = Ar.ReadArray <FGuid>();
 }