Пример #1
0
        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>();
            }
        }
Пример #2
0
 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>();
            }
        }
Пример #4
0
        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
        }
Пример #5
0
        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();
            }
        }
Пример #7
0
        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];
            }
        }
Пример #8
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));
     }
 }
Пример #9
0
        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>();
            }
        }
Пример #10
0
        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);
                    }
                }
            }
        }
Пример #11
0
 public FPositionVertexBuffer(FArchive Ar)
 {
     Stride      = Ar.Read <int>();
     NumVertices = Ar.Read <int>();
     Verts       = Ar.ReadBulkArray <FVector>();
 }
Пример #12
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];
            }
        }
Пример #13
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>();
            }
        }