Beispiel #1
0
        private PathInfo(
            DisplayConfigPathSourceInfo sourceInfo,
            DisplayConfigSourceMode?sourceMode,
            IEnumerable <
                Tuple <
                    DisplayConfigPathInfoFlags,
                    DisplayConfigPathTargetInfo,
                    DisplayConfigTargetMode?,
                    DisplayConfigDesktopImageInfo?
                    >
                > targets
            )
        {
            DisplaySource = new PathDisplaySource(new PathDisplayAdapter(sourceInfo.AdapterId), sourceInfo.SourceId);

            IsInUse = sourceInfo.StatusFlags.HasFlag(DisplayConfigPathSourceInfoFlags.InUse);
            IsModeInformationAvailable = sourceMode.HasValue;

            if (sourceMode.HasValue)
            {
                _resolution  = new Size((int)sourceMode.Value.Width, (int)sourceMode.Value.Height);
                _pixelFormat = sourceMode.Value.PixelFormat;
                _position    = new Point(sourceMode.Value.Position.X, sourceMode.Value.Position.Y);
            }

            TargetsInfo = targets.Select(t => new PathTargetInfo(t.Item1, t.Item2, t.Item3, t.Item4)).ToArray();

            if (TargetsInfo.Any(info => info.IsVirtualModeSupportedByPath) &&
                sourceInfo.CloneGroupId != DisplayConfigPathSourceInfo.InvalidCloneGroupId
                )
            {
                _cloneGroupId = sourceInfo.CloneGroupId;
                IsCloneMember = true;
            }
        }
Beispiel #2
0
        private static bool IsTargetsToolkitVersionCurrent()
        {
            var targetsInfo = new TargetsInfo
            {
                TargetsPath = TargetsFilePath,
            };

            VersionHelper.ReadTargetsValues(targetsInfo);
            return(AuthoringPackage.CurrentToolkitVersion.Equals(targetsInfo.ToolkitVersion));
        }
Beispiel #3
0
        private static bool IsTargetsFileExtensionPathsCurrent()
        {
            var targetsInfo = new TargetsInfo
            {
                TargetsPath = TargetsFilePath,
                InstalledExtensionProperties = AuthoringPackage.InstalledExtensionProperties,
            };

            VersionHelper.ReadTargetsValues(targetsInfo);
            return(!targetsInfo.InstalledExtensionProperties.Any(ie => string.IsNullOrEmpty(ie.Value)));
        }
Beispiel #4
0
        private static TargetsInfo GetTargetInfos(CR2WFile cr2w, int subMeshC)
        {
            var morphBlob     = (MorphTargetMesh)cr2w.RootChunk;
            var rendMorphBlob = (rendRenderMorphTargetMeshBlob)morphBlob.Blob.Chunk;

            uint NumTargets = rendMorphBlob.Header.NumTargets;

            var  NumVertexDiffsInEachChunk = new uint[NumTargets, subMeshC];
            uint NumDiffs        = rendMorphBlob.Header.NumDiffs;
            uint NumDiffsMapping = rendMorphBlob.Header.NumDiffsMapping;
            var  NumVertexDiffsMappingInEachChunk = new uint[NumTargets, subMeshC];
            var  TargetStartsInVertexDiffs        = new uint[NumTargets];
            var  TargetStartsInVertexDiffsMapping = new uint[NumTargets];
            var  TargetPositionDiffOffset         = new Vec4[NumTargets];
            var  TargetPositionDiffScale          = new Vec4[NumTargets];

            for (var i = 0; i < NumTargets; i++)
            {
                for (var e = 0; e < subMeshC; e++)
                {
                    NumVertexDiffsInEachChunk[i, e]        = rendMorphBlob.Header.NumVertexDiffsInEachChunk[i][e];
                    NumVertexDiffsMappingInEachChunk[i, e] = rendMorphBlob.Header.NumVertexDiffsMappingInEachChunk[i][e];
                }

                TargetStartsInVertexDiffs[i]        = rendMorphBlob.Header.TargetStartsInVertexDiffs[i];
                TargetStartsInVertexDiffsMapping[i] = rendMorphBlob.Header.TargetStartsInVertexDiffsMapping[i];


                var o = rendMorphBlob.Header.TargetPositionDiffOffset[i];
                TargetPositionDiffOffset[i] = new Vec4(o.X, o.Y, o.Z, o.W);
                var s = rendMorphBlob.Header.TargetPositionDiffScale[i];
                TargetPositionDiffScale[i] = new Vec4(s.X, s.Y, s.Z, s.W);
            }

            var    Names       = new string[NumTargets];
            var    RegionNames = new string[NumTargets];
            string BaseMesh    = morphBlob.BaseMesh.DepotPath;
            string BaseTexture = morphBlob.BaseTexture.DepotPath;

            for (var i = 0; i < NumTargets; i++)
            {
                Names[i]       = morphBlob.Targets[i].Name;
                RegionNames[i] = morphBlob.Targets[i].RegionName;
            }

            var targetsInfo = new TargetsInfo()
            {
                NumVertexDiffsInEachChunk = NumVertexDiffsInEachChunk,
                NumDiffs        = NumDiffs,
                NumDiffsMapping = NumDiffsMapping,
                NumVertexDiffsMappingInEachChunk = NumVertexDiffsMappingInEachChunk,
                TargetStartsInVertexDiffs        = TargetStartsInVertexDiffs,
                TargetStartsInVertexDiffsMapping = TargetStartsInVertexDiffsMapping,
                TargetPositionDiffOffset         = TargetPositionDiffOffset,
                TargetPositionDiffScale          = TargetPositionDiffScale,
                Names       = Names,
                RegionNames = RegionNames,
                NumTargets  = NumTargets,
                BaseMesh    = BaseMesh,
                BaseTexture = BaseTexture,
            };

            return(targetsInfo);
        }
Beispiel #5
0
        public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }

            RawArmature             Rig        = null;
            MemoryStream            meshbuffer = MESH.GetMeshBufferStream(targetStream, cr2w);
            MeshesInfo              meshinfo   = MESH.GetMeshesinfo(cr2w);
            List <RawMeshContainer> expMeshes  = MESH.ContainRawMesh(meshbuffer, meshinfo, true);
            int subMeshC = expMeshes.Count;

            var    buffers      = cr2w.Buffers;
            var    blob         = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First();
            string baseMeshPath = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First().BaseMesh.DepotPath;
            ulong  hash         = FNV1A64HashAlgorithm.HashString(baseMeshPath);

            foreach (Archive ar in archives)
            {
                if (ar.Files.ContainsKey(hash))
                {
                    var meshStream = new MemoryStream();
                    ModTools.ExtractSingleToStream(ar, hash, meshStream);
                    var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream);

                    if (meshCr2w == null || !meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
                    {
                        break;
                    }

                    MESH.MeshBones meshBones = new MESH.MeshBones();
                    meshBones.boneCount = meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count;
                    if (meshBones.boneCount != 0)    // for rigid meshes
                    {
                        meshBones.Names     = RIG.GetboneNames(meshCr2w);
                        meshBones.WorldPosn = MESH.GetMeshBonesPosn(meshCr2w);
                    }

                    Rig = MESH.GetNonParentedRig(meshBones);

                    MemoryStream ms = MESH.GetMeshBufferStream(meshStream, meshCr2w);
                    meshinfo  = MESH.GetMeshesinfo(meshCr2w);
                    expMeshes = MESH.ContainRawMesh(ms, meshinfo, true);
                    subMeshC  = expMeshes.Count;
                    if (meshBones.boneCount == 0)    // for rigid meshes
                    {
                        for (int i = 0; i < expMeshes.Count; i++)
                        {
                            expMeshes[i].weightcount = 0;
                        }
                    }
                    MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones);

                    break;
                }
            }

            MemoryStream diffsbuffer   = new MemoryStream();
            MemoryStream mappingbuffer = new MemoryStream();
            MemoryStream texbuffer     = new MemoryStream();

            if (blob.DiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(diffsbuffer, buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.MappingBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(mappingbuffer, buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.TextureDiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(texbuffer, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize);
            }

            TargetsInfo targetsInfo = GetTargetInfos(cr2w, subMeshC);

            List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>();

            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                UInt32[] temp_NumVertexDiffsInEachChunk        = new UInt32[subMeshC];
                UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[subMeshC];
                for (int e = 0; e < subMeshC; e++)
                {
                    temp_NumVertexDiffsInEachChunk[e]        = targetsInfo.NumVertexDiffsInEachChunk[i, e];
                    temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e];
                }
                expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], subMeshC));
            }

            string[] names = new string[targetsInfo.NumTargets];
            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                names[i] = targetsInfo.Names[i] + "_" + targetsInfo.RegionNames[i];
            }

            List <MemoryStream> textureStreams = ContainTextureStreams(cr2w, texbuffer);
            ModelRoot           model          = RawTargetsToGLTF(expMeshes, expTargets, names, Rig);

            if (WolvenTesting.IsTesting)
            {
                return(true);
            }
            model.Extras = SharpGLTF.IO.JsonContent.Serialize(new { BaseMesh = targetsInfo.BaseMesh });
            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures");

            if (textureStreams.Count > 0)
            {
                Directory.CreateDirectory(dir.FullName);
            }

            for (int i = 0; i < textureStreams.Count; i++)
            {
                File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray());
            }

            targetStream.Dispose();
            targetStream.Close();

            return(true);
        }
Beispiel #6
0
        static TargetsInfo GetTargetInfos(CR2WFile cr2w, int SubMeshC)
        {
            int Index = int.MaxValue;

            for (int i = 0; i < cr2w.Chunks.Count; i++)
            {
                if (cr2w.Chunks[i].REDType == "rendRenderMorphTargetMeshBlob")
                {
                    Index = i;
                }
            }

            UInt32 NumTargets = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.NumTargets.Value;

            UInt32[,] NumVertexDiffsInEachChunk = new UInt32[NumTargets, SubMeshC];
            UInt32 NumDiffs        = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.NumDiffs.Value;
            UInt32 NumDiffsMapping = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.NumDiffsMapping.Value;

            UInt32[,] NumVertexDiffsMappingInEachChunk = new UInt32[NumTargets, SubMeshC];
            UInt32[] TargetStartsInVertexDiffs        = new UInt32[NumTargets];
            UInt32[] TargetStartsInVertexDiffsMapping = new UInt32[NumTargets];
            Vec4[]   TargetPositionDiffOffset         = new Vec4[NumTargets];
            Vec4[]   TargetPositionDiffScale          = new Vec4[NumTargets];
            for (int i = 0; i < NumTargets; i++)
            {
                for (int e = 0; e < SubMeshC; e++)
                {
                    NumVertexDiffsInEachChunk[i, e]        = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.NumVertexDiffsInEachChunk[i][e].Value;
                    NumVertexDiffsMappingInEachChunk[i, e] = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.NumVertexDiffsMappingInEachChunk[i][e].Value;
                }

                TargetStartsInVertexDiffs[i]        = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.TargetStartsInVertexDiffs[i].Value;
                TargetStartsInVertexDiffsMapping[i] = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.TargetStartsInVertexDiffsMapping[i].Value;


                var o = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.TargetPositionDiffOffset[i];
                TargetPositionDiffOffset[i] = new Vec4(o.X.Value, o.Y.Value, o.Z.Value, o.W.Value);
                var s = (cr2w.Chunks[Index].Data as rendRenderMorphTargetMeshBlob).Header.TargetPositionDiffScale[i];
                TargetPositionDiffScale[i] = new Vec4(s.X.Value, s.Y.Value, s.Z.Value, s.W.Value);
            }


            Index = int.MaxValue;
            for (int i = 0; i < cr2w.Chunks.Count; i++)
            {
                if (cr2w.Chunks[i].REDType == "MorphTargetMesh")
                {
                    Index = i;
                }
            }

            string[] Names       = new string[NumTargets];
            string[] RegionNames = new string[NumTargets];
            string   BaseMesh    = (cr2w.Chunks[Index].Data as MorphTargetMesh).BaseMesh.DepotPath;
            string   BaseTexture = (cr2w.Chunks[Index].Data as MorphTargetMesh).BaseTexture.DepotPath;

            for (int i = 0; i < NumTargets; i++)
            {
                Names[i]       = (cr2w.Chunks[Index].Data as MorphTargetMesh).Targets[i].Name.Value;
                RegionNames[i] = (cr2w.Chunks[Index].Data as MorphTargetMesh).Targets[i].RegionName.Value;
            }

            TargetsInfo targetsInfo = new TargetsInfo()
            {
                NumVertexDiffsInEachChunk = NumVertexDiffsInEachChunk,
                NumDiffs        = NumDiffs,
                NumDiffsMapping = NumDiffsMapping,
                NumVertexDiffsMappingInEachChunk = NumVertexDiffsMappingInEachChunk,
                TargetStartsInVertexDiffs        = TargetStartsInVertexDiffs,
                TargetStartsInVertexDiffsMapping = TargetStartsInVertexDiffsMapping,
                TargetPositionDiffOffset         = TargetPositionDiffOffset,
                TargetPositionDiffScale          = TargetPositionDiffScale,
                Names       = Names,
                RegionNames = RegionNames,
                NumTargets  = NumTargets,
                BaseMesh    = BaseMesh,
                BaseTexture = BaseTexture,
            };

            return(targetsInfo);
        }
        public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, string modFolder, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream);

            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
            {
                return(false);
            }
            var morphBlob = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First();

            RawArmature Rig = null;
            {
                ulong        hash       = FNV1A64HashAlgorithm.HashString(morphBlob.BaseMesh.DepotPath);
                MemoryStream meshStream = new MemoryStream();
                foreach (Archive ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        ExtractSingleToStream(ar, hash, meshStream);
                        break;
                    }
                }
                var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream);
                if (meshCr2w != null && meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() && meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any())
                {
                    Rig = MeshTools.GetOrphanRig(meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().First());
                }
            }
            var rendblob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().First();

            var rendbuffer = cr2w.Buffers[rendblob.RenderBuffer.Buffer.Value - 1];

            targetStream.Seek(rendbuffer.Offset, SeekOrigin.Begin);
            var meshbuffer = new MemoryStream();

            targetStream.DecompressAndCopySegment(meshbuffer, rendbuffer.DiskSize, rendbuffer.MemSize);

            var meshesinfo = MeshTools.GetMeshesinfo(rendblob);
            List <RawMeshContainer> expMeshes = MeshTools.ContainRawMesh(meshbuffer, meshesinfo, true);

            var blob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First();

            MemoryStream diffsbuffer   = new MemoryStream();
            MemoryStream mappingbuffer = new MemoryStream();
            MemoryStream texbuffer     = new MemoryStream();

            if (blob.DiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(diffsbuffer, cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.MappingBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(mappingbuffer, cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize);
            }

            if (blob.TextureDiffsBuffer.IsSerialized)
            {
                targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin);
                targetStream.DecompressAndCopySegment(texbuffer, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize);
            }

            TargetsInfo targetsInfo = GetTargetInfos(cr2w, expMeshes.Count);

            List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>();

            for (int i = 0; i < targetsInfo.NumTargets; i++)
            {
                UInt32[] temp_NumVertexDiffsInEachChunk        = new UInt32[expMeshes.Count];
                UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[expMeshes.Count];
                for (int e = 0; e < expMeshes.Count; e++)
                {
                    temp_NumVertexDiffsInEachChunk[e]        = targetsInfo.NumVertexDiffsInEachChunk[i, e];
                    temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e];
                }
                expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], expMeshes.Count));
            }

            List <MemoryStream> textureStreams = ContainTextureStreams(blob, texbuffer);
            ModelRoot           model          = RawTargetsToGLTF(expMeshes, expTargets, targetsInfo.Names, Rig);

            if (WolvenTesting.IsTesting)
            {
                return(true);
            }

            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures");

            if (textureStreams.Count > 0)
            {
                Directory.CreateDirectory(dir.FullName);
            }

            for (int i = 0; i < textureStreams.Count; i++)
            {
                File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray());
            }

            targetStream.Dispose();
            targetStream.Close();

            return(true);
        }
        static TargetsInfo GetTargetInfos(CR2WFile cr2w, int SubMeshC)
        {
            var rendMorphBlob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First();

            UInt32 NumTargets = rendMorphBlob.Header.NumTargets.Value;

            UInt32[,] NumVertexDiffsInEachChunk = new UInt32[NumTargets, SubMeshC];
            UInt32 NumDiffs        = rendMorphBlob.Header.NumDiffs.Value;
            UInt32 NumDiffsMapping = rendMorphBlob.Header.NumDiffsMapping.Value;

            UInt32[,] NumVertexDiffsMappingInEachChunk = new UInt32[NumTargets, SubMeshC];
            UInt32[] TargetStartsInVertexDiffs        = new UInt32[NumTargets];
            UInt32[] TargetStartsInVertexDiffsMapping = new UInt32[NumTargets];
            Vec4[]   TargetPositionDiffOffset         = new Vec4[NumTargets];
            Vec4[]   TargetPositionDiffScale          = new Vec4[NumTargets];
            for (int i = 0; i < NumTargets; i++)
            {
                for (int e = 0; e < SubMeshC; e++)
                {
                    NumVertexDiffsInEachChunk[i, e]        = rendMorphBlob.Header.NumVertexDiffsInEachChunk[i][e].Value;
                    NumVertexDiffsMappingInEachChunk[i, e] = rendMorphBlob.Header.NumVertexDiffsMappingInEachChunk[i][e].Value;
                }

                TargetStartsInVertexDiffs[i]        = rendMorphBlob.Header.TargetStartsInVertexDiffs[i].Value;
                TargetStartsInVertexDiffsMapping[i] = rendMorphBlob.Header.TargetStartsInVertexDiffsMapping[i].Value;


                var o = rendMorphBlob.Header.TargetPositionDiffOffset[i];
                TargetPositionDiffOffset[i] = new Vec4(o.X.Value, o.Y.Value, o.Z.Value, o.W.Value);
                var s = rendMorphBlob.Header.TargetPositionDiffScale[i];
                TargetPositionDiffScale[i] = new Vec4(s.X.Value, s.Y.Value, s.Z.Value, s.W.Value);
            }

            var morphBlob = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First();

            string[] Names       = new string[NumTargets];
            string[] RegionNames = new string[NumTargets];
            string   BaseMesh    = morphBlob.BaseMesh.DepotPath;
            string   BaseTexture = morphBlob.BaseTexture.DepotPath;

            for (int i = 0; i < NumTargets; i++)
            {
                Names[i]       = morphBlob.Targets[i].Name.Value;
                RegionNames[i] = morphBlob.Targets[i].RegionName.Value;
            }

            TargetsInfo targetsInfo = new TargetsInfo()
            {
                NumVertexDiffsInEachChunk = NumVertexDiffsInEachChunk,
                NumDiffs        = NumDiffs,
                NumDiffsMapping = NumDiffsMapping,
                NumVertexDiffsMappingInEachChunk = NumVertexDiffsMappingInEachChunk,
                TargetStartsInVertexDiffs        = TargetStartsInVertexDiffs,
                TargetStartsInVertexDiffsMapping = TargetStartsInVertexDiffsMapping,
                TargetPositionDiffOffset         = TargetPositionDiffOffset,
                TargetPositionDiffScale          = TargetPositionDiffScale,
                Names       = Names,
                RegionNames = RegionNames,
                NumTargets  = NumTargets,
                BaseMesh    = BaseMesh,
                BaseTexture = BaseTexture,
            };

            return(targetsInfo);
        }