Exemple #1
0
        private RawMaterial ContainRawMaterial(CMaterialInstance cMaterialInstance, string Name, List <Archive> archives)
        {
            RawMaterial rawMaterial = new RawMaterial();

            rawMaterial.Name         = Name;
            rawMaterial.BaseMaterial = cMaterialInstance.BaseMaterial.DepotPath;

            List <CMaterialInstance> BaseMaterials = new List <CMaterialInstance>();

            string path = cMaterialInstance.BaseMaterial.DepotPath;

            while (!Path.GetExtension(path).Contains("mt"))
            {
                ulong hash = FNV1A64HashAlgorithm.HashString(path);
                foreach (Archive ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        var ms = new MemoryStream();
                        ModTools.ExtractSingleToStream(ar, hash, ms);
                        var mi = _wolvenkitFileService.TryReadCr2WFile(ms);
                        BaseMaterials.Add(mi.Chunks[0].Data as CMaterialInstance);
                        path = (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath;
                        break;
                    }
                }
            }

            string type = Path.GetFileName(path);

            BaseMaterials.Reverse();
            for (int i = 0; i < BaseMaterials.Count; i++)
            {
                MATERIAL.ContainRawMaterialEnum(ref rawMaterial, BaseMaterials[i], type);
            }

            MATERIAL.ContainRawMaterialEnum(ref rawMaterial, cMaterialInstance, type);
            return(rawMaterial);
        }
Exemple #2
0
        public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, Archive ar)
        {
            if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any() || cr2w.Buffers.Count < 1)
            {
                return(false);
            }

            ulong hash = FNV1A64HashAlgorithm.HashString("base\\characters\\common\\skin\\old_mat_instances\\skin_ma_a__head.mi");

            if (!ar.Files.ContainsKey(hash))
            {
                return(false);
            }

            var ms = new MemoryStream();

            ModTools.ExtractSingleToStream(ar, hash, ms);
            _wolvenkitFileService.TryReadRED4File(ms);
            ms.Seek(0, SeekOrigin.Begin);

            var obj = JsonConvert.DeserializeObject <MatData>(_matData);

            var           materialbuffer = new MemoryStream();
            List <UInt32> offsets        = new List <UInt32>();
            List <UInt32> sizes          = new List <UInt32>();
            List <string> names          = new List <string>();

            if (obj.Materials.Count < 1)
            {
                return(false);
            }

            for (int i = 0; i < obj.Materials.Count; i++)
            {
                var mat = obj.Materials[i];
                names.Add(mat.Name);
                var mi = _wolvenkitFileService.TryReadRED4File(ms);
                ms.Seek(0, SeekOrigin.Begin);
                MATERIAL.WriteMatToMeshEnum(ref mi, ref mat);
                (mi.Chunks[0].Data as CMaterialInstance).BaseMaterial.DepotPath = mat.BaseMaterial;

                offsets.Add((UInt32)materialbuffer.Position);
                var m = new MemoryStream();
                var b = new BinaryWriter(m);
                mi.Write(b);
                materialbuffer.Write(m.ToArray(), 0, (int)m.Length);
                sizes.Add((UInt32)m.Length);
            }

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

            // remove existing data
            while (blob.MaterialEntries.Count != 0)
            {
                blob.MaterialEntries.Remove(blob.MaterialEntries[blob.MaterialEntries.Count - 1]);
            }
            while (blob.LocalMaterialBuffer.RawDataHeaders.Count != 0)
            {
                blob.LocalMaterialBuffer.RawDataHeaders.Remove(blob.LocalMaterialBuffer.RawDataHeaders[blob.LocalMaterialBuffer.RawDataHeaders.Count - 1]);
            }
            while (blob.PreloadLocalMaterialInstances.Count != 0)
            {
                blob.PreloadLocalMaterialInstances.Remove(blob.PreloadLocalMaterialInstances[blob.PreloadLocalMaterialInstances.Count - 1]);
            }
            while (blob.PreloadExternalMaterials.Count != 0)
            {
                blob.PreloadExternalMaterials.Remove(blob.PreloadExternalMaterials[blob.PreloadExternalMaterials.Count - 1]);
            }
            while (blob.ExternalMaterials.Count != 0)
            {
                blob.ExternalMaterials.Remove(blob.ExternalMaterials[blob.ExternalMaterials.Count - 1]);
            }
            while (blob.LocalMaterialInstances.Count != 0)
            {
                blob.LocalMaterialInstances.Remove(blob.LocalMaterialInstances[blob.LocalMaterialInstances.Count - 1]);
            }
            //
            for (int i = 0; i < names.Count; i++)
            {
                var c = new CMeshMaterialEntry(cr2w, blob.MaterialEntries, Convert.ToString(i))
                {
                    IsSerialized = true,
                };
                c.IsLocalInstance = new CBool(cr2w, c, "isLocalInstance")
                {
                    Value = true, IsSerialized = true
                };
                c.Name = new CName(cr2w, c, "name")
                {
                    Value = names[i], IsSerialized = true
                };
                c.Index = new CUInt16(cr2w, c, "index")
                {
                    Value = (UInt16)i, IsSerialized = true
                };
                blob.MaterialEntries.Add(c);

                var m = new meshLocalMaterialHeader(cr2w, blob.LocalMaterialBuffer.RawDataHeaders, Convert.ToString(i))
                {
                    IsSerialized = true
                };
                m.Offset = new CUInt32(cr2w, m, "offset")
                {
                    Value = offsets[i], IsSerialized = true
                };
                m.Size = new CUInt32(cr2w, m, "size")
                {
                    Value = sizes[i], IsSerialized = true
                };
                blob.LocalMaterialBuffer.RawDataHeaders.Add(m);
            }

            var compressed = new MemoryStream();

            using var buff  = new BinaryWriter(compressed);
            var(zsize, crc) = buff.CompressAndWrite(materialbuffer.ToArray());

            bool check = false;

            check = blob.LocalMaterialBuffer.RawData.IsSerialized;
            if (!check)
            {
                blob.LocalMaterialBuffer.RawData = new DataBuffer(cr2w, blob.LocalMaterialBuffer, "rawData")
                {
                    IsSerialized = true
                };
                blob.LocalMaterialBuffer.RawData.Buffer = new CUInt16(cr2w, blob.LocalMaterialBuffer.RawData, "Buffer")
                {
                    Value = (UInt16)(cr2w.Buffers.Count + 1), IsSerialized = true
                };

                uint idx = (uint)cr2w.Buffers.Count;
                cr2w.Buffers.Add(new CR2WBufferWrapper(new CR2WBuffer()
                {
                    flags    = 0,
                    index    = idx,
                    offset   = 0,
                    diskSize = zsize,
                    memSize  = (UInt32)materialbuffer.Length,
                    crc32    = crc
                }));

                cr2w.Buffers[(int)idx].ReadData(new BinaryReader(compressed));
                cr2w.Buffers[(int)idx].Offset = cr2w.Buffers[(int)idx - 1].Offset + cr2w.Buffers[(int)idx - 1].DiskSize;
            }
            else
            {
                UInt16 p = (blob.LocalMaterialBuffer.RawData.Buffer.Value);
                cr2w.Buffers[p - 1].DiskSize = zsize;
                cr2w.Buffers[p - 1].Crc32    = crc;
                cr2w.Buffers[p - 1].MemSize  = (UInt32)materialbuffer.Length;
                var off = cr2w.Buffers[p - 1].Offset;
                cr2w.Buffers[p - 1].Offset = 0;
                cr2w.Buffers[p - 1].ReadData(new BinaryReader(compressed));
                cr2w.Buffers[p - 1].Offset = off;
            }

            return(true);
        }