def __init__(self, reader: BinaryStream):
        StripFlags = FStripDataFlags(
            reader, Versions.VER_UE4_STATIC_SKELETAL_MESH_SERIALIZATION_FIX)
        self.NumTexCoords = reader.readInt32()
        self.Strides = reader.readInt32() if reader.game < GAME_UE4(19) else -1

        self.NumVertices = reader.readInt32()
        self.UseFullPrecisionUVs = reader.readBool()
        self.UseHighPrecisionTangentBasis = reader.readBool(
        ) if reader.game >= GAME_UE4(12) else False

        if not StripFlags.isDataStrippedForServer():
            if reader.game < GAME_UE4(19):
                self.UV = reader.readTArray_W_Arg(
                    FStaticMeshUVItem().read, reader,
                    self.UseHighPrecisionTangentBasis, self.NumTexCoords,
                    self.UseFullPrecisionUVs)
            else:
                # reader.readBulkTArray()
                itemSize = reader.readInt32()
                itemCount = reader.readInt32()

                if itemCount != self.NumVertices:
                    raise ParserException(
                        f"{itemCount=} != {self.NumVertices=}")

                pos = reader.tell()
                self.UV = [
                    FStaticMeshUVItem().construct(
                        FStaticMeshUVItem().serialize_tangents(
                            reader, self.UseHighPrecisionTangentBasis), [])
                    for _ in range(self.NumVertices)
                ]

                if reader.tell() - pos != itemSize * itemCount:
                    raise ParserException(
                        f"Read incorrect amount of tangent bytes, at {reader.tell()}, should be: {pos + itemSize * itemCount} behind: {pos + (itemSize * itemCount) - pos}"
                    )

                itemSize = reader.readInt32()
                itemCount = reader.readInt32()
                if itemCount != self.NumVertices * self.NumTexCoords:
                    raise ParserException(
                        f"{itemCount=} != NumVertices * NumTexCoords = {self.NumVertices * self.NumTexCoords}"
                    )

                pos = reader.tell()
                for i in range(self.NumVertices):
                    self.UV[i].UV = FStaticMeshUVItem().serialize_texcoords(
                        reader, self.NumTexCoords, self.UseFullPrecisionUVs)

                if reader.tell() - pos != itemSize * itemCount:
                    raise ParserException(
                        f"Read incorrect amount of Texture Coordinate bytes, at {reader.tell()}, should be: {pos + itemSize * itemCount} behind: {pos + (itemSize * itemCount) - pos}"
                    )
        else:
            self.UV = []
    def __init__(self, reader: BinaryStream):
        if reader.version < Versions.VER_UE4_SUPPORT_32BIT_STATIC_MESH_INDICES:
            self.indices16 = reader.readBulkTArray(reader.readUInt16)
            self.indices32 = []
        else:
            is32bit = reader.readBool()
            data = bytearray(reader.readBulkTArray(reader.readInt8))

            tr = BinaryStream(data)
            tr.game = reader.game
            tr.version = reader.version

            if reader.game >= GAME_UE4(25):
                reader.readBool()

            if len(data) == 0:
                self.indices16 = []
                self.indices32 = []
                return

            if is32bit:
                count = int(len(data) / 4)
                self.indices32 = [tr.readUInt32() for _ in range(count)]
                self.indices16 = []
            else:
                count = int(len(data) / 2)
                self.indices16 = [tr.readUInt16() for _ in range(count)]
                self.indices32 = []
Exemple #3
0
    def serializeBuffer(self, reader: BinaryStream):
        stripFlags = FStripDataFlags(reader)

        self.positionVertexBuffer = FPositionVertexBuffer(reader)
        self.vertexBuffer = FStaticMeshVertexBuffer(reader)
        self.colorVertexBuffer = FColorVertexBuffer(reader)
        self.indexBuffer = FRawStaticIndexBuffer(reader)

        if not stripFlags.isClassDataStripped(CDSF_ReversedIndexBuffer):
            self.reversedIndexBuffer = FRawStaticIndexBuffer(reader)

        self.depthOnlyIndexBuffer = FRawStaticIndexBuffer(reader)

        if not stripFlags.isClassDataStripped(CDSF_ReversedIndexBuffer):
            self.reversedDepthOnlyIndexBuffer = FRawStaticIndexBuffer(reader)

        if not stripFlags.isEditorDataStripped():
            self.wireframeIndexBuffer = FRawStaticIndexBuffer(reader)

        if not stripFlags.isClassDataStripped(CDSF_AdjancencyData):
            self.adjacencyIndexBuffer = FRawStaticIndexBuffer(reader)

        # UE 4.25+
        if reader.game >= GAME_UE4(25) and not stripFlags.isClassDataStripped(
                CDSF_RaytracingResources):
            reader.readBulkTArray(reader.readByte)  # Raw data

        # 25178
        for i in range(len(self.sections)):
            FWeightedRandomSampler(
                reader)  # FStaticMeshSectionAreaWeightedTriangleSampler
        FWeightedRandomSampler(reader)  # FStaticMeshAreaWeightedSectionSampler
Exemple #4
0
    def __init__(self, reader: Optional[BinaryStream] = None):
        if reader is None:
            return

        self.value = reader.readUInt32()
        if reader.game >= GAME_UE4(20):
            self.value = self.value ^ 0x80808080
Exemple #5
0
    def deserialize(self, validpos):
        reader = self.reader
        bulk = reader.ubulk_stream
        bulkOffset = reader.bulk_offset
        super().deserialize(validpos)

        FStripDataFlags(reader)
        FStripDataFlags(reader)

        bIsCooked = reader.version >= Versions.VER_UE4_ADD_COOKED_TO_TEXTURE2D and reader.readBool(
        )  # 203
        if bIsCooked:
            PixelFormatName = reader.readFName()
            pos = reader.base_stream.tell()
            while not PixelFormatName.isNone:
                SkipOffset = reader.readInt32()
                if reader.game >= GAME_UE4(20):
                    SkipOffsetH = reader.readInt32()
                    assert SkipOffsetH == 0

                data = FTexturePlatformData(reader,
                                            ubulk=bulk,
                                            ubulkOffset=bulkOffset)
                self.data.append(data)
                PixelFormatName = reader.readFName()

                try:
                    EPixelFormat[PixelFormatName.GetValue()]
                except:
                    break
Exemple #6
0
    def __init__(self, reader: BinaryStream):
        self.X = reader.readUInt16()
        self.Y = reader.readUInt16()
        self.Z = reader.readUInt16()
        self.W = reader.readUInt16()

        if reader.game >= GAME_UE4(20):
            self.X = self.X ^ 0x8000
            self.Y = self.Y ^ 0x8000
            self.Z = self.Z ^ 0x8000
            self.W = self.W ^ 0x8000
Exemple #7
0
    def __init__(self, reader: BinaryStream):
        self.stripFlags = FStripDataFlags(reader)
        self.sections = reader.readTArray_W_Arg(FStaticMeshSection, reader)
        self.maxDeviation = reader.readFloat()

        if reader.game < GAME_UE4(23):
            if not self.stripFlags.isDataStrippedForServer(
            ) and not self.stripFlags.isClassDataStripped(CDSF_MinLodData):
                self.serializeBuffer_legacy(reader)
            return

        self.is_lod_cooked_out = reader.readBool()
        self.inlined = reader.readBool()

        if not self.stripFlags.isDataStrippedForServer(
        ) and not self.is_lod_cooked_out:
            pos = reader.tellfake()
            if self.inlined:
                self.serializeBuffer(reader)
            else:
                bulk: FByteBulkData = FByteBulkData(
                    reader,
                    ubulk=reader.ubulk_stream,
                    bulkOffset=reader.PackageReader.PackageFileSummary.
                    BulkDataStartOffset)
                if bulk.Header.ElementCount > 0:
                    tr = BinaryStream(bulk.Data)
                    tr.game = reader.game
                    tr.version = reader.version
                    self.serializeBuffer(tr)

                reader.readUInt32()  # DepthOnlyNumTriangles
                reader.readUInt32()  # PackedData
                reader.seek(4 * 4 + 2 * 4 + 2 * 4 + 6 * (2 * 4), 1)
                """
                            StaticMeshVertexBuffer = 2x int32, 2x bool
                            PositionVertexBuffer = 2x int32
                            ColorVertexBuffer = 2x int32
                            IndexBuffer = int32 + bool
                            ReversedIndexBuffer
                            DepthOnlyIndexBuffer
                            ReversedDepthOnlyIndexBuffer
                            WireframeIndexBuffer
                            AdjacencyIndexBuffer
                """
        # FStaticMeshBuffersSize
        reader.readUInt32()  # SerializedBuffersSize
        reader.readUInt32()  # DepthOnlyIBSize
        reader.readUInt32()  # ReversedIBsSize
    def deserialize(self, reader: BinaryStream, ubulk: BinaryStream,
                    ubulkOffset: int):
        self.SizeX = reader.readInt32()
        self.SizeY = reader.readInt32()
        self.NumSlices = reader.readInt32()  # 1 for normal textures
        self.PixelFormat = EPixelFormat[reader.readFString()]

        self.FirstMipToSerialize = reader.readInt32() - 1
        self.Mips = reader.readTArray_W_Arg(FTexture2DMipMap, reader, ubulk,
                                            ubulkOffset)
        if reader.game >= GAME_UE4(23):
            self.bIsVirtual = reader.readInt32() != 0
            if self.bIsVirtual:
                raise NotImplementedError(
                    "Virtual Textures ar not Not implemented")
Exemple #9
0
 def __init__(self, reader: BinaryStream):
     super().__init__()
     if reader.game >= GAME_UE4(16):
         self.CompressedDistanceFieldVolume = reader.readTArray(
             reader.readByteToInt)
         self.Size = FIntVector(reader)
         self.LocalBoundingBox = FBox(reader)
         self.DistanceMinMax = FVector(reader)
         self.MeshWasClosed = reader.readBool()
         self.BuiltAsIfTwoSided = reader.readBool()
         self.MeshwasPlane = reader.readBool()
         self.DistanceFieldVolume = []
     else:
         self.DistanceFieldVolume = reader.readTArray(reader.readUInt16)
         self.Size = FIntVector(reader)
         self.LocalBoundingBox = FBox(reader)
         self.MeshWasClosed = reader.readBool()
         self.BuiltAsIfTwoSided = reader.readBool(
         ) if reader.version >= Versions.VER_UE4_RENAME_CROUCHMOVESCHARACTERDOWN else False
         self.MeshwasPlane = reader.readBool(
         ) if reader.version >= Versions.VER_UE4_DEPRECATE_UMG_STYLE_ASSETS else False
         self.CompressedDistanceFieldVolume = []
         self.DistanceMinMax = FVector2D().construct(0, 0)
Exemple #10
0
 def get(self, reader: BinaryStream):
     version = reader.game
     if version < GAME_UE4(12):
         return self.BeforeCustomVersionWasAdded
     elif version < GAME_UE4(13):
         return 2
     elif version < GAME_UE4(14):
         return 4
     elif version < GAME_UE4(16):
         return 12  # 4.14 and 4.15
     elif version < GAME_UE4(17):
         return 15
     elif version < GAME_UE4(18):
         return 19
     elif version < GAME_UE4(19):
         return 20
     elif version < GAME_UE4(20):
         return 25
     elif version < GAME_UE4(21):
         return self.IncreaseNormalPrecision
     elif version < GAME_UE4(22):
         return 27
     elif version < GAME_UE4(23):
         return 28
     elif version < GAME_UE4(24):
         return 31
     elif version < GAME_UE4(25):
         return 36
     elif version < GAME_UE4(26):
         return 43
     else:
         return EUEVersion.LATEST
Exemple #11
0
    def deserialize(self, validpos) -> None:
        super().deserialize(validpos)
        reader = self.reader

        self.StripData = FStripDataFlags(reader)
        bCooked = reader.readBool()
        self.BodySetup = reader.readObject()

        if reader.version >= Versions.VER_UE4_STATIC_MESH_STORE_NAV_COLLISION:
            self.NavCollision = reader.readObject()

        if not self.StripData.isEditorDataStripped():
            if reader.version < Versions.VER_UE4_DEPRECATED_STATIC_MESH_THUMBNAIL_PROPERTIES_REMOVED:
                FRotator(reader)  # dummyThumbnailAngle
                reader.readFloat()  # dummyThumbnailDistance
            highResSourceMeshName = reader.readString(
            )  # highResSourceMeshName
            highResSourceMeshCRC = reader.readUInt32()  #

        self.LightingGuid = FGuid(reader)

        self.Sockets = reader.readTArray(reader.readObject)

        if not self.StripData.isEditorDataStripped:
            raise ParserException("Mesh with editor data not supported")

        # FStaticMeshRenderData
        if bCooked:
            if not bCooked:  # how possible
                pass  # https://github.com/FabianFG/JFortniteParse/blob/558fb2b96985aad5b90c96c8f28950021cf801a0/src/main/kotlin/me/fungames/jfortniteparse/ue4/assets/exports/UStaticMesh.kt#L59
            # if unversioned MinMobileLODIdx int32
            self.LODs = reader.readTArray_W_Arg(FStaticMeshLODResources,
                                                reader)  #TODO fix this

            if reader.game >= GAME_UE4(23):
                NumInlinedLODs = reader.readUInt8()

            if bCooked:
                if reader.version >= Versions.VER_UE4_RENAME_CROUCHMOVESCHARACTERDOWN:
                    isStripped = False
                    if reader.version >= Versions.VER_UE4_RENAME_WIDGET_VISIBILITY:
                        stripflag = FStripDataFlags(reader)
                        isStripped = stripflag.isDataStrippedForServer()
                        if reader.game >= GAME_UE4(21):
                            # 4.21 uses additional strip flag for distance field
                            distanceFieldDataStripFlag = 1
                            isStripped = isStripped | stripflag.isClassDataStripped(
                                distanceFieldDataStripFlag)  # ?
                    if not isStripped:
                        # serialize FDistanceFieldVolumeData for each LOD
                        for _ in range(len(self.LODs) - 1):  # wut why
                            hasDistanceDataField = reader.readBool()
                            if hasDistanceDataField:
                                FDistanceFieldVolumeData(reader)  # VolumeData

            self.Bounds = FBoxSphereBounds(reader)

            if reader.game != GAME_UE4(15):
                self.LODsShareStaticLighting = reader.readBool()

            if reader.game < GAME_UE4(15):
                reader.readBool()  # bReducedBySimplygon

            if FRenderingObjectVersion().get(
                    reader
            ) < FRenderingObjectVersion.TextureStreamingMeshUVChannelData:
                for _ in range(
                        MAX_STATIC_UV_SETS_UE4):  # StreamingTextureFactors
                    reader.readFloat(
                    )  # StreamingTextureFactor for each UV set
                reader.readFloat()  # MaxStreamingTextureFactor

            if bCooked:
                maxNumLods = MAX_STATIC_LODS_UE4 if reader.game >= GAME_UE4(
                    9) else 4
                for x in range(maxNumLods):
                    if reader.game >= GAME_UE4(20):
                        reader.readBool()  # bFloatCooked
                    self.ScreenSize.append(reader.readFloat())
        # End of FStaticMeshRenderData

        if bCooked and reader.game >= GAME_UE4(20):
            hasOccluderData = reader.readBool()
            if hasOccluderData:
                reader.readTArray(FVector, reader)  # Vertices
                reader.readTArray(reader.readUInt16)  # Indics

        if reader.game >= GAME_UE4(14):
            hasSpeedTreeWind = reader.readBool()
            if hasSpeedTreeWind:
                pass  # ignore
            else:
                if FEditorObjectVersion().get(
                        reader
                ) >= FEditorObjectVersion.RefactorMeshEditorMaterials:
                    # UE4.14+ - "Materials" are deprecated, added StaticMaterials
                    self.StaticMaterials = reader.readTArray_W_Arg(
                        FStaticMaterial, reader)

        if len(self.Materials) == 0 and len(self.StaticMaterials) > 0:
            material: FStaticMaterial
            for material in self.StaticMaterials:
                self.Materials.append(material.MaterialInterface)