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.XZfromNode3D( blockSize, blockSize ); this.LogInfo( "Grid Created", grid ); var instances = Nodes.AllIn( source ); this.LogInfo( "Grabbed instances", instances.Count ); grid.AddAll( instances ); this.LogInfo( "Added instance to grid" ); grid.ForEachCell( ( cellID, list ) => { var meshList = new MapList(); 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( "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.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( list[ 0 ] ) ); cIDCount++; } ); } ); } } }