84 lines
2.2 KiB
C#
84 lines
2.2 KiB
C#
|
|
using Godot;
|
|
using Rokojori;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Spline.svg") ]
|
|
public partial class SplineMesh : Action
|
|
{
|
|
[Export]
|
|
public Spline spline;
|
|
|
|
[Export]
|
|
public float splineRadius = 0.5f;
|
|
|
|
[Export]
|
|
public float resolutionU = 0.1f;
|
|
|
|
[Export]
|
|
public int maxSegmentsU = 64;
|
|
|
|
|
|
[Export]
|
|
public float resolutionV = 0.5f;
|
|
|
|
[Export]
|
|
public int maxSegmentsV = 1024;
|
|
|
|
[Export]
|
|
public MeshInstance3D output;
|
|
|
|
[Export]
|
|
public bool undistortSplineSegments = false;
|
|
|
|
protected override void _OnTrigger()
|
|
{
|
|
CreateMesh();
|
|
}
|
|
|
|
public void CreateMesh()
|
|
{
|
|
var curve = spline.GetCurve();
|
|
|
|
var length = curve.ComputeLength( 100 );
|
|
var numPoints = Mathf.Clamp( length / resolutionU, 2, maxSegmentsU );
|
|
|
|
var uSegments = (int) ( Mathf.Clamp( splineRadius * 2f * 3.14f / resolutionV, 3, maxSegmentsV ) );
|
|
var vSegments = (int) ( numPoints - 1 );
|
|
|
|
|
|
var uvFunction = ( Vector2 uv ) =>
|
|
{
|
|
var t = undistortSplineSegments ? curve.ComputeTforNormalizedCurveLength( uv.Y, vSegments ) : uv.Y;
|
|
var index = curve.NormalizedToPointIndex( t );
|
|
var pose = curve.PoseAt( t );
|
|
var radiusSize = splineRadius;
|
|
|
|
var angle = uv.X * 2f * Mathf.Pi;
|
|
var circlePose = Pose.Create( Vector3.Zero, pose.rotation * Math3D.RotateZ( angle ) );
|
|
|
|
circlePose.rotation = circlePose.rotation.Normalized();
|
|
var circleStart = Vector3.Up * radiusSize;
|
|
var positionOnCircle = circlePose.Apply( circleStart );
|
|
|
|
return Pose.Create( positionOnCircle + pose.position, circlePose.rotation );
|
|
};
|
|
|
|
var mg = MeshGeometry.CreateFromUVFunction( uvFunction, uSegments, vSegments );
|
|
mg.Add( MeshGeometry.CreateCapUVFunction( uvFunction, uSegments, true ) );
|
|
mg.Add( MeshGeometry.CreateCapUVFunction( uvFunction, uSegments, false ) );
|
|
|
|
if ( output == null )
|
|
{
|
|
output = this.CreateChild<MeshInstance3D>( "Spline MeshInstance");
|
|
}
|
|
|
|
output.Mesh = mg.GenerateMesh();
|
|
|
|
|
|
}
|
|
}
|
|
} |