public static int MetadataSize(FArchive Ar) { var numBytes = 0; var bNewWeightFormat = FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.UnlimitedBoneInfluences; if (!Ar.Versions["SkeletalMesh.UseNewCookedFormat"]) { numBytes = 2 * 4; } else if (!bNewWeightFormat) { numBytes = 3 * 4; } else { numBytes = 4 * 4; if (FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.IncreaseBoneIndexLimitPerChunk) { numBytes += 4; } } if (bNewWeightFormat) { numBytes += 4; } return(numBytes); }
public static int MetadataSize(FArchive Ar) { var numBytes = 0; var bNewWeightFormat = FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.UnlimitedBoneInfluences; if (Ar.Game < EGame.GAME_UE4_24) { numBytes = 2 * 4; } else if (!bNewWeightFormat) { numBytes = 3 * 4; } else { numBytes = 4 * 4; if (FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.IncreaseBoneIndexLimitPerChunk) { numBytes += 4; } } if (bNewWeightFormat) { numBytes += 4; } return(numBytes); }
public override void Deserialize(FAssetArchive Ar, long validPos) { base.Deserialize(Ar, validPos); // UObject Properties BoneTree = GetOrDefault <FBoneNode[]>(nameof(BoneTree)); VirtualBoneGuid = GetOrDefault <FGuid>(nameof(VirtualBoneGuid)); if (Ar.Ver >= EUnrealEngineObjectUE4Version.REFERENCE_SKELETON_REFACTOR) { ReferenceSkeleton = new FReferenceSkeleton(Ar); } if (Ar.Ver >= EUnrealEngineObjectUE4Version.FIX_ANIMATIONBASEPOSE_SERIALIZATION) { var numOfRetargetSources = Ar.Read <int>(); AnimRetargetSources = new Dictionary <FName, FReferencePose>(numOfRetargetSources); for (var i = 0; i < numOfRetargetSources; i++) { var name = Ar.ReadFName(); var pose = new FReferencePose(Ar); ReferenceSkeleton.AdjustBoneScales(pose.ReferencePose); AnimRetargetSources[name] = pose; } } else { Log.Warning(""); // not sure what to put here } if (Ar.Ver >= EUnrealEngineObjectUE4Version.SKELETON_GUID_SERIALIZATION) { Guid = Ar.Read <FGuid>(); } if (Ar.Ver >= EUnrealEngineObjectUE4Version.SKELETON_ADD_SMARTNAMES) { var mapLength = Ar.Read <int>(); NameMappings = new Dictionary <FName, FSmartNameMapping>(mapLength); for (var i = 0; i < mapLength; i++) { NameMappings[Ar.ReadFName()] = new FSmartNameMapping(Ar); } } if (FAnimObjectVersion.Get(Ar) >= FAnimObjectVersion.Type.StoreMarkerNamesOnSkeleton) { var stripDataFlags = Ar.Read <FStripDataFlags>(); if (!stripDataFlags.IsEditorDataStripped()) { ExistingMarkerNames = Ar.ReadArray(Ar.ReadFName); } } }
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); } } } }