public SubmeshBuilder GetSubmeshBuilder(int submeshIndex, GeometryType geomType) { SubmeshBuilder builder; if (!m_submeshesBySubmeshIndex.TryGetValue(submeshIndex, out builder)) { builder = new SubmeshBuilder(new SubmeshBuilder.AddVertexDelegate((fv) => { if (Mode == GenerateMode.CollisionMesh) { // Collision meshes ignore UV, Normals, and Color data fv.ClearUV1(); fv.ClearUV2(); fv.ClearUV3(); fv.ClearNormal(); fv.SetColor(new Vector4(1.0f, 1.0f, 1.0f, 1.0f)); } UInt64 vertHash = fv.CalculateHash(); Dictionary <UInt64, int> submesh_verthash_to_index; if (!m_vert_hash_by_submesh_to_index.TryGetValue(submeshIndex, out submesh_verthash_to_index)) { submesh_verthash_to_index = new Dictionary <UInt64, int>(); m_vert_hash_by_submesh_to_index.Add(submeshIndex, submesh_verthash_to_index); } // For combined mesh int combined_index; if (!m_combined_vert_hash_to_index.TryGetValue(vertHash, out combined_index)) { combined_index = m_combined_verts.Count; m_combined_vert_hash_to_index.Add(vertHash, combined_index); m_combined_verts.Add(fv); } // For individual submesh int submesh_index; if (!submesh_verthash_to_index.TryGetValue(vertHash, out submesh_index)) { List <FaceVertex> submesh_vert_list; if (!m_verts_by_submesh.TryGetValue(submeshIndex, out submesh_vert_list)) { submesh_vert_list = new List <FaceVertex>(); m_verts_by_submesh.Add(submeshIndex, submesh_vert_list); } submesh_index = submesh_vert_list.Count; submesh_verthash_to_index.Add(vertHash, submesh_index); submesh_vert_list.Add(fv); } return(new SubmeshBuilder.AddVertexResult() { CombinedVertexIndex = combined_index, SubmeshVertexIndex = submesh_index }); }), geomType); m_submeshesBySubmeshIndex.Add(submeshIndex, builder); } return(builder); }
public void GenerateMeshObject(GenerateMode generateMode, float smoothingAngleSameMaterial, float smoothingAngleDiffMaterial, List <Mesh> output_mesh_list, List <int> output_submesh_index_list) { if (generateMode == GenerateMode.RenderMesh) { // // Building a render mesh -- materials matter // foreach (var kvp in m_submeshesBySubmeshIndex) { int submesh_index = kvp.Key; SubmeshBuilder submesh_builder = kvp.Value; // Sometimes we may create a submesh builder but not add any verts // to it. This could be for no-render decal face flags. List <FaceVertex> faceVerts; if (!m_verts_by_submesh.TryGetValue(submesh_index, out faceVerts)) { continue; } BuildMeshWorkerResult submesh_mesh_data = new BuildMeshWorkerResult(); submesh_mesh_data.Build(faceVerts); Mesh m = new Mesh(); m.vertices = submesh_mesh_data.m_vertices; // Needs UVs and colors m.uv = submesh_mesh_data.m_uv1s; if (submesh_mesh_data.m_has_uv2) { m.uv2 = submesh_mesh_data.m_uv2s; } if (submesh_mesh_data.m_has_uv3) { m.uv3 = submesh_mesh_data.m_uv3s; } if (submesh_mesh_data.m_has_translucent) { // Only take colors if there was a non-white color m.colors = submesh_mesh_data.m_colors; } // As an optimization - each material gets its own mesh (instead of using submeshes within the mesh) m.subMeshCount = 1; m.SetTriangles(submesh_builder.SubmeshTriangleList, 0); m.RecalculateNormals(smoothingAngleSameMaterial, smoothingAngleDiffMaterial, submesh_mesh_data.m_normal_lock, submesh_mesh_data.m_normals); // Recalculate tangents (AFTER normals, as RecalculateNormals will destroy tangents) m.RecalculateTangents(); m.RecalculateBounds(); output_mesh_list.Add(m); output_submesh_index_list.Add(submesh_index); } } else { // // Building a collision mesh -- combine the verts // BuildMeshWorkerResult combined_mesh_data = new BuildMeshWorkerResult(); combined_mesh_data.Build(m_combined_verts); Mesh m = new Mesh(); m.vertices = combined_mesh_data.m_vertices; // Collision mesh is one submesh m.subMeshCount = 1; var all_combined_triangles = new List <int>(); foreach (var kvp in m_submeshesBySubmeshIndex) { int submeshIndex = kvp.Key; if (submeshIndex < 0) { continue; } var submeshBuilder = kvp.Value; if (submeshBuilder.GeomType == GeometryType.Portal) { // don't include the debug portal geometry into the collision data continue; } all_combined_triangles.AddRange(submeshBuilder.CombinedTriangleList); } m.SetTriangles(all_combined_triangles.ToArray(), 0); m.RecalculateNormals(smoothingAngleSameMaterial, smoothingAngleDiffMaterial, combined_mesh_data.m_normal_lock, combined_mesh_data.m_normals); m.RecalculateBounds(); ; output_mesh_list.Add(m); output_submesh_index_list.Add(0); } }