示例#1
0
        private bool SaveScene(String targetdir, FBXManager pSdkManager, FBXScene pScene)
        {
            bool lResult = FBXHelper.SaveScene(pSdkManager, pScene, targetdir);

            FBXHelper.DestroySdkObjects(pSdkManager, lResult);
            return(lResult);
        }
示例#2
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));
        }
示例#3
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);
        }
示例#4
0
    public FBXScene __deref__()
    {
        global::System.IntPtr cPtr = FBXImporterUnmanagedPINVOKE.FBXScenePtr___deref__(swigCPtr);
        FBXScene ret = (cPtr == global::System.IntPtr.Zero) ? null : new FBXScene(cPtr, false);

        return(ret);
    }
示例#5
0
        public static void InitializeSdkObjects(string sceneName, out FBXManager pManager, out FBXScene pScene)
        {
            // The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK
            pManager = FBXManager.Create();
            if (pManager == null)
            {
                Debug.WriteLine("Error: Unable to create FBX Manager!");
                Environment.Exit(1);
            }
            else
            {
                Debug.WriteLine("Autodesk FBX SDK version {0}", FBXManager.GetVersion(true));
            }

            // Create an IOSettings object. This object holds all import/export settings.
            FBXIOSettings ios = FBXIOSettings.Create(pManager, "IOSRoot");

            pManager.SetIOSettings(ios);

            // Load plugins from the executable directory (optional)
            pManager.LoadPluginsDirectory(Environment.CurrentDirectory, string.Empty);

            // Create an FBX scene. This object holds most objects imported/exported from/to files.
            pScene = FBXScene.Create(pManager, sceneName);
            if (pScene == null)
            {
                Debug.WriteLine("Error: Unable to create FBX scene!\n");
                Environment.Exit(1);
            }
        }
示例#6
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);
        }
示例#7
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);
        }
示例#8
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);
            }
        }
示例#9
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);
        }
示例#10
0
        private static void PerformTests(FBXScene scene)
        {
            if (scene == null)
            {
                throw new ArgumentNullException("The scene that was specified is either null or empty.");
            }

            DisplayHierarachy(scene);
            DisplayMetaData(scene);
            DisplayContent(scene);
        }
示例#11
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);
        }
示例#12
0
        public void Load()
        {
            LogMessage("Instantiating the FBX Manager...");
            FBXManager managerInstance = ArcManagedFBX.FBXManager.Create();

            if (string.IsNullOrEmpty(Filename))
            {
                throw new FileNotFoundException("The file that is being loaded in does not exist!");
            }

            if (!File.Exists(Filename))
            {
                throw new FileNotFoundException("The file that is being loaded was not found on disk.");
            }

            LogMessage("Instantiating the FBX Settings...");
            FBXIOSettings settings = FBXIOSettings.Create(managerInstance, "IOSRoot");

            managerInstance.SetIOSettings(settings);

            LogMessage("Loading plugins directory...");
            managerInstance.LoadPluginsDirectory(Environment.CurrentDirectory, "");

            int fileMajorNumber = 0, fileMinorNumber = 0, fileRevisionNumber = 0;

            LogMessage("Instantiating the Scene...");

            FBXScene    scene    = FBXScene.Create(managerInstance, "My Scene");
            FBXImporter importer = FBXImporter.Create(managerInstance, "");

            // Instantiate the framework for the scene as required.
            m_SceneFramework = new SceneFramework(scene);

            LogMessage("Load the importer for the file '{0}'", Filename);
            bool initializeResult = importer.Initialize(Filename, -1, managerInstance.GetIOSettings());

            FBXManager.GetFileFormatVersion(ref fileMajorNumber, ref fileMinorNumber, ref fileRevisionNumber);

            bool importResult = importer.Import(scene);

            m_SceneFramework.Operation();

            if (importResult)
            {
                PerformTests(scene);
            }
            else
            {
                LogError("Import failed. Nothing to do!");
            }
        }
示例#13
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);
        }
示例#14
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);
        }
示例#15
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);
        }
示例#16
0
        /// <summary>
        ///     Display the information that is relevant to the scene (in the form of a documentinfo)
        /// </summary>
        /// <param name="instance">The instance that we are retrieving metadata for</param>
        private static void DisplayMetaData(FBXScene instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("The instance specified is either null or invalid.");
            }

            FBXDocumentInfo metaDataContainer = instance.GetSceneInfo();

            if (metaDataContainer == null)
            {
                throw new ArgumentNullException("The FBXDocumentInfo instance is either null or invalid.");
            }

            // Output the contents of the metadata class.
            Logger.LogMessage("Title: {0}", metaDataContainer.Title);
            Logger.LogMessage("Subject: {0}", metaDataContainer.Subject);
            Logger.LogMessage("Author: {0}", metaDataContainer.Author);
            Logger.LogMessage("Keywords: {0}", metaDataContainer.Keywords);
            Logger.LogMessage("Revision: {0}", metaDataContainer.Revision);
        }
示例#17
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);
            }
        }
示例#18
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);
            }
        }
示例#19
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));
        }
示例#20
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));
        }
示例#21
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);
        }
示例#22
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;
                    }
                }
            }
        }
示例#23
0
        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;
            }
        }
 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);
     }
 }
示例#26
0
 public SceneFramework(FBXScene sceneInstance)
 {
     m_SceneInstance = sceneInstance;
 }
示例#27
0
 public SceneFramework(FBXScene sceneInstance)
 {
     m_SceneInstance = sceneInstance;
 }
示例#28
0
    public FBXScene __ref__()
    {
        FBXScene ret = new FBXScene(FBXImporterUnmanagedPINVOKE.FBXScenePtr___ref__(swigCPtr), false);

        return(ret);
    }
示例#29
0
 public FBXScenePtr(FBXScene p) : this(FBXImporterUnmanagedPINVOKE.new_FBXScenePtr__SWIG_1(FBXScene.getCPtr(p)), true)
 {
 }
示例#30
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);
        }
示例#31
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);
            }
        }
示例#32
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);
        }
示例#33
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);
        }