rj-action-library/Runtime/LOD/MultiMeshGenerator.cs

122 lines
2.6 KiB
C#
Raw Normal View History

2025-01-03 12:09:23 +00:00
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class MultiMeshGenerator:Node
{
[Export]
public Node3D source;
[Export]
public Node3D output;
[Export]
public float blockSize = 50;
[Export]
public bool clearOutput = true;
[Export]
public bool update = false;
public override void _Process( double delta )
{
if ( ! update )
{
return;
}
update = false;
Generate();
}
public void Generate()
{
if ( clearOutput )
{
Nodes.RemoveAndDeleteChildren( output );
}
var grid = Grid2D<MeshInstance3D>.XZfromNode3D<MeshInstance3D>( blockSize, blockSize );
this.LogInfo( "Grid Created", grid );
var instances = Nodes.AllIn<MeshInstance3D>( source );
this.LogInfo( "Grabbed instances", instances.Count );
grid.AddAll( instances );
this.LogInfo( "Added instance to grid" );
grid.ForEachCell(
( cellID, list ) =>
{
var meshList = new MapList<Mesh,MeshInstance3D>();
list.ForEach(
( n )=>
{
var m = n.Mesh;
meshList.Add( m, n );
}
);
var cIDCount = 0;
meshList.ForEach(
( mesh, list ) =>
{
var cellIDInfo = "[" + cellID.X + "," + cellID.Y+"]";
var mmi = output.CreateChild<LODMultiMesh>( "Cell" + cellIDInfo + "(" + cIDCount + ")" );
var mm = new MultiMesh();
mm.Mesh = mesh;
mm.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D;
mm.InstanceCount = list.Count;
mm.VisibleInstanceCount = list.Count;
var random = new LCG();
random.SetSeed( 12134 + (int)( Noise.Perlin( cellID ) * 10083 ) );
var randomList = RandomList<MeshInstance3D>.Randomize( list, random );
var center = Math3D.Center( randomList );
mmi.GlobalPosition = center;
for ( int i = 0; i < randomList.Count; i++ )
{
var trsf = randomList[ i ].GlobalTransform;
trsf.Origin -= center;
mm.SetInstanceTransform( i, trsf );
}
mmi.Multimesh = mm;
mmi.CacheTransforms();
Materials.Set( mmi, Materials.Get<Material>( list[ 0 ] ) );
cIDCount++;
}
);
}
);
}
}
}