@@ -929,7 +929,7 @@ static int follow(int* parents, int index)
929
929
return index ;
930
930
}
931
931
932
- void meshlets (const Mesh& mesh, bool scan)
932
+ void meshlets (const Mesh& mesh, bool scan = false )
933
933
{
934
934
const size_t max_vertices = 64 ;
935
935
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)
963
963
964
964
double avg_vertices = 0 ;
965
965
double avg_triangles = 0 ;
966
+ double avg_boundary = 0 ;
966
967
size_t not_full = 0 ;
967
968
size_t not_connected = 0 ;
968
969
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
+
969
980
for (size_t i = 0 ; i < meshlets.size (); ++i)
970
981
{
971
982
const meshopt_Meshlet& m = meshlets[i];
@@ -974,6 +985,10 @@ void meshlets(const Mesh& mesh, bool scan)
974
985
avg_triangles += m.triangle_count ;
975
986
not_full += m.vertex_count < max_vertices;
976
987
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
+
977
992
// union-find vertices to check if the meshlet is connected
978
993
int parents[max_vertices];
979
994
for (unsigned int j = 0 ; j < m.vertex_count ; ++j)
@@ -1000,10 +1015,11 @@ void meshlets(const Mesh& mesh, bool scan)
1000
1015
1001
1016
avg_vertices /= double (meshlets.size ());
1002
1017
avg_triangles /= double (meshlets.size ());
1018
+ avg_boundary /= double (meshlets.size ());
1003
1019
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 " ,
1005
1021
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 );
1007
1023
1008
1024
float camera[3 ] = {100 , 100 , 100 };
1009
1025
@@ -1015,6 +1031,7 @@ void meshlets(const Mesh& mesh, bool scan)
1015
1031
size_t accepted_s8 = 0 ;
1016
1032
1017
1033
std::vector<float > radii (meshlets.size ());
1034
+ std::vector<float > cones (meshlets.size ());
1018
1035
1019
1036
double startc = timestamp ();
1020
1037
for (size_t i = 0 ; i < meshlets.size (); ++i)
@@ -1024,6 +1041,7 @@ void meshlets(const Mesh& mesh, bool scan)
1024
1041
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));
1025
1042
1026
1043
radii[i] = bounds.radius ;
1044
+ cones[i] = 90 .f - acosf (bounds.cone_cutoff ) * (180 .f / 3 .1415926f );
1027
1045
1028
1046
// trivial accept: we can't ever backface cull this meshlet
1029
1047
accepted += (bounds.cone_cutoff >= 1 );
@@ -1047,11 +1065,16 @@ void meshlets(const Mesh& mesh, bool scan)
1047
1065
double endc = timestamp ();
1048
1066
1049
1067
double radius_mean = 0 ;
1068
+ double cone_mean = 0 ;
1050
1069
1051
1070
for (size_t i = 0 ; i < meshlets.size (); ++i)
1071
+ {
1052
1072
radius_mean += radii[i];
1073
+ cone_mean += cones[i];
1074
+ }
1053
1075
1054
1076
radius_mean /= double (meshlets.size ());
1077
+ cone_mean /= double (meshlets.size ());
1055
1078
1056
1079
double radius_variance = 0 ;
1057
1080
@@ -1067,10 +1090,10 @@ void meshlets(const Mesh& mesh, bool scan)
1067
1090
for (size_t i = 0 ; i < meshlets.size (); ++i)
1068
1091
meshlets_std += radii[i] < radius_mean + radius_stddev;
1069
1092
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 );
1074
1097
1075
1098
printf (" ConeCull : rejected apex %d (%.1f%%) / center %d (%.1f%%), trivially accepted %d (%.1f%%) in %.2f msec\n " ,
1076
1099
int (rejected), double (rejected) / double (meshlets.size ()) * 100 ,
@@ -1392,7 +1415,7 @@ void processDev(const char* path)
1392
1415
if (!loadMesh (mesh, path))
1393
1416
return ;
1394
1417
1395
- simplifyAttr (mesh, 0 . 1f , meshopt_SimplifyPrune );
1418
+ meshlets (mesh);
1396
1419
}
1397
1420
1398
1421
void processNanite (const char * path)
0 commit comments