public static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Missing input argument!");
                Console.ReadKey();
                return;
            }
            if (args.Length == 1)
            {
                Console.WriteLine("Missing output argument!");
                Console.ReadKey();
                return;
            }

            SBMLoader loader = new SBMLoader(args[0]);
            string err;
            if (!loader.Load(out err))
            {
                Console.WriteLine("Failed to load SBM file! {0}", err);
                Console.ReadKey();
                return;
            }

            Mesh merged;
            string[] materials;
            MergeMeshes(loader, out merged, out materials);

            using (FileStream strm = File.OpenWrite(args[1]))
            {
                ExportSBM(strm, merged, materials);
                strm.Close();
            }

            Console.WriteLine("SBM file written, task complete.");
            Console.ReadKey();
        }
        private static void MergeMeshes(SBMLoader loader, out Mesh result, out string[] materials)
        {
            if (loader.MeshCount == 0)
            {
                result = null;
                materials = null;
                return;
            }
            if (loader.MeshCount == 1)
            {
                loader.GetMesh(0, out result, out materials);
                return;
            }

            List<string> finalmaterials = new List<string>();

            MeshBuilder merged = new MeshBuilder();
            merged.UseNormals = true;
            merged.UseTangents = true;
            merged.UseTexCoords = true;

            int totalsubmeshes = 0;

            for (int i = 0; i < loader.MeshCount; i++)
            {
                Mesh cmesh;
                string[] curmats;
                loader.GetMesh(i, out cmesh, out curmats);

                totalsubmeshes += cmesh.Submeshes.Length;

                int baseindex = merged.CurrentVertexCount;
                merged.AddPositions(cmesh.Positions);
                merged.AddNormals(cmesh.Normals);
                merged.AddTextureCoords(cmesh.TextureCoordinates);
                merged.AddTangents(cmesh.Tangents);

                for (int j = 0; j < cmesh.Submeshes.Length; j++)
                {
                    int submeshindex;
                    if (finalmaterials.Contains(curmats[j]))
                        submeshindex = finalmaterials.IndexOf(curmats[j]);
                    else
                    {
                        submeshindex = finalmaterials.Count;
                        finalmaterials.Add(curmats[j]);
                    }

                    merged.AddIndices(submeshindex, cmesh.Submeshes[j], (uint)baseindex);
                }

            }

            Console.WriteLine("Merged {0} meshes with a total of {1} submeshes into 1 mesh with a total of {2} submeshes.", loader.MeshCount, totalsubmeshes, finalmaterials.Count);

            result = merged.Build();
            materials = finalmaterials.ToArray();
        }
        private Actor LoadModel(JToken source)
        {
            // Create the actor
            Actor actor = new Actor(Owner.MessagePool);

            // Add the required components to it
            Transform transform = actor.AddComponent<Transform>();

            // Load generic transform
            LoadTransform(transform, source);

            // Load model
            if (source["model"] != null)
            {
                string model = (string)source["model"];
                SBMLoader loader = new SBMLoader("models/" + model + ".sbm");
                string err;
                if (!loader.Load(out err))
                {
                    Console.WriteLine("Failed to load model '{0}'! ({1})", model, err);
                    return null;
                }

                // Is there more than 1 mesh?
                if (loader.MeshCount > 1)
                {
                    for (int i = 0; i < loader.MeshCount; i++)
                    {
                        Actor tmp = new Actor(Owner.MessagePool);
                        tmp.AddComponent<Transform>();
                        MeshRenderer renderer = tmp.AddComponent<MeshRenderer>();
                        Mesh mesh;
                        string[] materialnames;
                        loader.GetMesh(i, out mesh, out materialnames);
                        Material[] materials = new Material[materialnames.Length];
                        for (int j = 0; j < materials.Length; j++)
                        {
                            materials[j] = Owner.GetComponent<MaterialSystem>().GetMaterial(materialnames[j]);
                            if (materials[j] == null) Console.WriteLine("Failed to load material '{0}'!", materialnames[j]);
                        }
                        renderer.Mesh = mesh;
                        renderer.Materials = materials;
                        tmp.Parent = actor;
                        tmp.Init();
                    }
                }
                else
                {
                    MeshRenderer renderer = actor.AddComponent<MeshRenderer>();
                    Mesh mesh;
                    string[] materialnames;
                    loader.GetMesh(0, out mesh, out materialnames);
                    Material[] materials = new Material[materialnames.Length];
                    for (int j = 0; j < materials.Length; j++)
                        materials[j] = Owner.GetComponent<MaterialSystem>().GetMaterial(materialnames[j]);
                    renderer.Mesh = mesh;
                    renderer.Materials = materials;
                }
            }

            // Initialise and return
            actor.Init();
            return actor;
        }