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