public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true) { if (matRepo == null) { throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required."); } var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } MeshTools.MeshBones meshBones = new MeshTools.MeshBones(); meshBones.boneCount = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count; if (meshBones.boneCount != 0) // for rigid meshes { meshBones.Names = RIG.GetboneNames(cr2w); meshBones.WorldPosn = MeshTools.GetMeshBonesPosn(cr2w); } RawArmature Rig = MeshTools.GetNonParentedRig(meshBones); MemoryStream ms = MeshTools.GetMeshBufferStream(meshStream, cr2w); MeshesInfo meshinfo = MeshTools.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MeshTools.ContainRawMesh(ms, meshinfo, LodFilter); if (meshBones.boneCount == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } MeshTools.UpdateMeshJoints(ref expMeshes, Rig, meshBones); ModelRoot model = MeshTools.RawMeshesToGLTF(expMeshes, Rig); ParseMaterials(cr2w, meshStream, outfile, archives, matRepo, eUncookExtension); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } meshStream.Dispose(); meshStream.Close(); return(true); }
public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true) { if (matRepo == null) { throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required."); } var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } var rendblob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().First(); var rendbuffer = cr2w.Buffers[rendblob.RenderBuffer.Buffer.Value - 1]; meshStream.Seek(rendbuffer.Offset, SeekOrigin.Begin); var ms = new MemoryStream(); meshStream.DecompressAndCopySegment(ms, rendbuffer.DiskSize, rendbuffer.MemSize); var meshesinfo = MeshTools.GetMeshesinfo(rendblob); List <RawMeshContainer> expMeshes = MeshTools.ContainRawMesh(ms, meshesinfo, LodFilter); MeshTools.UpdateSkinningParamCloth(ref expMeshes, meshStream, cr2w); RawArmature Rig = MeshTools.GetOrphanRig(rendblob); ModelRoot model = MeshTools.RawMeshesToGLTF(expMeshes, Rig); ParseMaterials(cr2w, meshStream, outfile, archives, matRepo, eUncookExtension); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } meshStream.Dispose(); meshStream.Close(); return(true); }
public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true) { if (matRepo == null) { throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required."); } var cr2w = _wolvenkitFileService.ReadRed4File(meshStream); if (cr2w == null || cr2w.RootChunk is not CMesh cMesh || cMesh.RenderResourceBlob.Chunk is not rendRenderMeshBlob rendblob) { return(false); } using var ms = new MemoryStream(rendblob.RenderBuffer.Buffer.GetBytes()); var meshesinfo = MeshTools.GetMeshesinfo(rendblob, cr2w); var expMeshes = MeshTools.ContainRawMesh(ms, meshesinfo, LodFilter); MeshTools.UpdateSkinningParamCloth(ref expMeshes, meshStream, cr2w); var Rig = MeshTools.GetOrphanRig(rendblob, cr2w); var model = MeshTools.RawMeshesToGLTF(expMeshes, Rig); ParseMaterials(cr2w, meshStream, outfile, archives, matRepo, eUncookExtension); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } meshStream.Dispose(); meshStream.Close(); return(true); }
public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, string modFolder, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.ReadRed4File(targetStream); if (cr2w == null || cr2w.RootChunk is not MorphTargetMesh morphBlob || morphBlob.Blob.Chunk is not rendRenderMorphTargetMeshBlob blob || blob.BaseBlob.Chunk is not rendRenderMeshBlob rendblob) { return(false); } RawArmature Rig = null; { var hash = FNV1A64HashAlgorithm.HashString(morphBlob.BaseMesh.DepotPath); var meshStream = new MemoryStream(); foreach (var ar in archives) { if (ar.Files.ContainsKey(hash)) { ExtractSingleToStream(ar, hash, meshStream); break; } } var meshCr2w = _wolvenkitFileService.ReadRed4File(meshStream); if (meshCr2w != null && meshCr2w.RootChunk is MorphTargetMesh tBlob1 && tBlob1.Blob.Chunk is rendRenderMorphTargetMeshBlob tBlob2 && tBlob2.BaseBlob.Chunk is rendRenderMeshBlob tBlob3) { Rig = MeshTools.GetOrphanRig(tBlob3, meshCr2w); } } using var meshbuffer = new MemoryStream(rendblob.RenderBuffer.Buffer.GetBytes()); var meshesinfo = MeshTools.GetMeshesinfo(rendblob, cr2w); var expMeshes = MeshTools.ContainRawMesh(meshbuffer, meshesinfo, true); var diffsbuffer = new MemoryStream(); var mappingbuffer = new MemoryStream(); var texbuffer = new MemoryStream(); if (blob.DiffsBuffer is not null) { diffsbuffer = new MemoryStream(blob.DiffsBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(diffsbuffer, cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.DiffsBuffer.Buffer - 1].MemSize); } if (blob.MappingBuffer is not null) { mappingbuffer = new MemoryStream(blob.MappingBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(mappingbuffer, cr2w.Buffers[blob.MappingBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.MappingBuffer.Buffer - 1].MemSize); } if (blob.TextureDiffsBuffer is not null) { texbuffer = new MemoryStream(blob.TextureDiffsBuffer.Buffer.GetBytes()); //targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].Offset, SeekOrigin.Begin); //targetStream.DecompressAndCopySegment(texbuffer, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].DiskSize, cr2w.Buffers[blob.TextureDiffsBuffer.Buffer - 1].MemSize); } var targetsInfo = GetTargetInfos(cr2w, expMeshes.Count); var expTargets = new List <RawTargetContainer[]>(); for (var i = 0; i < targetsInfo.NumTargets; i++) { var temp_NumVertexDiffsInEachChunk = new uint[expMeshes.Count]; var temp_NumVertexDiffsMappingInEachChunk = new uint[expMeshes.Count]; for (var 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)); } var textureStreams = ContainTextureStreams(blob, texbuffer); var 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 (var 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); }
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); }
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); } RawArmature Rig = null; MemoryStream meshbuffer = MeshTools.GetMeshBufferStream(targetStream, cr2w); MeshesInfo meshinfo = MeshTools.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MeshTools.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); MemoryStream meshStream = new MemoryStream(); if (File.Exists(Path.Combine(modFolder, baseMeshPath))) { meshStream = new MemoryStream(File.ReadAllBytes(Path.Combine(modFolder, baseMeshPath))); } else { 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()) { MeshTools.MeshBones meshBones = new MeshTools.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 = MeshTools.GetMeshBonesPosn(meshCr2w); } Rig = MeshTools.GetNonParentedRig(meshBones); MemoryStream ms = MeshTools.GetMeshBufferStream(meshStream, meshCr2w); meshinfo = MeshTools.GetMeshesinfo(meshCr2w); expMeshes = MeshTools.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; } } MeshTools.UpdateMeshJoints(ref expMeshes, Rig, meshBones); } } 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(blob, 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); }