@@ -202,17 +202,17 @@ public void Update()
202202 }
203203 }
204204 {
205- m_Features =
206- "Vertices : " + m_VertCount + " total, " + ( m_VertOrphan > 0 ? m_VertOrphan + " orphan, " : "" ) + ( m_VertDuplicates > 0 ? m_VertDuplicates + " duplicates, " : "" ) +
205+ m_Features = "Mesh Features:" +
206+ "\n Vertices : " + m_VertCount + " total, " + ( m_VertOrphan > 0 ? m_VertOrphan + " orphan, " : "" ) + ( m_VertDuplicates > 0 ? m_VertDuplicates + " duplicates, " : "" ) +
207207 "\n Indices: " + m_IndiceCountNormalized + " total, " + m_IndiceCount + " buffer capacity, " + m_IndiceAreaTotal . ToString ( "0.##" ) + " unit surface area, " +
208208 ( m_MeshSubmeshCount > 1 ? m_MeshSubmeshCount + " submeshes, " : "" ) + ( m_IndiceInvalidArea > 0 ? m_IndiceInvalidArea + " invalid, " : "" ) +
209- "\n Channels: position," + ( m_NormalChannels >= 1 ? "normals," + ( m_NormalChannels >= 3 ? "tangents," : "" ) : "" ) + InternalMeshUtil . GetVertexFormat ( m_Mesh ) +
209+ "\n Channels: position, " + ( m_NormalChannels >= 1 ? "normals, " + ( m_NormalChannels >= 3 ? "tangents, " : "" ) : "" ) + InternalMeshUtil . GetVertexFormat ( m_Mesh ) . Replace ( "," , ", " ) +
210210 "\n Size: " + m_MeshBounds . size . ToString ( "0.00" ) ;
211211 }
212212 m_lastMeshId = m_Mesh . GetInstanceID ( ) ;
213213 }
214214
215- static public Dictionary < MeshTopology , int > m_TopologyDivision = new Dictionary < MeshTopology , int > ( )
215+ static public Dictionary < MeshTopology , int > m_TopologyDivision = new Dictionary < MeshTopology , int > ( new MeshTopologyComparer ( ) )
216216 {
217217 { MeshTopology . Lines , 2 } ,
218218 { MeshTopology . LineStrip , 2 } ,
@@ -221,6 +221,20 @@ public void Update()
221221 { MeshTopology . Triangles , 3 } ,
222222 } ;
223223
224+ // for performance godsake
225+ public class MeshTopologyComparer : IEqualityComparer < MeshTopology >
226+ {
227+ public bool Equals ( MeshTopology x , MeshTopology y )
228+ {
229+ return x == y ;
230+ }
231+
232+ public int GetHashCode ( MeshTopology obj )
233+ {
234+ return ( int ) obj ;
235+ }
236+ }
237+
224238 private static float GetTriArea ( Vector3 A , Vector3 B , Vector3 C )
225239 {
226240 var a = Vector3 . Distance ( B , C ) ;
@@ -310,10 +324,89 @@ internal static class InternalMeshUtil
310324{
311325 public static Func < Mesh , string > GetVertexFormat ;
312326
327+
313328 static InternalMeshUtil ( )
314329 {
315330 var type = typeof ( Editor ) . Assembly . GetTypes ( ) . First ( ( x ) => x . Name == "InternalMeshUtil" ) ;
316331 GetVertexFormat = ( Func < Mesh , string > ) Delegate . CreateDelegate ( typeof ( Func < Mesh , string > ) , null ,
317332 type . GetMethod ( "GetVertexFormat" , BindingFlags . Static | BindingFlags . Public ) ) ;
318333 }
334+
335+ // https://gist.github.com/willnode/032eb0c73733ffc862bdfec0a8e8af0e
336+
337+ static Func < object , Array > _ExtractArrayFromList ;
338+
339+ static void CreateExtractDelegate ( )
340+ {
341+
342+ #if UNITY_2017_2 || UNITY_2017_1 || UNITY_5 || UNITY_4
343+ var type = typeof ( Mesh ) ;
344+ #else
345+ var type = typeof ( Mesh ) . Assembly . GetTypes ( ) . First ( x => x . Name == "NoAllocHelpers" ) ;
346+ #endif
347+
348+ var m = type . GetMethod ( "ExtractArrayFromList" , BindingFlags . NonPublic | BindingFlags . Public | BindingFlags . Static | BindingFlags . FlattenHierarchy ) ;
349+ _ExtractArrayFromList = ( Func < object , Array > ) Delegate . CreateDelegate ( typeof ( Func < object , Array > ) , m ) ;
350+ }
351+
352+ /// <summary>
353+ /// Extract array from list
354+ /// </summary>
355+ public static Array ExtractArrayFromList < T > ( List < T > list )
356+ {
357+ if ( _ExtractArrayFromList == null )
358+ CreateExtractDelegate ( ) ;
359+ return _ExtractArrayFromList ( list ) ;
360+ }
361+
362+ // -----------------------------------------------------
363+
364+ private delegate void Action < T1 , T2 , T3 , T4 , T5 , T6 > ( T1 a , T2 b , T3 c , T4 d , T5 e , T6 f ) ;
365+ private delegate void Action < T1 , T2 , T3 , T4 , T5 , T6 , T7 > ( T1 a , T2 b , T3 c , T4 d , T5 e , T6 f , T7 g ) ;
366+
367+ #if UNITY_2017_2 || UNITY_2017_1 || UNITY_5 || UNITY_4
368+
369+ static Action < Mesh , int , MeshTopology , Array , int , bool > _SetIndices ;
370+
371+ static void CreateSetIndicesDelegate ( )
372+ {
373+ // See ILSpy for this hidden feature
374+ var m = typeof ( Mesh ) . GetMethod ( "SetIndicesImpl" , BindingFlags . DeclaredOnly | BindingFlags . NonPublic | BindingFlags . Instance , null , new Type [ ] { typeof ( int ) , typeof ( MeshTopology ) , typeof ( Array ) , typeof ( int ) , typeof ( bool ) } , null ) ;
375+ _SetIndices = ( Action < Mesh , int , MeshTopology , Array , int , bool > ) Delegate . CreateDelegate ( typeof ( Action < Mesh , int , MeshTopology , Array , int , bool > ) , null , m ) ;
376+ }
377+
378+ /// <summary>
379+ /// Mesh.SetIndices with generic list variant
380+ /// </summary>
381+ public static void SetIndices ( Mesh m , List < int > buffer , MeshTopology topology , int submesh , bool recalculate )
382+ {
383+ if ( _SetIndices == null )
384+ CreateSetIndicesDelegate ( ) ;
385+ _SetIndices ( m , submesh , topology , ExtractArrayFromList ( buffer ) , buffer . Count , recalculate ) ;
386+ }
387+
388+ #else
389+
390+ static Action < Mesh , int , MeshTopology , Array , int , bool , int > _SetIndices ;
391+
392+ static void CreateSetIndicesDelegate ( )
393+ {
394+ // See ILSpy for this hidden feature
395+ var m = typeof ( Mesh ) . GetMethod ( "SetIndicesImpl" , BindingFlags . DeclaredOnly | BindingFlags . NonPublic | BindingFlags . Instance , null , new Type [ ] { typeof ( int ) , typeof ( MeshTopology ) , typeof ( Array ) , typeof ( int ) , typeof ( bool ) , typeof ( int ) } , null ) ;
396+ _SetIndices = ( Action < Mesh , int , MeshTopology , Array , int , bool , int > ) Delegate . CreateDelegate ( typeof ( Action < Mesh , int , MeshTopology , Array , int , bool , int > ) , null , m ) ;
397+ }
398+
399+ /// <summary>
400+ /// Mesh.SetIndices with generic list variant
401+ /// </summary>
402+ public static void SetIndices ( Mesh m , List < int > buffer , MeshTopology topology , int submesh , bool recalculate )
403+ {
404+ if ( _SetIndices == null )
405+ CreateSetIndicesDelegate ( ) ;
406+ _SetIndices ( m , submesh , topology , ExtractArrayFromList ( buffer ) , buffer . Count , recalculate , 0 ) ;
407+ }
408+
409+
410+ #endif
411+
319412}
0 commit comments