Exemplo n.º 1
0
 /// <summary>   Converts this object to a row. </summary>
 ///
 /// <returns>   This object as a string. </returns>
 public string ToRow()
 {
     return
         ($"{FormatIdentifier.ToDatev()};{Version};{DataCategory.Number};{DataCategory.Name.ToDatev()};{DataCategory.Version};" +
          $"{Created.ToDatevDateTime()};{Imported};{Source.ToDatev()};{ExportedBy.ToDatev()};{ImportedBy.ToDatev()};" +
          $"{ConsultantNumber};{ClientNumber};{StartOfBusinessYear.ToDatevDate()};{ImpersonalAccountsLength};" +
          $"{BookingsFrom.ToDatevDate()};{BookingsTill.ToDatevDate()};{Description.ToDatev()};{DictationShortName.ToDatev()};" +
          $"{BookingType};{BillingIntention};{Fixing.ToDatev()};{CurrencySymbol.ToDatev()};;;;;;;;;");
 }
Exemplo n.º 2
0
            public Int32 Decode(Byte[] buf, Int32 ptr, out String s)
            {
                String r = "";

                formatID = (FormatIdentifier)buf[ptr++];
                groupID  = (GroupIdentifier)buf[ptr++];
                PLVLen   = (buf[ptr++] << 8) | buf[ptr++];

                s = "|" + formatID.ToString() +
                    "|" + groupID.ToString() +
                    "|len:" + PLVLen.ToString();

                while (PLVLen > 0)
                {
                    PLV tmpPLV = new PLV();
                    ptr = tmpPLV.Decode(buf, ptr, out r);
                    s  += r;
                    PLVList.Add(tmpPLV);
                    PLVLen -= (tmpPLV.PL + 2);
                }

                return(ptr);
            }
Exemplo n.º 3
0
        private void BtnConvert_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(TxtInputFolder.Text))
            {
                MessageBox.Show(
                    "Input folder not found!",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

                return;
            }

            if (!Directory.Exists(TxtOutFolder.Text))
            {
                MessageBox.Show(
                    "Output folder not found!",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

                return;
            }

            string[] Files = Directory.GetFiles(TxtInputFolder.Text);

            bool ExportModels = ChkExportModels.Checked;
            bool ExportAnims  = ChkExportAnimations.Checked;
            bool ExportTexs   = ChkExportTextures.Checked;
            bool PrefixNames  = ChkPrefixNames.Checked;

            int Format = CmbFormat.SelectedIndex;

            int FileIndex = 0;

            //TODO: Use Parallel loop for more speed and keep UI responsive
            foreach (string File in Files)
            {
                H3D Data = FormatIdentifier.IdentifyAndOpen(File);

                if (Data != null)
                {
                    string BaseName = PrefixNames ? Path.GetFileNameWithoutExtension(File) + "_" : string.Empty;

                    BaseName = Path.Combine(TxtOutFolder.Text, BaseName);

                    if (!PrefixNames)
                    {
                        BaseName += Path.DirectorySeparatorChar;
                    }

                    if (ExportModels)
                    {
                        for (int Index = 0; Index < Data.Models.Count; Index++)
                        {
                            string FileName = BaseName + Data.Models[Index].Name;

                            switch (Format)
                            {
                            case 0: new DAE(Data, Index).Save(FileName + ".dae"); break;

                            case 1: new SMD(Data, Index).Save(FileName + ".smd"); break;
                            }
                        }
                    }

                    if (ExportAnims && Data.Models.Count > 0)
                    {
                        for (int Index = 0; Index < Data.SkeletalAnimations.Count; Index++)
                        {
                            string FileName = BaseName + Data.Models[0].Name + "_" + Data.SkeletalAnimations[Index].Name;

                            switch (Format)
                            {
                            case 0: new DAE(Data, 0, new int[] { Index }).Save(FileName + ".dae"); break;

                            case 1: new SMD(Data, 0, Index).Save(FileName + ".smd"); break;
                            }
                        }
                    }

                    if (ExportTexs)
                    {
                        foreach (H3DTexture Tex in Data.Textures)
                        {
                            Tex.ToBitmap().Save(Path.Combine(TxtOutFolder.Text, Tex.Name + ".png"));
                        }
                    }
                }

                float Progress = ++FileIndex;

                Progress = (Progress / Files.Length) * 100;

                ProgressConv.Value = (int)Progress;

                Application.DoEvents();
            }
        }
Exemplo n.º 4
0
        private void BtnConvert_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(TxtInputFolder.Text))
            {
                MessageBox.Show(
                    "Input folder not found!",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

                return;
            }

            if (!Directory.Exists(TxtOutFolder.Text))
            {
                //TODO: offer to create output dir "Output folder not found!  Should it be created?"
                MessageBox.Show(
                    "Output folder not found!",
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

                return;
            }


            bool ExportModels = ChkExportModels.Checked;
            bool ExportAnims  = ChkExportAnimations.Checked;
            bool ExportTexs   = ChkExportTextures.Checked;
            bool PrefixNames  = ChkPrefixNames.Checked;
            bool ExportMats   = ChkExportMaterials.Checked;
            bool Recurse      = ChkRecurse.Checked;

            int Format    = CmbFormat.SelectedIndex;
            int MatFormat = CmbMatFormat.SelectedIndex;

            BtnConvert.Enabled = false;

            //get all files (optionally recursive) in input folder
            DirectoryInfo Folder = new DirectoryInfo(TxtInputFolder.Text);

            FileInfo[] Files = Folder.GetFiles("*.*", Recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            //TODO: check and warn on empty input folder

            string subPath;
            string outPath = TxtOutFolder.Text;

            if (!outPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                outPath += Path.DirectorySeparatorChar;
            }

            int FileIndex = 0;

            string[] ignoredExts = TxtIgnoredExt.Text.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

            //for each one      //TODO: Use Parallel loop for more speed and keep UI responsive
            foreach (FileInfo File in Files)
            {
                //TODO: add ext blacklist
                if (Array.IndexOf(ignoredExts, File.Extension.ToLower().Remove(0, 1)) > -1)
                {
                    FileIndex++;
                    continue;
                }

                subPath = GetRelativePath(File.DirectoryName, TxtInputFolder.Text);

                if (subPath.Length > 0 && !Directory.Exists(outPath + subPath))
                {
                    Directory.CreateDirectory(outPath + subPath);
                }

                //open input file, read and convert to H3D data
                H3D Data = FormatIdentifier.IdentifyAndOpen(File.FullName);

                //if there is data (input file was valid)
                if (Data != null)
                {
                    string BaseName = PrefixNames ? Path.GetFileNameWithoutExtension(File.FullName) + "_" : string.Empty;

                    BaseName = Path.Combine(outPath + subPath, BaseName);

                    if (!PrefixNames)
                    {
                        BaseName += Path.DirectorySeparatorChar;
                    }

                    if (ExportModels)
                    {
                        for (int Index = 0; Index < Data.Models.Count; Index++)
                        {
                            string FileName = BaseName + Data.Models[Index].Name;

                            switch (Format)
                            {
                            case 0: new DAE(Data, Index, -1, Settings.Default.DebugCopyVtxAlpha).Save(FileName + ".dae"); break;

                            case 1: new SMD(Data, Index).Save(FileName + ".smd"); break;
                            }
                        }
                    }

                    if (ExportMats)
                    {
                        for (int Index = 0; Index < Data.Models.Count; Index++)
                        {
                            string FileName = BaseName + Data.Models[Index].Name;

                            switch (MatFormat)
                            {
                            case 0: new MaterialScript(Data, Index).Save(FileName + ".ms"); break;

                            case 1: new MaterialDump(Data, Index).Save(FileName + ".txt"); break;
                            }
                        }
                    }

                    if (ExportAnims && Data.Models.Count > 0)
                    {
                        for (int Index = 0; Index < Data.SkeletalAnimations.Count; Index++)
                        {
                            string FileName = BaseName + Data.Models[0].Name + "_" + Data.SkeletalAnimations[Index].Name;

                            switch (Format)
                            {
                            case 0: new DAE(Data, 0, Index).Save(FileName + ".dae"); break;

                            case 1: new SMD(Data, 0, Index).Save(FileName + ".smd"); break;
                            }
                        }
                    }

                    if (ExportTexs)
                    {
                        foreach (H3DTexture Tex in Data.Textures)
                        {
                            Tex.ToBitmap().Save(Path.Combine(outPath + subPath, Tex.Name + ".png"));
                        }
                    }
                }

                //update progress bar
                float Progress = ++FileIndex;
                Progress           = (Progress / Files.Length) * 100;
                ProgressConv.Value = (int)Progress;

                Application.DoEvents();
            }

            ProgressConv.Value = 100;
            BtnConvert.Enabled = true;
        }
Exemplo n.º 5
0
        public static H3D Merge(string[] FileNames, string[] MotionNames, bool DeleteBadAnims, H3D Scene = null)
        {
            string[] motionNames     = MotionNames;
            int      fightAnimsCount = motionNames.Count(motion => motion.Contains("Fighting"));
            // Console.WriteLine("fightAnimsCount " + fightAnimsCount);
            int petAnimsCount = motionNames.Count(motion => motion.Contains("Pet"));
            // Console.WriteLine("petAnimsCount " + petAnimsCount);
            int mapAnimsCount = motionNames.Count(motion => motion.Contains("Map"));

            // Console.WriteLine("mapAnimsCount " + mapAnimsCount);
            // Console.WriteLine("FileNames " + FileNames.Length);

            if (Scene == null)
            {
                Scene = new H3D();
            }

            int OpenFiles = 0;
            int filesOpen = 0;
            int animCount = 0;

            foreach (string FileName in FileNames)
            {
                filesOpen++;
                H3DDict <H3DBone> Skeleton = null;

                if (Scene.Models.Count > 0)
                {
                    Skeleton = Scene.Models[0].Skeleton;
                }
                // Console.WriteLine("Scene.SkeletalAnimations.Count "+Scene.SkeletalAnimations.Count);
                if (filesOpen == 5)
                {
                    animCount = fightAnimsCount;
                }
                else if (filesOpen == 6)
                {
                    animCount = petAnimsCount;
                }
                else if (filesOpen == 7)
                {
                    animCount = mapAnimsCount;
                }
                H3D Data = FormatIdentifier.IdentifyAndOpen(FileName, filesOpen, animCount, Skeleton);

                if (Data != null)
                {
                    Scene.Merge(Data);
                    OpenFiles++;
                }
            }

            // Console.WriteLine(Scene.SkeletalAnimations.Count);
            // Console.WriteLine(motionNames.Length);
            // if (Scene.SkeletalAnimations.Count == motionNames.Length)
            // {
            for (var i = 0; i < Scene.SkeletalAnimations.Count; i++)
            {
                Scene.SkeletalAnimations[i].Name = motionNames[i];
            }
            // }
            // else
            // {
            //     File.WriteAllText("C:\\Users\\User\\Documents\\spice-enchanted\\SPICA\\SPICA.CLI\\bin\\Debug\\net462\\out\\" + CurrentPoke + ".txt",
            //         CurrentPoke);
            //
            // }

            if (OpenFiles == 0)
            {
                //todo: improve this error message by making the format discovery return some kind of report
                Console.Write("Unsupported file format!", "Can't open file!");
            }

            return(Scene);
        }
Exemplo n.º 6
0
        public static H3D Merge(string[] FileNames, H3D Scene = null)
        {
            if (Scene == null)
            {
                Scene = new H3D();
            }

            int OpenFiles = 0;

            foreach (string FileName in FileNames)
            {
                H3DDict <H3DBone> Skeleton = null;

                if (Scene.Models.Count > 0)
                {
                    Skeleton = Scene.Models[0].Skeleton;
                }

                H3D Data = FormatIdentifier.IdentifyAndOpen(FileName, Skeleton);

                if (Data != null)
                {
                    Scene.Merge(Data);
                    OpenFiles++;
                }
            }

            // string[] names =
            // {
            //     "FightingAction1",
            //     "FightingAction2",
            //     "FightingAction4",
            //     "FightingAction5",
            //     "FightingAction6",
            //     "FightingAction9",
            //     "FightingAction13",
            //     "FightingAction17",
            //     "FightingAction18",
            //     "PetAction1-Pose",
            //     "PetAction5-Falling Asleep",
            //     "PetAction6-Sleepy",
            //     "PetAction7-Sleepy Awaken",
            //     "PetAction8-Sleeping",
            //     "PetAction9-Awaken",
            //     "PetAction10-Refuse",
            //     "PetAction12-Agree",
            //     "PetAction13-Happy",
            //     "PetAction14-Very Happy",
            //     "PetAction15-Look Around",
            //     "PetAction17-Comfortable",
            //     "PetAction19-Sad",
            //     "PetAction20-Salutate",
            //     "PetAction22-Angry",
            //     "PetAction23-Begin Eating",
            //     "PetAction24-Eating",
            //     "PetAction25-Eating Finished",
            //     "PetAction26-No Eating",
            //     "MapAction1",
            //     "MapAction3",
            //     "MapAction4"
            // };
            // for (var i = 0; i < Scene.SkeletalAnimations.Count; i++)
            // {
            //     Scene.SkeletalAnimations[i].Name = names[i];
            // }
            if (OpenFiles == 0)
            {
                //todo: improve this error message by making the format discovery return some kind of report
                Console.Write("Unsupported file format!", "Can't open file!");
            }

            return(Scene);
        }
Exemplo n.º 7
0
        static void Main(string[] args)
        {
            ArgumentBuilder ab = new ArgumentBuilder(
                new ArgumentPattern("input", "One or more converter input files", ArgumentType.STRING, null, true, "-i"),
                new ArgumentPattern("output", "An optional specified output file.", ArgumentType.STRING, null, "-o"),
                new ArgumentPattern("outputType", "The output format type (h3d/gfmbdlp/gfx)", ArgumentType.STRING, "h3d", "-t", "--type"),
                new ArgumentPattern("outputVersion", "The output format version", ArgumentType.INT, (int)0x21, "-v", "--version"),
                new ArgumentPattern("filter", "Output format filters (model/texture/animation/all)", ArgumentType.STRING, "all", true, "-f", "--filter")
                );

            Console.WriteLine("SPICA Embedded Command Line Interface\n");
            ab.parse(args);

            ArgumentContent inputs = ab.getContent("input");

            if (inputs.contents.Count == 0)
            {
                Console.WriteLine("No inputs given. Stopping.\n");

                printHelp(ab);
            }
            else
            {
                string formatName = ab.getContent("outputType").stringValue();
                string formatExtension;
                switch (formatName)
                {
                case "h3d":
                    formatExtension = "bch";
                    break;

                case "gfbmdlp":
                    formatExtension = formatName;
                    break;

                case "gfx":
                    formatExtension = "bcres";
                    break;

                default:
                    Console.WriteLine("Unknown output type: " + formatName);
                    return;
                }

                H3D Scene = new H3D();

                Scene.BackwardCompatibility = (byte)ab.getContent("outputVersion").intValue();
                Scene.ForwardCompatibility  = Scene.BackwardCompatibility;

                for (int i = 0; i < inputs.contents.Count; i++)
                {
                    string inPath = inputs.stringValue(i);
                    if (File.Exists(inPath))
                    {
                        Scene.Merge(FormatIdentifier.IdentifyAndOpen(inPath));
                    }
                }

                ArgumentContent flt = ab.getContent("filter");

                bool deleteModel = true;
                bool deleteTex   = true;
                bool deleteAnime = true;

                for (int i = 0; i < flt.contents.Count; i++)
                {
                    string filter = flt.stringValue(i);
                    switch (filter)
                    {
                    case "model":
                        deleteModel = false;
                        break;

                    case "texture":
                        deleteModel = false;
                        break;

                    case "animation":
                        deleteAnime = false;
                        break;

                    case "all":
                        deleteAnime = false;
                        deleteModel = false;
                        deleteTex   = false;
                        break;

                    default:
                        Console.WriteLine("Warning: unknown filter - " + filter);
                        break;
                    }
                }

                if (deleteModel)
                {
                    Scene.Models.Clear();
                }
                if (deleteTex)
                {
                    Scene.Textures.Clear();
                }
                if (deleteAnime)
                {
                    Scene.MaterialAnimations.Clear();
                    Scene.SkeletalAnimations.Clear();
                    Scene.VisibilityAnimations.Clear();
                    Scene.FogAnimations.Clear();
                    Scene.CameraAnimations.Clear();
                    Scene.LightAnimations.Clear();
                }

                string          outputFilePath = Path.Combine(Directory.GetParent(inputs.stringValue(0)).FullName, Path.GetFileNameWithoutExtension(inputs.stringValue(0)) + "." + formatExtension);
                ArgumentContent outCnt         = ab.getContent("output", true);
                if (outCnt != null)
                {
                    outputFilePath = outCnt.stringValue();
                }

                switch (formatName)
                {
                case "h3d":
                    H3D.Save(outputFilePath, Scene);
                    break;

                case "gfbmdlp":
                    using (BinaryWriter Writer = new BinaryWriter(new FileStream(outputFilePath, FileMode.Create, FileAccess.Write)))
                    {
                        GFModelPack ModelPack = new GFModelPack(Scene);
                        ModelPack.Write(Writer);
                        Writer.Close();
                    }
                    break;

                case "gfx":
                    Gfx.Save(outputFilePath, new Gfx(Scene));
                    break;
                }
            }
        }
Exemplo n.º 8
0
        public override NodeContent Import(string filename, ContentImporterContext context)
        {
            context.Logger.LogMessage("Importing H3D file: {0}", filename);

            _identity = new ContentIdentity(filename, GetType().Name);
            _rootNode = new NodeContent()
            {
                Identity = _identity, Name = "RootNode"
            };

            var scene = FormatIdentifier.IdentifyAndOpen(filename);
            var model = scene.Models[0];

            if (!scene.Textures.Any())
            {
                var path = Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}@Textures{Path.GetExtension(filename)}");
                if (File.Exists(path))
                {
                    context.Logger.LogMessage($"Found texture file {path}. Loading data...");
                    scene.Merge(FormatIdentifier.IdentifyAndOpen(path, model.Skeleton));
                }
                else
                {
                    context.Logger.LogMessage($"Couldn't find texture file {path}!");
                }
            }

            // Textures
            var textures = new Dictionary <string, Texture2DContent>();

            foreach (var texture in scene.Textures)
            {
                var bitmapContent = new PixelBitmapContent <Color>(texture.Width, texture.Height)
                {
                    Identity = _identity,
                    Name     = texture.Name
                };
                bitmapContent.SetPixelData(texture.ToRGBA());

                var textureContent = new Texture2DContent()
                {
                    Identity = _identity,
                    Name     = texture.Name
                };
                textureContent.Faces[0].Add(bitmapContent);
                textures.Add(textureContent.Name, textureContent);
            }

            // Materials
            var materials = new Dictionary <string, H3DMaterialContent>();

            foreach (var material in model.Materials)
            {
#if DEBUG
                var hlslCode = new HLSLShaderGenerator(material.MaterialParams)
                {
                    BoneCount = model.Skeleton.Count
                }.GetShader();
                var glslCode = new GLSLFragmentShaderGenerator(material.MaterialParams).GetFragShader();
#endif
                var materialContent = new H3DMaterialContent()
                {
                    Identity = _identity,
                    Name     = material.Name,

                    Effect = new EffectContent
                    {
                        Identity   = _identity,
                        Name       = "H3DEffect",
                        EffectCode = new HLSLShaderGenerator(material.MaterialParams)
                        {
                            BoneCount = model.Skeleton.Count
                        }.GetShader()
                    },
                    Material = material.Name,

                    FaceCulling = (H3DFaceCulling?)material.MaterialParams.FaceCulling,

                    EmissionColor      = material.MaterialParams.EmissionColor.ToXNA(),
                    AmbientColor       = material.MaterialParams.AmbientColor.ToXNA(),
                    DiffuseColor       = material.MaterialParams.DiffuseColor.ToXNA(),
                    Specular0Color     = material.MaterialParams.Specular0Color.ToXNA(),
                    Specular1Color     = material.MaterialParams.Specular1Color.ToXNA(),
                    Constant0Color     = material.MaterialParams.Constant0Color.ToXNA(),
                    Constant1Color     = material.MaterialParams.Constant1Color.ToXNA(),
                    Constant2Color     = material.MaterialParams.Constant2Color.ToXNA(),
                    Constant3Color     = material.MaterialParams.Constant3Color.ToXNA(),
                    Constant4Color     = material.MaterialParams.Constant4Color.ToXNA(),
                    Constant5Color     = material.MaterialParams.Constant5Color.ToXNA(),
                    BlendColor         = material.MaterialParams.BlendColor.ToXNA(),
                    DepthBufferRead    = material.MaterialParams.DepthBufferRead,
                    DepthBufferWrite   = material.MaterialParams.DepthBufferWrite,
                    StencilBufferRead  = material.MaterialParams.StencilBufferRead,
                    StencilBufferWrite = material.MaterialParams.StencilBufferWrite,
                };

                var texCount = 0;
                if (material.EnabledTextures[0])
                {
                    texCount++;
                }
                if (material.EnabledTextures[1])
                {
                    texCount++;
                }
                if (material.EnabledTextures[2])
                {
                    texCount++;
                }
                materialContent.TextureList = new Texture2DContent[texCount];
                if (material.EnabledTextures[0])
                {
                    materialContent.TextureList[0] = textures[material.Texture0Name];
                }
                if (material.EnabledTextures[1])
                {
                    materialContent.TextureList[1] = textures[material.Texture1Name];
                }
                if (material.EnabledTextures[2])
                {
                    materialContent.TextureList[2] = textures[material.Texture2Name];
                }

                materialContent.TextureSamplerSettings = material.TextureMappers.Select(tm => new TextureSamplerSettings()
                {
                    WrapU     = tm.WrapU.ToXNAWrap(),
                    WrapV     = tm.WrapV.ToXNAWrap(),
                    MagFilter = (TextureSamplerSettings.TextureMagFilter)tm.MagFilter,
                    MinFilter = (TextureSamplerSettings.TextureMinFilter)tm.MinFilter
                }).ToArray();

                materials.Add(material.Name, materialContent);
            }

            // Geometry
            var meshes = new List <MeshContent>();
            for (var i = 0; i < model.Meshes.Count; i++)
            {
                var modelMesh = model.Meshes[i];

                if (modelMesh.Type == H3DMeshType.Silhouette)
                {
                    continue;
                }

                var mesh = new MeshContent()
                {
                    Identity = _identity,
                    Name     = $"{model.Materials[modelMesh.MaterialIndex].Name}_node{i}",
                };
                var geometry = new GeometryContent
                {
                    Identity = _identity,
                    Material = materials[model.Materials[modelMesh.MaterialIndex].Name]
                };
                var vertices   = GetWorldSpaceVertices(model.Skeleton, modelMesh);
                var baseVertex = mesh.Positions.Count;
                foreach (var vertex in vertices)
                {
                    mesh.Positions.Add(vertex.Position.ToVector3());
                }
                geometry.Vertices.AddRange(Enumerable.Range(baseVertex, vertices.Length));

                foreach (var attribute in modelMesh.Attributes)
                {
                    if (attribute.Name >= PICAAttributeName.BoneIndex)
                    {
                        continue;
                    }

                    switch (attribute.Name)
                    {
                    case PICAAttributeName.Position: break;     // Already added

                    case PICAAttributeName.Normal:
                        geometry.Vertices.Channels.Add(VertexChannelNames.Normal(0), vertices.Select(vertex => vertex.Normal.ToVector3()));
                        break;

                    case PICAAttributeName.Tangent:
                        geometry.Vertices.Channels.Add(VertexChannelNames.Tangent(0), vertices.Select(vertex => vertex.Tangent.ToVector3()));
                        break;

                    case PICAAttributeName.Color:
                        geometry.Vertices.Channels.Add(VertexChannelNames.Color(0), vertices.Select(vertex => vertex.Color.ToColor()));
                        break;

                    case PICAAttributeName.TexCoord0:
                        geometry.Vertices.Channels.Add(VertexChannelNames.TextureCoordinate(0), vertices.Select(vertex => vertex.TexCoord0.ToVector2().ToUV()));
                        break;

                    case PICAAttributeName.TexCoord1:
                        geometry.Vertices.Channels.Add(VertexChannelNames.TextureCoordinate(1), vertices.Select(vertex => vertex.TexCoord1.ToVector2().ToUV()));
                        break;

                    case PICAAttributeName.TexCoord2:
                        geometry.Vertices.Channels.Add(VertexChannelNames.TextureCoordinate(2), vertices.Select(vertex => vertex.TexCoord2.ToVector2().ToUV()));
                        break;
                    }
                }

                var vertexOffset = 0;
                var xnaWeights   = new List <BoneWeightCollection>();
                foreach (var modelSubMesh in modelMesh.SubMeshes)
                {
                    geometry.Indices.AddRange(modelSubMesh.Indices.Select(index => (int)index));

                    var vertexCount     = modelSubMesh.MaxIndex + 1 - vertexOffset;
                    var subMeshVertices = vertices.Skip(vertexOffset).Take(vertexCount).ToList();

                    if (modelSubMesh.Skinning == H3DSubMeshSkinning.Smooth)
                    {
                        foreach (var vertex in subMeshVertices)
                        {
                            var list = new BoneWeightCollection();
                            for (var index = 0; index < 4; index++)
                            {
                                var bIndex = vertex.Indices[index];
                                var weight = vertex.Weights[index];

                                if (weight == 0)
                                {
                                    break;
                                }

                                if (bIndex < modelSubMesh.BoneIndicesCount && bIndex > -1)
                                {
                                    bIndex = modelSubMesh.BoneIndices[bIndex];
                                }
                                else
                                {
                                    bIndex = 0;
                                }

                                list.Add(new BoneWeight(model.Skeleton[bIndex].Name, weight));
                            }
                            xnaWeights.Add(list);
                        }
                    }
                    else
                    {
                        foreach (var vertex in vertices)
                        {
                            var bIndex = vertex.Indices[0];

                            if (bIndex < modelSubMesh.BoneIndices.Length && bIndex > -1)
                            {
                                bIndex = modelSubMesh.BoneIndices[bIndex];
                            }
                            else
                            {
                                bIndex = 0;
                            }

                            xnaWeights.Add(new BoneWeightCollection()
                            {
                                new BoneWeight(model.Skeleton[bIndex].Name, 0)
                            });
                        }
                    }
                    vertexOffset += vertexCount;
                }
                geometry.Vertices.Channels.Add(VertexChannelNames.Weights(0), xnaWeights);
                mesh.Geometry.Add(geometry);
                meshes.Add(mesh);
            }

            foreach (var mesh in meshes)
            {
                _rootNode.Children.Add(mesh);
            }

            var rootBone = ImportBones(model);
            _rootNode.Children.Add(rootBone);

            if (!scene.SkeletalAnimations.Any())
            {
                var path = Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}@Animations{Path.GetExtension(filename)}");
                if (File.Exists(path))
                {
                    context.Logger.LogMessage($"Found animation file {path}. Loading data...");
                    scene.Merge(FormatIdentifier.IdentifyAndOpen(path, model.Skeleton));
                }
                else
                {
                    context.Logger.LogMessage($"Couldn't find animation file {path}!");
                }
            }

            foreach (var animation in ImportSkeletalAnimations(scene))
            {
                rootBone.Animations.Add(animation.Name, animation);
            }

            foreach (var animation in ImportMaterialAnimations(scene))
            {
                _rootNode.Children.Add(animation);
            }

            return(_rootNode);
        }