Пример #1
0
 public static extern int AddMesh(AtlasStruct *Atlas, ref XAtlas_MeshDecl MeshDecl, uint MeshCountHit = 0);
Пример #2
0
        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();
        }