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();
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
  }
 | 
						|
} |