public static extern int AddMesh(AtlasStruct *Atlas, ref XAtlas_MeshDecl MeshDecl, uint MeshCountHit = 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(); }