public static RawArmature GetNonParentedRig(MeshBones meshBones) { if (meshBones.boneCount != 0) // for rigid meshes { RawArmature Rig = new RawArmature(); Rig.BoneCount = meshBones.boneCount + 1; Rig.LocalPosn = new Vec3[Rig.BoneCount]; Rig.LocalRot = new System.Numerics.Quaternion[Rig.BoneCount]; Rig.LocalScale = new Vec3[Rig.BoneCount]; Rig.Parent = new Int16[Rig.BoneCount]; Rig.Names = new string[Rig.BoneCount]; Rig.Parent[0] = -1; Rig.Names[0] = "WolvenKit_Root"; Rig.LocalPosn[0] = new Vec3(0f, 0f, 0f); Rig.LocalRot[0] = new System.Numerics.Quaternion(0f, 0f, 0f, 1f); Rig.LocalScale[0] = new Vec3(1f, 1f, 1f); for (int i = 0; i < Rig.BoneCount - 1; i++) { Rig.LocalPosn[i + 1] = meshBones.WorldPosn[i]; Rig.Names[i + 1] = meshBones.Names[i]; Rig.LocalRot[i + 1] = new System.Numerics.Quaternion(-0.707107f, 0f, 0f, 0.707107f); Rig.LocalScale[i + 1] = new Vec3(1f, 1f, 1f); Rig.Parent[i + 1] = 0; } return(Rig); } return(null); }
public bool ExportMeshWithRig(Stream meshStream, Stream rigStream, FileInfo outfile, bool LodFilter = true, bool isGLBinary = true) { RawArmature Rig = _rig.ProcessRig(rigStream); var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any()) { return(false); } if (!cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } MemoryStream ms = GetMeshBufferStream(meshStream, cr2w); MeshesInfo meshinfo = GetMeshesinfo(cr2w); MeshBones bones = new MeshBones(); CMesh cmesh = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); if (cmesh.BoneNames.Count != 0) // for rigid meshes { bones.Names = RIG.GetboneNames(cr2w); bones.WorldPosn = GetMeshBonesPosn(cr2w); } List <RawMeshContainer> expMeshes = ContainRawMesh(ms, meshinfo, LodFilter); if (cmesh.BoneNames.Count == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } UpdateMeshJoints(ref expMeshes, Rig, bones); ModelRoot model = RawMeshesToGLTF(expMeshes, Rig); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } meshStream.Dispose(); meshStream.Close(); rigStream.Dispose(); rigStream.Close(); return(true); }
public static void UpdateMeshJoints(ref List <RawMeshContainer> Meshes, RawArmature Rig, MeshBones Bones) { // updating mesh bone indexes for (int i = 0; i < Meshes.Count; i++) { for (int e = 0; e < Meshes[i].vertices.Length; e++) { for (int eye = 0; eye < Meshes[i].weightcount; eye++) { bool found = false; for (UInt16 r = 0; r < Rig.BoneCount; r++) { if (Rig.Names[r] == Bones.Names[Meshes[i].boneindices[e, eye]]) { Meshes[i].boneindices[e, eye] = r; found = true; break; } } if (!found) { throw new Exception("Bone: " + Bones.Names[Meshes[i].boneindices[e, eye]] + " is not present in the Provided .rig(s).\nInput .rig(s) are incompatible or incomplete, Please provide a/more compatible .rig(s)\nTIP: 1. For body .rig(s) provide {BodyType}_base_deformations.rig instead of {BodyType}_base.rig.\n2. if Input .mesh(s) contains any dangle/physics bones, provide the compatible dangle.rig also.\n"); } } } } }
public bool ExportMultiMeshWithRig(List <Stream> meshStreamS, List <Stream> rigStreamS, FileInfo outfile, bool LodFilter = true, bool isGLBinary = true) { List <RawArmature> Rigs = new List <RawArmature>(); rigStreamS = rigStreamS.OrderByDescending(r => r.Length).ToList(); // not so smart hacky method to get bodybase rigs on top/ orderby descending for (int r = 0; r < rigStreamS.Count; r++) { RawArmature Rig = _rig.ProcessRig(rigStreamS[r]); Rigs.Add(Rig); } RawArmature expRig = RIG.CombineRigs(Rigs); List <RawMeshContainer> expMeshes = new List <RawMeshContainer>(); for (int m = 0; m < meshStreamS.Count; m++) { var cr2w = _wolvenkitFileService.TryReadRED4File(meshStreamS[m]); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { continue; } MemoryStream ms = GetMeshBufferStream(meshStreamS[m], cr2w); MeshesInfo meshinfo = GetMeshesinfo(cr2w); MeshBones bones = new MeshBones(); CMesh cmesh = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First(); if (cmesh.BoneNames.Count != 0) // for rigid meshes { bones.Names = RIG.GetboneNames(cr2w); bones.WorldPosn = GetMeshBonesPosn(cr2w); } List <RawMeshContainer> Meshes = ContainRawMesh(ms, meshinfo, LodFilter); for (int i = 0; i < Meshes.Count; i++) { Meshes[i].name = m + "_" + Meshes[i].name; if (cmesh.BoneNames.Count == 0) // for rigid meshes { Meshes[i].weightcount = 0; } } UpdateMeshJoints(ref Meshes, expRig, bones); expMeshes.AddRange(Meshes); } ModelRoot model = RawMeshesToGLTF(expMeshes, expRig); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } for (int i = 0; i < meshStreamS.Count; i++) { meshStreamS[i].Dispose(); meshStreamS[i].Close(); } for (int i = 0; i < rigStreamS.Count; i++) { rigStreamS[i].Dispose(); rigStreamS[i].Close(); } return(true); }
public bool ExportMesh(Stream meshStream, FileInfo outfile, bool LodFilter = true, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any()) { return(false); } if (!cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(WriteFakeMeshToFile()); } MeshBones meshBones = new 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 = GetMeshBonesPosn(cr2w); } RawArmature Rig = GetNonParentedRig(meshBones); MemoryStream ms = GetMeshBufferStream(meshStream, cr2w); MeshesInfo meshinfo = GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = ContainRawMesh(ms, meshinfo, LodFilter); if (meshBones.boneCount == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } UpdateMeshJoints(ref expMeshes, Rig, meshBones); ModelRoot model = RawMeshesToGLTF(expMeshes, Rig); WriteMeshToFile(); meshStream.Dispose(); meshStream.Close(); return(true); bool WriteFakeMeshToFile() { if (WolvenTesting.IsTesting) { return(true); } if (isGLBinary) { ModelRoot.CreateModel().SaveGLB(outfile.FullName); } else { ModelRoot.CreateModel().SaveGLTF(outfile.FullName); } return(true); } void WriteMeshToFile() { if (WolvenTesting.IsTesting) { return; } if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } } }