UI + Procedural Geometry
This commit is contained in:
parent
9a07e22b05
commit
575431f868
|
@ -0,0 +1,89 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public abstract class GraphWalker<N> where N:class
|
||||||
|
{
|
||||||
|
public virtual int NumConnectedFrom( N node ){ return 0;}
|
||||||
|
public virtual N GetConnectedFrom( N node, int index ){ return default(N);}
|
||||||
|
|
||||||
|
public abstract int NumConnectedTo( N node );
|
||||||
|
public abstract N GetConnectedTo( N node, int index );
|
||||||
|
|
||||||
|
public int NumConnectedAll( N node )
|
||||||
|
{
|
||||||
|
return NumConnectedTo( node ) + NumConnectedFrom( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
public N GetConnected( N node, int index )
|
||||||
|
{
|
||||||
|
var fromConnections = NumConnectedFrom( node );
|
||||||
|
|
||||||
|
return index < fromConnections ? GetConnectedFrom( node, index ) : GetConnectedTo( node, index - fromConnections );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsConnectedTo( N source, N destination )
|
||||||
|
{
|
||||||
|
var processed = new HashSet<N>();
|
||||||
|
var toDo = new List<N>();
|
||||||
|
|
||||||
|
toDo.Add( source );
|
||||||
|
|
||||||
|
while ( toDo.Count > 0 )
|
||||||
|
{
|
||||||
|
var current = Lists.RemoveFirst( toDo );
|
||||||
|
|
||||||
|
if ( processed.Contains( current ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
processed.Add( current );
|
||||||
|
|
||||||
|
var numConnected = NumConnectedTo( current );
|
||||||
|
|
||||||
|
for ( int i = 0; i < numConnected; i++ )
|
||||||
|
{
|
||||||
|
var connected = GetConnected( current, i );
|
||||||
|
|
||||||
|
if ( connected == destination )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! processed.Contains( connected ) )
|
||||||
|
{
|
||||||
|
toDo.Add( connected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsDirectlyConnectedTo( N node, N other )
|
||||||
|
{
|
||||||
|
if ( node == null || other == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var connected = NumConnectedTo( node );
|
||||||
|
|
||||||
|
for ( int i = 0; i < connected; i++ )
|
||||||
|
{
|
||||||
|
if ( GetConnected( node, i ) == other )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -240,7 +240,7 @@ namespace Rokojori
|
||||||
return NextNonChild( node );
|
return NextNonChild( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
public N GetParent( N node, Func<N,bool> predicate )
|
public N GetInParents( N node, Func<N,bool> predicate )
|
||||||
{
|
{
|
||||||
var p = Parent( node );
|
var p = Parent( node );
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,13 @@ namespace Rokojori
|
||||||
GD.PrintRich( trace );
|
GD.PrintRich( trace );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LogMessageWithFullTrace( string message )
|
||||||
|
{
|
||||||
|
var trace = GetFullTrace();
|
||||||
|
GD.PrintRich("\n[b]" + message + "[/b]");
|
||||||
|
GD.PrintRich( trace );
|
||||||
|
}
|
||||||
|
|
||||||
static void LogErrorMessage( string message )
|
static void LogErrorMessage( string message )
|
||||||
{
|
{
|
||||||
var trace = GetTrace();
|
var trace = GetTrace();
|
||||||
|
@ -49,6 +56,11 @@ namespace Rokojori
|
||||||
GD.PrintRich( trace );
|
GD.PrintRich( trace );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string GetFullTrace()
|
||||||
|
{
|
||||||
|
return ( new System.Diagnostics.StackTrace( true ) ).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
static string GetTrace()
|
static string GetTrace()
|
||||||
{
|
{
|
||||||
var stackTrace = new System.Diagnostics.StackTrace( true );
|
var stackTrace = new System.Diagnostics.StackTrace( true );
|
||||||
|
@ -86,6 +98,23 @@ namespace Rokojori
|
||||||
return "[color=gray] " + trace + "[/color]" ;
|
return "[color=gray] " + trace + "[/color]" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LogWithFullTrace( params object[] objects)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
for ( int i = 0; i < objects.Length; i++ )
|
||||||
|
{
|
||||||
|
if ( i != 0 )
|
||||||
|
{
|
||||||
|
sb.Append( " " );
|
||||||
|
}
|
||||||
|
|
||||||
|
Stringify( objects[ i ], sb );
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessageWithFullTrace( sb.ToString() );
|
||||||
|
}
|
||||||
|
|
||||||
public static void Log( params object[] objects)
|
public static void Log( params object[] objects)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Capsule3
|
||||||
|
{
|
||||||
|
public Vector3 start = Vector3.Zero;
|
||||||
|
public Vector3 end = Vector3.Zero;
|
||||||
|
public float radius = 1;
|
||||||
|
|
||||||
|
public Capsule3( Vector3 start, Vector3 end, float radius )
|
||||||
|
{
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Capsule3 Copy()
|
||||||
|
{
|
||||||
|
return new Capsule3( start, end, radius );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 center
|
||||||
|
{
|
||||||
|
get { return start.Lerp( end, 0.5f ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line3 centerLine
|
||||||
|
{
|
||||||
|
get { return new Line3( start, end ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DistanceToPoint( Vector3 p )
|
||||||
|
{
|
||||||
|
var lineDistance = centerLine.DistanceToPoint( p );
|
||||||
|
return Mathf.Max( 0, lineDistance - radius );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public abstract class Curve3
|
||||||
|
{
|
||||||
|
float _gradientSamplingRange = Mathf.Pow( 10f, -13f );
|
||||||
|
public abstract Vector3 SampleAt( float t );
|
||||||
|
|
||||||
|
public virtual void SampleMultiple( int numSamples, List<Vector3> output )
|
||||||
|
{
|
||||||
|
SampleMultiple( new Range( 0, 1 ), numSamples, output );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SampleMultiple( Range range, int numSamples, List<Vector3> output )
|
||||||
|
{
|
||||||
|
|
||||||
|
var diff = range.length / ( numSamples - 1 ) ;
|
||||||
|
|
||||||
|
for ( var i = 0 ; i < numSamples; i++ )
|
||||||
|
{
|
||||||
|
var t = range.min + i * diff;
|
||||||
|
output.Add( SampleAt( t ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Vector3 GradientAt( float t )
|
||||||
|
{
|
||||||
|
|
||||||
|
return SampleAt( t + _gradientSamplingRange ) - SampleAt( t - _gradientSamplingRange );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual float ComputeLength( int numSamples )
|
||||||
|
{
|
||||||
|
return ComputeSubLength( Range.Of_01 , numSamples );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual float ComputeSubLength( Range range, int numSamples )
|
||||||
|
{
|
||||||
|
var diff = range.length / ( numSamples - 1 ) ;
|
||||||
|
var it = SampleAt( range.min );
|
||||||
|
var length = 0f;
|
||||||
|
|
||||||
|
for ( var i = 1 ; i < numSamples; i++ )
|
||||||
|
{
|
||||||
|
var t = range.min + i * diff;
|
||||||
|
var next = SampleAt( t );
|
||||||
|
length += ( next - it ).Length();
|
||||||
|
it = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int ComputeNumSamplesFor( Range range,
|
||||||
|
float minimumDistance, int minSamples = 2,
|
||||||
|
int numSamplesForLengthComputation = -1 )
|
||||||
|
{
|
||||||
|
if ( minSamples < 2 )
|
||||||
|
{ minSamples = 2; }
|
||||||
|
|
||||||
|
if ( numSamplesForLengthComputation <= 0 )
|
||||||
|
{ numSamplesForLengthComputation = minSamples * 4; }
|
||||||
|
|
||||||
|
float distance = ComputeSubLength( range, numSamplesForLengthComputation );
|
||||||
|
float numFloatingCuts = distance / minimumDistance;
|
||||||
|
int numSamples = Mathf.CeilToInt( numFloatingCuts );
|
||||||
|
|
||||||
|
return Mathf.Max( minSamples, numSamples );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Distance
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
P = Point,
|
||||||
|
S = Sphere
|
||||||
|
L = Line,
|
||||||
|
C = Capsule
|
||||||
|
|
||||||
|
|
||||||
|
P S L C
|
||||||
|
P y y y y
|
||||||
|
S y y y
|
||||||
|
L y y
|
||||||
|
C y
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static float Of( Vector3 a, Vector3 b )
|
||||||
|
{
|
||||||
|
return ( a - b ).Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Vector3 a, Sphere b )
|
||||||
|
{
|
||||||
|
return b.DistanceToPoint( a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Sphere a, Vector3 b )
|
||||||
|
{
|
||||||
|
return Of( b, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Vector3 a, Line3 b )
|
||||||
|
{
|
||||||
|
return b.DistanceToPoint( a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Line3 b, Vector3 a )
|
||||||
|
{
|
||||||
|
return Of( a, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Vector3 a, Capsule3 b )
|
||||||
|
{
|
||||||
|
return b.DistanceToPoint( a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Capsule3 a, Vector3 b )
|
||||||
|
{
|
||||||
|
return Of( b, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Sphere a, Sphere b )
|
||||||
|
{
|
||||||
|
return a.DistanceToSphere( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Sphere a, Line3 b )
|
||||||
|
{
|
||||||
|
var centerDistance = Of( a.center, b );
|
||||||
|
return Mathf.Max( centerDistance - a.radius, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Line3 a, Sphere b )
|
||||||
|
{
|
||||||
|
return Of( b, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Sphere a, Capsule3 b )
|
||||||
|
{
|
||||||
|
var centerDistance = Of( a.center, b );
|
||||||
|
return Mathf.Max( centerDistance - a.radius, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Capsule3 a, Sphere b )
|
||||||
|
{
|
||||||
|
return Of( b, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Line3 a, Line3 b )
|
||||||
|
{
|
||||||
|
return a.DistanceToLine( b );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Line3 a, Capsule3 b )
|
||||||
|
{
|
||||||
|
var lineDistance = Of( a, b.centerLine );
|
||||||
|
return Mathf.Max( 0, lineDistance - b.radius );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Capsule3 a, Line3 b )
|
||||||
|
{
|
||||||
|
return Of( b, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Of( Capsule3 a, Capsule3 b )
|
||||||
|
{
|
||||||
|
var lineDistance = Of( a.centerLine, b.centerLine );
|
||||||
|
return Mathf.Max( 0, lineDistance - ( a.radius + b.radius ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public class SubdivisionData
|
||||||
|
{
|
||||||
|
public Vector3 point;
|
||||||
|
public bool isCorner;
|
||||||
|
public Vector3 direction;
|
||||||
|
|
||||||
|
public SubdivisionData( Vector3 p, Vector3 d, bool corner = false )
|
||||||
|
{
|
||||||
|
point = p;
|
||||||
|
direction = d;
|
||||||
|
isCorner = corner;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LerpCurveClosestToPointResult
|
||||||
|
{
|
||||||
|
public float parameter;
|
||||||
|
public float distance;
|
||||||
|
public Vector3 point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LerpCurve3:Curve3
|
||||||
|
{
|
||||||
|
List<Vector3> list;
|
||||||
|
|
||||||
|
public LerpCurve3( List<Vector3> list )
|
||||||
|
{
|
||||||
|
this.list = list;
|
||||||
|
|
||||||
|
if ( list.Count == 0 )
|
||||||
|
{
|
||||||
|
RJLog.Log( "LERP CURVE WITH EMPTY LIST" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float ComputeLength( int numSamples )
|
||||||
|
{
|
||||||
|
var length = 0f;
|
||||||
|
var end = list.Count - 1;
|
||||||
|
|
||||||
|
for ( int i = 0; i < end; i++ )
|
||||||
|
{
|
||||||
|
var p0 = list[ i ];
|
||||||
|
var p1 = list[ i + 1 ];
|
||||||
|
|
||||||
|
length += p0.DistanceTo( p1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float UndistortParameter( float parameter )
|
||||||
|
{
|
||||||
|
var completeLength = ComputeLength( 0 );
|
||||||
|
|
||||||
|
var end = list.Count - 1;
|
||||||
|
var normalizer = 1f / ( list.Count - 1 );
|
||||||
|
|
||||||
|
var length = 0f;
|
||||||
|
|
||||||
|
for ( int i = 0; i < end; i++ )
|
||||||
|
{
|
||||||
|
var p0 = list[ i ];
|
||||||
|
var p1 = list[ i + 1 ];
|
||||||
|
var t0 = i * normalizer;
|
||||||
|
var t1 = ( i + 1 ) * normalizer;
|
||||||
|
var distance = p0.DistanceTo( p1 );
|
||||||
|
|
||||||
|
if ( t0 <= parameter && parameter <= t1 )
|
||||||
|
{
|
||||||
|
length += distance * ( parameter - t0 );
|
||||||
|
return length / completeLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
length += distance;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubdivisionData> Subdivide( float distance, bool close )
|
||||||
|
{
|
||||||
|
var output = new List<SubdivisionData>();
|
||||||
|
|
||||||
|
var num = list.Count - 1;
|
||||||
|
|
||||||
|
if ( close )
|
||||||
|
{
|
||||||
|
num ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( var i = 0; i < num; i++ )
|
||||||
|
{
|
||||||
|
var start = list[ i ];
|
||||||
|
var end = list[ i == list.Count ? 0 : i + 1 ];
|
||||||
|
|
||||||
|
var dir = ( end - start );
|
||||||
|
var length = dir.Length();
|
||||||
|
var samples = Mathf.CeilToInt( length / distance );
|
||||||
|
|
||||||
|
output.Add( new SubdivisionData( start, dir, true ) );
|
||||||
|
|
||||||
|
for ( int j = 1; j < samples; j++ )
|
||||||
|
{
|
||||||
|
var samplePoint = j / (float) samples;
|
||||||
|
var point = start.Lerp( end, samplePoint );
|
||||||
|
output.Add( new SubdivisionData( point, dir ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( ! close )
|
||||||
|
{
|
||||||
|
var start = list[ list.Count - 2];
|
||||||
|
var end = list[ list.Count - 1];
|
||||||
|
|
||||||
|
var dir = ( end - start );
|
||||||
|
|
||||||
|
output.Add( new SubdivisionData( end, dir, true ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var dirCount = close ? output.Count : ( output.Count - 1 );
|
||||||
|
|
||||||
|
for ( int i = 0; i < dirCount; i++ )
|
||||||
|
{
|
||||||
|
var next = i == output.Count ? 0 : i + 1;
|
||||||
|
output[ i ].direction = output[ next ].point - output[ i ].point;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Vector3 SampleAt( float t )
|
||||||
|
{
|
||||||
|
if ( t < 0 )
|
||||||
|
{
|
||||||
|
return list[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( t >= 1 )
|
||||||
|
{
|
||||||
|
return list[ list.Count - 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( list.Count == 1 )
|
||||||
|
{
|
||||||
|
return list[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var listIndex = t * ( list.Count - 1 );
|
||||||
|
var flooredIndex = (int) Mathf.Floor( listIndex );
|
||||||
|
|
||||||
|
var lerpAmount = listIndex - flooredIndex;
|
||||||
|
|
||||||
|
if ( flooredIndex < 0 || ( flooredIndex >= list.Count - 1 ) )
|
||||||
|
{
|
||||||
|
RJLog.Log( "Out of range index:",flooredIndex, " t:", t, " listIndex", listIndex, "Count:", list.Count );
|
||||||
|
}
|
||||||
|
|
||||||
|
var lower = list[ flooredIndex ];
|
||||||
|
var upper = list[ flooredIndex + 1 ];
|
||||||
|
|
||||||
|
return Math3D.LerpUnclamped( lower, upper, lerpAmount );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public LerpCurve3 FromRange( Curve3 curve, Range range, int numSamples )
|
||||||
|
{
|
||||||
|
var points = new List<Vector3>();
|
||||||
|
curve.SampleMultiple( range, numSamples, points );
|
||||||
|
return new LerpCurve3( points );
|
||||||
|
}
|
||||||
|
|
||||||
|
public LerpCurve3 From( Curve3 curve, int numSamples )
|
||||||
|
{
|
||||||
|
return FromRange( curve, Range.Of_01, numSamples );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LerpCurve3 FromPoints( Vector3 first, Vector3 second, params Vector3[] others )
|
||||||
|
{
|
||||||
|
var points = new List<Vector3>();
|
||||||
|
points.Add( first );
|
||||||
|
points.Add( second );
|
||||||
|
points.AddRange( others );
|
||||||
|
|
||||||
|
return new LerpCurve3( points );
|
||||||
|
}
|
||||||
|
|
||||||
|
Line3 line;
|
||||||
|
|
||||||
|
public void GetClosest( Vector3 point, LerpCurveClosestToPointResult result )
|
||||||
|
{
|
||||||
|
var closestDistance = float.MaxValue;
|
||||||
|
Vector3 closestPoint = Vector3.Zero;
|
||||||
|
var closestParameter = 0f;
|
||||||
|
|
||||||
|
if ( line == null )
|
||||||
|
{
|
||||||
|
line = new Line3( Vector3.Zero, Vector3.Zero );
|
||||||
|
}
|
||||||
|
|
||||||
|
var end = list.Count - 1;
|
||||||
|
|
||||||
|
var parameterNormalizer = 1f / ( list.Count - 1f );
|
||||||
|
|
||||||
|
for ( int i = 0; i < end; i++ )
|
||||||
|
{
|
||||||
|
line.start = list[ i ];
|
||||||
|
line.end = list[ i + 1 ];
|
||||||
|
|
||||||
|
var currentParameter = line.ClostestParameterToPoint( point );
|
||||||
|
var currentClosestPoint = line.GetPointAtParameter( currentParameter );
|
||||||
|
var currentDistance = ( point - currentClosestPoint ).LengthSquared();
|
||||||
|
|
||||||
|
if ( currentDistance < closestDistance )
|
||||||
|
{
|
||||||
|
closestDistance = currentDistance;
|
||||||
|
closestPoint = currentClosestPoint;
|
||||||
|
closestParameter = ( currentParameter + i ) * parameterNormalizer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.distance = Mathf.Sqrt( closestDistance );
|
||||||
|
result.point = closestPoint;
|
||||||
|
result.parameter = closestParameter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Line3:Curve3
|
||||||
|
{
|
||||||
|
public Vector3 start = Vector3.Zero;
|
||||||
|
public Vector3 end = Vector3.Zero;
|
||||||
|
|
||||||
|
public Line3( Vector3 start, Vector3 end )
|
||||||
|
{
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Vector3 SampleAt( float t )
|
||||||
|
{
|
||||||
|
return start.Lerp( end, t );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line3 Copy( )
|
||||||
|
{
|
||||||
|
return new Line3( start, end );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 direction { get { return end - start; } }
|
||||||
|
|
||||||
|
public float length { get { return direction.Length(); } }
|
||||||
|
|
||||||
|
public Vector3 GetPointAtParameter( float t )
|
||||||
|
{
|
||||||
|
return start + direction * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 center{ get { return ( start + end ) * 0.5f; } }
|
||||||
|
|
||||||
|
public Line3 ScaleFromCenter( float scale )
|
||||||
|
{
|
||||||
|
var lineCenter = center;
|
||||||
|
var halfDirection = direction * ( 0.5f * scale );
|
||||||
|
|
||||||
|
var scaledStart = lineCenter - halfDirection;
|
||||||
|
var scaledEnd = lineCenter + halfDirection;
|
||||||
|
|
||||||
|
return new Line3( scaledStart, scaledEnd );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line3 ChangeLengthFromCenter( float lengthChange )
|
||||||
|
{
|
||||||
|
var lineCenter = center;
|
||||||
|
var halfDirection = direction * 0.5f;
|
||||||
|
var length = halfDirection.Length();
|
||||||
|
length += lengthChange * 0.5f;
|
||||||
|
|
||||||
|
halfDirection = halfDirection.Normalized() * length;
|
||||||
|
|
||||||
|
var scaledStart = lineCenter - halfDirection;
|
||||||
|
var scaledEnd = lineCenter + halfDirection;
|
||||||
|
|
||||||
|
return new Line3( scaledStart, scaledEnd );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Line3 SetLengthFromCenter( float length )
|
||||||
|
{
|
||||||
|
var lineCenter = center;
|
||||||
|
var halfDirection = direction.Normalized() * ( length * 0.5f );
|
||||||
|
|
||||||
|
var scaledStart = lineCenter - halfDirection;
|
||||||
|
var scaledEnd = lineCenter + halfDirection;
|
||||||
|
|
||||||
|
return new Line3( scaledStart, scaledEnd );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Vector3 ClosestPointToPoint( Vector3 point )
|
||||||
|
{
|
||||||
|
var parameter = MathX.Clamp01( ClostestParameterToPoint( point ) );
|
||||||
|
return GetPointAtParameter( parameter );
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ClostestParameterToPoint( Vector3 point )
|
||||||
|
{
|
||||||
|
var startP = point - start;
|
||||||
|
var startEnd = end - start;
|
||||||
|
var startEnd2 = startEnd.Dot( startEnd );
|
||||||
|
var startEnd_startP = startEnd.Dot( startP );
|
||||||
|
|
||||||
|
if ( startEnd2 == 0 )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var t = startEnd_startP / startEnd2;
|
||||||
|
|
||||||
|
return t;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DistanceToPoint( Vector3 point )
|
||||||
|
{
|
||||||
|
return ( point - ClosestPointToPoint( point ) ).Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public float DistanceToLine( Line3 s )
|
||||||
|
{
|
||||||
|
var points = ClosestPointsToLine( s );
|
||||||
|
return ( points[ 1 ] - points[ 0 ] ).Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3[] ClosestPointsToLine( Line3 s )
|
||||||
|
{
|
||||||
|
var parameters = ClosestParametersToLine( s );
|
||||||
|
var x = this.GetPointAtParameter( parameters.X );
|
||||||
|
var y = s.GetPointAtParameter( parameters.Y );
|
||||||
|
|
||||||
|
return new Vector3[]{ x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 ClosestParametersToLine( Line3 s )
|
||||||
|
{
|
||||||
|
float epsilon = 0.00000001f;
|
||||||
|
|
||||||
|
var u = this.direction;
|
||||||
|
var v = s.direction;
|
||||||
|
var w = start - s.start;
|
||||||
|
|
||||||
|
var a = u.Dot( u );
|
||||||
|
var b = u.Dot( v );
|
||||||
|
var c = v.Dot( v );
|
||||||
|
var d = u.Dot( w );
|
||||||
|
var e = v.Dot( w );
|
||||||
|
|
||||||
|
var DD = a * c - b * b;
|
||||||
|
|
||||||
|
var sc = 0f;
|
||||||
|
var sN = 0f;
|
||||||
|
var sD = 0f;
|
||||||
|
|
||||||
|
var tc = 0f;
|
||||||
|
var tN = 0f;
|
||||||
|
var tD = 0f;
|
||||||
|
|
||||||
|
sD = DD;
|
||||||
|
tD = DD;
|
||||||
|
|
||||||
|
if ( DD < epsilon )
|
||||||
|
{
|
||||||
|
sN = 0.0f;
|
||||||
|
sD = 1.0f;
|
||||||
|
tN = e;
|
||||||
|
tD = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sN = b * e - c * d ;
|
||||||
|
tN = a * e - b * d ;
|
||||||
|
|
||||||
|
if ( sN < 0.0f )
|
||||||
|
{
|
||||||
|
sN = 0.0f;
|
||||||
|
tN = e;
|
||||||
|
tD = c;
|
||||||
|
}
|
||||||
|
else if ( sN > sD )
|
||||||
|
{
|
||||||
|
sN = sD;
|
||||||
|
tN = e + b;
|
||||||
|
tD = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( tN < 0f || tN > tD )
|
||||||
|
{
|
||||||
|
var tN_bigger_tD = tN >= 0f && tN > tD;
|
||||||
|
|
||||||
|
tN = tN_bigger_tD ? tD : 0f;
|
||||||
|
|
||||||
|
var inbetween = tN_bigger_tD ? ( -d + b ) : ( -d );
|
||||||
|
var isSmaller = inbetween < 0;
|
||||||
|
var isBigger = inbetween > a;
|
||||||
|
|
||||||
|
sN = isSmaller ? 0f : isBigger ? sD : inbetween;
|
||||||
|
sD = ! isSmaller && ! isBigger ? a : sD;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = Mathf.Abs( sN ) < epsilon ? 0f : sN / sD;
|
||||||
|
tc = Mathf.Abs( tN ) < epsilon ? 0f : tN / tD;
|
||||||
|
|
||||||
|
return new Vector2( sc, tc );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Sphere
|
||||||
|
{
|
||||||
|
public Vector3 center = Vector3.Zero;
|
||||||
|
public float radius = 1;
|
||||||
|
|
||||||
|
public Sphere( Vector3 center, float radius )
|
||||||
|
{
|
||||||
|
this.center = center;
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sphere Copy()
|
||||||
|
{
|
||||||
|
return new Sphere( center, radius );
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DistanceToPoint( Vector3 point )
|
||||||
|
{
|
||||||
|
return Mathf.Max( 0, ( point - center ).Length() - radius );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsPoint( Vector3 point )
|
||||||
|
{
|
||||||
|
return DistanceToPoint( point ) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DistanceToSphere( Sphere sphere )
|
||||||
|
{
|
||||||
|
var distance = sphere.center - center;
|
||||||
|
var radiusBoth = sphere.radius + radius;
|
||||||
|
return Mathf.Max( 0, distance.Length() - radiusBoth );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IntersectsSphere( Sphere sphere )
|
||||||
|
{
|
||||||
|
return DistanceToSphere( sphere ) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Box3 CreateBox()
|
||||||
|
{
|
||||||
|
var offset = radius * Vector3.One;
|
||||||
|
return Box3.Create( center -offset, center + offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public enum TriangleSide
|
||||||
|
{
|
||||||
|
AB,
|
||||||
|
BC,
|
||||||
|
CA
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TriangleSides
|
||||||
|
{
|
||||||
|
public static readonly TriangleSide[] ALL =
|
||||||
|
{
|
||||||
|
TriangleSide.AB,
|
||||||
|
TriangleSide.BC,
|
||||||
|
TriangleSide.CA
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Triangle3
|
||||||
|
{
|
||||||
|
public Vector3 a;
|
||||||
|
public Vector3 b;
|
||||||
|
public Vector3 c;
|
||||||
|
|
||||||
|
public Triangle3( Vector3 a, Vector3 b, Vector3 c )
|
||||||
|
{
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float perimeter
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var sideA = ( b - a ).Length();
|
||||||
|
var sideB = ( c - b ).Length();
|
||||||
|
var sideC = ( a - c ).Length();
|
||||||
|
|
||||||
|
return sideA + sideB + sideC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float semiperimeter
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return perimeter * 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float ComputeTriangleArea( Vector3 a, Vector3 b, Vector3 c )
|
||||||
|
{
|
||||||
|
var sideA = ( b - a ).Length();
|
||||||
|
var sideB = ( c - b ).Length();
|
||||||
|
var sideC = ( a - c ).Length();
|
||||||
|
|
||||||
|
|
||||||
|
var perimeter = sideA + sideB + sideC;
|
||||||
|
var semiperimeter = 0.5f * perimeter;
|
||||||
|
var areaValue = Mathf.Sqrt( semiperimeter * ( semiperimeter - sideA )
|
||||||
|
* ( semiperimeter - sideB )
|
||||||
|
* ( semiperimeter - sideC )) ;
|
||||||
|
|
||||||
|
return areaValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float area
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ComputeTriangleArea( a, b, c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Line3 GetSide( TriangleSide side )
|
||||||
|
{
|
||||||
|
switch ( side )
|
||||||
|
{
|
||||||
|
case TriangleSide.AB: return new Line3( a, b );
|
||||||
|
case TriangleSide.BC: return new Line3( b, c );
|
||||||
|
case TriangleSide.CA: return new Line3( c, a );
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,16 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
public class Math3D
|
public class Math3D
|
||||||
{
|
{
|
||||||
|
public static Vector3 LerpUnclamped( Vector3 a, Vector3 b, float amount )
|
||||||
|
{
|
||||||
|
return a + amount * ( b - a );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 LerpClamped( Vector3 a, Vector3 b, float amount )
|
||||||
|
{
|
||||||
|
return LerpUnclamped( a, b, MathX.Clamp01( amount ) );
|
||||||
|
}
|
||||||
|
|
||||||
public static Quaternion GetGlobalRotation( Node3D node )
|
public static Quaternion GetGlobalRotation( Node3D node )
|
||||||
{
|
{
|
||||||
return node.GlobalBasis.GetRotationQuaternion();
|
return node.GlobalBasis.GetRotationQuaternion();
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public class RationalCubicBezier
|
||||||
|
{
|
||||||
|
public static float Compute(
|
||||||
|
float t,
|
||||||
|
float p0, float p1, float p2, float p3,
|
||||||
|
float w0, float w1, float w2, float w3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var bp0 = ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * w0;
|
||||||
|
var bp1 = 3 * ( 1 - t ) * ( 1 - t ) * t * w1;
|
||||||
|
var bp2 = 3 * ( 1 - t ) * t * t * w2;
|
||||||
|
var bp3 = t * t * t * w3;
|
||||||
|
|
||||||
|
var weighted = p0 * bp0 + p1 * bp1 + p2 * bp2 + p3 * bp3;
|
||||||
|
|
||||||
|
var projection = bp0 + bp1 + bp2 + bp3;
|
||||||
|
|
||||||
|
return weighted / projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 Compute(
|
||||||
|
float t,
|
||||||
|
Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3,
|
||||||
|
float w0, float w1, float w2, float w3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var bp0 = ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * w0;
|
||||||
|
var bp1 = 3 * ( 1 - t ) * ( 1 - t ) * t * w1;
|
||||||
|
var bp2 = 3 * ( 1 - t ) * t * t * w2;
|
||||||
|
var bp3 = t * t * t * w3;
|
||||||
|
|
||||||
|
var weighted = p0 * bp0 + p1 * bp1 + p2 * bp2 + p3 * bp3;
|
||||||
|
|
||||||
|
var projection = bp0 + bp1 + bp2 + bp3;
|
||||||
|
|
||||||
|
return weighted / projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 Compute(
|
||||||
|
float t,
|
||||||
|
Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3,
|
||||||
|
float w0, float w1, float w2, float w3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var bp0 = ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * w0;
|
||||||
|
var bp1 = 3 * ( 1 - t ) * ( 1 - t ) * t * w1;
|
||||||
|
var bp2 = 3 * ( 1 - t ) * t * t * w2;
|
||||||
|
var bp3 = t * t * t * w3;
|
||||||
|
|
||||||
|
var weighted = p0 * bp0 + p1 * bp1 + p2 * bp2 + p3 * bp3;
|
||||||
|
|
||||||
|
var projection = bp0 + bp1 + bp2 + bp3;
|
||||||
|
|
||||||
|
return weighted / projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Vector2 Compute( float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3 )
|
||||||
|
{
|
||||||
|
var bp0 = ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * p0.Z;
|
||||||
|
var bp1 = 3 * ( 1 - t ) * ( 1 - t ) * t * p1.Z;
|
||||||
|
var bp2 = 3 * ( 1 - t ) * t * t * p2.Z;
|
||||||
|
var bp3 = t * t * t * p3.Z;
|
||||||
|
|
||||||
|
var weighted = p0 * bp0 + p1 * bp1 + p2 * bp2 + p3 * bp3;
|
||||||
|
|
||||||
|
var projection = bp0 + bp1 + bp2 + bp3;
|
||||||
|
|
||||||
|
var result = weighted / projection;
|
||||||
|
|
||||||
|
return new Vector2( result.X, result.Y );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 Compute( float t, Vector4 p0, Vector4 p1, Vector4 p2, Vector4 p3 )
|
||||||
|
{
|
||||||
|
var bp0 = ( 1 - t ) * ( 1 - t ) * ( 1 - t ) * p0.W;
|
||||||
|
var bp1 = 3 * ( 1 - t ) * ( 1 - t ) * t * p1.W;
|
||||||
|
var bp2 = 3 * ( 1 - t ) * t * t * p2.W;
|
||||||
|
var bp3 = t * t * t * p3.W;
|
||||||
|
|
||||||
|
var weighted = p0 * bp0 + p1 * bp1 + p2 * bp2 + p3 * bp3;
|
||||||
|
|
||||||
|
var projection = bp0 + bp1 + bp2 + bp3;
|
||||||
|
|
||||||
|
var result = weighted / projection;
|
||||||
|
|
||||||
|
return new Vector3( result.X, result.Y, result.Z );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
Match: \.magnitude
|
||||||
|
Replace: .Length()
|
||||||
|
|
||||||
|
Match: \.normalized
|
||||||
|
Replace: .Normalized()
|
||||||
|
|
||||||
|
Match: Vector3\.(Lerp|Dot)\(\s*(\w+)\s*,\s*
|
||||||
|
Replace: $2.$1(
|
||||||
|
|
||||||
|
Match: Vector3\.Distance\(\s*(\w+)\s*,\s*
|
||||||
|
Replace: $1.DistanceTo(
|
||||||
|
|
||||||
|
Match: \.x
|
||||||
|
Replace: .X
|
||||||
|
|
||||||
|
Match: \.Y
|
||||||
|
Replace: .Y
|
||||||
|
|
||||||
|
Match: \.z
|
||||||
|
Replace: .Z
|
|
@ -0,0 +1,138 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class MeshGeometry
|
||||||
|
{
|
||||||
|
public List<Vector3> vertices;
|
||||||
|
public List<int> indices;
|
||||||
|
|
||||||
|
public List<Vector3> normals;
|
||||||
|
public List<Vector2> uvs;
|
||||||
|
public List<Vector2> uv2s;
|
||||||
|
public List<Color> colors;
|
||||||
|
|
||||||
|
|
||||||
|
public void Initialize( bool normals = true, bool uvs = true, bool colors = false, bool uvs2 = false)
|
||||||
|
{
|
||||||
|
this.vertices = new List<Vector3>();
|
||||||
|
this.indices = new List<int>();
|
||||||
|
|
||||||
|
this.normals = normals ? new List<Vector3>() : null;
|
||||||
|
this.uvs = uvs ? new List<Vector2>() : null;
|
||||||
|
this.uv2s = uvs2 ? new List<Vector2>() : null;
|
||||||
|
this.colors = colors ? new List<Color>() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTriangle(
|
||||||
|
Vector3 va, Vector3 vb, Vector3 vc,
|
||||||
|
Vector3 na, Vector3 nb, Vector3 nc,
|
||||||
|
Vector2 uva, Vector2 uvb, Vector2 uvc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var index = vertices.Count;
|
||||||
|
Lists.Add( vertices, va, vb, vc );
|
||||||
|
Lists.Add( normals, na, nb, nc );
|
||||||
|
Lists.Add( uvs, uva, uvb, uvc );
|
||||||
|
Lists.Add( indices, index, index + 1, index + 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddQuad(
|
||||||
|
Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd,
|
||||||
|
Vector3 na, Vector3 nb, Vector3 nc, Vector3 nd,
|
||||||
|
Vector2 uva, Vector2 uvb, Vector2 uvc, Vector2 uvd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddTriangle( va, vb, vc, na, nb, nc, uva, uvb, uvc );
|
||||||
|
AddTriangle( vc, vd, va, nc, nd, na, uvc, uvd, uva );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTriangle(
|
||||||
|
Vector3 va, Vector3 vb, Vector3 vc,
|
||||||
|
Vector2 uva, Vector2 uvb, Vector2 uvc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var n = Vector3.Up;
|
||||||
|
|
||||||
|
AddTriangle( va, vb, vc,
|
||||||
|
n, n, n,
|
||||||
|
uva, uvb, uvc );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddQuad(
|
||||||
|
Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd,
|
||||||
|
Vector2 uva, Vector2 uvb, Vector2 uvc, Vector2 uvd
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
AddTriangle( va, vb, vc, uva, uvb, uvc );
|
||||||
|
AddTriangle( vc, vd, va, uvc, uvd, uva );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddTriangle( Vector3 va, Vector3 vb, Vector3 vc )
|
||||||
|
{
|
||||||
|
var n = Vector3.Up;
|
||||||
|
var uv = Vector2.Zero;
|
||||||
|
|
||||||
|
AddTriangle( va, vb, vc, n, n, n, uv, uv, uv );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddQuad( Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd )
|
||||||
|
{
|
||||||
|
AddTriangle( va, vb, vc );
|
||||||
|
AddTriangle( vc, vd, va );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ArrayMesh Generate( Mesh.PrimitiveType type = Mesh.PrimitiveType.Triangles, ArrayMesh arrayMesh = null )
|
||||||
|
{
|
||||||
|
if ( arrayMesh == null )
|
||||||
|
{
|
||||||
|
arrayMesh = new ArrayMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
var surfaceArray = new Godot.Collections.Array();
|
||||||
|
surfaceArray.Resize( (int) Mesh.ArrayType.Max );
|
||||||
|
|
||||||
|
if ( vertices != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.Vertex ] = vertices.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( normals != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.Normal ] = normals.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( uvs != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.TexUV ] = uvs.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( uv2s != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.TexUV2 ] = uv2s.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( colors != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.Color ] = colors.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( indices != null )
|
||||||
|
{
|
||||||
|
surfaceArray[ (int) Mesh.ArrayType.Index ] = indices.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayMesh.AddSurfaceFromArrays( Mesh.PrimitiveType.Triangles, surfaceArray );
|
||||||
|
|
||||||
|
return arrayMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ using System;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
public abstract class RandomEngine
|
public abstract class RandomEngine
|
||||||
{
|
{
|
||||||
public abstract float Next();
|
public abstract float Next();
|
||||||
|
|
||||||
|
@ -208,6 +208,106 @@ namespace Rokojori
|
||||||
|
|
||||||
return list[ index ];
|
return list[ index ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T RemoveFrom<T>( List<T> list )
|
||||||
|
{
|
||||||
|
if ( list.Count == 0 )
|
||||||
|
{
|
||||||
|
return default ( T );
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = this.IntegerExclusive( 0, list.Count );
|
||||||
|
|
||||||
|
var item = list[ index ];
|
||||||
|
|
||||||
|
list.RemoveAt( index );
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveMutlipleFrom<T>( List<T> list, int amount )
|
||||||
|
{
|
||||||
|
if ( amount >= list.Count )
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new List<T>();
|
||||||
|
|
||||||
|
for ( int i = 0; i < amount; i++ )
|
||||||
|
{
|
||||||
|
var itemIndex = this.IntegerExclusive( 0, list.Count );
|
||||||
|
var item = list[ itemIndex ];
|
||||||
|
list.RemoveAt( itemIndex );
|
||||||
|
items.Add( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T RemoveWeightedFrom<T>( List<T> list, List<float> weights )
|
||||||
|
{
|
||||||
|
if ( list == null || list.Count == 0 )
|
||||||
|
{
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( list.Count == 1 )
|
||||||
|
{
|
||||||
|
return list[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
var weightedSelection = RemoveMultipleWeightedFrom( list, weights, 1 );
|
||||||
|
|
||||||
|
|
||||||
|
return weightedSelection[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> RemoveMultipleWeightedFrom<T>( List<T> list, List<float> weights, int amount )
|
||||||
|
{
|
||||||
|
if ( amount >= list.Count )
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sumWeights = 0f;
|
||||||
|
|
||||||
|
weights.ForEach( w => sumWeights += w );
|
||||||
|
|
||||||
|
var selection = new List<T>();
|
||||||
|
|
||||||
|
for ( int i = 0; i < amount; i++ )
|
||||||
|
{
|
||||||
|
var number = Range( 0, sumWeights );
|
||||||
|
|
||||||
|
var index = _FindElementIndexWithWeights( weights, Range( 0, sumWeights ) );
|
||||||
|
var element = list[ index ];
|
||||||
|
var weight = weights[ index ];
|
||||||
|
list.RemoveAt( index );
|
||||||
|
sumWeights -= weight;
|
||||||
|
selection.Add( element );
|
||||||
|
}
|
||||||
|
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _FindElementIndexWithWeights( List<float> weights, float value )
|
||||||
|
{
|
||||||
|
var limit = 0f;
|
||||||
|
|
||||||
|
for ( int i = 0; i < weights.Count; i++ )
|
||||||
|
{
|
||||||
|
var before = limit;
|
||||||
|
limit += weights[ i ];
|
||||||
|
|
||||||
|
if ( before <= value && value < limit )
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return weights.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class SeedableRandomEngine:RandomEngine
|
public abstract class SeedableRandomEngine:RandomEngine
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
vec3 localToWorld( vec3 _VERTEX, mat4 _MODEL_MATRIX )
|
||||||
|
{
|
||||||
|
return ( _MODEL_MATRIX * vec4( _VERTEX, 1.0 ) ).xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 worldToLocal( vec3 _VERTEX, mat4 _MODEL_MATRIX )
|
||||||
|
{
|
||||||
|
return ( inverse( _MODEL_MATRIX ) * vec4( _VERTEX, 1.0 ) ).xyz;
|
||||||
|
}
|
|
@ -36,6 +36,28 @@ namespace Rokojori
|
||||||
return list.IndexOf( item ) != - 1;
|
return list.IndexOf( item ) != - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static T RemoveAt<T>( List<T> list, int index )
|
||||||
|
{
|
||||||
|
if ( list.Count == 0 || index < 0 || ( index > ( list.Count - 1 ) ) )
|
||||||
|
{
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
var first = list[ index ];
|
||||||
|
list.RemoveAt( index );
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T RemoveFirst<T>( List<T> list )
|
||||||
|
{
|
||||||
|
return RemoveAt( list, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T RemoveLast<T>( List<T> list )
|
||||||
|
{
|
||||||
|
return RemoveAt( list, list.Count - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
public static T Pop<T>( List<T> list )
|
public static T Pop<T>( List<T> list )
|
||||||
{
|
{
|
||||||
if ( list.Count == 0 ){ return default(T); }
|
if ( list.Count == 0 ){ return default(T); }
|
||||||
|
@ -143,6 +165,23 @@ namespace Rokojori
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<U> FilterAndMap<T,U>( List<T> list, Func<T,int,bool> filter, Func<T,U> map)
|
||||||
|
{
|
||||||
|
var mapped = new List<U>();
|
||||||
|
|
||||||
|
for ( int i = 0; i < list.Count; i++ )
|
||||||
|
{
|
||||||
|
if ( ! filter( list[ i ], i ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped.Add( map( list[ i ] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapped;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Filter<T>( List<T> inputList, List<T> list, Func<T,int,bool> filter )
|
public static void Filter<T>( List<T> inputList, List<T> list, Func<T,int,bool> filter )
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < inputList.Count; i++ )
|
for ( int i = 0; i < inputList.Count; i++ )
|
||||||
|
@ -200,6 +239,24 @@ namespace Rokojori
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Add<T>( List<T> list, params T[] entries )
|
||||||
|
{
|
||||||
|
list.AddRange( entries );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Insert<T>( List<T> list, T item, int index )
|
||||||
|
{
|
||||||
|
if ( index >= list.Count )
|
||||||
|
{
|
||||||
|
list.Add( item );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = index < 0 ? 0 : index;
|
||||||
|
|
||||||
|
list.Insert( index, item );
|
||||||
|
}
|
||||||
|
|
||||||
public static T Find<T>( List<T> list, Func<T,bool> callback )
|
public static T Find<T>( List<T> list, Func<T,bool> callback )
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < list.Count; i++ )
|
for ( int i = 0; i < list.Count; i++ )
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Safe
|
||||||
|
{
|
||||||
|
static readonly int maxWhileIterations = 1000 * 1000;
|
||||||
|
|
||||||
|
public static void While( Func<bool> condition, Action action, Action onTooManyIterations = null )
|
||||||
|
{
|
||||||
|
var it = 0;
|
||||||
|
|
||||||
|
while ( it < Safe.maxWhileIterations && condition() )
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it >= Safe.maxWhileIterations )
|
||||||
|
{
|
||||||
|
RJLog.LogWithFullTrace( "Loop with too many iterations" );
|
||||||
|
|
||||||
|
if ( onTooManyIterations != null )
|
||||||
|
{
|
||||||
|
onTooManyIterations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,13 +67,13 @@ namespace Rokojori
|
||||||
var maxWidth = 0f;
|
var maxWidth = 0f;
|
||||||
var maxHeight = 0f;
|
var maxHeight = 0f;
|
||||||
|
|
||||||
if ( UINumber.IsNullOrNone( region.width ) )
|
if ( UINumber.IsNullOrNone( UIStyle.Width( region ) ) )
|
||||||
{
|
{
|
||||||
lines.ForEach( l => { maxWidth = Mathf.Max( maxWidth, l.maxX ); } );
|
lines.ForEach( l => { maxWidth = Mathf.Max( maxWidth, l.maxX ); } );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maxWidth = UINumber.Compute( region, region.width );
|
maxWidth = UINumber.Compute( region, UIStyle.Width( region ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lines.Count > 0 )
|
if ( lines.Count > 0 )
|
||||||
|
@ -81,12 +81,12 @@ namespace Rokojori
|
||||||
maxHeight = lines[ lines.Count - 1 ].maxY;
|
maxHeight = lines[ lines.Count - 1 ].maxY;
|
||||||
}
|
}
|
||||||
|
|
||||||
var margin = UINumber.Compute( region, region.margin, 0 );
|
var margin = UINumber.Compute( region, UIStyle.Margin( region ), 0 );
|
||||||
var marginLeft = margin + UINumber.Compute( region, region.marginLeft, 0 );
|
var marginLeft = margin + UINumber.Compute( region, UIStyle.MarginLeft( region ), 0 );
|
||||||
var marginTop = margin + UINumber.Compute( region, region.marginTop, 0 );
|
var marginTop = margin + UINumber.Compute( region, UIStyle.MarginTop( region ), 0 );
|
||||||
|
|
||||||
var marginRight = margin + UINumber.Compute( region, region.marginRight, 0 );
|
var marginRight = margin + UINumber.Compute( region, UIStyle.MarginRight( region ), 0 );
|
||||||
var marginBottom = margin + UINumber.Compute( region, region.marginBottom, 0 );
|
var marginBottom = margin + UINumber.Compute( region, UIStyle.MarginBottom( region ), 0 );
|
||||||
|
|
||||||
|
|
||||||
var marginOffset = new Vector2( marginLeft, marginTop );
|
var marginOffset = new Vector2( marginLeft, marginTop );
|
||||||
|
@ -98,46 +98,38 @@ namespace Rokojori
|
||||||
|
|
||||||
region.Size = new Vector2( maxWidth + horizontalMargins, maxHeight + verticalMargins );
|
region.Size = new Vector2( maxWidth + horizontalMargins, maxHeight + verticalMargins );
|
||||||
|
|
||||||
if ( region.position == UIPosition.Parent_Anchor )
|
if ( UIStyle.Position( region ) == UIPosition.Parent_Anchor )
|
||||||
{
|
{
|
||||||
var p = NodesWalker.Get().Parent( region ) as Control;
|
UILayouting.SetPositionInParentAnchor( region );
|
||||||
|
}
|
||||||
|
|
||||||
if ( p != null )
|
Nodes.ForEachDirectChild<Control>( region,
|
||||||
|
child =>
|
||||||
{
|
{
|
||||||
var pWidth = UILayouting.GetWidth( p );
|
|
||||||
var pHeight = UILayouting.GetHeight( p );
|
|
||||||
|
|
||||||
var x = p.Position.X;
|
var styleContainer = child as UIStylePropertyContainer;
|
||||||
var y = p.Position.Y;
|
|
||||||
|
|
||||||
|
if ( styleContainer == null || UIStyle.Position( styleContainer ) != UIPosition.Parent_Anchor )
|
||||||
if ( ! UINumber.IsNullOrNone( region.left ))
|
|
||||||
{
|
{
|
||||||
var left = UINumber.Compute( region, region.left, 0 );
|
return;
|
||||||
x = left;
|
|
||||||
}
|
|
||||||
else if ( ! UINumber.IsNullOrNone( region.right ) )
|
|
||||||
{
|
|
||||||
var right = UINumber.Compute( region, region.right, 0 );
|
|
||||||
x = ( pWidth - UILayouting.GetWidth( region ) ) - right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UILayouting.SetPosition( region, new Vector2( x, y ) );
|
UILayouting.UpdateChild( child );
|
||||||
|
UILayouting.SetPositionInParentAnchor( styleContainer );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Line> CreateLines( UIRegion region )
|
static List<Line> CreateLines( UIRegion region )
|
||||||
{
|
{
|
||||||
var x = 0f;
|
var x = 0f;
|
||||||
var width = UINumber.Compute( region, region.width, 100000000f );
|
var width = UINumber.Compute( region, UIStyle.Width( region ), 100000000f );
|
||||||
|
|
||||||
var lines = new List<Line>();
|
var lines = new List<Line>();
|
||||||
var currentLine = new Line();
|
var currentLine = new Line();
|
||||||
|
|
||||||
var elementSpacing = UINumber.Compute( region, region.elementSpacing, 0f );
|
var elementSpacing = UINumber.Compute( region, UIStyle.ElementSpacing( region ), 0f );
|
||||||
|
|
||||||
Nodes.ForEachDirectChild<Control>( region, c => UILayouting.UpdateChild( c ) );
|
Nodes.ForEachDirectChild<Control>( region, c => UILayouting.UpdateChild( c ) );
|
||||||
|
|
||||||
|
@ -146,6 +138,13 @@ namespace Rokojori
|
||||||
child =>
|
child =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
var styleContainer = child as UIStylePropertyContainer;
|
||||||
|
|
||||||
|
if ( styleContainer != null && UIStyle.Position( styleContainer ) == UIPosition.Parent_Anchor )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var cWidth = UILayouting.GetWidth( child );
|
var cWidth = UILayouting.GetWidth( child );
|
||||||
var cHeight = UILayouting.GetHeight( child );
|
var cHeight = UILayouting.GetHeight( child );
|
||||||
|
|
||||||
|
@ -193,13 +192,13 @@ namespace Rokojori
|
||||||
|
|
||||||
lines.ForEach( line => AdjustVerticalAlignment( region, line, verticalAlignment ) );
|
lines.ForEach( line => AdjustVerticalAlignment( region, line, verticalAlignment ) );
|
||||||
|
|
||||||
if ( UINumber.IsNullOrNone( region.width ) )
|
if ( UINumber.IsNullOrNone( UIStyle.Width( region ) ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var horizontalAlignment = UINumber.Compute( region, region.horizontalAlignment, 0.5f, 1 );
|
var horizontalAlignment = UINumber.Compute( region, region.horizontalAlignment, 0.5f, 1 );
|
||||||
var maxWidth = UINumber.Compute( region, region.width, 0 );
|
var maxWidth = UINumber.Compute( region, UIStyle.Width( region ), 0 );
|
||||||
|
|
||||||
lines.ForEach( line => AdjustHorizontalAlignment( region, line, horizontalAlignment, maxWidth ) );
|
lines.ForEach( line => AdjustHorizontalAlignment( region, line, horizontalAlignment, maxWidth ) );
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,45 @@ namespace Rokojori
|
||||||
UILayouting.UpdatePivot( control );
|
UILayouting.UpdatePivot( control );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetPositionInParentAnchor( UIStylePropertyContainer region )
|
||||||
|
{
|
||||||
|
var control = (Control) region;
|
||||||
|
var p = NodesWalker.Get().Parent( control ) as Control;
|
||||||
|
|
||||||
|
var pWidth = p == null ? UI.GetWindowWidth( control ) : UILayouting.GetWidth( p );
|
||||||
|
var pHeight = p == null ? UI.GetWindowHeight( control ) : UILayouting.GetHeight( p );
|
||||||
|
|
||||||
|
var x = p.Position.X;
|
||||||
|
var y = p.Position.Y;
|
||||||
|
|
||||||
|
|
||||||
|
if ( ! UINumber.IsNullOrNone( UIStyle.Left( region ) ))
|
||||||
|
{
|
||||||
|
var left = UINumber.Compute( control, UIStyle.Left( region ), 0 );
|
||||||
|
x = left;
|
||||||
|
}
|
||||||
|
else if ( ! UINumber.IsNullOrNone( UIStyle.Right( region ) ) )
|
||||||
|
{
|
||||||
|
var right = UINumber.Compute( control, UIStyle.Right( region ), 0 );
|
||||||
|
x = ( pWidth - UILayouting.GetWidth( control ) ) - right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! UINumber.IsNullOrNone( UIStyle.Top( region ) ))
|
||||||
|
{
|
||||||
|
var top = UINumber.Compute( control, UIStyle.Top( region ), 0 );
|
||||||
|
y = top;
|
||||||
|
}
|
||||||
|
else if ( ! UINumber.IsNullOrNone( UIStyle.Bottom( region ) ) )
|
||||||
|
{
|
||||||
|
var bottom = UINumber.Compute( control, UIStyle.Bottom( region ), 0 );
|
||||||
|
y = ( pHeight - UILayouting.GetHeight( control ) ) - bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
UILayouting.SetPosition( control, new Vector2( x, y ) );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void UpdatePivot( Control c )
|
public static void UpdatePivot( Control c )
|
||||||
{
|
{
|
||||||
if ( ! ( c is UIImage || c is UIRegion || c is UIText ) )
|
if ( ! ( c is UIImage || c is UIRegion || c is UIText ) )
|
||||||
|
@ -49,8 +88,8 @@ namespace Rokojori
|
||||||
|
|
||||||
var container = c as UIStylePropertyContainer;
|
var container = c as UIStylePropertyContainer;
|
||||||
|
|
||||||
var pivotX = UINumber.Compute( c, UIStyle.PivotX( container ), 0, c.Size.X );
|
var pivotX = UINumber.Compute( c, UIStyle.PivotX( container ), 0.5f * c.Size.X, c.Size.X );
|
||||||
var pivotY = UINumber.Compute( c, UIStyle.PivotY( container ), 0, c.Size.Y );
|
var pivotY = UINumber.Compute( c, UIStyle.PivotY( container ), 0.5f * c.Size.Y, c.Size.Y );
|
||||||
|
|
||||||
c.PivotOffset = new Vector2( pivotX, pivotY );
|
c.PivotOffset = new Vector2( pivotX, pivotY );
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ namespace Rokojori
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class UIImage:TextureRect, UIStylePropertyContainer
|
public partial class UIImage:TextureRect, UIStylePropertyContainer
|
||||||
{
|
{
|
||||||
|
[Export]
|
||||||
|
public UIStyle parentStyle;
|
||||||
|
|
||||||
[ExportCategory("Size & Margins")]
|
[ExportCategory("Size & Margins")]
|
||||||
[Export]
|
[Export]
|
||||||
public UINumber width;
|
public UINumber width;
|
||||||
|
@ -60,6 +63,16 @@ namespace Rokojori
|
||||||
public UINumber scaleY;
|
public UINumber scaleY;
|
||||||
|
|
||||||
|
|
||||||
|
public UIStyle GetUIStyleParent()
|
||||||
|
{
|
||||||
|
return parentStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIPosition GetUIPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
||||||
{
|
{
|
||||||
switch ( property )
|
switch ( property )
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace Rokojori
|
||||||
public partial class UIRegion : Control, UIStylePropertyContainer
|
public partial class UIRegion : Control, UIStylePropertyContainer
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public UIStyle parent;
|
public UIStyle parentStyle;
|
||||||
|
|
||||||
[ExportCategory("Layout")]
|
[ExportCategory( "Layout" )]
|
||||||
[Export]
|
[Export]
|
||||||
public UILayout layout;
|
public UILayout layout;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace Rokojori
|
||||||
public UINumber lineSpacing;
|
public UINumber lineSpacing;
|
||||||
|
|
||||||
|
|
||||||
[ExportCategory("Size & Margins")]
|
[ExportCategory( "Size & Margins" )]
|
||||||
[Export]
|
[Export]
|
||||||
public UINumber width;
|
public UINumber width;
|
||||||
[Export]
|
[Export]
|
||||||
|
@ -44,7 +44,27 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public UINumber marginBottom;
|
public UINumber marginBottom;
|
||||||
|
|
||||||
[ExportCategory("Position")]
|
[ExportCategory( "Font" )]
|
||||||
|
[Export]
|
||||||
|
public Font font;
|
||||||
|
[Export]
|
||||||
|
public UINumber fontSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor fontColor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber outlineSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor outlineColor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber shadowSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor shadowColor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[ExportCategory( "Position" )]
|
||||||
[Export]
|
[Export]
|
||||||
public UIPosition position;
|
public UIPosition position;
|
||||||
[Export]
|
[Export]
|
||||||
|
@ -57,6 +77,16 @@ namespace Rokojori
|
||||||
public UINumber bottom;
|
public UINumber bottom;
|
||||||
|
|
||||||
|
|
||||||
|
public UIStyle GetUIStyleParent()
|
||||||
|
{
|
||||||
|
return parentStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIPosition GetUIPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
||||||
{
|
{
|
||||||
switch ( property )
|
switch ( property )
|
||||||
|
@ -69,6 +99,10 @@ namespace Rokojori
|
||||||
case UIStyleNumberProperty.Width: return width;
|
case UIStyleNumberProperty.Width: return width;
|
||||||
case UIStyleNumberProperty.Height: return height;
|
case UIStyleNumberProperty.Height: return height;
|
||||||
|
|
||||||
|
|
||||||
|
case UIStyleNumberProperty.ElementSpacing: return elementSpacing;
|
||||||
|
case UIStyleNumberProperty.LineSpacing: return lineSpacing;
|
||||||
|
|
||||||
case UIStyleNumberProperty.Margin: return margin;
|
case UIStyleNumberProperty.Margin: return margin;
|
||||||
|
|
||||||
case UIStyleNumberProperty.MarginLeft: return marginLeft;
|
case UIStyleNumberProperty.MarginLeft: return marginLeft;
|
||||||
|
|
|
@ -8,6 +8,12 @@ namespace Rokojori
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class UIText:Label,UIStylePropertyContainer
|
public partial class UIText:Label,UIStylePropertyContainer
|
||||||
{
|
{
|
||||||
|
[Export]
|
||||||
|
public UIStyle parentStyle;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber fontSize;
|
||||||
|
|
||||||
[ExportCategory("Size & Margins")]
|
[ExportCategory("Size & Margins")]
|
||||||
[Export]
|
[Export]
|
||||||
public UINumber width;
|
public UINumber width;
|
||||||
|
@ -59,6 +65,15 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public UINumber scaleY;
|
public UINumber scaleY;
|
||||||
|
|
||||||
|
public UIStyle GetUIStyleParent()
|
||||||
|
{
|
||||||
|
return parentStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIPosition GetUIPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using Rokojori;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class UIColor : Resource
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Color color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ namespace Rokojori
|
||||||
return number.IsNone;
|
return number.IsNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static float Compute( Control control, UINumber number, float alternative = 0, float relative = 100 )
|
public static float Compute( Control control, UINumber number, float alternative = 0, float relative = 100 )
|
||||||
{
|
{
|
||||||
if ( number == null || control == null || number.IsNone )
|
if ( number == null || control == null || number.IsNone )
|
||||||
|
@ -41,19 +42,9 @@ namespace Rokojori
|
||||||
return alternative;
|
return alternative;
|
||||||
}
|
}
|
||||||
|
|
||||||
var width = 0;
|
var width = UI.GetWindowWidth( control );
|
||||||
var height = 0;
|
var height = UI.GetWindowHeight( control );
|
||||||
|
|
||||||
if ( Engine.IsEditorHint() )
|
|
||||||
{
|
|
||||||
width = ProjectSettings.GetSetting( "display/window/size/viewport_width" ).AsInt32();
|
|
||||||
height = ProjectSettings.GetSetting( "display/window/size/viewport_height" ).AsInt32();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = control.GetWindow().Size.X;
|
|
||||||
height = control.GetWindow().Size.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Compute( control, number, width, height, relative );
|
return Compute( control, number, width, height, relative );
|
||||||
|
|
||||||
|
@ -75,7 +66,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( _ui == null )
|
if ( _ui == null )
|
||||||
{
|
{
|
||||||
// _ui = NodesWalker.Get().GetParent( control, n => n is UI ) as UI;
|
_ui = NodesWalker.Get().GetInParents( control, n => n is UI ) as UI;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( number.unit )
|
switch ( number.unit )
|
||||||
|
@ -95,6 +86,18 @@ namespace Rokojori
|
||||||
return number.value * height / 100f;
|
return number.value * height / 100f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "pw":
|
||||||
|
{
|
||||||
|
var parent = control.GetParent<Control>();
|
||||||
|
return number.value / 100f * ( parent == null ? width : parent.Size.X );
|
||||||
|
}
|
||||||
|
|
||||||
|
case "ph":
|
||||||
|
{
|
||||||
|
var parent = control.GetParent<Control>();
|
||||||
|
return number.value / 100f * ( parent == null ? height : parent.Size.Y );
|
||||||
|
}
|
||||||
|
|
||||||
case "px": case "":
|
case "px": case "":
|
||||||
{
|
{
|
||||||
return number.value;
|
return number.value;
|
||||||
|
@ -110,17 +113,25 @@ namespace Rokojori
|
||||||
|
|
||||||
|
|
||||||
var expressionText = number.unit == null ? "" : RegexUtility.Replace( number.unit, "%", " * relative " );
|
var expressionText = number.unit == null ? "" : RegexUtility.Replace( number.unit, "%", " * relative " );
|
||||||
var parseResult = expression.Parse( expressionText, new string[]{ "em","vw", "vh", "px", "relative", "value" } );
|
var parseResult = expression.Parse( expressionText,
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"em","vw", "vh", "pw", "ph", "px", "relative", "value" }
|
||||||
|
);
|
||||||
|
|
||||||
if ( Error.Ok != parseResult )
|
if ( Error.Ok != parseResult )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentControl = control.GetParent<Control>();
|
||||||
|
|
||||||
var inputs = new Godot.Collections.Array();
|
var inputs = new Godot.Collections.Array();
|
||||||
inputs.Add( em() );
|
inputs.Add( em() );
|
||||||
inputs.Add( width / 100f );
|
inputs.Add( width / 100f );
|
||||||
inputs.Add( height / 100f );
|
inputs.Add( height / 100f );
|
||||||
|
inputs.Add( ( parentControl == null ? width : parentControl.Size.X ) / 100f );
|
||||||
|
inputs.Add( ( parentControl == null ? height : parentControl.Size.Y ) / 100f );
|
||||||
inputs.Add( 1 );
|
inputs.Add( 1 );
|
||||||
inputs.Add( relative / 100f );
|
inputs.Add( relative / 100f );
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
public enum UIPosition
|
public enum UIPosition
|
||||||
{
|
{
|
||||||
|
___,
|
||||||
From_Layout,
|
From_Layout,
|
||||||
Parent_Anchor
|
Parent_Anchor
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,106 +7,236 @@ namespace Rokojori
|
||||||
|
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class UIStyle:Resource
|
public partial class UIStyle:Resource, UIStylePropertyContainer
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public UIStyle parent;
|
public UIStyle parentStyle;
|
||||||
|
|
||||||
|
[ExportCategory( "Layout" )]
|
||||||
|
[Export]
|
||||||
|
public UILayout layout;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public UILayout layoutType;
|
public UINumber horizontalAlignment;
|
||||||
|
[Export]
|
||||||
|
public UINumber verticalAlignment;
|
||||||
|
|
||||||
[ExportCategory("Width")]
|
|
||||||
[Export]
|
[Export]
|
||||||
public float widthValue = 1;
|
public UINumber elementSpacing;
|
||||||
[Export]
|
[Export]
|
||||||
public string widthUnit = "vw";
|
public UINumber lineSpacing;
|
||||||
|
|
||||||
[ExportCategory("Height")]
|
|
||||||
[Export]
|
|
||||||
public float heightValue = 1;
|
|
||||||
[Export]
|
|
||||||
public string heightUnit = "vw";
|
|
||||||
|
|
||||||
[ExportCategory("LineSpacing")]
|
[ExportCategory( "Size & Margins" )]
|
||||||
[Export]
|
[Export]
|
||||||
public float lineSpacingValue = 1;
|
public UINumber width;
|
||||||
[Export]
|
[Export]
|
||||||
public string ineSpacingtUnit = "vw";
|
public UINumber height;
|
||||||
|
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber margin;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber marginLeft;
|
||||||
|
[Export]
|
||||||
|
public UINumber marginTop;
|
||||||
|
[Export]
|
||||||
|
public UINumber marginRight;
|
||||||
|
[Export]
|
||||||
|
public UINumber marginBottom;
|
||||||
|
|
||||||
|
[ExportCategory( "Font" )]
|
||||||
|
[Export]
|
||||||
|
public Font font;
|
||||||
|
[Export]
|
||||||
|
public UINumber fontSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor fontColor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber outlineSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor outlineColor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public UINumber shadowSize;
|
||||||
|
[Export]
|
||||||
|
public UIColor shadowColor;
|
||||||
|
|
||||||
|
[ExportCategory( "Position" )]
|
||||||
|
[Export]
|
||||||
|
public UIPosition position;
|
||||||
|
[Export]
|
||||||
|
public UINumber left;
|
||||||
|
[Export]
|
||||||
|
public UINumber top;
|
||||||
|
[Export]
|
||||||
|
public UINumber right;
|
||||||
|
[Export]
|
||||||
|
public UINumber bottom;
|
||||||
|
|
||||||
|
public UIStyle GetUIStyleParent()
|
||||||
|
{
|
||||||
|
return parentStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UIPosition GetUIPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property )
|
||||||
|
{
|
||||||
|
switch ( property )
|
||||||
|
{
|
||||||
|
case UIStyleNumberProperty.Left: return left;
|
||||||
|
case UIStyleNumberProperty.Right: return right;
|
||||||
|
case UIStyleNumberProperty.Top: return top;
|
||||||
|
case UIStyleNumberProperty.Bottom: return bottom;
|
||||||
|
|
||||||
|
case UIStyleNumberProperty.ElementSpacing: return elementSpacing;
|
||||||
|
case UIStyleNumberProperty.LineSpacing: return lineSpacing;
|
||||||
|
|
||||||
|
|
||||||
|
case UIStyleNumberProperty.Width: return width;
|
||||||
|
case UIStyleNumberProperty.Height: return height;
|
||||||
|
|
||||||
|
case UIStyleNumberProperty.Margin: return margin;
|
||||||
|
|
||||||
|
case UIStyleNumberProperty.MarginLeft: return marginLeft;
|
||||||
|
case UIStyleNumberProperty.MarginRight: return marginRight;
|
||||||
|
case UIStyleNumberProperty.MarginTop: return marginTop;
|
||||||
|
case UIStyleNumberProperty.MarginBottom: return marginBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UINumber GetReferenceableNumberProperty( UIStylePropertyContainer container, UIStyleNumberProperty property )
|
||||||
|
{
|
||||||
|
if ( container == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ownProperty = container.GetUIStyleNumberProperty( property );
|
||||||
|
|
||||||
|
if ( ownProperty != null )
|
||||||
|
{
|
||||||
|
return ownProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var style = container.GetUIStyleParent();
|
||||||
|
|
||||||
|
return GetReferenceableNumberProperty( style, property );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UIPosition Position( UIStylePropertyContainer container )
|
||||||
|
{
|
||||||
|
var ownProperty = container.GetUIPosition();
|
||||||
|
|
||||||
|
if ( ownProperty != UIPosition.___ )
|
||||||
|
{
|
||||||
|
return ownProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return container.GetUIPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UINumber Width( UIStylePropertyContainer container )
|
||||||
|
{
|
||||||
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Width );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UINumber Height( UIStylePropertyContainer container )
|
||||||
|
{
|
||||||
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Height );
|
||||||
|
}
|
||||||
|
|
||||||
public static UINumber Left( UIStylePropertyContainer container )
|
public static UINumber Left( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Left );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Left );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Right( UIStylePropertyContainer container )
|
public static UINumber Right( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Right );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Right );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Top( UIStylePropertyContainer container )
|
public static UINumber Top( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Top );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Top );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Bottom( UIStylePropertyContainer container )
|
public static UINumber Bottom( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Bottom );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Bottom );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Margin( UIStylePropertyContainer container )
|
public static UINumber Margin( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Margin );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Margin );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber MarginLeft( UIStylePropertyContainer container )
|
public static UINumber MarginLeft( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.MarginLeft );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.MarginLeft );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber MarginRight( UIStylePropertyContainer container )
|
public static UINumber MarginRight( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.MarginRight );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.MarginRight );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber MarginTop( UIStylePropertyContainer container )
|
public static UINumber MarginTop( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.MarginTop );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.MarginTop );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber MarginBottom( UIStylePropertyContainer container )
|
public static UINumber MarginBottom( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.MarginBottom );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.MarginBottom );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber PivotX( UIStylePropertyContainer container )
|
public static UINumber PivotX( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.PivotX );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.PivotX );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber PivotY( UIStylePropertyContainer container )
|
public static UINumber PivotY( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.PivotY );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.PivotY );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Rotation( UIStylePropertyContainer container )
|
public static UINumber Rotation( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Rotation );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Rotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber Scale( UIStylePropertyContainer container )
|
public static UINumber Scale( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.Scale );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.Scale );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber ScaleX( UIStylePropertyContainer container )
|
public static UINumber ScaleX( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.ScaleX );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.ScaleX );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UINumber ScaleY( UIStylePropertyContainer container )
|
public static UINumber ScaleY( UIStylePropertyContainer container )
|
||||||
{
|
{
|
||||||
return container.GetUIStyleNumberProperty( UIStyleNumberProperty.ScaleY );
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.ScaleY );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UINumber ElementSpacing( UIStylePropertyContainer container )
|
||||||
|
{
|
||||||
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.ElementSpacing );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UINumber LineSpacing( UIStylePropertyContainer container )
|
||||||
|
{
|
||||||
|
return GetReferenceableNumberProperty( container, UIStyleNumberProperty.LineSpacing );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ namespace Rokojori
|
||||||
Width,
|
Width,
|
||||||
Height,
|
Height,
|
||||||
|
|
||||||
|
ElementSpacing,
|
||||||
|
LineSpacing,
|
||||||
|
|
||||||
Margin,
|
Margin,
|
||||||
MarginLeft,
|
MarginLeft,
|
||||||
MarginRight,
|
MarginRight,
|
||||||
|
@ -27,6 +30,17 @@ namespace Rokojori
|
||||||
|
|
||||||
Scale,
|
Scale,
|
||||||
ScaleX,
|
ScaleX,
|
||||||
ScaleY
|
ScaleY,
|
||||||
|
|
||||||
|
FontSize,
|
||||||
|
FontOutlineSize,
|
||||||
|
FontShadowSize
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UIStyleColorProperty
|
||||||
|
{
|
||||||
|
FontColor,
|
||||||
|
FontOutlineColor,
|
||||||
|
FontShadowColor
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,9 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
public interface UIStylePropertyContainer
|
public interface UIStylePropertyContainer
|
||||||
{
|
{
|
||||||
|
UIStyle GetUIStyleParent();
|
||||||
|
|
||||||
|
UIPosition GetUIPosition();
|
||||||
UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property );
|
UINumber GetUIStyleNumberProperty( UIStyleNumberProperty property );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,6 +54,30 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float GetWindowWidth( Control control )
|
||||||
|
{
|
||||||
|
if ( Engine.IsEditorHint() )
|
||||||
|
{
|
||||||
|
return ProjectSettings.GetSetting( "display/window/size/viewport_width" ).AsInt32();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return control.GetWindow().Size.X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GetWindowHeight( Control control )
|
||||||
|
{
|
||||||
|
if ( Engine.IsEditorHint() )
|
||||||
|
{
|
||||||
|
return ProjectSettings.GetSetting( "display/window/size/viewport_height" ).AsInt32();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return control.GetWindow().Size.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue