105 lines
2.5 KiB
C#
105 lines
2.5 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 TubeShape:Node
|
|
{
|
|
[Export]
|
|
public Spline spline;
|
|
|
|
[Export]
|
|
public Node3D pivotPose;
|
|
|
|
[Export]
|
|
public float tubePosition;
|
|
|
|
[Export]
|
|
public float scale = 1f;
|
|
|
|
[Export]
|
|
public float widthScale = 1f;
|
|
|
|
[Export]
|
|
public float heightScale = 1f;
|
|
|
|
[Export]
|
|
public ShapeOrientationMode shapeOrientationMode = ShapeOrientationMode.Auto;
|
|
|
|
bool cached = false;
|
|
|
|
bool shapeForward = true;
|
|
SplineCurve radialShape;
|
|
|
|
|
|
public void ClearCache()
|
|
{
|
|
cached = false;
|
|
}
|
|
|
|
public Pose GetPose( bool undistort, int splineSegments, int radialSegments, Pose pose, Vector2 uv, Vector3 scale, Quaternion twistRotation )
|
|
{
|
|
if ( ! cached )
|
|
{
|
|
radialShape = spline.GetCurve();
|
|
shapeForward = true;
|
|
|
|
if ( pivotPose != null )
|
|
{
|
|
radialShape = radialShape.ApplyPose( Pose.InverseFrom( pivotPose ) );
|
|
}
|
|
|
|
radialShape = radialShape.CloneForXY();
|
|
|
|
if ( ShapeOrientationMode.Original != shapeOrientationMode )
|
|
{
|
|
if ( ShapeOrientationMode.Auto == shapeOrientationMode )
|
|
{
|
|
var path = radialShape.SampleXYPath( radialSegments );
|
|
shapeForward = path.isClockwise;
|
|
}
|
|
|
|
if ( ShapeOrientationMode.Reverse == shapeOrientationMode )
|
|
{
|
|
shapeForward = false;
|
|
}
|
|
|
|
}
|
|
|
|
cached = true;
|
|
}
|
|
|
|
|
|
scale.X *= widthScale * this.scale;
|
|
scale.Y *= heightScale * this.scale;
|
|
|
|
var radialT = ! shapeForward ? uv.X : ( 1f - uv.X );
|
|
radialT = undistort ?
|
|
radialShape.UtoT( radialT, splineSegments ) :
|
|
radialT;
|
|
|
|
var shapePosition = radialShape.PositionAt( radialT ) * scale;
|
|
var shapeTangent = radialShape.TangentAt( radialT, 1f / radialSegments ) * scale;
|
|
|
|
|
|
shapePosition = twistRotation * shapePosition;
|
|
shapeTangent = twistRotation * shapeTangent;
|
|
|
|
var angle = Math3D.AngleXY( shapeTangent ) + Mathf.Pi;
|
|
var rotation = Math3D.RotateZ( angle );
|
|
|
|
var combinedRotation = pose.rotation * rotation;
|
|
|
|
var rotatedShapePosition = Vector3.Zero;
|
|
|
|
rotatedShapePosition = pose.rotation * shapePosition;
|
|
|
|
return Pose.Create( rotatedShapePosition + pose.position, combinedRotation );
|
|
}
|
|
}
|
|
|
|
} |