311 lines
7.7 KiB
C#
311 lines
7.7 KiB
C#
|
|
using Godot;
|
||
|
|
using System.Text;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
|
||
|
|
namespace Rokojori
|
||
|
|
{
|
||
|
|
public static class Node3DExtensions
|
||
|
|
{
|
||
|
|
public static Vector3 ToLocalFromLocal( this Node3D self, Node3D from, Vector3 fromLocalPosition )
|
||
|
|
{
|
||
|
|
var world = from.ToGlobal( fromLocalPosition );
|
||
|
|
return self.ToLocal( world );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 ToLocalFromLocalDirection( this Node3D self, Node3D from, Vector3 fromLocalDirection )
|
||
|
|
{
|
||
|
|
var world = from.ToGlobalDirection( fromLocalDirection );
|
||
|
|
return self.ToLocalDirection( world );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 ToLocalDirection( this Node3D self, Vector3 globalDirection )
|
||
|
|
{
|
||
|
|
return self.GlobalTransform.Basis.Inverse() * globalDirection;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 ToGlobalDirection( this Node3D self, Vector3 localDirection )
|
||
|
|
{
|
||
|
|
return self.GlobalTransform.Basis * localDirection;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void LookTowards( this Node3D self, Vector3 direction )
|
||
|
|
{
|
||
|
|
self.LookAt( direction + self.GlobalPosition );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static float DistanceTo( this Node3D self, Node3D other )
|
||
|
|
{
|
||
|
|
return self.DirectionTowards( other ).Length();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 DirectionTowards( this Node3D self, Node3D other )
|
||
|
|
{
|
||
|
|
return ( other.GlobalPosition - self.GlobalPosition );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 DirectionTowards( this Node3D self, Vector3 other )
|
||
|
|
{
|
||
|
|
return ( other - self.GlobalPosition );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static bool IsInRange( this Node3D a, Node3D other, float distance )
|
||
|
|
{
|
||
|
|
return a.DistanceTo( other ) <= distance;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 GetLocalOrGlobalPosition( this Node3D node, bool global )
|
||
|
|
{
|
||
|
|
return global ? node.GlobalPosition : node.Position;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalOrGlobalPosition( this Node3D node, Vector3 position, bool global )
|
||
|
|
{
|
||
|
|
if ( global )
|
||
|
|
{
|
||
|
|
node.GlobalPosition = position;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
node.Position = position;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalOrGlobalRotation( this Node3D node, Vector3 rotation, bool global )
|
||
|
|
{
|
||
|
|
if ( global )
|
||
|
|
{
|
||
|
|
node.GlobalRotation = rotation;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
node.Rotation = rotation;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalPose( this Node3D node, Vector3 position, Quaternion rotation )
|
||
|
|
{
|
||
|
|
node.SetGlobalQuaternion( rotation );
|
||
|
|
node.GlobalPosition = position;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalPose( this Node3D node, Pose pose )
|
||
|
|
{
|
||
|
|
node.SetGlobalPose( pose.position, pose.rotation );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Pose GetGlobalPose( this Node3D node )
|
||
|
|
{
|
||
|
|
return Pose.From( node );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void CopyGlobalPoseFrom( this Node3D node, Node3D other )
|
||
|
|
{
|
||
|
|
node.SetGlobalPose( other.GetGlobalPose() );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalQuaternion( this Node3D node, Quaternion quaternion )
|
||
|
|
{
|
||
|
|
var localScale = node.Scale;
|
||
|
|
node.GlobalBasis = new Basis( quaternion );
|
||
|
|
node.Scale = localScale;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalQuaternion( this Node3D node, Quaternion quaternion )
|
||
|
|
{
|
||
|
|
var localScale = node.Scale;
|
||
|
|
node.Basis = new Basis( quaternion );
|
||
|
|
node.Scale = localScale;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void LookTowards( this Node3D node, Vector3 forwardDirection, Vector3 upDirection, Quaternion rotation )
|
||
|
|
{
|
||
|
|
node.LookTowards( forwardDirection, upDirection );
|
||
|
|
node.SetGlobalQuaternion( node.GlobalQuaternion() * rotation );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void LookTowards( this Node3D node, Vector3 forward, Vector3 up, Vector3? up2 = null )
|
||
|
|
{
|
||
|
|
if ( forward == up )
|
||
|
|
{
|
||
|
|
up = up2 == null ? Vector3.Back : (Vector3)up2;
|
||
|
|
}
|
||
|
|
|
||
|
|
node.LookAt( forward + node.GlobalPosition, up );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static Vector3 GetGlobalOffset( this Node3D node, Vector3 direction )
|
||
|
|
{
|
||
|
|
return direction.X * node.GlobalRight() +
|
||
|
|
direction.Y * node.GlobalUp() +
|
||
|
|
direction.Z * node.GlobalForward() ;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 GlobalForward( this Node3D node )
|
||
|
|
{
|
||
|
|
return -node.GlobalBasis.Z;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 GetPosition( this Node3D node, bool global = false )
|
||
|
|
{
|
||
|
|
return global ? node.GlobalPosition : node.Position;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 GlobalUp( this Node3D node )
|
||
|
|
{
|
||
|
|
return node.GlobalBasis.Y;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static Vector3 GlobalRight( this Node3D node )
|
||
|
|
{
|
||
|
|
return node.GlobalBasis.X;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalX( this Node3D node, float x )
|
||
|
|
{
|
||
|
|
var gp = node.GlobalPosition;
|
||
|
|
|
||
|
|
gp.X = x;
|
||
|
|
|
||
|
|
node.GlobalPosition = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalY( this Node3D node, float y )
|
||
|
|
{
|
||
|
|
var gp = node.GlobalPosition;
|
||
|
|
|
||
|
|
gp.Y = y;
|
||
|
|
|
||
|
|
node.GlobalPosition = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalZ( this Node3D node, float z )
|
||
|
|
{
|
||
|
|
var gp = node.GlobalPosition;
|
||
|
|
|
||
|
|
gp.Z = z;
|
||
|
|
|
||
|
|
node.GlobalPosition = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalX( this Node3D node, float x )
|
||
|
|
{
|
||
|
|
var gp = node.Position;
|
||
|
|
|
||
|
|
gp.X = x;
|
||
|
|
|
||
|
|
node.Position = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalY( this Node3D node, float y )
|
||
|
|
{
|
||
|
|
var gp = node.Position;
|
||
|
|
|
||
|
|
gp.Y = y;
|
||
|
|
|
||
|
|
node.Position = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetLocalZ( this Node3D node, float z )
|
||
|
|
{
|
||
|
|
var gp = node.Position;
|
||
|
|
|
||
|
|
gp.Z = z;
|
||
|
|
|
||
|
|
node.Position = gp;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector3 GetOrientationBasedGlobalOffset( this Node3D node, Vector3 offset )
|
||
|
|
{
|
||
|
|
return offset.X * node.GlobalRight() + offset.Y * node.GlobalUp() + offset.Z * node.GlobalForward();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static Box3 GetWorldBox( this Node3D node, bool onlyVisible = true )
|
||
|
|
{
|
||
|
|
var aabb = GetWorldBounds( node, onlyVisible );
|
||
|
|
|
||
|
|
return aabb == null ? null : ( (Aabb)aabb).ToBox3();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Aabb? GetWorldBounds( this Node3D node, bool onlyVisible = true )
|
||
|
|
{
|
||
|
|
return node.GetWorldBoundsFrom( onlyVisible );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Aabb? GetWorldBoundsFrom( this Node3D node, bool onlyVisible = true )
|
||
|
|
{
|
||
|
|
Aabb? worldBounds = null;
|
||
|
|
|
||
|
|
Nodes.ForEach<VisualInstance3D>( node,
|
||
|
|
( vi )=>
|
||
|
|
{
|
||
|
|
if ( onlyVisible && ! vi.IsVisibleInTree() )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var nBounds = vi.GetAabb();
|
||
|
|
|
||
|
|
nBounds.Size *= Math3D.GetGlobalUniScale( vi );
|
||
|
|
nBounds.Position += vi.GlobalPosition;
|
||
|
|
nBounds.End += vi.GlobalPosition;
|
||
|
|
|
||
|
|
worldBounds = worldBounds == null ? nBounds : ( ((Aabb)worldBounds).Merge( nBounds ) );
|
||
|
|
}
|
||
|
|
);
|
||
|
|
|
||
|
|
return worldBounds;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static Quaternion GlobalQuaternion( this Node3D self )
|
||
|
|
{
|
||
|
|
return self.GlobalBasis.GetRotationQuaternion();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Quaternion GlobalYawQuaterntion( this Node3D self )
|
||
|
|
{
|
||
|
|
return Math3D.RotateY( self.GlobalYawRadians() + Mathf.Pi );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static float GlobalYawDegrees( this Node3D node3D )
|
||
|
|
{
|
||
|
|
return Math3D.GlobalYawDegrees( node3D.GlobalForward() );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static float GlobalYawRadians( this Node3D node3D )
|
||
|
|
{
|
||
|
|
return Math3D.GlobalYaw( node3D.GlobalForward() );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Vector2 GlobalXZ( this Node3D n )
|
||
|
|
{
|
||
|
|
var v = n.GlobalPosition;
|
||
|
|
return new Vector2( v.X, v.Z );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalXZ( this Node3D n, Vector2 xz )
|
||
|
|
{
|
||
|
|
var p = n.GlobalPosition;
|
||
|
|
p.X = xz.X;
|
||
|
|
p.Z = xz.Y;
|
||
|
|
|
||
|
|
n.GlobalPosition = p;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalYaw( this Node3D n, float yawRadians )
|
||
|
|
{
|
||
|
|
n.SetGlobalQuaternion( Math3D.RotateY( yawRadians ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetGlobalYawDegrees( this Node3D n, float yawDegrees )
|
||
|
|
{
|
||
|
|
n.SetGlobalQuaternion( Math3D.RotateY( yawDegrees * MathX.DegreesToRadians ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|