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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
                }
            }
        }
Beispiel #4
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);
                    }
                }
            }
        }