예제 #1
0
        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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        // 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);
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        /// <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);
        }
예제 #8
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;
     }
 }
예제 #9
0
        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);
        }
예제 #10
0
        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));
        }
예제 #11
0
        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);
        }
예제 #12
0
 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;
     }
 }
예제 #13
0
        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);
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        /// <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);
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
        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;
        }
예제 #18
0
        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);
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
 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);
         }
     }
 }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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);
            }
        }
예제 #23
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));
        }
예제 #24
0
        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));
        }
예제 #25
0
        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);
        }
예제 #26
0
        /// <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;
                    }
                }
            }
        }
예제 #27
0
 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);
     }
 }
예제 #28
0
 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);
     }
 }
예제 #29
0
        // SkeletalMesh
        private void CreateMeshSkinning(MESkeletalMesh mesh, int lod, FBXNode pFbxMesh, FBXNode pSkeletonRoot, FBXScene pScene)
        {
            var vg = GetVertexGroups(mesh, lod);

            CreateMeshSkinning(vg, pFbxMesh, pSkeletonRoot, pScene);
        }
예제 #30
0
        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);
        }
예제 #31
0
        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);
                }
            }
        }
예제 #32
0
        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();
            }
        }