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); } DirectoryInfo outDir = new DirectoryInfo(Path.Combine(outfile.DirectoryName, Path.GetFileNameWithoutExtension(outfile.FullName))); MESH.MeshBones meshBones = new MESH.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 = MESH.GetMeshBonesPosn(cr2w); } RawArmature Rig = MESH.GetNonParentedRig(meshBones); MemoryStream ms = MESH.GetMeshBufferStream(meshStream, cr2w); MeshesInfo meshinfo = MESH.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(ms, meshinfo, LodFilter); 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); ModelRoot model = MESH.RawMeshesToGLTF(expMeshes, Rig); if (!outDir.Exists) { Directory.CreateDirectory(outDir.FullName); } ParseMaterials(cr2w, meshStream, outDir, 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, 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); }