using System.Collections; using System.Collections.Generic; using Godot; using System; namespace Rokojori { public class MeshExtractor { public static bool CanExtract( Node3D n ) { if ( n is MeshInstance3D mi ) { return mi.Mesh != null; } if ( n is MultiMeshInstance3D mmi ) { var mm = mmi.Multimesh; return mm.Mesh != null; } return false; } public static List> ExtractMeshesInHierarchy( Node n, List> list = null ) { list = list == null ? new List>() : list; Nodes.ForEach( n, n => { ExtractMeshes( n, list ); } ); return list; } public static List> ExtractMeshes( Node n, List> list = null ) { list = list == null ? new List>() : list; if ( n is MeshInstance3D mi ) { var mesh = mi.Mesh; var singleMaterialMesh = new SingleMaterialMesh( mesh ); if ( mi.GetSurfaceOverrideMaterialCount() > 0 && mi.GetSurfaceOverrideMaterial( 0 ) != null ) { singleMaterialMesh.material = mi.GetSurfaceOverrideMaterial( 0 ); } if ( mi.MaterialOverride != null ) { singleMaterialMesh.material = mi.MaterialOverride; } list.Add( new Transformable( singleMaterialMesh, mi.GlobalTransform ) ); } if ( n is MultiMeshInstance3D mmi ) { var mm = mmi.Multimesh; for ( var j = 0; j < mm.InstanceCount; j++ ) { var mesh = mm.Mesh; var transform = mm.GetInstanceTransform( j ); var singleMaterialMesh = new SingleMaterialMesh( mesh ); if ( mmi.MaterialOverride != null ) { singleMaterialMesh.material = mmi.MaterialOverride; } list.Add( new Transformable( singleMaterialMesh, transform ) ); } } return list; } public static List> ExtractSurfacesInHierarchy( Node n, List> list = null ) { list = list == null ? new List>() : list; Nodes.ForEach( n, n => { ExtractSurfaces( n, list ); } ); return list; } public static List> ExtractSurfaces( Node n, List> list = null ) { list = list == null ? new List>() : list; if ( n is MeshInstance3D mi ) { var mesh = mi.Mesh; for ( int i = 0; i < mesh.GetSurfaceCount(); i++ ) { var surface = new MeshSurface( mesh, mesh.SurfaceGetMaterial( i ), i ); if ( i < mi.GetSurfaceOverrideMaterialCount() && mi.GetSurfaceOverrideMaterial( i ) != null ) { surface.material = mi.GetSurfaceOverrideMaterial( i ); } if ( mi.MaterialOverride != null ) { surface.material = mi.MaterialOverride; } list.Add( new Transformable( surface, mi.GlobalTransform ) ); } } if ( n is MultiMeshInstance3D mmi ) { var mm = mmi.Multimesh; for ( var j = 0; j < mm.InstanceCount; j++ ) { var mesh = mm.Mesh; var transform = mm.GetInstanceTransform( j ); for ( int i = 0; i < mesh.GetSurfaceCount(); i++ ) { var surface = new MeshSurface( mesh, mesh.SurfaceGetMaterial( i ), i ); if ( mmi.MaterialOverride != null ) { surface.material = mmi.MaterialOverride; } list.Add( new Transformable( surface, transform ) ); } } } return list; } } }