179 lines
3.6 KiB
C#
179 lines
3.6 KiB
C#
using Godot;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class Materials
|
|
{
|
|
|
|
public static int CountOf( Node node )
|
|
{
|
|
var s = new StandardMaterial3D();
|
|
|
|
if ( node is MeshInstance3D mi )
|
|
{
|
|
return mi.GetSurfaceOverrideMaterialCount();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
public static List<M> GetAll<M>( Node node, int index = 0 ) where M:Material
|
|
{
|
|
var list = new List<M>();
|
|
|
|
var count = CountOf( node );
|
|
|
|
for ( int i = 0; i < count; i++ )
|
|
{
|
|
list.Add( Get<M>( node, index ) );
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static M Get<M>( Node node, int index = 0 ) where M:Material
|
|
{
|
|
if ( node is MeshInstance3D mi )
|
|
{
|
|
var material = mi.GetSurfaceOverrideMaterial( index ) as M;
|
|
|
|
if ( material != null )
|
|
{
|
|
return material;
|
|
}
|
|
}
|
|
else if ( node is CsgPrimitive3D )
|
|
{
|
|
return ReflectionHelper.GetMemberValue( node, "material" ) as M;
|
|
}
|
|
|
|
else if ( node is GpuParticles3D gp)
|
|
{
|
|
return gp.ProcessMaterial as M;
|
|
}
|
|
|
|
if ( node is GeometryInstance3D gi )
|
|
{
|
|
return gi.MaterialOverride as M;
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
public static void SetAll( Node node, Material material )
|
|
{
|
|
var count = CountOf( node );
|
|
|
|
for ( int i = 0; i < count; i++ )
|
|
{
|
|
Set( node, material, i );
|
|
}
|
|
}
|
|
|
|
public static void Set( Node node, List<Material> materials )
|
|
{
|
|
var count = CountOf( node );
|
|
|
|
for ( int i = 0; i < count && i < materials.Count; i++ )
|
|
{
|
|
Set( node, materials[ i ], i );
|
|
}
|
|
}
|
|
|
|
public static void Set( Node node, Material material, int index = 0 )
|
|
{
|
|
if ( node is MeshInstance3D mi)
|
|
{
|
|
mi.SetSurfaceOverrideMaterial( index, material );
|
|
|
|
if ( index == 0 && mi.MaterialOverride != null )
|
|
{
|
|
mi.MaterialOverride = null;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ( node is CsgPrimitive3D csg )
|
|
{
|
|
ReflectionHelper.SetMemberValue( node, "material", material );
|
|
|
|
if ( csg.MaterialOverride != null )
|
|
{
|
|
csg.MaterialOverride = null;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if ( node is GpuParticles3D gp )
|
|
{
|
|
gp.ProcessMaterial = material;
|
|
|
|
if ( gp.MaterialOverride != null )
|
|
{
|
|
gp.MaterialOverride = null;
|
|
}
|
|
}
|
|
|
|
if ( node is GeometryInstance3D gi )
|
|
{
|
|
gi.MaterialOverride = material;
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
public static void AddOverlay( Node node, Material material, bool forceTop = true )
|
|
{
|
|
if ( node is GeometryInstance3D gi )
|
|
{
|
|
if ( gi.MaterialOverlay == null || forceTop )
|
|
{
|
|
gi.MaterialOverlay = material;
|
|
}
|
|
else
|
|
{
|
|
gi.MaterialOverlay.NextPass = material;
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public static void RemoveOverlay( Node node, Material material, bool forceTop = true )
|
|
{
|
|
|
|
if ( node is GeometryInstance3D gi )
|
|
{
|
|
if ( forceTop )
|
|
{
|
|
gi.MaterialOverlay = null;
|
|
}
|
|
else if ( gi.MaterialOverlay == material )
|
|
{
|
|
gi.MaterialOverlay = gi.MaterialOverlay.NextPass;
|
|
}
|
|
else
|
|
{
|
|
var mo = gi.MaterialOverlay;
|
|
|
|
while ( mo != null && mo.NextPass != material )
|
|
{
|
|
mo = mo.NextPass;
|
|
}
|
|
|
|
var next = material.NextPass;
|
|
|
|
mo.NextPass = next;
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
} |