rj-action-library/Runtime/Procedural/Scatter/Generators/GenerateInBox.cs

104 lines
2.6 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GenerateInBox:GeneratorScatterer
{
[Export]
public Node3D cornerA;
[Export]
public Node3D cornerB;
[Export]
public bool xzOnly = true;
[Export]
public float density = 10;
[Export]
public bool snapToWorldGrid = false;
protected override List<ScatterPoint> _Scatter( List<ScatterPoint> points )
{
CreateWeights();
var minPosition = Math3D.MinPosition( cornerA, cornerB );
var maxPosition = Math3D.MaxPosition( cornerA, cornerB );
if ( snapToWorldGrid )
{
var snapping = Vector3.One / density;
minPosition = Math3D.SnapCeiled( minPosition, snapping );
maxPosition = Math3D.SnapFloored( maxPosition, snapping );
}
var pointsX = Mathf.CeilToInt( ( maxPosition.X - minPosition.X ) * density );
var pointsY = Mathf.CeilToInt( ( maxPosition.Y - minPosition.Y ) * density );
var pointsZ = Mathf.CeilToInt( ( maxPosition.Z - minPosition.Z ) * density );
var id = 0;
if ( xzOnly )
{
var y = ( cornerA.GlobalPosition.Y + cornerB.GlobalPosition.Y ) / 2f;
for ( int x = 0; x < pointsX; x++ )
{
var xPosition = MathX.Map( x, 0, pointsX - 1, minPosition.X, maxPosition.X );
for ( int z = 0; z < pointsZ; z++ )
{
var zPosition = MathX.Map( z, 0, pointsZ- 1, minPosition.Z, maxPosition.Z );
id = CreatePoint( points, id, xPosition, y, zPosition );
}
}
}
else
{
for ( int x = 0; x < pointsX; x++ )
{
var xPosition = MathX.Map( x, 0, pointsX - 1, minPosition.X, maxPosition.X );
for ( int y = 0; y < pointsY; y++ )
{
var yPosition = MathX.Map( y, 0, pointsY- 1, minPosition.Y, maxPosition.Y );
for ( int z = 0; z < pointsZ; z++ )
{
var zPosition = MathX.Map( z, 0, pointsZ- 1, minPosition.Z, maxPosition.Z );
id = CreatePoint( points, id, xPosition, yPosition, zPosition );
}
}
}
}
return points;
}
int CreatePoint( List<ScatterPoint> points, int id, float x, float y, float z )
{
var p = new ScatterPoint( this, id++ );
p.position = new Vector3( x, y, z );
p.visible = ! setDiscarded;
p.seed = Noise.CreateSeed( p.position );
AssginSceneAndContainer( p );
points.Add( p );
return id;
}
}
}