217 lines
4.7 KiB
C#
217 lines
4.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
using System;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public partial class MassRenderer:Node3D
|
|
{
|
|
public enum Mode
|
|
{
|
|
MultiMeshInstance3D,
|
|
Combined,
|
|
MeshInstance3D
|
|
}
|
|
|
|
[Export]
|
|
public Mode mode = Mode.MultiMeshInstance3D;
|
|
|
|
[Export]
|
|
public int randomizeQueue = 1984;
|
|
|
|
[ExportGroup("Mesh")]
|
|
[Export]
|
|
public Mesh mesh;
|
|
|
|
[Export]
|
|
public Material materialOveride;
|
|
|
|
[ExportGroup("Layout")]
|
|
[Export]
|
|
public Vector3[] positions;
|
|
|
|
[Export]
|
|
public Vector4[] rotations;
|
|
|
|
[Export]
|
|
public Vector3[] scales;
|
|
|
|
[ExportGroup("Outputs")]
|
|
[Export]
|
|
public LODMultiMeshInstance3D multiMeshNode;
|
|
[Export]
|
|
public Node3D meshesContainer;
|
|
[Export]
|
|
public MeshInstance3D combinedMesh;
|
|
|
|
List<Transform3D> _queuedTransforms = new List<Transform3D>();
|
|
|
|
|
|
|
|
public void QueueObject( Transform3D transform )
|
|
{
|
|
_queuedTransforms.Add( transform );
|
|
}
|
|
|
|
public void AddQueued()
|
|
{
|
|
if ( positions == null )
|
|
{
|
|
positions = new Vector3[0];
|
|
}
|
|
|
|
if ( rotations == null )
|
|
{
|
|
rotations = new Vector4[0];
|
|
}
|
|
|
|
if ( scales == null )
|
|
{
|
|
scales = new Vector3[0];
|
|
}
|
|
|
|
if ( randomizeQueue >= 0 )
|
|
{
|
|
_queuedTransforms = RandomList<Transform3D>.Randomize( _queuedTransforms, LCG.WithSeed( randomizeQueue ) );
|
|
}
|
|
|
|
var queuedPositions = Lists.Map( _queuedTransforms, t => t.Origin );
|
|
var queuedRotations = Lists.Map( _queuedTransforms, t => Math3D.QuaternionToVector4( t.Basis.GetRotationQuaternion() ) );
|
|
var queuedScales = Lists.Map( _queuedTransforms, t => t.Basis.Scale );
|
|
|
|
positions = Arrays.Concat( positions, queuedPositions.ToArray() );
|
|
rotations = Arrays.Concat( rotations, queuedRotations.ToArray() );
|
|
scales = Arrays.Concat( scales, queuedScales.ToArray() );
|
|
|
|
_queuedTransforms.Clear();
|
|
}
|
|
|
|
public void Create()
|
|
{
|
|
AddQueued();
|
|
|
|
if ( Mode.MultiMeshInstance3D == mode )
|
|
{
|
|
CreateMultiMeshes();
|
|
}
|
|
else if ( Mode.MeshInstance3D == mode )
|
|
{
|
|
CreateMeshes();
|
|
}
|
|
else if ( Mode.Combined == mode )
|
|
{
|
|
CreateCombined();
|
|
}
|
|
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
multiMeshNode = Nodes.EnsureValid( multiMeshNode );
|
|
meshesContainer = Nodes.EnsureValid( meshesContainer );
|
|
combinedMesh = Nodes.EnsureValid( combinedMesh );
|
|
|
|
|
|
if ( multiMeshNode != null )
|
|
{
|
|
multiMeshNode.Multimesh.InstanceCount = 0;
|
|
}
|
|
|
|
if ( meshesContainer != null )
|
|
{
|
|
Nodes.RemoveAndDeleteChildren( meshesContainer );
|
|
}
|
|
|
|
if ( combinedMesh != null )
|
|
{
|
|
combinedMesh.Mesh = null;
|
|
}
|
|
}
|
|
|
|
void CreateMultiMeshes()
|
|
{
|
|
multiMeshNode = Nodes.EnsureValid( multiMeshNode );
|
|
|
|
if ( multiMeshNode == null )
|
|
{
|
|
multiMeshNode = this.CreateChild<LODMultiMeshInstance3D>();
|
|
multiMeshNode.Multimesh = new MultiMesh();
|
|
multiMeshNode.Multimesh.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D;
|
|
}
|
|
|
|
var mm = multiMeshNode.Multimesh;
|
|
|
|
|
|
mm.Mesh = mesh;
|
|
mm.InstanceCount = positions.Length;
|
|
|
|
if ( materialOveride != null )
|
|
{
|
|
multiMeshNode.MaterialOverride = materialOveride;
|
|
}
|
|
|
|
for ( int i = 0; i < positions.Length; i++ )
|
|
{
|
|
var trsf = Math3D.TRS( positions[ i ], rotations[ i ], scales[ i ] );
|
|
mm.SetInstanceTransform( i, trsf );
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void CreateMeshes()
|
|
{
|
|
if ( meshesContainer == null )
|
|
{
|
|
meshesContainer = this.CreateChild<Node3D>();
|
|
}
|
|
|
|
for ( int i = 0; i < positions.Length; i++ )
|
|
{
|
|
var trsf = Math3D.TRS( positions[ i ], rotations[ i ], scales[ i ] );
|
|
|
|
var child = meshesContainer.CreateChild<MeshInstance3D>();
|
|
child.Mesh = mesh;
|
|
|
|
if ( materialOveride != null )
|
|
{
|
|
child.MaterialOverride = materialOveride;
|
|
}
|
|
|
|
child.GlobalTransform = trsf;
|
|
}
|
|
}
|
|
|
|
void CreateCombined()
|
|
{
|
|
if ( meshesContainer == null )
|
|
{
|
|
combinedMesh = this.CreateChild<MeshInstance3D>();
|
|
}
|
|
|
|
var combinedMG = new MeshGeometry();
|
|
|
|
var meshMG = MeshGeometry.From( mesh as ArrayMesh );
|
|
|
|
for ( int i = 0; i < positions.Length; i++ )
|
|
{
|
|
var trsf = Math3D.TRS( positions[ i ], rotations[ i ], scales[ i ] );
|
|
combinedMG.Add( meshMG, trsf );
|
|
}
|
|
|
|
if ( materialOveride != null )
|
|
{
|
|
combinedMesh.MaterialOverride = materialOveride;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
} |