diff --git a/Docs/UE4Props.pl b/Docs/UE4Props.pl index 2aa52604..1e44853e 100644 --- a/Docs/UE4Props.pl +++ b/Docs/UE4Props.pl @@ -1,8 +1,16 @@ #!/usr/bin/perl -w +# TODO: +# - command line (has some commented code here) +# - show file/line where class defined +# - command line: show particular class and its parents +# - when there's parent, parse its prpos and add count to the 1st property (e.g. for UMaterialInstanceConstant) + + @dirs = ( - "../../Epic/UnrealEngine4-latest/Engine/Source/Runtime/Engine", + "../../Epic/UnrealEngine4/Engine/Source/Runtime/Engine", +# "../../Epic/UnrealEngine4-latest/Engine/Source/Runtime/Engine", ); @files = diff --git a/Docs/UE4Version.pl b/Docs/UE4Version.pl index 3c951ef3..aa1f3fea 100644 --- a/Docs/UE4Version.pl +++ b/Docs/UE4Version.pl @@ -13,6 +13,7 @@ "EditorObjectVersion.h", "../../../Engine/Public/SkeletalMeshTypes.h", # for newer UE4 (post UE4.18) "../../../Engine/Private/SkeletalMesh.cpp", # for older UE4 version (UE4.18 and less) + "../../../Engine/Public/SkeletalMeshLegacyCustomVersions.h", # UE4.27 and newer "CoreObjectVersion.h", "RenderingObjectVersion.h", "AnimObjectVersion.h", diff --git a/Unreal/UE4Version.h b/Unreal/UE4Version.h index 57cbdc2a..d9e853bf 100644 --- a/Unreal/UE4Version.h +++ b/Unreal/UE4Version.h @@ -95,13 +95,30 @@ enum VER_UE4_SKINWEIGHT_PROFILE_DATA_LAYOUT_CHANGES = 519, VER_UE4_NON_OUTER_PACKAGE_IMPORT = 520, VER_UE4_26 = 522, - VER_UE4_27 = 523, //?? TODO + VER_UE4_27 = 522, // look for NEW_ENGINE_VERSION over the code to find places where version constants should be inserted. // LATEST_SUPPORTED_UE4_VERSION should be updated too. }; int GetUE4CustomVersion(const FArchive& Ar, const FGuid& Guid); + +/* + * Rules for writing code for custom versions + * - Each version is a "struct". Ideally could use "enum class", however we're adding some code into it, so "struct" is ideal. + * - Use "enum Type" inside of it. + * - Each enum has members: + * - VersionPlusOne - equals to the recent declared constant + 1, used to correctly set up LatestVersion without explicit + * mentioning of the latest constant name. + * - optional: ForceVersion - use it in a case we're not declaring the latest version as a constant, so LatestVersion value + * will work correctly. + * - There's "static Type Get(const FArchive& Ar)" function, it computes custom version based on Game constant. Needed in order + * to make unversioned packages to work. + * - This function does comparison of game constant with engine number PLUS ONE, so games which are derived from e.g. UE4.25 + * will work correctly after using logic "Game < GAME_UE4(26)", i.e. game is using engine smaller than UE4.26. If we'll use + * "Game <= GAME_UE4.25", this WILL work for UE4.25, but not for 4.25-based games which has custom override. + */ + struct FFrameworkObjectVersion { enum Type @@ -124,7 +141,9 @@ struct FFrameworkObjectVersion // UE4.20, UE4.21 = 34 // UE4.22, UE4.23 = 35 // UE4.24 = 36 - // UE4.25, UE4.26 = 37 + // UE4.25-UE4.27 = 37 + + ForceVersion = 37, // the recent version, added here just to force LatestVersion to be correct VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -165,10 +184,10 @@ struct FFrameworkObjectVersion return (Type)35; if (Ar.Game < GAME_UE4(25)) return (Type)36; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)37; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -195,7 +214,9 @@ struct FEditorObjectVersion // UE4.23 = 34 // UE4.24 = 37 // UE4.25 = 38 - // UE4.26 = 40 + // UE4.26, UE4.27 = 40 + + ForceVersion = 40, VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -243,10 +264,10 @@ struct FEditorObjectVersion return (Type)37; if (Ar.Game < GAME_UE4(26)) return (Type)38; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)40; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -278,7 +299,7 @@ struct FSkeletalMeshCustomVersion SectionIgnoreByReduceAdded = 16, // UE4.23-UE4.25 = 17 SkinWeightProfiles = 17, //todo: FSkeletalMeshLODModel::Serialize (editor mesh) - // UE4.26 = 18 + // UE4.26, UE4.27 = 18 RemoveEnableClothLOD = 18, //todo VersionPlusOne, @@ -316,10 +337,10 @@ struct FSkeletalMeshCustomVersion return SectionIgnoreByReduceAdded; if (Ar.Game < GAME_UE4(26)) return SkinWeightProfiles; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return RemoveEnableClothLOD; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -333,7 +354,7 @@ struct FCoreObjectVersion // UE4.15-UE4.21 = 2 // UE4.22-UE4.24 = 3 SkeletalMaterialEditorDataStripping = 3, - // UE4.25-UE4.26 = 4 + // UE4.25-UE4.27 = 4 VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -353,10 +374,10 @@ struct FCoreObjectVersion return (Type)2; if (Ar.Game < GAME_UE4(25)) return SkeletalMaterialEditorDataStripping; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)4; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -378,9 +399,12 @@ struct FRenderingObjectVersion // UE4.22 = 28 // UE4.23 = 31 // UE4.24 = 36 + StaticMeshSectionForceOpaqueField = 37, // UE4.25 = 43 // UE4.26 = 44 - StaticMeshSectionForceOpaqueField = 37, + // UE4.27 = 45 + + ForceVersion = 45, VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -425,10 +449,12 @@ struct FRenderingObjectVersion return (Type)36; if (Ar.Game < GAME_UE4(26)) return (Type)43; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(27)) return (Type)44; + if (Ar.Game < GAME_UE4(28)) + return (Type)45; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -442,7 +468,9 @@ struct FAnimObjectVersion // UE4.25 = 7 IncreaseBoneIndexLimitPerChunk = 4, UnlimitedBoneInfluences = 5, - // UE4.26 = 15 + // UE4.26, UE4.27 = 15 + + ForceVersion = 15, VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -460,11 +488,10 @@ struct FAnimObjectVersion return StoreMarkerNamesOnSkeleton; if (Ar.Game < GAME_UE4(26)) return (Type)7; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)15; - // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -481,7 +508,9 @@ struct FAnimPhysObjectVersion AddLODToCurveMetaData = 12, // UE4.19 = 16 ChangeRetargetSourceReferenceToSoftObjectPtr = 15, - // UE4.20-UE4.26 = 17 + // UE4.20-UE4.27 = 17 + + ForceVersion = 17, VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -503,10 +532,10 @@ struct FAnimPhysObjectVersion return AddLODToCurveMetaData; if (Ar.Game < GAME_UE4(20)) return (Type)16; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)17; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -517,6 +546,9 @@ struct FReleaseObjectVersion BeforeCustomVersionWasAdded = 0, // UE4.19 = 12 AddSkeletalMeshSectionDisable = 12, + // Not used in our code, so for version mapping please refer to "Get()" method below... + + ForceVersion = 43, VersionPlusOne, LatestVersion = VersionPlusOne - 1 @@ -554,10 +586,12 @@ struct FReleaseObjectVersion return (Type)28; if (Ar.Game < GAME_UE4(26)) return (Type)30; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(27)) return (Type)37; + if (Ar.Game < GAME_UE4(28)) + return (Type)43; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; @@ -569,6 +603,8 @@ struct FEnterpriseObjectVersion // UE4.24 = 8 MeshDescriptionBulkDataGuidIsHash = 8, + ForceVersion = 10, + VersionPlusOne, LatestVersion = VersionPlusOne - 1 }; @@ -589,10 +625,10 @@ struct FEnterpriseObjectVersion return (Type)6; if (Ar.Game < GAME_UE4(25)) return MeshDescriptionBulkDataGuidIsHash; -// if (Ar.Game < GAME_UE4(27)) + if (Ar.Game < GAME_UE4(28)) return (Type)10; // NEW_ENGINE_VERSION -// return LatestVersion; + return LatestVersion; } }; diff --git a/Unreal/UnObject4.cpp b/Unreal/UnObject4.cpp index 1aeecf43..9eb8f653 100644 --- a/Unreal/UnObject4.cpp +++ b/Unreal/UnObject4.cpp @@ -85,7 +85,11 @@ struct PropInfo static const PropInfo PropData[] = { +// UStaticMesh BEGIN("UStaticMesh4") + VERSION_BLOCK(GAME_UE4(27)) + DROP_INT8(14) // uint8 bSupportRayTracing + VERSION_BLOCK(0) DROP_INT64(0) // FPerPlatformInt MinLOD - serialized as 2x int32, didn't find why MAP(StaticMaterials, 2) MAP(LightmapUVDensity, 3) @@ -97,7 +101,11 @@ BEGIN("UStaticMesh4") DROP_OBJ_ARRAY(22) // TArray AssetUserData END +// USkeletalMesh BEGIN("USkeletalMesh4") + VERSION_BLOCK(GAME_UE4(27)) + DROP_INT8(21) // uint8 bSupportRayTracing + VERSION_BLOCK(0) MAP(Skeleton, 0) DROP_VECTOR3(3) // PositiveBoundsExtension DROP_VECTOR3(4) // PositiveBoundsExtension @@ -125,7 +133,11 @@ BEGIN("USkeleton") DROP_OBJ_ARRAY(8) // TArray AssetUserData END +// UAnimSequence BEGIN("UAnimSequence4") + VERSION_BLOCK(GAME_UE4(27)) + MAP(RetargetSourceAssetReferencePose, 9) + VERSION_BLOCK(0) MAP(NumFrames, 0) MAP(TrackToSkeletonMapTable, 1) MAP(AdditiveAnimType, 4) @@ -133,12 +145,11 @@ BEGIN("UAnimSequence4") MAP(RefPoseSeq, 6) MAP(RefFrameIndex, 7) MAP(RetargetSource, 8) - MAP(RetargetSourceAssetReferencePose, 9) - MAP(Interpolation, 10) - MAP(bEnableRootMotion, 11) - DROP_INT8(12, 13, 14, 15) - MAP(AuthoredSyncMarkers, 16) - MAP(BakedPerBoneCustomAttributeData, 17) + MAP(Interpolation, 9) + MAP(bEnableRootMotion, 10) + DROP_INT8(11, 12, 13, 14) + MAP(AuthoredSyncMarkers, 15) + MAP(BakedPerBoneCustomAttributeData, 16) END BEGIN("UAnimationAsset") @@ -147,6 +158,7 @@ BEGIN("UAnimationAsset") DROP_OBJ_ARRAY(2) // AssetUserData END +// UTexture2D BEGIN("UTexture2D") DROP_INT8(2) // uint8 bTemporarilyDisableStreaming:1 DROP_INT8(3) // TEnumAsByte AddressX @@ -161,6 +173,7 @@ BEGIN("UTexture3") DROP_OBJ_ARRAY(14) // AssetUserData END +// UMaterialInstance BEGIN("UMaterialInstance") MAP(Parent, 9) DROP_INT8(10, 11) @@ -174,6 +187,7 @@ BEGIN("UMaterialInstance") DROP_OBJ_ARRAY(20) //todo: TArray CachedReferencedTextures END +// UMaterial BEGIN("UMaterial3") // known properties MAP(BlendMode, 17) @@ -278,13 +292,18 @@ static const ParentInfo ParentData[] = { "UTexture2D", "UTexture3", 6 }, { "UTexture3", "UStreamableRenderAsset", 15 }, // Mesh classes + { "USkeletalMesh4", "UStreamableRenderAsset", 29, GAME_UE4(27) }, { "USkeletalMesh4", "UStreamableRenderAsset", 28 }, + { "UStaticMesh4", "UStreamableRenderAsset", 26, GAME_UE4(27) }, { "UStaticMesh4", "UStreamableRenderAsset", 25 }, // Material classes { "UMaterialInstanceConstant", "UMaterialInstance", 1 }, // contains just a single UObject* property { "UMaterialInstance", "UMaterialInterface", 21 }, + { "UMaterial3", "UMaterialInterface", 119, GAME_UE4(27) }, { "UMaterial3", "UMaterialInterface", 117 }, - { "UAnimSequence4", "UAnimSequenceBase", 18 }, + // Animation classes + { "UAnimSequence4", "UAnimSequenceBase", 18, GAME_UE4(27) }, + { "UAnimSequence4", "UAnimSequenceBase", 17 }, { "UAnimSequenceBase", "UAnimationAsset", 4 }, // Structures { "FStaticSwitchParameter", "FStaticParameterBase", 1 }, diff --git a/Unreal/UnrealMesh/UnMesh4.cpp b/Unreal/UnrealMesh/UnMesh4.cpp index 00725cde..91b22fa5 100644 --- a/Unreal/UnrealMesh/UnMesh4.cpp +++ b/Unreal/UnrealMesh/UnMesh4.cpp @@ -53,6 +53,8 @@ #error MAX_STATIC_UV_SETS_UE4 too large #endif +// This is a CVar in UE4.27+. Set to false by default, some games might have it set to "true". +static bool KeepMobileMinLODSettingOnDesktop = false; /*----------------------------------------------------------------------------- Common data types @@ -1831,7 +1833,7 @@ void USkeletalMesh4::Serialize(FArchive &Ar) bool bCooked; Ar << bCooked; - if (Ar.Game >= GAME_UE4(27)) + if (Ar.Game >= GAME_UE4(27) && KeepMobileMinLODSettingOnDesktop) { // The serialization of this variable is cvar-dependent in UE4, so there's no clear way to understand // if it should be serialize in our code or not. @@ -2728,7 +2730,7 @@ void UStaticMesh4::Serialize(FArchive &Ar) // Note: code below still contains 'if (bCooked)' switches, this is because the same // code could be used to read data from DDC, for non-cooked assets. DBG_STAT("Serializing RenderData\n"); - if (Ar.Game >= GAME_UE4(27)) + if (Ar.Game >= GAME_UE4(27) && KeepMobileMinLODSettingOnDesktop) { // The serialization of this variable is cvar-dependent in UE4, so there's no clear way to understand // if it should be serialize in our code or not. diff --git a/readme.txt b/readme.txt index 141ba8a8..c580ef7a 100644 --- a/readme.txt +++ b/readme.txt @@ -216,6 +216,9 @@ Oodle Changes ~~~~~~~ +05.09.2021 +- UE4.27 support + 05.07.2021 - providing Win32 and Win64 builds of UE Viewer diff --git a/umodel b/umodel index 17f897b3..fdfcad56 100644 Binary files a/umodel and b/umodel differ diff --git a/umodel.exe b/umodel.exe index 9f027d21..58177637 100644 Binary files a/umodel.exe and b/umodel.exe differ