rj-action-library/Runtime/Procedural/ConnectionPin.cs

170 lines
3.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class ConnectionPin:Node3D
#if TOOLS
, GizmoDrawer
#endif
{
[Export]
public bool updateAlways = false;
[Export]
public Node3D root;
[Export]
public bool moveToMinX = false;
[Export]
public bool moveToMaxX = false;
[Export]
public bool moveToMinY = false;
[Export]
public bool moveToMaxY = false;
[Export]
public bool moveToMinZ = false;
[Export]
public bool moveToMaxZ = false;
[Export]
public float editorGizmoSize = 1;
float _editorGizmoSize = 1;
#if TOOLS
public void DrawGizmo( EditorNode3DGizmoPlugin gizmoPlugin, EditorNode3DGizmo gizmo )
{
gizmo.Clear();
var center = Vector3.Zero;
var up = Vector3.Up * editorGizmoSize;
var forward = Vector3.Forward * editorGizmoSize;
var right = Vector3.Right * editorGizmoSize;
var material = gizmoPlugin.GetMaterial( "main", gizmo );
gizmo.AddLines(
new Vector3[]
{
center, up,
center, -forward,
center, right,
center, -right,
right, -forward,
-right, -forward,
up, -forward,
up, -right,
up, right
},
material
);
}
public override void _Process( double delta )
{
var changed = false;
if ( editorGizmoSize != _editorGizmoSize )
{
_editorGizmoSize = editorGizmoSize;
changed = true;
}
if ( changed )
{
UpdateGizmos();
}
if ( ! ( moveToMinX || moveToMaxX || moveToMinY || moveToMaxY || moveToMinZ || moveToMaxZ ) )
{
return;
}
if ( root == null )
{
RJLog.Log( "No Root!" );
ClearFlags();
return;
}
var optionalBbounds = root.GetWorldBounds();
if ( optionalBbounds == null )
{
RJLog.Log( "No Bounds!" );
ClearFlags();
return;
}
var bounds = (Aabb) optionalBbounds;
if ( moveToMinX || moveToMaxX )
{
this.SetGlobalX( ( moveToMinX ? bounds.Position : bounds.End ).X );
}
if ( moveToMinY || moveToMaxY )
{
this.SetGlobalY( ( moveToMinY ? bounds.Position : bounds.End ).Y );
}
if ( moveToMinZ || moveToMaxZ )
{
this.SetGlobalZ( ( moveToMinZ ? bounds.Position : bounds.End ).Z );
}
ClearFlags();
}
void ClearFlags()
{
moveToMinX = false;
moveToMaxX = false;
moveToMinY = false;
moveToMaxY = false;
moveToMinZ = false;
moveToMaxZ = false;
}
#endif
public static readonly Quaternion YawFlipRotation = Quaternion.FromEuler( new Vector3( 0, 180, 0 ) / 180 * Mathf.Pi );
public static void Connect( Node3D target, Node3D targetPin, Node3D sourcePin )
{
var targetRotation = target.GetGlobalQuaternion();
var targetPinRotation = targetPin.GetGlobalQuaternion();
var pinToParent = targetPinRotation.GetDifference( targetRotation );
var forward = sourcePin.GlobalForward();
var up = sourcePin.GlobalUp();
var rotation = ConnectionPin.YawFlipRotation * pinToParent;
target.LookTowards( forward, up, rotation );
var offset = ( sourcePin.GlobalPosition - targetPin.GlobalPosition );
target.GlobalTranslate( offset );
}
}
}