257 lines
6.8 KiB
C#
257 lines
6.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
using System;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class MeshExtractor
|
|
{
|
|
public static List<MaterialSurfaceContainer> ExtractMaterialContainersInHierarchy( Node n, List<MaterialSurfaceContainer> list = null, bool ownersOnly = false )
|
|
{
|
|
list = list == null ? new List<MaterialSurfaceContainer>() : list;
|
|
|
|
Nodes.ForEach<Node3D>( n,
|
|
|
|
n =>
|
|
{
|
|
ExtractMaterialContainers( n, list, ownersOnly );
|
|
}
|
|
);
|
|
|
|
return list;
|
|
}
|
|
|
|
|
|
public static List<MaterialSurfaceContainer> ExtractMaterialContainers( Node n, List<MaterialSurfaceContainer> list = null, bool ownersOnly = false )
|
|
{
|
|
list = list == null ? new List<MaterialSurfaceContainer>() : list;
|
|
|
|
|
|
if ( n is MeshInstance3D mi && mi.Mesh != null )
|
|
{
|
|
if ( ! ownersOnly )
|
|
{
|
|
for ( int i = 0; i < mi.Mesh.GetSurfaceCount(); i++ )
|
|
{
|
|
list.Add( new MeshSurfaceContainer( mi, i ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list.Add( new MeshSurfaceContainer( mi, -1 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( n is MultiMeshInstance3D mmi && mmi.Multimesh != null && mmi.Multimesh.Mesh != null )
|
|
{
|
|
if ( ! ownersOnly )
|
|
{
|
|
for ( int i = 0; i < mmi.Multimesh.Mesh.GetSurfaceCount(); i++ )
|
|
{
|
|
list.Add( new MultiMeshSurfaceContainer( mmi, i ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list.Add( new MultiMeshSurfaceContainer( mmi, -1 ) );
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
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<Transformable<SingleMaterialMesh>> ExtractMeshesInHierarchy( Node n, List<Transformable<SingleMaterialMesh>> list = null )
|
|
{
|
|
list = list == null ? new List<Transformable<SingleMaterialMesh>>() : list;
|
|
|
|
Nodes.ForEach<Node3D>( n,
|
|
|
|
n =>
|
|
{
|
|
ExtractMeshes( n, list );
|
|
}
|
|
);
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<Transformable<SingleMaterialMesh>> ExtractMeshes( Node n, List<Transformable<SingleMaterialMesh>> list = null )
|
|
{
|
|
list = list == null ? new List<Transformable<SingleMaterialMesh>>() : 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>( 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>( singleMaterialMesh, transform ) );
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<Transformable<MeshSurface>> ExtractSurfacesInHierarchy( Node n, List<Transformable<MeshSurface>> list = null )
|
|
{
|
|
list = list == null ? new List<Transformable<MeshSurface>>() : list;
|
|
|
|
Nodes.ForEach<Node3D>( n,
|
|
|
|
n =>
|
|
{
|
|
ExtractSurfaces( n, list );
|
|
}
|
|
);
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<Transformable<MeshSurface>> ExtractSurfaces( Node n, List<Transformable<MeshSurface>> list = null )
|
|
{
|
|
list = list == null ? new List<Transformable<MeshSurface>>() : list;
|
|
|
|
if ( n is CsgShape3D c )
|
|
{
|
|
// RJLog.Log( "Extracting:", c, c.IsRootShape() );
|
|
|
|
if ( ! c.IsRootShape() )
|
|
{
|
|
return list;
|
|
}
|
|
|
|
var meshesData = c.GetMeshes();
|
|
|
|
// RJLog.Log( "MeshData:", meshesData );
|
|
// RJLog.Log( "MeshData 0:",meshesData[ 0 ] );
|
|
// RJLog.Log( "MeshData 1:", meshesData[ 1 ] );
|
|
var trsf = (Transform3D) meshesData[ 0 ] * c.Transform;
|
|
var mesh = (ArrayMesh) meshesData[ 1 ];
|
|
|
|
var mg = MeshGeometry.From( mesh );
|
|
|
|
|
|
Material material = null;
|
|
|
|
if ( c is CsgBox3D bx ){ material = bx.Material; }
|
|
if ( c is CsgCylinder3D cy ){ material = cy.Material; }
|
|
if ( c is CsgMesh3D ms ){ material = ms.Material; }
|
|
if ( c is CsgPolygon3D pl ){ material = pl.Material; }
|
|
if ( c is CsgSphere3D sp ){ material = sp.Material; }
|
|
if ( c is CsgTorus3D tr ){ material = tr.Material; }
|
|
|
|
RJLog.Log( "MeshInfo ", c, mesh, material, "\n",
|
|
"tris:", mg.numTriangles
|
|
);
|
|
|
|
var surface = new MeshSurface( mesh, material, 0, c );
|
|
|
|
list.Add( new Transformable<MeshSurface>( surface, trsf ) );
|
|
}
|
|
|
|
if ( n is MeshInstance3D mi )
|
|
{
|
|
var owner = mi;
|
|
var mesh = mi.Mesh;
|
|
|
|
|
|
for ( int i = 0; i < mesh.GetSurfaceCount(); i++ )
|
|
{
|
|
var surface = new MeshSurface( mesh, mesh.SurfaceGetMaterial( i ), i, owner );
|
|
|
|
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<MeshSurface>( surface, mi.GlobalTransform ) );
|
|
}
|
|
}
|
|
|
|
|
|
if ( n is MultiMeshInstance3D mmi )
|
|
{
|
|
var owner = 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, mmi, j );
|
|
|
|
if ( mmi.MaterialOverride != null )
|
|
{
|
|
surface.material = mmi.MaterialOverride;
|
|
}
|
|
|
|
list.Add( new Transformable<MeshSurface>( surface, transform ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
}
|
|
|
|
} |