private RawMaterial ContainRawMaterial(CMaterialInstance cMaterialInstance, string name, List <Archive> archives, ref Dictionary <string, CMaterialTemplate> mts) { var(materialTemplatePath, valueDict) = GetMaterialChain(cMaterialInstance, archives, ref mts); var rawMaterial = new RawMaterial { Name = name, BaseMaterial = cMaterialInstance.BaseMaterial.DepotPath, MaterialTemplate = materialTemplatePath, Data = new Dictionary <string, object>() }; foreach (var pair in valueDict) { var value = pair.Value; if (value is IRedType redValue) { value = GetSerializableValue(redValue); } rawMaterial.Data.Add(pair.Key, value); } return(rawMaterial); }
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); }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, List <Archive> archives) { if (cr2w == null || cr2w.RootChunk is not CMesh cMesh || cMesh.RenderResourceBlob.Chunk is not rendRenderMeshBlob) { return(false); } var matData = RedJsonSerializer.Deserialize <MatData>(_matData); var materialbuffer = new MemoryStream(); var offsets = new List <uint>(); var sizes = new List <uint>(); var names = new List <string>(); if (matData.Materials.Count < 1) { return(false); } var mts = new Dictionary <string, CMaterialTemplate>(); for (var i = 0; i < matData.Materials.Count; i++) { var mat = matData.Materials[i]; names.Add(mat.Name); var mi = new CR2WFile(); { var chunk = RedTypeManager.Create <CMaterialInstance>(); chunk.CookingPlatform = Enums.ECookingPlatform.PLATFORM_PC; chunk.EnableMask = true; chunk.ResourceVersion = 4; chunk.BaseMaterial = new CResourceReference <IMaterial>() { DepotPath = mat.BaseMaterial }; chunk.Values = new CArray <CKeyValuePair>(); CMaterialTemplate mt = null; if (mts.ContainsKey(mat.MaterialTemplate)) { mt = mts[mat.MaterialTemplate]; } else { var hash = FNV1A64HashAlgorithm.HashString(mat.MaterialTemplate); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ExtractSingleToStream(ar, hash, ms); ms.Seek(0, SeekOrigin.Begin); mt = (CMaterialTemplate)_wolvenkitFileService.ReadRed4File(ms).RootChunk; mts.Add(mat.MaterialTemplate, mt); break; } } } var fakeMaterialInstance = new CMaterialInstance() { BaseMaterial = new CResourceReference <IMaterial> { DepotPath = mat.BaseMaterial }, Values = new CArray <CKeyValuePair>() }; var orgChain = GetMaterialChain(fakeMaterialInstance, archives, ref mts); if (mt != null) { foreach (var(key, value) in matData.Materials[i].Data) { var found = false; for (var k = 0; k < mt.Parameters[2].Count; k++) { var refer = mt.Parameters[2][k].Chunk; if (refer.ParameterName == key) { found = true; object convValue = GetMaterialParameterValue(refer.GetType(), value); if (orgChain.valueDict.ContainsKey(refer.ParameterName) && !Equals(orgChain.valueDict[refer.ParameterName], convValue)) { chunk.Values.Add(new CKeyValuePair(refer.ParameterName, (IRedType)convValue)); } } } if (!found) { var wrapper = ((JsonElement)value).Deserialize <MaterialValueWrapper>(); var(type, _) = RedReflection.GetCSTypeFromRedType(wrapper.Type); var nValue = ((JsonElement)wrapper.Value).Deserialize(type, RedJsonSerializer.Options); chunk.Values.Add(new CKeyValuePair(key, (IRedType)nValue)); } } } mi.RootChunk = chunk; } offsets.Add((uint)materialbuffer.Position); using var m = new MemoryStream(); using var writer = new CR2WWriter(m); writer.WriteFile(mi); materialbuffer.Write(m.ToArray(), 0, (int)m.Length); sizes.Add((uint)m.Length); } var blob = (CMesh)cr2w.RootChunk; // remove existing data while (blob.MaterialEntries.Count != 0) { blob.MaterialEntries.Remove(blob.MaterialEntries[^ 1]);
private (string materialTemplate, Dictionary <string, object> valueDict) GetMaterialChain(CMaterialInstance cMaterialInstance, List <Archive> archives, ref Dictionary <string, CMaterialTemplate> mts) { var resultDict = new Dictionary <string, object>(); var baseMaterials = new List <CMaterialInstance>(); string path = cMaterialInstance.BaseMaterial.DepotPath; while (!Path.GetExtension(path).Contains("mt")) { var file = LoadFile(path, archives); if (file.RootChunk is not CMaterialInstance mi) { throw new Exception("Invalid .mi file"); } baseMaterials.Add(mi); path = mi.BaseMaterial.DepotPath; } baseMaterials.Reverse(); CMaterialTemplate mt; if (mts.ContainsKey(path)) { mt = mts[path]; } else { var file = LoadFile(path, archives); mt = (CMaterialTemplate)file.RootChunk; mts.Add(path, mt); } foreach (var usedParameter in mt.UsedParameters[2]) { foreach (var parameterHandle in mt.Parameters[2]) { var refer = parameterHandle.Chunk; if (refer.ParameterName == usedParameter.Name) { resultDict.Add(refer.ParameterName, GetMaterialParameterValue(refer)); } } } baseMaterials.Add(cMaterialInstance); foreach (var mi in baseMaterials) { foreach (var kvp in mi.Values) { object value = null; foreach (var handle in mt.Parameters[2]) { if (Equals(handle.Chunk.ParameterName, kvp.Key)) { value = kvp.Value; } } if (value == null) { value = new MaterialValueWrapper { Type = kvp.Value.RedType, Value = kvp.Value }; } if (resultDict.ContainsKey(kvp.Key)) { resultDict[kvp.Key] = value; } else { resultDict.Add(kvp.Key, value); } } } return(path, resultDict); }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData) { if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any() || cr2w.Buffers.Count < 1) { return(false); } 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); CR2WFile mi = new CR2WFile(); { var chunk = new CMaterialInstance(mi, null, "CMaterialInstance") { IsSerialized = true }; chunk.CookingPlatform = new CEnum <Enums.ECookingPlatform>(mi, chunk, "cookingPlatform") { IsSerialized = true, Value = Enums.ECookingPlatform.PLATFORM_PC }; chunk.CookingPlatform.EnumValueList.Add("PLATFORM_PC"); chunk.ResourceVersion = new CUInt8(mi, chunk, "resourceVersion") { IsSerialized = true, Value = 4 }; chunk.BaseMaterial = new rRef <IMaterial>(mi, chunk, "baseMaterial") { IsSerialized = true, DepotPath = mat.BaseMaterial }; chunk.CMaterialInstanceData = new CArray <CVariantSizeNameType>(mi, chunk, "CMaterialInstanceData") { IsSerialized = true }; mi.CreateChunk(chunk, 0); } MATERIAL.WriteMatToMeshEnum(ref mi, ref mat); 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); }
public bool WriteMatToMesh(ref CR2WFile cr2w, string _matData, List <Archive> archives) { if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any() || cr2w.Buffers.Count < 1) { return(false); } var matData = 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 (matData.Materials.Count < 1) { return(false); } Dictionary <string, CMaterialTemplate> mts = new Dictionary <string, CMaterialTemplate>(); for (int i = 0; i < matData.Materials.Count; i++) { var mat = matData.Materials[i]; names.Add(mat.Name); CR2WFile mi = new CR2WFile(); { var chunk = new CMaterialInstance(mi, null, "CMaterialInstance") { IsSerialized = true }; chunk.CookingPlatform = new CEnum <Enums.ECookingPlatform>(mi, chunk, "cookingPlatform") { IsSerialized = true, Value = Enums.ECookingPlatform.PLATFORM_PC }; chunk.CookingPlatform.EnumValueList.Add("PLATFORM_PC"); chunk.EnableMask = new CBool(mi, chunk, "enableMask") { IsSerialized = true, Value = true }; chunk.ResourceVersion = new CUInt8(mi, chunk, "resourceVersion") { IsSerialized = true, Value = 4 }; chunk.BaseMaterial = new rRef <IMaterial>(mi, chunk, "baseMaterial") { IsSerialized = true, DepotPath = mat.BaseMaterial }; chunk.CMaterialInstanceData = new CArray <CVariantSizeNameType>(mi, chunk, "CMaterialInstanceData") { IsSerialized = true }; CMaterialTemplate mt = null; if (mts.ContainsKey(mat.MaterialTemplate)) { mt = mts[mat.MaterialTemplate]; } else { ulong hash = FNV1A64HashAlgorithm.HashString(mat.MaterialTemplate); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); mt = _wolvenkitFileService.TryReadRED4File(ms).Chunks.Select(_ => _.Data).OfType <CMaterialTemplate>().First(); mts.Add(mat.MaterialTemplate, mt); break; } } } var keys = matData.Materials[i].Data.Keys.ToList(); if (mt != null) { for (int j = 0; j < keys.Count; j++) { string typename = null; for (int k = 0; k < mt.Parameters[2].Count; k++) { var refer = mt.Parameters[2][k].GetReference().Data; if ((refer.ChildrEditableVariables[0] as CName).Value == keys[j]) { if (refer.ChildrEditableVariables.Count > 2) { typename = refer.ChildrEditableVariables[2].REDType; } } } if (typename != null) { // remove when setfromobj deserialization is fixed if (typename == "Color") { CColor_ value0 = new CColor_(new CR2WFile(), null, keys[j]); value0.IsSerialized = true; value0.SetFromJObject(matData.Materials[i].Data[keys[j]]); var variant = new CVariantSizeNameType(mi, chunk.CMaterialInstanceData, keys[j]); CColor value = new CColor(mi, variant, keys[j]); value.IsSerialized = true; value.Red = new CUInt8(mi, value, "Red") { IsSerialized = true, Value = value0.Red.Value }; value.Green = new CUInt8(mi, value, "Green") { IsSerialized = true, Value = value0.Green.Value }; value.Blue = new CUInt8(mi, value, "Blue") { IsSerialized = true, Value = value0.Blue.Value }; value.Alpha = new CUInt8(mi, value, "Alpha") { IsSerialized = true, Value = value0.Alpha.Value }; variant.SetVariant(value); chunk.CMaterialInstanceData.Add(variant); } else { var variant = new CVariantSizeNameType(mi, chunk.CMaterialInstanceData, keys[j]); var value = CR2WTypeManager.Create(typename, keys[j], mi, variant); value.IsSerialized = true; value.SetFromJObject(matData.Materials[i].Data[keys[j]]); variant.SetVariant(value); chunk.CMaterialInstanceData.Add(variant); } } } } mi.CreateChunk(chunk, 0); } 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); }
private RawMaterial ContainRawMaterial(CMaterialInstance cMaterialInstance, string Name, List <Archive> archives, ref Dictionary <string, CMaterialTemplate> mts) { RawMaterial rawMaterial = new RawMaterial(); rawMaterial.Name = Name; rawMaterial.BaseMaterial = cMaterialInstance.BaseMaterial.DepotPath; List <CMaterialInstance> BaseMaterials = new List <CMaterialInstance>(); string path = cMaterialInstance.BaseMaterial.DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(path); while (!Path.GetExtension(path).Contains("mt")) { 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; } } } BaseMaterials.Reverse(); CMaterialTemplate mt = null; if (mts.ContainsKey(path)) { mt = mts[path]; } else { hash = FNV1A64HashAlgorithm.HashString(path); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var ms = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, ms); mt = _wolvenkitFileService.TryReadRED4File(ms).Chunks.Select(_ => _.Data).OfType <CMaterialTemplate>().First(); mts.Add(path, mt); break; } } } rawMaterial.MaterialTemplate = path; rawMaterial.Data = new Dictionary <string, object>(); for (int i = 0; i < mt.UsedParameters[2].Count; i++) { for (int e = 0; e < mt.Parameters[2].Count; e++) { var refer = mt.Parameters[2][e].GetReference().Data; if ((refer.ChildrEditableVariables[0] as CName).Value == mt.UsedParameters[2][i].Name.Value) { // childreditablevars indexing is dangerous(what if someone changes order of vars), just works :D if (refer.ChildrEditableVariables.Count > 2 && refer.ChildrEditableVariables[2].IsSerialized) { if (refer.ChildrEditableVariables[2] is CColor col) { var col_ = new CColor_(col.Cr2wFile as CR2WFile, null, mt.UsedParameters[2][i].Name.Value); col_.Red = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Red") { Value = col.Red.Value, IsSerialized = true }; col_.Green = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Green") { Value = col.Green.Value, IsSerialized = true }; col_.Blue = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Blue") { Value = col.Blue.Value, IsSerialized = true }; col_.Alpha = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Alpha") { Value = col.Alpha.Value, IsSerialized = true }; rawMaterial.Data.Add(mt.UsedParameters[2][i].Name.Value, col_.ToObject()); } else { rawMaterial.Data.Add(mt.UsedParameters[2][i].Name.Value, refer.ChildrEditableVariables[2].ToObject()); } } } } } BaseMaterials.Add(cMaterialInstance); for (int i = 0; i < BaseMaterials.Count; i++) { for (int e = 0; e < BaseMaterials[i].CMaterialInstanceData.Count; e++) { var variant = BaseMaterials[i].CMaterialInstanceData[e].Variant; // remove when tobj serialization is fixed if (variant is CColor col) { var col_ = new CColor_(col.Cr2wFile as CR2WFile, null, BaseMaterials[i].CMaterialInstanceData[e].REDName); col_.Red = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Red") { Value = col.Red.Value, IsSerialized = true }; col_.Green = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Green") { Value = col.Green.Value, IsSerialized = true }; col_.Blue = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Blue") { Value = col.Blue.Value, IsSerialized = true }; col_.Alpha = new CUInt8(col.Cr2wFile as CR2WFile, col_, "Alpha") { Value = col.Alpha.Value, IsSerialized = true }; if (rawMaterial.Data.ContainsKey(BaseMaterials[i].CMaterialInstanceData[e].REDName)) { rawMaterial.Data[BaseMaterials[i].CMaterialInstanceData[e].REDName] = col_.ToObject(); } else { rawMaterial.Data.Add(BaseMaterials[i].CMaterialInstanceData[e].REDName, col_.ToObject()); } } else { if (rawMaterial.Data.ContainsKey(BaseMaterials[i].CMaterialInstanceData[e].REDName)) { rawMaterial.Data[BaseMaterials[i].CMaterialInstanceData[e].REDName] = variant.ToObject(); } else { rawMaterial.Data.Add(BaseMaterials[i].CMaterialInstanceData[e].REDName, variant.ToObject()); } } } } return(rawMaterial); }