示例#1
0
        static void UpdateModelAnimation(FoamModel Mdl)
        {
            if (Mdl.Animations != null)
            {
                FoamAnimation Anim   = Mdl.Animations[0];
                int           Frames = Anim.Frames.Length;

                float TicksPerSecond = Anim.TicksPerSecond;
                if (TicksPerSecond == 0)
                {
                    TicksPerSecond = 21;
                }

                float SecondsPerFrame = (Anim.DurationInTicks / TicksPerSecond) / Frames;

                if (AnimStopwatch == null)
                {
                    AnimStopwatch = Stopwatch.StartNew();
                }

                if ((AnimStopwatch.ElapsedMilliseconds / 1000.0f) >= SecondsPerFrame)
                {
                    FrameIndex++;

                    if (FrameIndex >= Anim.Frames.Length)
                    {
                        FrameIndex = 0;
                    }

                    UpdateModel(Mdl, FrameIndex);

                    AnimStopwatch.Restart();
                }
            }
        }
示例#2
0
        static void Convert(string FilePath)
        {
            string FileName  = Path.GetFileNameWithoutExtension(FilePath);
            string Extension = Path.GetExtension(FilePath).ToLower();
            string RootDir   = Path.GetDirectoryName(FilePath);

            FoamModel Foam = null;

            switch (Extension)
            {
            case ".md3": {
                string           AnimationCfgFile = Path.Combine(RootDir, "animation.cfg");
                MD3_AnimationCfg AnimationCfg     = new MD3_AnimationCfg(AnimationCfgFile);

                bool IsHead  = FilePath.Contains("head");
                bool IsUpper = FilePath.Contains("upper");
                bool IsLower = FilePath.Contains("lower");

                //Foam = new FoamModel(FileName, FoamFlags.Model, null, null, null, null);
                Foam = Load(FilePath);

                // TODO: Manual MD3 loader
                break;
            }

            default:
                Foam = Load(FilePath);
                break;
            }

            Foam.SaveToFile(Path.Combine(RootDir, FileName + ".foam"));
        }
示例#3
0
        static void Convert(string FilePath)
        {
            Console.WriteLine("Converting {0}", FilePath);

            string    FileName = Path.GetFileNameWithoutExtension(FilePath);
            FoamModel Model    = LoadMdl(FilePath);

            if (!Directory.Exists("foam"))
            {
                Directory.CreateDirectory("foam");
            }

            Model.SaveToFile("foam/" + FileName + ".foam");
        }
示例#4
0
        static FoamModel[] LoadAllFrames(string MD3File)
        {
            List <FoamModel> Frames = new List <FoamModel>();

            try {
                for (int i = 0; i < 1025; i++)
                {
                    FoamModel Frame = Load(MD3File, i);
                    Frames.Add(Frame);
                }
            } catch (AssimpException) {
            }

            return(Frames.ToArray());
        }
示例#5
0
        static Model[] LoadModels(string FileName, out float Scale, out FoamModel FoamModel)
        {
            string RootDir = Path.GetDirectoryName(FileName);

            Scale     = 0;
            FoamModel = null;

            string Ext = Path.GetExtension(FileName).ToLower();

            if (!(Ext == ".foam" || Ext == ".mapfoam"))
            {
                FoamModel = FoamConverter.Load(FileName);
                // FoamModel.SaveToFile(Path.Combine(RootDir, Path.GetFileNameWithoutExtension(FileName) + ".foam"));
            }

            //try {
            if (FoamModel == null)
            {
                FoamModel = FoamModel.FromFile(FileName);
            }

            FoamModel.CalcBounds(out Vector3 Min, out Vector3 Max);
            Scale = Utils.Max(Max - Min);

            List <Model> LoadedModels = new List <Model>();

            foreach (var M in FoamModel.Meshes)
            {
                LoadedModels.Add(FoamMeshToModel(RootDir, M, FoamModel));
            }

            return(LoadedModels.ToArray());

            /*} catch (Exception E) {
             *      Console.WriteLine("{0}", E.Message);
             * }*/

            return(null);
        }
示例#6
0
        static void UpdateModel(FoamModel Model, int FrameIndex)
        {
            if (Model.Animations == null)
            {
                return;
            }

            //Matrix4x4 ParentRotMat = Matrix4x4.CreateFromYawPitchRoll(0, -Pi / 2, 0);

            foreach (var Msh in Model.Meshes)
            {
                List <Vertex3> Verts = new List <Vertex3>();
                if (Msh.BoneInformation == null)
                {
                    continue;
                }

                foreach (var Index in Msh.Indices)
                {
                    FoamVertex3  Vert  = Msh.Vertices[Index];
                    FoamBoneInfo Info  = Msh.BoneInformation[Index];
                    FoamBone     Bone1 = Model.Bones[Info.Bone1];

                    // TODO: Weights
                    Matrix4x4 BindWorld  = Bone1.BindMatrix;
                    Matrix4x4 WorldTrans = Model.CalcWorldTransform(0, FrameIndex, Info.Bone1);
                    Vector3   Pos        = Vector3.Transform(Vert.Position, BindWorld * WorldTrans);

                    // TODO: Flip?
                    Verts.Add(new Vertex3(Pos, Vert.UV));
                }

                Mesh *RayMesh = ((Model)Msh.Userdata).meshes;
                Raylib.UnloadMesh(*RayMesh);
                *RayMesh = Raylib.GenMeshRaw(Verts.ToArray());
            }
        }
示例#7
0
        static Model FoamMeshToModel(string RootDir, FoamMesh Mesh, FoamModel FoamModel)
        {
            Vertex3[] Verts      = Mesh.GetFlatVertices().Select(V => ToVert3(V)).ToArray();
            Mesh      RaylibMesh = Raylib.GenMeshRaw(Verts);

            Model Mdl = Raylib.LoadModelFromMesh(RaylibMesh);

            // Mdl.transform = Matrix4x4.CreateFromYawPitchRoll(0, Pi / 2, 0);

            Mesh.Userdata = Mdl;

            foreach (var Ext in FoamModel.Extensions)
            {
                if (Ext.Name.Contains("lightmap"))
                {
                    Texture2D LightmapTex = LoadTexture(Ext);

                    for (int i = 0; i < FoamModel.Materials.Length; i++)
                    {
                        if (FoamModel.Materials[i].FindTexture(FoamTextureType.LightMap, out FoamTexture LightTex))
                        {
                            SetTexture(Mdl, LightmapTex);
                        }
                    }
                    break;
                }
            }

            if (FoamModel.Materials[Mesh.MaterialIndex].FindTexture(FoamTextureType.Diffuse, out FoamTexture Tex))
            {
                SetTexture(Mdl, Path.Combine(RootDir, Tex.Name));
            }

            //Mdl.transform = Matrix4x4.CreateFromYawPitchRoll(0, Pi / 2, 0);
            Mdl.transform = Matrix4x4.CreateScale(0.01f);
            return(Mdl);
        }
示例#8
0
        static void Main(string[] args)
        {
            Raylib.InitWindow(1366, 768, "Foam Test");
            Raylib.SetTargetFPS(60);

            //args = new string[] { "C:/Projekti/Foam/bin/mapfoam/sample/test.mapfoam" };
            //args = new[] { "C:/Projekti/Ray/build/bin/sample/light_test.mapfoam" };

            Cam3D = new Camera3D(new Vector3(1, 1, 1), Vector3.Zero, Vector3.UnitY);
            Raylib.SetCameraMode(Cam3D, CameraMode.CAMERA_FREE);

            Model[]   Models    = null;
            FoamModel FoamModel = null;

            bool DrawText        = true;
            bool DrawWireframe   = false;
            bool DrawSkeleton    = true;
            bool UpdateAnimation = true;

            while (!Raylib.WindowShouldClose())
            {
                if (Raylib.IsKeyPressed(KeyboardKey.KEY_F1))
                {
                    DrawText = !DrawText;
                }

                if (Raylib.IsKeyPressed(KeyboardKey.KEY_F2))
                {
                    DrawWireframe = !DrawWireframe;
                }

                if (Raylib.IsKeyPressed(KeyboardKey.KEY_F3))
                {
                    DrawSkeleton = !DrawSkeleton;
                }

                if (Raylib.IsKeyPressed(KeyboardKey.KEY_F4))
                {
                    UpdateAnimation = !UpdateAnimation;
                }

                if (Raylib.IsFileDropped() || (args != null && args.Length > 0))
                {
                    string DroppedFile = null;

                    if (args != null && args.Length > 0)
                    {
                        DroppedFile = args[0];
                        args        = null;
                    }
                    else
                    {
                        DroppedFile = Raylib.GetDroppedFiles()[0];
                    }

                    Model[] NewModels = LoadModels(DroppedFile, out float Scale, out FoamModel NewFoamModel);

                    if (NewModels != null && NewFoamModel != null)
                    {
                        if (NewModels.Length == 0 && NewFoamModel.Animations != null && FoamModel != null)
                        {
                            foreach (var NewAnim in NewFoamModel.Animations)
                            {
                                Utils.Append(ref FoamModel.Animations, NewAnim);
                            }
                        }
                        else
                        {
                            if (Models != null)
                            {
                                foreach (var M in Models)
                                {
                                    Raylib.UnloadModel(M);
                                }
                            }

                            Models    = NewModels;
                            FoamModel = NewFoamModel;

                            //Cam3D.position = new Vector3(0.5f, 0.25f, 0.5f) * Scale;
                            //Cam3D.target = new Vector3(0, 0.25f, 0) * Scale;
                        }
                    }

                    Raylib.ClearDroppedFiles();
                }

                /*if (Models != null)
                 *      UpdateModel(FoamModel, FrameIndex);*/

                Raylib.BeginDrawing();
                Raylib.ClearBackground(new Color(50, 50, 50));
                //Raylib.ClearBackground(new Color(0, 0, 0));

                if (Models != null)
                {
                    Raylib.UpdateCamera(ref Cam3D);
                    Raylib.BeginMode3D(Cam3D);


                    for (int i = 0; i < Models.Length; i++)
                    {
                        if (DrawWireframe)
                        {
                            Raylib.DrawModelWires(Models[i], Vector3.Zero, 1, Color.White);
                        }
                        else
                        {
                            Raylib.DrawModel(Models[i], Vector3.Zero, 1, Color.White);
                        }
                    }

                    if (UpdateAnimation)
                    {
                        UpdateModelAnimation(FoamModel);
                    }

                    if (FoamModel != null && DrawSkeleton)
                    {
                        DrawBones(FoamModel);
                    }

                    Raylib.EndMode3D();

                    if (DrawText)
                    {
                        if (WorldTexts != null)
                        {
                            foreach (var KV in WorldTexts)
                            {
                                Raylib.DrawText(KV.Value, (int)KV.Key.X, (int)KV.Key.Y, 10, Color.White);
                            }
                        }
                    }
                }

                DrawTextLine("F1 - Toggle bone names", 0);
                DrawTextLine("F2 - Toggle wireframe", 1);
                DrawTextLine("F3 - Toggle skeleton", 2);
                DrawTextLine("F4 - Toggle animations", 3);

                Raylib.DrawFPS(5, 5);
                Raylib.EndDrawing();
            }
        }
示例#9
0
        static void DrawBones(FoamModel Mdl)
        {
            if (Mdl.Bones == null)
            {
                return;
            }

            if (WorldTexts == null || WorldTexts.Length != Mdl.Bones.Length)
            {
                WorldTexts = new KeyValuePair <Vector2, string> [Mdl.Bones.Length];
                for (int i = 0; i < WorldTexts.Length; i++)
                {
                    WorldTexts[i] = new KeyValuePair <Vector2, string>(new Vector2(0, 0), "null");
                }
            }

            //Matrix4x4 ParentRotMat = Matrix4x4.CreateFromYawPitchRoll(0, -Pi / 2, 0);

            for (int i = 0; i < Mdl.Bones.Length; i++)
            {
                FoamBone Bone = Mdl.Bones[i];


                //*
                if (Mdl.Animations != null)
                {
                    // Actual bones
                    Matrix4x4 ParentWorld = Matrix4x4.Identity;
                    if (Bone.ParentBoneIndex != -1)
                    {
                        ParentWorld = Mdl.CalcWorldTransform(0, FrameIndex, Bone.ParentBoneIndex);
                    }
                    Matrix4x4.Decompose(ParentWorld, out Vector3 ParentScale, out Quaternion ParentRot, out Vector3 ParentPos);

                    Matrix4x4 World = Mdl.CalcWorldTransform(0, FrameIndex, i);
                    Matrix4x4.Decompose(World, out Vector3 Scale, out Quaternion Rot, out Vector3 Pos);

                    DrawLine3D(ParentPos, Pos, Color.Red);

                    // Text
                    Vector3 Center = (Pos + ParentPos) / 2;
                    WorldTexts[i] = new KeyValuePair <Vector2, string>(Raylib.GetWorldToScreen(RotateVec3(Center), Cam3D), Bone.Name);
                }
                //*/


                // Bind pose bones
                Matrix4x4 BindParentWorld = Matrix4x4.Identity;
                if (Bone.ParentBoneIndex != -1)
                {
                    BindParentWorld = Mdl.CalcBindTransform(Bone.ParentBoneIndex);
                }
                Matrix4x4.Decompose(BindParentWorld, out Vector3 BindParentScale, out Quaternion BindParentRot, out Vector3 BindParentPos);

                Matrix4x4 BindWorld = Mdl.CalcBindTransform(i);
                Matrix4x4.Decompose(BindWorld, out Vector3 BindScale, out Quaternion BindRot, out Vector3 BindPos);

                DrawLine3D(BindParentPos, BindPos, Color.Green);
                //*/
            }
        }
示例#10
0
文件: MapFoam.cs 项目: sbarisic/Foam
        static void Run()
        {
            string ObjInput      = ArgumentParser.GetSingle("obj");
            string MtlInput      = ArgumentParser.GetSingle("mtl");
            string MapOutput     = ArgumentParser.GetSingle("out");
            bool   EmbedTextures = ArgumentParser.Defined("e");
            bool   ComputeLights = !ArgumentParser.Defined("l");

            string ObjName = "test";

            if (ObjInput == null)
            {
                ObjInput  = "sample/" + ObjName + ".obj";
                MtlInput  = "sample/" + ObjName + ".mtl";
                MapOutput = "sample/" + ObjName + ".mapfoam";
            }

            if (!File.Exists(ObjInput))
            {
                throw new Exception("Obj input file not found");
            }

            if (!File.Exists(MtlInput))
            {
                throw new Exception("Mtl input file not found");
            }

            string OutDir = Path.GetDirectoryName(Path.GetFullPath(MapOutput));

            Console.WriteLine("obj = '{0}'", ObjInput);
            Console.WriteLine("mtl = '{0}'", MtlInput);
            Console.WriteLine("out = '{0}'", MapOutput);
            Console.WriteLine("Embed textures? {0}", EmbedTextures);
            Console.WriteLine("Compute lights? {0}", ComputeLights);

            FoamModel LevelModel = ObjLoader.Load(ObjInput, MtlInput);


            MeshAtlasMap AtlasMap;

            LevelModel.CalcBounds(out Vector3 Min, out Vector3 Max);
            Console.WriteLine("Level min = {0}; max = {1}", Min, Max);

            // Generate atlas
            {
                Console.WriteLine("Generating lightmap");
                GenAtlas(OutDir, LevelModel, out AtlasMap);
            }

            if (ComputeLights)
            {
                Light[] Lights = new Light[] {
                    new Light(new Vector3(-32, 104, 368), new Vector3(1, 0, 0), 10000),
                    new Light(new Vector3(-80, 104, 704), new Vector3(0, 1, 0), 10000),
                    new Light(new Vector3(0, 312, 304), new Vector3(0, 0, 1), 20000)
                };

                //LightMapping.Compute(LevelModel, AtlasMap, Lights);

                //Vector4[] Pixels = new Vector4[1024 * 1024];
                //RayLightmapper.raylight_render_scene(1024, 1024, 512, new Vector3(1, 1, 1), 0, null, 0, null, null, null, ref Pixels);

                {
                    string TexName = "lightmap.png";

                    FoamMaterial LightmapMat = new FoamMaterial(Path.GetFileNameWithoutExtension(TexName), new[] { new FoamTexture(TexName, FoamTextureType.LightMap) });
                    Utils.Append(ref LevelModel.Materials, LightmapMat);

                    foreach (var M in LevelModel.Meshes)
                    {
                        M.MaterialIndex = LevelModel.Materials.Length - 1;
                    }

                    //AtlasMap.Atlas.Resize(4);
                    AtlasMap.Atlas.FlipY();
                    AtlasMap.Atlas.Save(Path.Combine(OutDir, TexName));

                    Utils.Append(ref LevelModel.Extensions, FoamExtension.CreateEmbeddedPng(TexName, AtlasMap.Atlas.GetImage()));
                }
            }

            //ObjLoader.Save(LevelModel, "sample/EXPORTED.obj");
            LevelModel.SaveToFile(MapOutput);

            //Console.WriteLine("Done!");
            //Console.ReadLine();
        }
示例#11
0
文件: MapFoam.cs 项目: sbarisic/Foam
        static void ApplyEmissive(Vector4[] Pixels, int W, int H, List <FoamVertex3> ModelVerts, List <FoamMesh> Meshes, FoamModel Model)
        {
            Vector4 ClrR = new Vector4(1, 0, 0, 1);
            Vector4 ClrG = new Vector4(0, 1, 0, 1);
            Vector4 ClrB = new Vector4(0, 0, 1, 1);
            Vector4 ClrW = new Vector4(1, 1, 1, 1);

            Vector2 Size = new Vector2(W, H);

            for (int i = 0; i < ModelVerts.Count; i += 3)
            {
                FoamMaterial Mat = Model.Materials[Meshes[i].MaterialIndex];

                // TODO: Move somewhere else
                switch (Mat.MaterialName)
                {
                case "base/emissive_red":
                    DrawTriangle(Pixels, W, H, ClrR, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                case "base/emissive_green":
                    DrawTriangle(Pixels, W, H, ClrG, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                case "base/emissive_blue":
                    DrawTriangle(Pixels, W, H, ClrB, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                //case "base/emissive_sky":
                case "base/emissive_white":
                    DrawTriangle(Pixels, W, H, ClrW, ModelVerts[i + 0].UV2 * Size, ModelVerts[i + 1].UV2 * Size, ModelVerts[i + 2].UV2 * Size);
                    break;

                default:
                    break;
                }
            }
        }
示例#12
0
文件: MapFoam.cs 项目: sbarisic/Foam
        static void GenAtlas(string OutDir, FoamModel LevelModel, out MeshAtlasMap AtlasMap)
        {
            const bool  GenerateNewUVs = true;
            const float TextureScale   = 2;
            //const float VertexScale = 1.0f / 100;
            const float VertexScale = 1.0f;
            const int   BounceCount = 2;

            FoamMesh[] Meshes = LevelModel.Meshes;

            List <FoamMesh>    VertexMeshMap = new List <FoamMesh>();
            List <FoamVertex3> ModelVerts    = new List <FoamVertex3>();
            //ushort[] NewInds = null;

            int W;
            int H;

            {
                foreach (var Mesh in Meshes)
                {
                    IEnumerable <FoamVertex3> MeshVerts = Mesh.GetFlatVertices();

                    foreach (var V in MeshVerts)
                    {
                        VertexMeshMap.Add(Mesh);
                        ModelVerts.Add(V);
                    }

                    Mesh.Indices  = new ushort[] { };
                    Mesh.Vertices = new FoamVertex3[] { };
                }

                if (GenerateNewUVs)
                {
                    AtlasStruct *   _Atlas   = XAtlas.Create();
                    XAtlas_MeshDecl MeshDecl = new XAtlas_MeshDecl(ModelVerts.Select(V => V.Position).ToArray());
                    XAtlas.AddMesh(_Atlas, ref MeshDecl);
                    XAtlas.Generate(_Atlas, ChartOptions.CreateOptions(), null, PackOptions.CreatePackOptions());

                    XAtlasMesh *XMsh = &_Atlas->meshes[0];

                    /*NewInds = null;
                     * for (int i = 0; i < XMsh->indexCount; i++)
                     *      Utils.Append(ref NewInds, (ushort)XMsh->indexArray[i]);*/

                    W        = (int)(_Atlas->width * TextureScale);
                    H        = (int)(_Atlas->height * TextureScale);
                    AtlasMap = new MeshAtlasMap(W, H);

                    FoamVertex3[] OldModelVerts = ModelVerts.ToArray();
                    ModelVerts.Clear();

                    FoamMesh[] OldVertexMeshMap = VertexMeshMap.ToArray();
                    VertexMeshMap.Clear();

                    Vector2 AtlasSize = new Vector2((int)_Atlas->width, (int)_Atlas->height);
                    for (int i = 0; i < XMsh->vertexCount; i++)
                    {
                        XAtlasVertex *XVert   = &XMsh->vertexArray[i];
                        FoamVertex3   OldVert = OldModelVerts[(int)XVert->xref];
                        FoamMesh      OldMesh = OldVertexMeshMap[(int)XVert->xref];

                        //OldVert.UV = (XVert->UV) / AtlasSize;
                        OldVert.UV2 = (XVert->UV) / AtlasSize;

                        //OldVert.UV.X = (int)OldVert.UV.X;
                        //OldVert.UV.Y = (int)OldVert.UV.Y;

                        ModelVerts.Add(OldVert);
                        VertexMeshMap.Add(OldMesh);
                    }
                }
                else
                {
                    /*for (int i = 0; i < ModelVerts.Count; i++)
                     *      Utils.Append(ref NewInds, (ushort)i);*/
                    AtlasMap = new MeshAtlasMap(512, 512);
                }
            }


            Vector3[] RL_Pos = new Vector3[ModelVerts.Count];
            Vector2[] RL_UV  = new Vector2[ModelVerts.Count];

            // Calculate normals
            for (int i = 0; i < ModelVerts.Count; i += 3)
            {
                FoamVertex3 VA = ModelVerts[i + 0];
                FoamVertex3 VB = ModelVerts[i + 1];
                FoamVertex3 VC = ModelVerts[i + 2];

                Vector3 CB     = VC.Position - VB.Position;
                Vector3 AB     = VA.Position - VB.Position;
                Vector3 Normal = Vector3.Normalize(Vector3.Cross(CB, AB));

                VA.Normal = Normal;
                VB.Normal = Normal;
                VC.Normal = Normal;

                ModelVerts[i + 0] = VA;
                ModelVerts[i + 1] = VB;
                ModelVerts[i + 2] = VC;


                RL_Pos[i + 0] = VA.Position * VertexScale;
                RL_Pos[i + 1] = VB.Position * VertexScale;
                RL_Pos[i + 2] = VC.Position * VertexScale;

                RL_UV[i + 0] = VA.UV2;
                RL_UV[i + 1] = VB.UV2;
                RL_UV[i + 2] = VC.UV2;
            }

            Vector2 PixelsSize = new Vector2(W, H);

            Vector4[] Pixels = new Vector4[W * H];
            ApplyEmissive(Pixels, W, H, ModelVerts, VertexMeshMap, LevelModel);

            //int TriIdx = 6;
            //Vector4 TriClr = new Vector4(50.0f / 255, 100.0f / 255, 200.0f / 255, 1);
            //DrawTriangle(Pixels, W, H, TriClr, ModelVerts[TriIdx * 3 + 0].UV2 * PixelsSize, ModelVerts[TriIdx * 3 + 1].UV2 * PixelsSize, ModelVerts[TriIdx * 3 + 2].UV2 * PixelsSize);

            Lightmapper.GenerateLightmap(ref Pixels, W, H, RL_Pos, RL_UV, BounceCount);
            ApplyEmissive(Pixels, W, H, ModelVerts, VertexMeshMap, LevelModel);

            //DrawTriangle(Pixels, W, H, TriClr, ModelVerts[TriIdx * 3 + 0].UV2 * PixelsSize, ModelVerts[TriIdx * 3 + 1].UV2 * PixelsSize, ModelVerts[TriIdx * 3 + 2].UV2 * PixelsSize);


            for (int i = 0; i < Pixels.Length; i++)
            {
                int X = i % W;
                int Y = (i - X) / W;

                Vector4 Clr = Pixels[i];
                Clr = Utils.Clamp(Clr, Vector4.Zero, Vector4.One);

                AtlasMap.Atlas.SetPixel(X, Y, new FastColor((byte)(Clr.X * 255), (byte)(Clr.Y * 255), (byte)(Clr.Z * 255), 255));
            }


            for (int i = 0; i < VertexMeshMap.Count; i++)
            {
                FoamMesh CurMesh = VertexMeshMap[i];

                //Utils.Append(ref CurMesh.Indices, (ushort)(NewInds[i]));
                Utils.Append(ref CurMesh.Vertices, ModelVerts[i]);
            }

            for (int i = 0; i < Meshes.Length; i++)
            {
                int VertCount = Meshes[i].Vertices.Length;
                Meshes[i].Indices = new ushort[VertCount];

                for (int j = 0; j < VertCount; j++)
                {
                    Meshes[i].Indices[j] = (ushort)j;
                }
            }

            //Msh.Vertices = Verts.ToArray();
            //Msh.Indices = NewInds.ToArray();
        }