public void ExportSkeletalMeshToFbx(MESkeletalMesh mesh, string meshName, string targetdir) { FBXManager lSdkManager = new FBXManager(); FBXScene lScene = new FBXScene(); FBXHelper.InitializeSdkObjects(lSdkManager, lScene); FBXNode SceneRoot = lScene.GetRootNode(); FBXNode lSkeletonRoot = CreateFbxSkeleton(mesh.Bones, lScene); SceneRoot.AddChild(lSkeletonRoot); try { FBXNode fbxMesh = CreateFbxMesh(mesh, meshName, lScene); CreateMeshSkinning(mesh, 0, fbxMesh, lSkeletonRoot, lScene); SceneRoot.AddChild(fbxMesh); //StoreRestPose(lScene, lSkeletonRoot, skeleton); } catch (Exception e) { Console.WriteLine(e.Message); } bool lResult = FBXHelper.SaveScene(lSdkManager, lScene, targetdir); FBXHelper.DestroySdkObjects(lSdkManager, lResult); }
private List <int> GetSectionVertices(MESkeletalMesh mesh, int lod, int section) { var vertices = new HashSet <int>(); var cLOD = mesh.LODModels[lod]; for (int i = 0; i < cLOD.Sections[section].NumTriangles * 3; i++) { vertices.Add(cLOD.IndexBuffer.Indexes[(int)cLOD.Sections[section].BaseIndex + i]); } return(vertices.ToList()); }
public void ExportMeshesToFbx(string targetDir) { if (Pcc != null) { var meshExpIndexes = Pcc.Exports.Select((value, index) => new { value, index }) .Where(z => z.value.ClassName == "SkeletalMesh") .Select(z => z.index); foreach (int meshIndex in meshExpIndexes) { IExportEntry meshExp = Pcc.Exports[meshIndex]; MESkeletalMesh skMesh = new MESkeletalMesh(Pcc, meshIndex); string fileDest = System.IO.Path.Combine(targetDir, meshExp.ObjectName + ".fbx"); ExportSkeletalMeshToFbx(skMesh, meshExp.ObjectName, fileDest); } } }
private Dictionary <string, List <VertexWeight> > GetVertexGroups(MESkeletalMesh mesh, int lodIndex = 0) { Dictionary <string, List <VertexWeight> > VertexGroups = new Dictionary <string, List <VertexWeight> >(); var lod = mesh.LODModels[lodIndex]; for (int c = 0; c < lod.Chunks.Count; c++) { var chunk = lod.Chunks[c]; for (int v = chunk.BaseVertexIndex; v < chunk.BaseVertexIndex + chunk.NumRigidVertices + chunk.NumSoftVertices; v++) { var vertex = lod.VertexBufferGPUSkin.Vertices[v]; for (int x = 0; x < vertex.InfluenceWeights.Length; x++) { try { float weight = vertex.InfluenceWeights[x] / 255f; if (weight != 0) { int bone = vertex.InfluenceBones[x]; bone = chunk.BoneMap[bone]; string boneName = mesh.Bones[bone].BoneName; VertexWeight vw; vw.vertexIndex = v; vw.weight = weight; if (!VertexGroups.ContainsKey(boneName)) { VertexGroups.Add(boneName, new List <VertexWeight>()); } VertexGroups[boneName].Add(vw); } } catch (Exception e) { Console.WriteLine(e.Message); } } } } return(VertexGroups); }
private string GetMatName(MESkeletalMesh mesh, MESkeletalMesh.LODModelStruct lod, int s) { if (lod.Sections[s].MaterialIndex < mesh.Materials.Count) { if (mesh.Owner.isExport(mesh.Materials[lod.Sections[s].MaterialIndex] - 1)) { return(mesh.Owner.Exports[mesh.Materials[lod.Sections[s].MaterialIndex] - 1].ObjectName); } else if (mesh.Owner.isImport(-mesh.Materials[lod.Sections[s].MaterialIndex] - 1)) { return(mesh.Owner.Imports[-mesh.Materials[lod.Sections[s].MaterialIndex] - 1].ObjectName); } else { return("mat_" + s); } } else { return("mat_" + s); } }
public void ExportMeshWithMorph(Unreal.BioMorphFace morph, int lodIndex, String targetdir) { FBXManager lSdkManager = new FBXManager(); FBXScene lScene = new FBXScene(); FBXHelper.InitializeSdkObjects(lSdkManager, lScene); FBXNode SceneRoot = lScene.GetRootNode(); MESkeletalMesh mesh = morph.Apply(); FBXNode fbxMesh = CreateFbxMesh(mesh, morph.Name, lScene); SceneRoot.AddChild(fbxMesh); if (mesh.Bones != null) { FBXNode lSkeletonRoot = CreateFbxSkeleton(mesh.Bones, lScene); CreateMeshSkinning(mesh, lodIndex, fbxMesh, lSkeletonRoot, lScene); UpdateSkeletonWithMorph(morph, lSkeletonRoot); SceneRoot.AddChild(lSkeletonRoot); //StoreBindPose(lScene, fbxMesh); } bool lResult = FBXHelper.SaveScene(lSdkManager, lScene, targetdir); FBXHelper.DestroySdkObjects(lSdkManager, lResult); }
// SkeletalMesh private void CreateMeshSkinning(MESkeletalMesh mesh, int lod, FBXNode pFbxMesh, FBXNode pSkeletonRoot, FBXScene pScene) { var vg = GetVertexGroups(mesh, lod); CreateMeshSkinning(vg, pFbxMesh, pSkeletonRoot, pScene); }
private FBXNode CreateFbxMesh(MESkeletalMesh mesh, string mname, FBXScene pScene, float exportScale = 1.0f) { MESkeletalMesh.LODModelStruct lod = mesh.LODModels[0]; FBXMesh fbxMesh = FBXMesh.Create(pScene, mname); FBXNode lMeshNode = FBXNode.Create(pScene, mname); lMeshNode.SetNodeAttribute(fbxMesh); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); fbxMesh.InitControlPoints(lod.NumVertices); // init UV maps FBXGeometryElementUV[] UVs = new FBXGeometryElementUV[lod.Sections.Count]; for (int s = 0; s < lod.Sections.Count; s++) { string matName = GetMatName(mesh, lod, s); UVs[s] = fbxMesh.CreateElementUV(matName); UVs[s].SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); } // vertices for (int j = 0; j < lod.VertexBufferGPUSkin.Vertices.Count; j++) { var vertex = lod.VertexBufferGPUSkin.Vertices[j]; FBXVector4 position = new FBXVector4(vertex.Position.X * exportScale, -vertex.Position.Y * exportScale, vertex.Position.Z * exportScale, 0); FBXVector4 normal = new FBXVector4(vertex.TangentX, 0, vertex.TangentZ, 0); fbxMesh.SetControlPoint(j, position); lGeometryElementTangent.Add(normal); // uvs for (int s = 0; s < lod.Sections.Count; s++) { var sectionVerts = GetSectionVertices(mesh, 0, s); if (sectionVerts.Contains(j)) { FBXVector4 texCoords = new FBXVector4(vertex.U, 1 - vertex.V, 0, 0); UVs[s].Add(texCoords); } else { UVs[s].Add(new FBXVector4(0, 0, 0, 0)); } } } // faces & mats for (int s = 0; s < lod.Sections.Count; s++) { int chunkId = lod.Sections[s].ChunkIndex; var chunk = lod.Chunks[chunkId]; // mat string matName = GetMatName(mesh, lod, s); lMeshNode.AddMaterial(pScene, matName); // faces for (int j = 0; j < lod.Sections[s].NumTriangles; j++) { int baseI = lod.Sections[s].BaseIndex; fbxMesh.BeginPolygon(s); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3]); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 1]); fbxMesh.AddPolygon(lod.IndexBuffer.Indexes[baseI + j * 3 + 2]); fbxMesh.EndPolygon(); } } return(lMeshNode); }