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); }
public bool ExportSkinnedMeshToFBX(SkeletonAsset skeleton, MeshAsset mesh, int lodIndex, String targetdir, bool asOne) { FBXManager lSdkManager = new FBXManager(); FBXScene lScene = new FBXScene(); FBXHelper.InitializeSdkObjects(lSdkManager, lScene); FBXNode SceneRoot = lScene.GetRootNode(); FBXNode lSkeletonRoot = CreateFbxSkeleton(skeleton, lScene); SceneRoot.AddChild(lSkeletonRoot); if (asOne) { FBXNode fbxMesh = CreateFbxMesh(mesh.lods[lodIndex], lScene); CreateMeshSkinning(skeleton, mesh.lods[lodIndex], fbxMesh, lSkeletonRoot, lScene); SceneRoot.AddChild(fbxMesh); StoreRestPose(lScene, lSkeletonRoot, skeleton); } else { for (int i = 0; i < mesh.lods[lodIndex].sections.Count; i++) { FBXNode CurrentSectionMesh = CreateFbxMesh(mesh.lods[lodIndex].sections[i], lScene); CreateMeshSkinning(skeleton, mesh.lods[lodIndex].sections[i], CurrentSectionMesh, lSkeletonRoot, lScene); SceneRoot.AddChild(CurrentSectionMesh); StoreBindPose(lScene, CurrentSectionMesh); } } return(SaveScene(targetdir, lSdkManager, lScene)); }
/// <summary> /// /// </summary> /// <param name="sceneInstance">The fbx scene</param> private static void DisplayHierarachy(FBXScene sceneInstance) { if (sceneInstance == null) { throw new ArgumentNullException("The scene is invalid. Check and try again."); } FBXNode rootNode = sceneInstance.GetRootNode(); DisplayHierarchyRecursive(rootNode, 0); }
public bool ExportMeshWithMorph(SkeletonAsset Skeleton, MeshAsset mesh, int lodIndex, List <Vector> morphVertex, List <Vector> morphBones, String targetdir) { FBXManager lSdkManager = new FBXManager(); FBXScene lScene = new FBXScene(); FBXHelper.InitializeSdkObjects(lSdkManager, lScene); FBXNode SceneRoot = lScene.GetRootNode(); FBXNode fbxMesh = CreateFbxMesh(mesh.lods[lodIndex], lScene); AddMorphToMesh(lScene, fbxMesh, morphVertex); SceneRoot.AddChild(fbxMesh); if (Skeleton != null) { FBXNode lSkeletonRoot = CreateFbxSkeleton(Skeleton, lScene); CreateMeshSkinning(Skeleton, mesh.lods[lodIndex], fbxMesh, lSkeletonRoot, lScene); UpdateSkeletonWithMorph(Skeleton, lSkeletonRoot, morphBones); SceneRoot.AddChild(lSkeletonRoot); StoreBindPose(lScene, fbxMesh); } return(SaveScene(targetdir, lSdkManager, lScene)); }
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); }
public bool ExportStaticMeshToFBX(MeshAsset mesh, int lodIndex, String targetdir, bool asOne) { FBXManager lSdkManager = new FBXManager(); FBXScene lScene = new FBXScene(); FBXHelper.InitializeSdkObjects(lSdkManager, lScene); FBXNode SceneRoot = lScene.GetRootNode(); if (asOne) { FBXNode fbxMesh = CreateFbxMesh(mesh.lods[lodIndex], lScene); SceneRoot.AddChild(fbxMesh); } else { for (int i = 0; i < mesh.lods[lodIndex].sections.Count; i++) { FBXNode CurrentSectionMesh = CreateFbxMesh(mesh.lods[lodIndex].sections[i], lScene); SceneRoot.AddChild(CurrentSectionMesh); } } return(SaveScene(targetdir, lSdkManager, lScene)); }
/// <summary> /// The display content method /// </summary> /// <param name="sceneInstance">The scene that we are running on.</param> private static void DisplayContent(FBXScene sceneInstance) { FBXNode rootNode = sceneInstance.GetRootNode(); if (rootNode != null) { // Iterate over the children in this node. for (int index = 0; index < rootNode.GetChildCount(); index++) { var attributeType = rootNode.GetChild(index).GetNodeAttribute().GetAttributeType(); FBXNode nodeInstance = rootNode.GetChild(index); FBXNodeAttribute attributeInstance = nodeInstance.GetNodeAttribute(); // Cast out the node object based on the type of the attribute. switch (attributeType) { case EAttributeType.eMesh: DisplayMesh((FBXMesh)attributeInstance); break; case EAttributeType.eCamera: DisplayCamera((FBXCamera)attributeInstance); break; case EAttributeType.eLight: DisplayLight((FBXLight)attributeInstance); break; case EAttributeType.eSkeleton: DisplaySkeleton((FBXSkeleton)attributeInstance); break; } } } }
private void ImportFBX(string path) { FBXManager man = FBXManager.Create(); FBXIOSettings io = FBXIOSettings.Create(man, "IOSRoot"); man.SetIOSettings(io); FBXImporter fbx = FBXImporter.Create(man, ""); fbx.Initialize(path, -1, man.GetIOSettings()); FBXScene scene = FBXScene.Create(man, "importScene"); fbx.Import(scene); fbx.Destroy(); var root = scene.GetRootNode(); for (int i = 0; i < root.GetChildCount(); i++) { var child = root.GetChild(i); if (child.GetName() == "Root") { ParseNode(child, true); break; } } List <VMeshDataFile> lst_vmesh_data = new List <VMeshDataFile>(); VMeshDataFile cur_meshdata_file = null; for (int i = 0; i < cmpndData.Count; i++) { var cmpnd = cmpndData[i]; for (uint lod = 0; lod < cmpnd.object_data.lods; lod++) { if (cur_meshdata_file == null || cmpnd.object_data.data[lod].vmeshref.NumIndex + cur_meshdata_file.ref_vertices > 0xFFFF) { cur_meshdata_file = new VMeshDataFile(); cur_meshdata_file.filename = UniqueName + lst_vmesh_data.Count + ".vms"; cur_meshdata_file.ref_vertices = 0; cur_meshdata_file.vertices = 0; cur_meshdata_file.meshes = 0; lst_vmesh_data.Add(cur_meshdata_file); } cur_meshdata_file.ref_vertices += cmpnd.object_data.data[lod].vmeshref.NumIndex; cur_meshdata_file.vertices += cmpnd.object_data.data[lod].vmeshref.NumVert; cur_meshdata_file.meshes += cmpnd.object_data.data[lod].vmeshref.NumMeshes; cmpnd.object_data.data[lod].vmeshref.VMeshLibId = Utilities.FLModelCRC(cur_meshdata_file.filename); cmpnd.object_data.data[lod].vmeshdata = cur_meshdata_file; } cmpnd.object_data.file_name = UniqueName + "." + cmpnd.object_name + ".3db"; cmpndData.RemoveAt(i); cmpndData.Insert(i, cmpnd); } foreach (var vmesh in lst_vmesh_data) { /*VMeshData vmeshdata = new VMeshData(); * * switch (VertexType) * { * case ModelImportVertexType.Normals: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_NORMAL | VMeshData.D3DFVF_TEX1); * break; * case ModelImportVertexType.VertexColors: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_DIFFUSE | VMeshData.D3DFVF_TEX1); * break; * case ModelImportVertexType.VertexColorsNormals: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_DIFFUSE | VMeshData.D3DFVF_NORMAL | VMeshData.D3DFVF_DIFFUSE); * break; * case ModelImportVertexType.ExtraUVs: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_NORMAL | VMeshData.D3DFVF_TEX2); * break; * case ModelImportVertexType.TangentsBinormals: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_NORMAL | VMeshData.D3DFVF_TEX4); * break; * case ModelImportVertexType.ExtraUVsTangentsBinormals: * vmeshdata.FlexibleVertexFormat = (ushort)(VMeshData.D3DFVF_XYZ | VMeshData.D3DFVF_NORMAL | VMeshData.D3DFVF_TEX5); * break; * }*/ const uint HEADER_SIZE = 2 * 4 + 4 * 2; const uint MESH_HEADER_SIZE = 4 + 3 * 2 + 2; const uint INDEX_SIZE = 2; uint VERTEX_SIZE = 0; switch (VertexType) { case ModelImportVertexType.Normals: VERTEX_SIZE = 3 * 4 + 3 * 4 + 2 * 4; break; case ModelImportVertexType.VertexColors: VERTEX_SIZE = 3 * 4 + 1 * 4 + 2 * 4; break; case ModelImportVertexType.VertexColorsNormals: VERTEX_SIZE = 3 * 4 + 3 * 4 + 1 * 4 + 2 * 4; break; case ModelImportVertexType.ExtraUVs: VERTEX_SIZE = 3 * 4 + 3 * 4 + 2 * 4 + 2 * 4; break; case ModelImportVertexType.TangentsBinormals: VERTEX_SIZE = 3 * 4 + 3 * 4 + 2 * 4 + 3 * 4 + 3 * 4; break; case ModelImportVertexType.ExtraUVsTangentsBinormals: VERTEX_SIZE = 3 * 4 + 3 * 4 + 2 * 4 + 2 * 4 + 3 * 4 + 3 * 4; break; } int meshCount = 0; int indicesCount = 0; int verticesCount = 0; foreach (var cmpnd in cmpndData) { for (int lod = 0; lod < cmpnd.object_data.lods; lod++) { if (cmpnd.object_data.data[lod].vmeshdata == vmesh) { meshCount += cmpnd.object_data.data[lod].meshes.Count; foreach (var m in cmpnd.object_data.data[lod].meshes) { indicesCount += m.t.Length * 3; verticesCount += m.v.Length; } } } } byte[] data = new byte[HEADER_SIZE + MESH_HEADER_SIZE * meshCount + INDEX_SIZE * indicesCount + VERTEX_SIZE * verticesCount]; int pos = 0; // write header Utilities.WriteInt(data, 1, ref pos); Utilities.WriteInt(data, 4, ref pos); Utilities.WriteWord(data, (ushort)vmesh.meshes, ref pos); Utilities.WriteWord(data, (ushort)vmesh.ref_vertices, ref pos); ushort fvf = 0; switch (VertexType) { case ModelImportVertexType.Normals: fvf = 0x112; break; case ModelImportVertexType.VertexColors: fvf = 0x142; break; case ModelImportVertexType.VertexColorsNormals: fvf = 0x152; break; case ModelImportVertexType.ExtraUVs: fvf = 0x212; break; case ModelImportVertexType.TangentsBinormals: fvf = 0x412; break; case ModelImportVertexType.ExtraUVsTangentsBinormals: fvf = 0x512; break; } Utilities.WriteWord(data, fvf, ref pos); Utilities.WriteWord(data, (ushort)vmesh.vertices, ref pos); uint iMesh = 0; uint iGlobalStartVertex = 0; uint iGlobalStartIndex = 0; // save mesh header data foreach (var cmpnd in cmpndData) { for (int lod = 0; lod < cmpnd.object_data.lods; lod++) { if (cmpnd.object_data.data[lod].vmeshdata == vmesh) { cmpnd.object_data.data[lod].vmeshref.StartMesh = (ushort)iMesh; cmpnd.object_data.data[lod].vmeshref.StartVert = (ushort)iGlobalStartVertex; cmpnd.object_data.data[lod].vmeshref.StartIndex = (ushort)iGlobalStartIndex; uint iStartVert = 0; foreach (var m in cmpnd.object_data.data[lod].meshes) { Utilities.WriteDWord(data, Utilities.FLModelCRC(m.material_name), ref pos); Utilities.WriteWord(data, (ushort)iStartVert, ref pos); Utilities.WriteWord(data, (ushort)(iStartVert + m.nVerts - 1), ref pos); Utilities.WriteWord(data, (ushort)(m.nTris * 3), ref pos); Utilities.WriteWord(data, 0xCC, ref pos); iStartVert += (uint)m.nVerts; iGlobalStartIndex += (uint)m.nTris * 3; iGlobalStartVertex += (uint)m.nVerts; iMesh++; } } } } // save indices foreach (var cmpnd in cmpndData) { for (int lod = 0; lod < cmpnd.object_data.lods; lod++) { if (cmpnd.object_data.data[lod].vmeshdata == vmesh) { foreach (var m in cmpnd.object_data.data[lod].meshes) { foreach (var t in m.t) { Utilities.WriteWord(data, t.vertices[0], ref pos); Utilities.WriteWord(data, t.vertices[1], ref pos); Utilities.WriteWord(data, t.vertices[2], ref pos); } } } } } // save vertices foreach (var cmpnd in cmpndData) { for (int lod = 0; lod < cmpnd.object_data.lods; lod++) { if (cmpnd.object_data.data[lod].vmeshdata == vmesh) { foreach (var m in cmpnd.object_data.data[lod].meshes) { foreach (var v in m.v) { Utilities.WriteFloat(data, v.vert.X, ref pos); Utilities.WriteFloat(data, v.vert.Y, ref pos); Utilities.WriteFloat(data, v.vert.Z, ref pos); if (VertexType != ModelImportVertexType.VertexColors) { Utilities.WriteFloat(data, v.normal.X, ref pos); Utilities.WriteFloat(data, v.normal.Y, ref pos); Utilities.WriteFloat(data, v.normal.Z, ref pos); } if (VertexType == ModelImportVertexType.VertexColors || VertexType == ModelImportVertexType.VertexColorsNormals) { Utilities.WriteDWord(data, v.diffuse, ref pos); } Utilities.WriteFloat(data, v.uv.X, ref pos); Utilities.WriteFloat(data, v.uv.Y, ref pos); if (VertexType == ModelImportVertexType.ExtraUVs || VertexType == ModelImportVertexType.ExtraUVsTangentsBinormals) { Utilities.WriteFloat(data, v.uv2.X, ref pos); Utilities.WriteFloat(data, v.uv2.Y, ref pos); } if (VertexType == ModelImportVertexType.ExtraUVsTangentsBinormals || VertexType == ModelImportVertexType.TangentsBinormals) { Utilities.WriteFloat(data, v.tangent.X, ref pos); Utilities.WriteFloat(data, v.tangent.Y, ref pos); Utilities.WriteFloat(data, v.tangent.Z, ref pos); Utilities.WriteFloat(data, v.binormal.X, ref pos); Utilities.WriteFloat(data, v.binormal.Y, ref pos); Utilities.WriteFloat(data, v.binormal.Z, ref pos); } } } } } } TreeNode vmeshnode = CreateNode(vmesh.filename); vmeshlib.Nodes.Add(vmeshnode); TreeNode vmeshdatanode = CreateNode("VMeshData", data); vmeshnode.Nodes.Add(vmeshdatanode); } uint iTotalVWireIndices = 0; if (Wireframe) { } TreeNode consnode = CreateNode("Cons"); cmpnd.Nodes.Add(consnode); if (rev.Parts.Count > 0) { TreeNode revnode = CreateNode("Rev", rev.GetBytes()); consnode.Nodes.Add(revnode); } if (pris.Parts.Count > 0) { TreeNode prisnode = CreateNode("Pris", pris.GetBytes()); consnode.Nodes.Add(prisnode); } if (fix.Parts.Count > 0) { TreeNode fixnode = CreateNode("Fix", fix.GetBytes()); consnode.Nodes.Add(fixnode); } foreach (var cmpnd in cmpndData) { // Cmpnd child node { TreeNode cmpndnode = CreateNode(cmpnd.name); this.cmpnd.Nodes.Add(cmpndnode); TreeNode file_name = CreateNode("File name", Encoding.ASCII.GetBytes(cmpnd.object_data.file_name + "\u0000")); TreeNode index = CreateNode("Index", BitConverter.GetBytes(cmpnd.index)); TreeNode object_name = CreateNode("Object name", Encoding.ASCII.GetBytes(cmpnd.object_name + "\u0000")); cmpndnode.Nodes.Add(file_name); cmpndnode.Nodes.Add(index); cmpndnode.Nodes.Add(object_name); } // Root child node { TreeNode threedbnode = CreateNode(cmpnd.object_data.file_name); rootCMP.Nodes.Add(threedbnode); if (Wireframe) { } TreeNode multilevel = CreateNode("MultiLevel"); threedbnode.Nodes.Add(multilevel); if (cmpnd.object_data.lods > 1) { byte[] data = new byte[4 * cmpnd.object_data.lods]; int pos = 0; Utilities.WriteFloat(data, 0.0f, ref pos); for (int lod = 1; lod < cmpnd.object_data.lods; lod++) { Utilities.WriteFloat(data, (float)Math.Pow(10.0f, (float)(lod + 1)), ref pos); } Utilities.WriteFloat(data, 1000000.0f, ref pos); TreeNode switch2 = CreateNode("Switch2", data); multilevel.Nodes.Add(switch2); } for (int lod = 0; lod < cmpnd.object_data.lods; lod++) { TreeNode levelnode = CreateNode("Level" + lod); multilevel.Nodes.Add(levelnode); TreeNode vmeshpart = CreateNode("VMeshPart"); levelnode.Nodes.Add(vmeshpart); TreeNode vmeshref = CreateNode("VMeshRef", cmpnd.object_data.data[lod].vmeshref.GetBytes()); vmeshpart.Nodes.Add(vmeshref); } } } }
void FbxsdkLoadAnimations(FBXScene scene, AnimationClipCreateInfo[] clips) { const double FRAMES_PER_SECOND = 30; if (clips == null) return; List<FBXNode> fbxNodeList = new List<FBXNode>(); FbxsdkFindAllAnimatedNodes(scene, scene.GetRootNode(), fbxNodeList); if (fbxNodeList.Count == 0) { Debug.Log("Don't have animation data"); return; } foreach (var clipCreateInfo in clips) { var start = clipCreateInfo.Start; var frameCount = clipCreateInfo.End - start + 1; var clip = new AnimationClip(); clip.Name = clipCreateInfo.Name; clip.SecondsPerFrame = 1 / FRAMES_PER_SECOND; clip.Duration = frameCount / FRAMES_PER_SECOND; foreach (var fbxNode in fbxNodeList) { var channel = new AnimationNodeChannel(frameCount); channel.Clip = clip; for (int i = 0; i < frameCount; ++i) { channel.Frames[i] = FbxsdkConvertMatrix(fbxNode.EvaluateLocalTransform(start + i)); } clip.Channels[fbxNode.GetName()] = channel; } AnimationClips[clip.Name] = clip; } }