예제 #1
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];
            }
        }
예제 #2
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>();
            }
        }