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)); }
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 void StoreRestPose(FBXScene pScene, FBXNode pSkeletonRoot, SkeletonAsset Skeleton) { Dictionary <String, FBBone> pose = Skeleton.ModelBones; FBXAMatrix lTransformMatrix = new FBXAMatrix(); FBXVector4 lT, lR, lS; lS = new FBXVector4(1.0, 1.0, 1.0, 0); FBXPose lPose = FBXPose.Create(pScene, "A Bind Pose"); lT = new FBXVector4(); lR = new FBXVector4(); lTransformMatrix.SetTRS(lT, lR, lS); FBXNode lKFbxNode = pSkeletonRoot; lPose.Add(lKFbxNode, lTransformMatrix); foreach (string key in pose.Keys) { FBBone bonePose = pose[key]; FBXNode fbxBone = pSkeletonRoot.FindChild(key); FBXVector4 Forward = new FBXVector4(bonePose.Forward.members[0], bonePose.Forward.members[1], bonePose.Forward.members[2], 0); FBXVector4 Right = new FBXVector4(bonePose.Right.members[0], bonePose.Right.members[1], bonePose.Right.members[2], 0); FBXVector4 Up = new FBXVector4(bonePose.Up.members[0], bonePose.Up.members[1], bonePose.Up.members[2], 0); FBXVector4 Trans = new FBXVector4(bonePose.Location.members[0] * exportScale, bonePose.Location.members[1] * exportScale, bonePose.Location.members[2] * exportScale, 1); FBXAMatrix boneTransform = new FBXAMatrix(); boneTransform.SetRow(0, Right); boneTransform.SetRow(1, Up); boneTransform.SetRow(2, Forward); boneTransform.SetRow(3, Trans); lPose.Add(fbxBone, boneTransform); } lPose.SetIsBindPose(true); pScene.AddPose(lPose); }
private void AddMorphToMesh(FBXScene pScene, FBXNode pFbxNode, List <Vector> morph) { FBXShape lShape = FBXShape.Create(pScene, "MorphShape"); FBXMesh mesh = (FBXMesh)pFbxNode.GetMesh(); int count = mesh.GetControlPointsCount(); lShape.InitControlPoints(count); List <FBXVector4> lControlPoints = lShape.GetControlPoints(); for (int i = 0; i < count; i++) { FBXVector4 cp = new FBXVector4(morph[i].members[0] * exportScale, morph[i].members[1] * exportScale, morph[i].members[2] * exportScale, 0); lControlPoints[i] = cp; } lShape.SetControlPoints(lControlPoints); FBXBlendShape lBlendShape = FBXBlendShape.Create(pScene, "morph"); FBXBlendShapeChannel lBlendShapeChannel = FBXBlendShapeChannel.Create(pScene, "morphchannel"); mesh.AddDeformer(lBlendShape); lBlendShape.AddBlendShapeChannel(lBlendShapeChannel); lBlendShapeChannel.AddTargetShape(lShape); }
// skinning private void CreateMeshSkinning(Dictionary <string, List <VertexWeight> > vg, FBXNode pFbxMesh, FBXNode pSkeletonRoot, FBXScene pScene) { FBXSkin lFbxSkin = FBXSkin.Create(pScene, ""); FBXAMatrix lMeshMatTransform = pFbxMesh.EvaluateGlobalTransform(); foreach (string key in vg.Keys) { List <VertexWeight> bvg = vg[key]; FBXCluster lCluster = FBXCluster.Create(pScene, key); FBXNode lFbxBone = pSkeletonRoot.FindChild(key); if (lFbxBone != null) { lCluster.SetLink(lFbxBone); foreach (VertexWeight v in bvg) { lCluster.AddControlPointIndex(v.vertexIndex, v.weight); } lFbxSkin.AddCluster(lCluster); lCluster.SetTransformMatrix(lMeshMatTransform); FBXAMatrix lBoneMatTransform = lFbxBone.EvaluateGlobalTransform(); lCluster.SetTransformLinkMatrix(lBoneMatTransform); } } FBXGeometry lFbxMeshAtt = (FBXGeometry)pFbxMesh.GetNodeAttribute().ToGeometry(); if (lFbxMeshAtt != null) { lFbxMeshAtt.AddDeformer(lFbxSkin); } }
private void StoreBindPose(FBXScene pScene, FBXNode pMesh) { List <FBXNode> lClusteredFbxNodes = new List <FBXNode>(); int i, j; FBXNodeAttribute att = pMesh.GetNodeAttribute(); if (pMesh != null && att != null) { int lSkinCount = 0; int lClusterCount = 0; switch (pMesh.GetNodeAttribute().GetAttributeType()) { default: break; case NodeAttribType.eMesh: case NodeAttribType.eNurbs: case NodeAttribType.ePatch: FBXGeometry geo = (FBXGeometry)att.ToGeometry(); lSkinCount = geo.GetDeformerCount(EDeformerType.eSkin); for (i = 0; i < lSkinCount; ++i) { FBXSkin lSkin = geo.GetSkinDeformer(i); lClusterCount += lSkin.GetClusterCount(); } break; } if (lClusterCount != 0) { for (i = 0; i < lSkinCount; ++i) { FBXGeometry geo = (FBXGeometry)att.ToGeometry(); FBXSkin lSkin = geo.GetSkinDeformer(i); lClusterCount = lSkin.GetClusterCount(); for (j = 0; j < lClusterCount; ++j) { FBXNode lClusterNode = lSkin.GetClusterLink(j); AddNodeRecursively(lClusteredFbxNodes, lClusterNode); } } lClusteredFbxNodes.Add(pMesh); } } if (lClusteredFbxNodes.Count != 0) { FBXPose lPose = FBXPose.Create(pScene, "pose"); lPose.SetIsBindPose(true); for (i = 0; i < lClusteredFbxNodes.Count; i++) { FBXNode lKFbxNode = lClusteredFbxNodes[i]; FBXAMatrix lBindMatrix = lKFbxNode.EvaluateGlobalTransform(); lPose.Add(lKFbxNode, lBindMatrix); } pScene.AddPose(lPose); } }
/// <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); }
private void UpdateSkeletonWithMorph(Unreal.BioMorphFace morph, FBXNode pSkeletonNode) { foreach (var bo in morph.BonesOffset) { FBXNode fbxBone = pSkeletonNode.FindChild(bo.BoneName); List <double> tmp = fbxBone.LclTranslation; tmp[0] = bo.Offset.X; tmp[1] = -bo.Offset.Y; tmp[2] = bo.Offset.Z; fbxBone.LclTranslation = tmp; } }
private FBXNode CreateFbxMesh(MeshLodSection section, FBXScene pScene) { FBXMesh fbxMesh = FBXMesh.Create(pScene, section.matName); FBXGeometryElementNormal lGeometryElementNormal = fbxMesh.CreateElementNormal(); lGeometryElementNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementBinormal lGeometryElementBiNormal = fbxMesh.CreateElementBinormal(); lGeometryElementBiNormal.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); FBXGeometryElementTangent lGeometryElementTangent = fbxMesh.CreateElementTangent(); lGeometryElementTangent.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); fbxMesh.InitControlPoints(section.vertices.Count); FBXGeometryElementMaterial lMaterialElement = fbxMesh.CreateElementMaterial(); lMaterialElement.SetMappingMode(FBXWrapper.MappingMode.eByPolygon); lMaterialElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); FBXGeometryElementUV lUVDiffuseElement = fbxMesh.CreateElementUV(section.matName); lUVDiffuseElement.SetMappingMode(FBXWrapper.MappingMode.eByControlPoint); lUVDiffuseElement.SetReferenceMode(FBXWrapper.ReferenceMode.eIndexToDirect); lUVDiffuseElement.SetIndexArrayCount(section.vertices.Count); for (int j = 0; j < section.vertices.Count; j++) { FBXVector4 position = new FBXVector4(section.vertices[j].position.members[0] * exportScale, section.vertices[j].position.members[1] * exportScale, section.vertices[j].position.members[2] * exportScale, 0); FBXVector4 normal = new FBXVector4(section.vertices[j].normals.members[0], section.vertices[j].normals.members[1], section.vertices[j].normals.members[2], section.vertices[j].normals.members[3]); FBXVector4 textCoords = new FBXVector4(section.vertices[j].texCoords.members[0], (-section.vertices[j].texCoords.members[1] + 1), 0, 0); FBXVector4 bitangent = new FBXVector4(section.vertices[j].biTangents.members[0], section.vertices[j].biTangents.members[1], section.vertices[j].biTangents.members[2], section.vertices[j].biTangents.members[3]); FBXVector4 tangent = new FBXVector4(section.vertices[j].tangents.members[0], section.vertices[j].tangents.members[1], section.vertices[j].tangents.members[2], section.vertices[j].tangents.members[3]); fbxMesh.SetControlPoint(j, position); lGeometryElementNormal.Add(normal); lGeometryElementBiNormal.Add(bitangent); lGeometryElementTangent.Add(tangent); lUVDiffuseElement.Add(textCoords); } for (int j = 0; j < section.indicies.Count; j++) { if (j % 3 == 0) { fbxMesh.EndPolygon(); fbxMesh.BeginPolygon(); } fbxMesh.AddPolygon(section.indicies[j]); } fbxMesh.EndPolygon(); FBXNode lMeshNode = FBXNode.Create(pScene, section.matName); lMeshNode.SetNodeAttribute(fbxMesh); lMeshNode.AddMaterial(pScene, section.matName); return(lMeshNode); }
private void SetTransform(CSGGroup group, FBXNode node) { CSGVector position = new CSGVector(); group.GetPosition(group.Parent, -1, ref position); position.Z *= -1; node.LclTranslationSet(new FBXVector(position.X, position.Y, position.Z)); FBXVector eulerXYZRH = this.GetEulerXYZ(group, -1); node.LclRotationSet(new FBXVector(eulerXYZRH.x, eulerXYZRH.y, eulerXYZRH.z)); }
private FBXNode CreateFbxSkeleton(List <MESkeletalMesh.BoneStruct> Bones, FBXScene pScene) { FBXSkeleton lSkeletonRootAttribute = FBXSkeleton.Create(pScene, "Skeleton"); lSkeletonRootAttribute.SetSkeletonType(FBXWrapper.SkelType.eRoot); FBXNode lSkeletonRoot = FBXNode.Create(pScene, "Skeleton"); lSkeletonRoot.SetNodeAttribute(lSkeletonRootAttribute); lSkeletonRoot.LclTranslation = new FBXVector4().ToList(); FBXNode FbxSkeletonRootNode = CreateFbxBone(0, Bones, pScene, lSkeletonRoot); lSkeletonRoot.AddChild(FbxSkeletonRootNode); return(lSkeletonRoot); }
private void UpdateSkeletonWithMorph(SkeletonAsset Skeleton, FBXNode pSkeletonNode, List <Vector> morphBones) { for (int i = 0; i < Skeleton.Bones.Count; i++) { FBBone fbbone = Skeleton.Bones[i]; FBXNode fbxBone = pSkeletonNode.FindChild(fbbone.Name); Vector boneOffset = morphBones[i]; List <double> tmp = fbxBone.LclTranslation; tmp[0] += boneOffset.members[0] * exportScale; tmp[1] += boneOffset.members[1] * exportScale; tmp[2] += boneOffset.members[2] * exportScale; fbxBone.LclTranslation = tmp; } }
private FBXNode CreateFbxSkeleton(SkeletonAsset Skeleton, FBXScene pScene) { FBXSkeleton lSkeletonRootAttribute = FBXSkeleton.Create(pScene, "Skeleton"); lSkeletonRootAttribute.SetSkeletonType(FBXWrapper.SkelType.eRoot); FBXNode lSkeletonRoot = FBXNode.Create(pScene, "Skeleton"); lSkeletonRoot.SetNodeAttribute(lSkeletonRootAttribute); lSkeletonRoot.LclTranslation = new FBXVector4().ToList(); FBXNode FbxSkeletonRootNode = CreateFbxBone(Skeleton.RootBone, pScene, lSkeletonRoot); lSkeletonRoot.AddChild(FbxSkeletonRootNode); SetBoneTransform(Skeleton, lSkeletonRoot); return(lSkeletonRoot); }
private void ParseNode(FBXNode n, bool traverse) { CreateCMPData(n); if (!traverse) { return; } for (int i = 0; i < n.GetChildCount(); i++) { var child = n.GetChild(i); ParseNode(child, false); } }
/// <summary> /// /// </summary> /// <param name="nodeInstance">The node that we are recursing into.</param> /// <param name="depth">The depth of the hierarchy we are displaying</param> private static void DisplayHierarchyRecursive(FBXNode nodeInstance, int depth) { string output = string.Empty; for (int index = 0; index < depth; index++) { output += " "; } // Write the information out Logger.LogMessage("{0}{1}", output, nodeInstance.GetName()); for (int index = 0; index < nodeInstance.GetChildCount(); index++) { DisplayHierarchyRecursive(nodeInstance.GetChild(index), depth + 1); } }
private FBXNode CreateFbxBone(FBBone bone, FBXScene pScene, FBXNode parent) { FBXSkeleton lSkeletonLimbNodeAttribute1 = FBXSkeleton.Create(pScene, bone.Name); lSkeletonLimbNodeAttribute1.SetSkeletonType(FBXWrapper.SkelType.eLimbNode); lSkeletonLimbNodeAttribute1.SetSize(1.0); FBXNode lSkeletonLimbNode1 = FBXNode.Create(pScene, bone.Name); lSkeletonLimbNode1.SetNodeAttribute(lSkeletonLimbNodeAttribute1); for (int i = 0; i < bone.Children.Count; i++) { FBBone childBone = bone.Children[i]; FBXNode fbxChildBone = CreateFbxBone(childBone, pScene, lSkeletonLimbNode1); lSkeletonLimbNode1.AddChild(fbxChildBone); } return(lSkeletonLimbNode1); }
private void SetBoneTransform(FBBone bone, FBXNode fbxBoneNode) { List <double> tmp = new List <double>(); tmp.Add(bone.Location.members[0] * exportScale); tmp.Add(bone.Location.members[1] * exportScale); tmp.Add(bone.Location.members[2] * exportScale); fbxBoneNode.LclTranslation = tmp; FBXVector4 rot = CalculateBoneRotation(bone); tmp = new List <double>(); tmp.Add(rot.X); tmp.Add(rot.Y); tmp.Add(rot.Z); fbxBoneNode.LclRotation = tmp; }
private FBXNode CreateFbxBone(int boneIndex, List <MESkeletalMesh.BoneStruct> Skeleton, FBXScene pScene, FBXNode parent) { MESkeletalMesh.BoneStruct bone = Skeleton[boneIndex]; string boneName = bone.BoneName; FBXSkeleton lSkeletonLimbNodeAttribute1 = FBXSkeleton.Create(pScene, boneName); lSkeletonLimbNodeAttribute1.SetSkeletonType(FBXWrapper.SkelType.eLimbNode); lSkeletonLimbNodeAttribute1.SetSize(1.0); FBXNode lSkeletonLimbNode1 = FBXNode.Create(pScene, boneName); lSkeletonLimbNode1.SetNodeAttribute(lSkeletonLimbNodeAttribute1); lSkeletonLimbNode1.LclTranslation = new List <double> { bone.Position.X, -bone.Position.Y, bone.Position.Z }; ME3Explorer.Unreal.Classes.SkeletalMeshOld.Quad boneQuad; boneQuad.x = -bone.Orientation.X; boneQuad.y = bone.Orientation.Y; boneQuad.z = bone.Orientation.Z; boneQuad.w = -bone.Orientation.W; if (boneIndex == 0) { boneQuad.w = boneQuad.w * -1; } Rotator rot = QuatToRotator(boneQuad); lSkeletonLimbNode1.LclRotation = new List <double> { rot.Roll, rot.Pitch, rot.Yaw }; var children = Skeleton.Where(b => b.Parent == boneIndex).ToList(); foreach (var childBone in children) { int childIndexInSkeleton = Skeleton.FindIndex(b => b.Name == childBone.Name); if (childIndexInSkeleton != boneIndex) { FBXNode fbxChildBone = CreateFbxBone(childIndexInSkeleton, Skeleton, pScene, lSkeletonLimbNode1); lSkeletonLimbNode1.AddChild(fbxChildBone); } } return(lSkeletonLimbNode1); }
private void SetBoneTransform(SkeletonAsset Skeleton, FBXNode pSkeletonRoot) { Dictionary <String, FBBone> pose = Skeleton.ModelBones; foreach (string key in pose.Keys) { FBBone bonePose = pose[key]; FBXNode fbxBone = pSkeletonRoot.FindChild(key); FBXVector4 ForwardM = new FBXVector4(bonePose.Forward.members[0], bonePose.Forward.members[1], bonePose.Forward.members[2], 0); FBXVector4 RightM = new FBXVector4(bonePose.Right.members[0], bonePose.Right.members[1], bonePose.Right.members[2], 0); FBXVector4 UpM = new FBXVector4(bonePose.Up.members[0], bonePose.Up.members[1], bonePose.Up.members[2], 0); FBXVector4 TransM = new FBXVector4(bonePose.Location.members[0] * exportScale, bonePose.Location.members[1] * exportScale, bonePose.Location.members[2] * exportScale, 1); FBXAMatrix transfoMatrix = new FBXAMatrix(); transfoMatrix.SetRow(0, RightM); transfoMatrix.SetRow(1, UpM); transfoMatrix.SetRow(2, ForwardM); transfoMatrix.SetRow(3, TransM); FBXHelper.SetGlobalDefaultPosition(fbxBone, transfoMatrix); } }
private void AddNodeRecursively(List <FBXNode> pNodeArray, FBXNode pNode) { if (pNode != null) { AddNodeRecursively(pNodeArray, pNode.GetParent()); bool found = false; foreach (FBXNode n in pNodeArray) { if (n.Equals(pNode)) { found = true; break; } } if (found) { pNodeArray.Add(pNode); } } }
private void ExportGroupShapes(CSGGroup group, FBXScene fbxScene, FBXNode sceneNode, string groupName, FBXNode node) { CSGShapeArray childShapeList = group.GetShapes(); for (int shapeIndex = 0; shapeIndex < childShapeList.GetSize(); shapeIndex++) { // this little bit of weirdness is due to View3D and Paint3D not being able to have multiple shapes on the same node // there may need to be an export option for this at some point var subnode = node; if (shapeIndex > 0) { string subGroupName = this.GetUniqueName(groupName + "_" + shapeIndex.ToString(), "group"); subnode = FBXNode.Create(sceneNode, subGroupName); node.AddChild(subnode); } this.ExportShape(fbxScene, subnode, childShapeList.GetElement(shapeIndex)); subnode.SetShadingMode(ArcManagedFBX.Types.EShadingMode.eTextureShading); } }
private void ExportGroupRecursively(CSGGroup group, FBXScene fbxScene, FBXNode parentNode, FBXAnimLayer animationLayer, float keyFramesPerSecond) { string groupName = this.GetUniqueName(group.Name, "group"); var node = FBXNode.Create(parentNode, groupName); parentNode.AddChild(node); this.SetTransform(group, node); this.ExportGroupAnimation(group, animationLayer, keyFramesPerSecond, node); this.ExportGroupShapes(group, fbxScene, parentNode, groupName, node); CSGGroupArray childGroupList = group.GetChildren(); for (int groupIndex = 0; groupIndex < childGroupList.GetSize(); groupIndex++) { this.ExportGroupRecursively(childGroupList.GetElement(groupIndex), fbxScene, node, animationLayer, keyFramesPerSecond); } }
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 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)); }
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); }
/// <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; } } } }
void FbxsdkFindAllAnimatedNodes(FBXScene scene, FBXNode node, List<FBXNode> outputCollection) { if(scene.HasCurve(node)) outputCollection.Add(node); for(int i=0;i<node.GetChildCount();++i) { FbxsdkFindAllAnimatedNodes(scene, node.GetChild(i), outputCollection); } }
void FbxsdkBuildHierachy(FBXNode fbxNode, SkeletonNode parentNode, Dictionary<SkeletonNode, FBXMesh> outputMeshDict) { var node = new SkeletonNode(); node.Name = fbxNode.GetName(); node.PoseMatrix = FbxsdkConvertMatrix(fbxNode.GetLocalTransform()); node.Parent = parentNode; if (parentNode == null) skeleton = node; else parentNode.Children.Add(node); var mesh = fbxNode.GetMesh() ; if(mesh != null) { outputMeshDict[node] = mesh; } if (skeletonNodeDict.ContainsKey(node.Name)) { Debug.Log("Found duplicated skeleton node name: " + node.Name); } else { skeletonNodeDict.Add(node.Name, node); } for (int i = 0; i < fbxNode.GetChildCount(); ++i) { FbxsdkBuildHierachy(fbxNode.GetChild(i), node, outputMeshDict); } }
// 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); }
private void CreateCMPData(FBXNode n) { Vector3 vOffset = Vector3.Zero; CmpndData cmpnd = new CmpndData(); cmpnd.index = 0; cmpnd.object_name = n.GetName(); if (cmpnd.object_name == "Root") { cmpnd.name = "Root"; } else { cmpnd.name = "Part_" + cmpnd.object_name; if (Relocate) { vOffset = T(n.EvaluateLocalTranslation(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false)); } } cmpnd.object_data = new ThreeDBData(); cmpnd.object_data.data = new LodData[8]; cmpnd.object_data.wireframe_lod = 0; int lods = 0; for (int i = 0; i < n.GetChildCount(); i++) { var cur_lodnode = n.GetChild(i); var match = Regex.Match(cur_lodnode.GetName(), @"^.+_lod(?<lod>[0-9])(?<wireframe>_vwd)?"); if (match.Success) { uint lod = uint.Parse(match.Groups["lod"].Value); if (match.Groups["wireframe"].Success) { cmpnd.object_data.wireframe_lod = lod; } cmpnd.object_data.data[lod].meshes = new List <SMesh>(); lods++; int numVerts = 0; int numFaces = 0; Vector3 bbmin = new Vector3(float.MaxValue); Vector3 bbmax = new Vector3(float.MinValue); for (int j = 0; j < cur_lodnode.GetChildCount(); j++) { var cur_node = cur_lodnode.GetChild(j); var attr = cur_node.GetNodeAttribute(); if (attr == null) { continue; } if (attr.GetAttributeType() != ArcManagedFBX.Types.EAttributeType.eMesh) { continue; } var pmesh = attr as FBXMesh; var cur_node_trans = T(cur_node.EvaluateGlobalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false)); var cur_node_geo = T(cur_node.GetGeometricMatrix(ArcManagedFBX.Types.EPivotSet.eSourcePivot)); cur_node_trans = cur_node_geo * cur_node_trans; SMesh mesh = new SMesh(); int nTris = pmesh.GetPolygonCount(); if (nTris <= 0) { continue; } if (cur_node.GetMaterialCount() <= 0) { mesh.material_name = "default"; } else { var material = cur_node.GetMaterial(0); mesh.material_name = material.GetName(); } mesh.name = cur_node.GetName(); mesh.t = new VMSTri[nTris]; int nVerts = nTris * 3; mesh.v = new VMSVert[nVerts]; var vertices = pmesh.GetControlPoints(); int tangentLayerCount = pmesh.GetElementTangentCount(); var tangentLayer = tangentLayerCount > 0 ? pmesh.GetElementTangent().GetDirectArray() : null; int binormalLayerCount = pmesh.GetElementBinormalCount(); var binormalLayer = binormalLayerCount > 0 ? pmesh.GetElementBinormal().GetDirectArray() : null; for (int nTri = 0; nTri < nTris; nTri++) { mesh.t[nTri].vertices = new ushort[3]; for (int k = 0; k < 3; k++) { int nVert = (nTri * 3 + k); Vector3 vertice, normal; Vector2 uv; bool unmapped = false; FBXVector fbxuv = new FBXVector(); FBXVector fbxnormal = new FBXVector(); vertice = Vector3.TransformCoordinate(T(vertices[pmesh.GetPolygonVertex(nTri, k)]), cur_node_trans); // offset vertice vertice -= vOffset; pmesh.GetPolygonVertexUV(nTri, k, "map1", ref fbxuv, ref unmapped); uv = T2(fbxuv); pmesh.GetPolygonVertexNormal(nTri, k, ref fbxnormal); normal = Vector3.TransformNormal(T(fbxnormal), cur_node_trans); mesh.t[nTri].vertices[k] = (ushort)nVert; mesh.v[nVert].vert = vertice; mesh.v[nVert].normal = normal; mesh.v[nVert].uv = uv; mesh.v[nVert].tangent = tangentLayer != null?T(tangentLayer.GetAt(nVert)) : Vector3.Zero; mesh.v[nVert].binormal = binormalLayer != null?T(binormalLayer.GetAt(nVert)) : Vector3.Zero; /* * * float alpha = 1.0f; * int iVCindex = mesh->pMesh->GetFaceVertex(pTriangle->meshFaceIndex, i); * if (iVCindex != -1) * { * alpha = mesh->pMesh->GetAlphaVertex(pTriangle->alpha[i]); * color = mesh->pMesh->GetColorVertex(pTriangle->color[i]); * mesh->v[nVert].diffuse = (DWORD)(alpha * 255) << 24 | (DWORD)(color.x * 255) << 16 | (DWORD)(color.y * 255) << 8 | (DWORD)(color.z * 255); * mesh->v[nVert].uv = uv; * } * else * { * mesh->v[nVert].tangent = Point3(0, 0, 0); * mesh->v[nVert].binormal = Point3(0, 0, 0); * }*/ bbmin = Vector3.Min(bbmin, vertice); bbmax = Vector3.Max(bbmin, vertice); } } mesh.nVerts = nVerts; numVerts += mesh.nVerts; mesh.nTris = nTris; numFaces += mesh.nTris; cmpnd.object_data.data[lod].meshes.Add(mesh); } cmpnd.object_data.data[lod].vmeshref = new VMeshRef(); cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxX = bbmax.X; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxY = bbmax.Y; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMaxZ = bbmax.Z; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinX = bbmin.X; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinY = bbmin.Y; cmpnd.object_data.data[lod].vmeshref.BoundingBoxMinZ = bbmin.Z; var vCenter = (bbmax + bbmin) / 2; cmpnd.object_data.data[lod].vmeshref.CenterX = vCenter.X; cmpnd.object_data.data[lod].vmeshref.CenterY = vCenter.Y; cmpnd.object_data.data[lod].vmeshref.CenterZ = vCenter.Z; cmpnd.object_data.data[lod].vmeshref.Radius = (bbmax - vCenter).Length() * 1.25f; cmpnd.object_data.data[lod].vmeshref.HeaderSize = 60; cmpnd.object_data.data[lod].vmeshref.NumMeshes = (ushort)cmpnd.object_data.data[lod].meshes.Count; cmpnd.object_data.data[lod].vmeshref.NumVert = (ushort)numVerts; cmpnd.object_data.data[lod].vmeshref.NumIndex = (ushort)(numFaces * 3); if (numFaces * 3 > 0xFFFF) { throw new ArgumentException($"{cmpnd.object_name} references more than 65535 vertices. Split the group into smaller groups!"); } } } cmpnd.object_data.lods = (uint)lods; cmpnd.index = cmpndData.Count; cmpndData.Add(cmpnd); if (cmpnd.object_name != "Root") { if (cmpnd.object_name.EndsWith("_rev")) { CmpRevData.Part revdata = new CmpRevData.Part(); revdata.ParentName = "Root"; revdata.ChildName = cmpnd.object_name; revdata.OriginX = vOffset.X; revdata.OriginY = vOffset.Y; revdata.OriginZ = vOffset.Z; var mat = n.EvaluateLocalTransform(FBXTime.Infinite(), ArcManagedFBX.Types.EPivotSet.eSourcePivot, false, false); revdata.RotMatXX = (float)mat.mData[0].x; revdata.RotMatXY = (float)mat.mData[1].x; revdata.RotMatXZ = (float)mat.mData[2].x; revdata.RotMatYX = (float)mat.mData[0].y; revdata.RotMatYY = (float)mat.mData[1].y; revdata.RotMatYZ = (float)mat.mData[2].y; revdata.RotMatZX = (float)mat.mData[0].z; revdata.RotMatZY = (float)mat.mData[1].z; revdata.RotMatZZ = (float)mat.mData[2].z; revdata.AxisRotX = (float)mat.mData[0].x; revdata.AxisRotY = (float)mat.mData[1].x; revdata.AxisRotZ = (float)mat.mData[2].x; revdata.Max = 1; rev.Parts.Add(revdata); } else if (cmpnd.object_name.EndsWith("_pris")) { CmpRevData.Part revdata = new CmpRevData.Part(); revdata.ParentName = "Root"; revdata.ChildName = cmpnd.object_name; revdata.OriginX = vOffset.X; revdata.OriginY = vOffset.Y; revdata.OriginZ = vOffset.Z; revdata.RotMatXX = revdata.RotMatYY = revdata.RotMatZZ = 1; revdata.AxisRotZ = 1; revdata.Max = 360; pris.Parts.Add(revdata); } else { CmpFixData.Part fixdata = new CmpFixData.Part(); fixdata.ParentName = "Root"; fixdata.ChildName = cmpnd.object_name; fixdata.OriginX = vOffset.X; fixdata.OriginY = vOffset.Y; fixdata.OriginZ = vOffset.Z; fixdata.RotMatXX = fixdata.RotMatYY = fixdata.RotMatZZ = 1; fix.Parts.Add(fixdata); } } }
private void ExportGroupAnimation(CSGGroup group, FBXAnimLayer animationLayer, float keyFramesPerSecond, FBXNode node) { CSGAnimationKey[] animationKeyList = null; int keyListCount = 0; group.GetAnimationKeys(0, 999999, ref animationKeyList, ref keyListCount); int translationAnimationKeyCount = 0; int rotationAnimationKeyCount = 0; foreach (var animationKey in animationKeyList) { if (animationKey.Type == CSGAnimationKeyType.CSGAnimationPositionKey) { translationAnimationKeyCount++; } if (animationKey.Type == CSGAnimationKeyType.CSGAnimationOrientationKey) { rotationAnimationKeyCount++; } } if (translationAnimationKeyCount > 1) { FBXAnimCurveNode myTranslationAnimCurveNode = node.LclTranslationGetCurveNode(animationLayer); FBXAnimCurve myTranXCurve = node.LclTranslationGetCurve(animationLayer, "X"); FBXAnimCurve myTranYCurve = node.LclTranslationGetCurve(animationLayer, "Y"); FBXAnimCurve myTranZCurve = node.LclTranslationGetCurve(animationLayer, "Z"); myTranXCurve.KeyModifyBegin(); myTranYCurve.KeyModifyBegin(); myTranZCurve.KeyModifyBegin(); foreach (var animationKey in animationKeyList) { if (animationKey.Type == CSGAnimationKeyType.CSGAnimationPositionKey) { myTranXCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, animationKey.V.X); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationConstant); myTranYCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, animationKey.V.Y); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationConstant); myTranZCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, -animationKey.V.Z); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationConstant); } } myTranXCurve.KeyModifyEnd(); myTranYCurve.KeyModifyEnd(); myTranZCurve.KeyModifyEnd(); } if (rotationAnimationKeyCount > 1) { FBXAnimCurveNode myRotationAnimCurveNode = node.LclRotationGetCurveNode(animationLayer); FBXAnimCurve myRotXCurve = node.LclRotationGetCurve(animationLayer, "X"); FBXAnimCurve myRotYCurve = node.LclRotationGetCurve(animationLayer, "Y"); FBXAnimCurve myRotZCurve = node.LclRotationGetCurve(animationLayer, "Z"); myRotXCurve.KeyModifyBegin(); myRotYCurve.KeyModifyBegin(); myRotZCurve.KeyModifyBegin(); foreach (var animationKey in animationKeyList) { if (animationKey.Type == CSGAnimationKeyType.CSGAnimationOrientationKey) { FBXVector eulerXYZ = this.GetEulerXYZ(group, animationKey.Time); myRotXCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, (float)eulerXYZ.x); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationLinear); myRotYCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, (float)eulerXYZ.y); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationLinear); myRotZCurve.KeyAddSet(animationKey.Time / keyFramesPerSecond, (float)eulerXYZ.z); // , ArcManagedFBX.Types.EInterpolationType.eInterpolationLinear); } } myRotXCurve.KeyModifyEnd(); myRotYCurve.KeyModifyEnd(); myRotZCurve.KeyModifyEnd(); } }