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