@@ -929,7 +929,7 @@ static int follow(int* parents, int index)
929929 return index;
930930}
931931
932- void meshlets (const Mesh& mesh, bool scan)
932+ void meshlets (const Mesh& mesh, bool scan = false )
933933{
934934 const size_t max_vertices = 64 ;
935935 const size_t max_triangles = 124 ; // NVidia-recommended 126, rounded down to a multiple of 4
@@ -963,9 +963,20 @@ void meshlets(const Mesh& mesh, bool scan)
963963
964964 double avg_vertices = 0 ;
965965 double avg_triangles = 0 ;
966+ double avg_boundary = 0 ;
966967 size_t not_full = 0 ;
967968 size_t not_connected = 0 ;
968969
970+ std::vector<int > boundary (mesh.vertices .size ());
971+
972+ for (size_t i = 0 ; i < meshlets.size (); ++i)
973+ {
974+ const meshopt_Meshlet& m = meshlets[i];
975+
976+ for (unsigned int j = 0 ; j < m.vertex_count ; ++j)
977+ boundary[meshlet_vertices[m.vertex_offset + j]]++;
978+ }
979+
969980 for (size_t i = 0 ; i < meshlets.size (); ++i)
970981 {
971982 const meshopt_Meshlet& m = meshlets[i];
@@ -974,6 +985,10 @@ void meshlets(const Mesh& mesh, bool scan)
974985 avg_triangles += m.triangle_count ;
975986 not_full += m.vertex_count < max_vertices;
976987
988+ for (unsigned int j = 0 ; j < m.vertex_count ; ++j)
989+ if (boundary[meshlet_vertices[m.vertex_offset + j]] > 1 )
990+ avg_boundary += 1 ;
991+
977992 // union-find vertices to check if the meshlet is connected
978993 int parents[max_vertices];
979994 for (unsigned int j = 0 ; j < m.vertex_count ; ++j)
@@ -1000,10 +1015,11 @@ void meshlets(const Mesh& mesh, bool scan)
10001015
10011016 avg_vertices /= double (meshlets.size ());
10021017 avg_triangles /= double (meshlets.size ());
1018+ avg_boundary /= double (meshlets.size ());
10031019
1004- printf (" Meshlets%c: %d meshlets (avg vertices %.1f, avg triangles %.1f, not full %d, not connected %d) in %.2f msec\n " ,
1020+ printf (" Meshlets%c: %d meshlets (avg vertices %.1f, avg triangles %.1f, avg boundary %.1f, not full %d, not connected %d) in %.2f msec\n " ,
10051021 scan ? ' S' : ' ' ,
1006- int (meshlets.size ()), avg_vertices, avg_triangles, int (not_full), int (not_connected), (end - start) * 1000 );
1022+ int (meshlets.size ()), avg_vertices, avg_triangles, avg_boundary, int (not_full), int (not_connected), (end - start) * 1000 );
10071023
10081024 float camera[3 ] = {100 , 100 , 100 };
10091025
@@ -1015,6 +1031,7 @@ void meshlets(const Mesh& mesh, bool scan)
10151031 size_t accepted_s8 = 0 ;
10161032
10171033 std::vector<float > radii (meshlets.size ());
1034+ std::vector<float > cones (meshlets.size ());
10181035
10191036 double startc = timestamp ();
10201037 for (size_t i = 0 ; i < meshlets.size (); ++i)
@@ -1024,6 +1041,7 @@ void meshlets(const Mesh& mesh, bool scan)
10241041 meshopt_Bounds bounds = meshopt_computeMeshletBounds (&meshlet_vertices[m.vertex_offset ], &meshlet_triangles[m.triangle_offset ], m.triangle_count , &mesh.vertices [0 ].px , mesh.vertices .size (), sizeof (Vertex));
10251042
10261043 radii[i] = bounds.radius ;
1044+ cones[i] = 90 .f - acosf (bounds.cone_cutoff ) * (180 .f / 3 .1415926f );
10271045
10281046 // trivial accept: we can't ever backface cull this meshlet
10291047 accepted += (bounds.cone_cutoff >= 1 );
@@ -1047,11 +1065,16 @@ void meshlets(const Mesh& mesh, bool scan)
10471065 double endc = timestamp ();
10481066
10491067 double radius_mean = 0 ;
1068+ double cone_mean = 0 ;
10501069
10511070 for (size_t i = 0 ; i < meshlets.size (); ++i)
1071+ {
10521072 radius_mean += radii[i];
1073+ cone_mean += cones[i];
1074+ }
10531075
10541076 radius_mean /= double (meshlets.size ());
1077+ cone_mean /= double (meshlets.size ());
10551078
10561079 double radius_variance = 0 ;
10571080
@@ -1067,10 +1090,10 @@ void meshlets(const Mesh& mesh, bool scan)
10671090 for (size_t i = 0 ; i < meshlets.size (); ++i)
10681091 meshlets_std += radii[i] < radius_mean + radius_stddev;
10691092
1070- printf (" BoundDist: mean %f stddev %f; %.1f%% meshlets are under mean+stddev\n " ,
1071- radius_mean,
1072- radius_stddev ,
1073- double (meshlets_std) / double (meshlets. size ()) * 100 );
1093+ printf (" Bounds : radius mean %f stddev %f; %.1f%% meshlets are under mean+stddev; cone mean half angle %.1f \n " ,
1094+ radius_mean, radius_stddev,
1095+ double (meshlets_std) / double (meshlets. size ()) * 100 ,
1096+ cone_mean );
10741097
10751098 printf (" ConeCull : rejected apex %d (%.1f%%) / center %d (%.1f%%), trivially accepted %d (%.1f%%) in %.2f msec\n " ,
10761099 int (rejected), double (rejected) / double (meshlets.size ()) * 100 ,
@@ -1392,7 +1415,7 @@ void processDev(const char* path)
13921415 if (!loadMesh (mesh, path))
13931416 return ;
13941417
1395- simplifyAttr (mesh, 0 . 1f , meshopt_SimplifyPrune );
1418+ meshlets (mesh);
13961419}
13971420
13981421void processNanite (const char * path)
0 commit comments