Pose & Geometry Updates
This commit is contained in:
		
							parent
							
								
									31704452be
								
							
						
					
					
						commit
						1bcbcaaf99
					
				| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
using Godot;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Rokojori
 | 
			
		||||
{  
 | 
			
		||||
  public class ResourceHelper
 | 
			
		||||
  { 
 | 
			
		||||
    public static void Overwrite<T>( List<string> overwriteProperties, T sourceResource, T targetResource ) where T:Resource
 | 
			
		||||
    {  
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -202,6 +202,20 @@ namespace Rokojori
 | 
			
		|||
      target.SetGlobalQuaternion( source.GetGlobalQuaternion() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Rotate( Quaternion rotation )
 | 
			
		||||
    {
 | 
			
		||||
      position = rotation * position;
 | 
			
		||||
      this.rotation *= rotation;
 | 
			
		||||
      this.rotation = this.rotation.Normalized();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void RotateAround( Quaternion rotation, Vector3 pivot )
 | 
			
		||||
    {
 | 
			
		||||
      position -= pivot;
 | 
			
		||||
      Rotate( rotation );
 | 
			
		||||
      position += pivot;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static Pose Merge( List<Pose> poses, List<float> weights = null )
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,23 @@ namespace Rokojori
 | 
			
		|||
    public SplineCurveTangent tangentBefore = new SplineCurveTangent();
 | 
			
		||||
    public SplineCurveTangent tangentNext = new SplineCurveTangent();
 | 
			
		||||
 | 
			
		||||
    public Pose pose 
 | 
			
		||||
    { 
 | 
			
		||||
      get => Pose.Create( position, rotation );
 | 
			
		||||
      set 
 | 
			
		||||
      {
 | 
			
		||||
        position = value.position;
 | 
			
		||||
        rotation = value.rotation;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void RotateAround( Quaternion rotation, Vector3 pivot )
 | 
			
		||||
    {
 | 
			
		||||
      var p = pose;
 | 
			
		||||
      p.RotateAround( rotation, pivot );
 | 
			
		||||
      pose = p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SplineCurvePoint Clone()
 | 
			
		||||
    {
 | 
			
		||||
      var scp = new SplineCurvePoint();
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +94,11 @@ namespace Rokojori
 | 
			
		|||
      return cloned;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void LookTowards( Vector3 direction, Vector3 up )
 | 
			
		||||
    {
 | 
			
		||||
      rotation = Math3D.LookRotation( direction, up );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +116,34 @@ namespace Rokojori
 | 
			
		|||
      return splineCurve;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void AutoOrientateByTangents( Vector3 up, bool closed = false, float autoOrientationTangentAdjustment = 0f )
 | 
			
		||||
    {
 | 
			
		||||
      var list = _points;
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < list.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var point = list[ i ];     
 | 
			
		||||
 | 
			
		||||
        var tangentForward = Vector3.Zero;
 | 
			
		||||
 | 
			
		||||
        if ( i == ( list.Count - 1 ) && ! closed )
 | 
			
		||||
        {
 | 
			
		||||
          tangentForward = - SplineCurveCreator.GetTangentDirectionSmoothed( 1, autoOrientationTangentAdjustment, list, i, true, false );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          tangentForward = SplineCurveCreator.GetTangentDirectionSmoothed( 1, autoOrientationTangentAdjustment, list, i, false, closed );
 | 
			
		||||
        }          
 | 
			
		||||
        
 | 
			
		||||
        if ( tangentForward.Length() == 0 )
 | 
			
		||||
        {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        point.LookTowards( tangentForward, up );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Vector3 MinPointPosition()
 | 
			
		||||
    {
 | 
			
		||||
      if ( _points.Count == 0 )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,25 @@ namespace Rokojori
 | 
			
		|||
  {
 | 
			
		||||
    bool closed;   
 | 
			
		||||
 | 
			
		||||
    public SplineCurve Create( List<SplinePoint> splinePoints, bool close )
 | 
			
		||||
    public SplineCurve Create( List<SplinePoint> splinePoints, bool close = false )
 | 
			
		||||
    {
 | 
			
		||||
      closed = close;
 | 
			
		||||
      var points = new List<SplineCurvePoint>();
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < splinePoints.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        points.Add( CreatePoint( splinePoints, i ) );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ( closed )
 | 
			
		||||
      {
 | 
			
		||||
        points.Add( CreatePoint( splinePoints, 0 ) );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return SplineCurve.From( points );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public SplineCurve Create( List<Vector3> splinePoints, bool close = false )
 | 
			
		||||
    {
 | 
			
		||||
      closed = close;
 | 
			
		||||
      var points = new List<SplineCurvePoint>();
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +63,26 @@ namespace Rokojori
 | 
			
		|||
      return splineCurvePoint;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    SplineCurvePoint CreatePoint( List<Vector3> splinePoints, int index )
 | 
			
		||||
    {
 | 
			
		||||
      var splineCurvePoint = new SplineCurvePoint();
 | 
			
		||||
      var splinePoint = splinePoints[ index ];
 | 
			
		||||
      splineCurvePoint.position = splinePoint;
 | 
			
		||||
      splineCurvePoint.rotation = Quaternion.Identity;
 | 
			
		||||
      splineCurvePoint.scale  = Vector3.One;
 | 
			
		||||
      splineCurvePoint.twist = 0;
 | 
			
		||||
      splineCurvePoint.weight = 1f;
 | 
			
		||||
      
 | 
			
		||||
      splineCurvePoint.tangentBefore.position = GetTangentPosition( splinePoints, index, true, closed );
 | 
			
		||||
      splineCurvePoint.tangentNext.position   = GetTangentPosition( splinePoints, index, false, closed );
 | 
			
		||||
 | 
			
		||||
      splineCurvePoint.tangentBefore.weight = 1;
 | 
			
		||||
      splineCurvePoint.tangentNext.weight = 1;
 | 
			
		||||
 | 
			
		||||
      return splineCurvePoint;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentDirectionSmoothed( float smoothing, List<SplinePoint> splinePoints, int index, bool before, bool closed )
 | 
			
		||||
    {
 | 
			
		||||
      var previousIndex = MathX.SafeIndex( index - 1, splinePoints.Count, closed );
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +122,28 @@ namespace Rokojori
 | 
			
		|||
      return unsmoothedTangent + smoothing * ( smoothedTangent - unsmoothedTangent );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentDirectionSmoothed( int numSamples, float smoothing, List<SplineCurvePoint> splinePoints, int index, bool before, bool closed )
 | 
			
		||||
    {
 | 
			
		||||
      var smoothedTangent = Vector3.Zero;
 | 
			
		||||
      var unsmoothedTangent = Vector3.Zero;
 | 
			
		||||
 | 
			
		||||
      for ( int i = -numSamples; i <= numSamples; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var sampleIndex = MathX.SafeIndex( index + i, splinePoints.Count, closed );
 | 
			
		||||
        var direction = GetTangentDirection( splinePoints, sampleIndex, before, closed );
 | 
			
		||||
        smoothedTangent += direction;
 | 
			
		||||
 | 
			
		||||
        if ( i == 0 )
 | 
			
		||||
        {
 | 
			
		||||
          unsmoothedTangent = direction;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      smoothedTangent /= ( numSamples * 2 + 1 );
 | 
			
		||||
 | 
			
		||||
      return unsmoothedTangent + smoothing * ( smoothedTangent - unsmoothedTangent );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentDirection( List<SplinePoint> splinePoints, int index, bool before, bool closed )
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +152,78 @@ namespace Rokojori
 | 
			
		|||
      return GetTangentPosition( splinePoints, index, before, closed ) - splinePoint.GlobalPosition;
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentDirection( List<SplineCurvePoint> splinePoints, int index, bool before, bool closed,
 | 
			
		||||
    float overshootPrevention = 0, float tangentScale = 1, float symmetricTangentLength = 0 )
 | 
			
		||||
    {
 | 
			
		||||
      var splinePoint = splinePoints[ index ];
 | 
			
		||||
 | 
			
		||||
      return GetTangentPosition( splinePoints, index, before, closed, overshootPrevention, tangentScale, symmetricTangentLength ) - splinePoint.position;
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentPosition( List<SplineCurvePoint> splinePoints, int index, bool before, bool closed,
 | 
			
		||||
    float overshootPrevention = 0, float tangentScale = 1, float symmetricTangentLength = 0 )
 | 
			
		||||
    {
 | 
			
		||||
      var splinePoint = splinePoints[ index ];
 | 
			
		||||
      
 | 
			
		||||
      var previousIndex = index - 1;
 | 
			
		||||
      
 | 
			
		||||
      if ( previousIndex == -1 )      
 | 
			
		||||
      {
 | 
			
		||||
        previousIndex = closed ? splinePoints.Count -1  : 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var nextIndex = index + 1;
 | 
			
		||||
 | 
			
		||||
      if ( nextIndex == splinePoints.Count )  
 | 
			
		||||
      {
 | 
			
		||||
        nextIndex = closed ? 0 : splinePoints.Count - 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var previous = splinePoints[ previousIndex ];
 | 
			
		||||
      var next     = splinePoints[ nextIndex ];
 | 
			
		||||
 | 
			
		||||
      var previousPosition = previous.position;
 | 
			
		||||
      var nextPosition     = next.position;
 | 
			
		||||
 | 
			
		||||
      var position =  splinePoint.position;
 | 
			
		||||
 | 
			
		||||
      return GetTangentPosition( position, previousPosition, nextPosition, before, overshootPrevention, tangentScale, symmetricTangentLength );
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentPosition( List<Vector3> splinePoints, int index, bool before, bool closed,
 | 
			
		||||
    float overshootPrevention = 0, float tangentScale = 1, float symmetricTangentLength = 0 )
 | 
			
		||||
    {
 | 
			
		||||
      var splinePoint = splinePoints[ index ];
 | 
			
		||||
      
 | 
			
		||||
      var previousIndex = index - 1;
 | 
			
		||||
      
 | 
			
		||||
      if ( previousIndex == -1 )      
 | 
			
		||||
      {
 | 
			
		||||
        previousIndex = closed ? splinePoints.Count -1  : 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var nextIndex = index + 1;
 | 
			
		||||
 | 
			
		||||
      if ( nextIndex == splinePoints.Count )  
 | 
			
		||||
      {
 | 
			
		||||
        nextIndex = closed ? 0 : splinePoints.Count - 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var previous = splinePoints[ previousIndex ];
 | 
			
		||||
      var next     = splinePoints[ nextIndex ];
 | 
			
		||||
 | 
			
		||||
      var previousPosition = previous;
 | 
			
		||||
      var nextPosition     = next;
 | 
			
		||||
 | 
			
		||||
      var position =  splinePoint;
 | 
			
		||||
 | 
			
		||||
      return GetTangentPosition( position, previousPosition, nextPosition, before, overshootPrevention, tangentScale, symmetricTangentLength );
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Vector3 GetTangentPosition( List<SplinePoint> splinePoints, int index, bool before, bool closed )
 | 
			
		||||
    {
 | 
			
		||||
      var splinePoint = splinePoints[ index ];
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +256,22 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      var point =  splinePoint.GlobalPosition;
 | 
			
		||||
      var position =  splinePoint.GlobalPosition;
 | 
			
		||||
 | 
			
		||||
      var overshootPrevention = splinePoint.overshootPrevention;
 | 
			
		||||
      var tangentScale = splinePoint.tangentScale;
 | 
			
		||||
      var symmetricTangentLength = splinePoint.symmetricTangentLength;
 | 
			
		||||
 | 
			
		||||
      return GetTangentPosition( position, previousPosition, nextPosition, before, overshootPrevention, tangentScale, symmetricTangentLength );
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public static Vector3 GetTangentPosition( Vector3 point, Vector3 previousPosition, Vector3 nextPosition, bool before,
 | 
			
		||||
                                              float overshootPrevention = 0, float tangentScale = 1, float symmetricTangentLength = 0 )
 | 
			
		||||
    {
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      if ( overshootPrevention > 0 )
 | 
			
		||||
      {
 | 
			
		||||
        var previousDirection = ( previousPosition - point ) ;
 | 
			
		||||
| 
						 | 
				
			
			@ -179,9 +321,6 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
      return point + direction.Normalized() * length * 0.33333f * tangentScale;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    [ExportGroup( "Blade Triangles")]
 | 
			
		||||
    [Export( PropertyHint.Range, "1,20")]
 | 
			
		||||
    [Export( PropertyHint.Range, "1,256")]
 | 
			
		||||
    public int bladeSegments = 3;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +82,13 @@ namespace Rokojori
 | 
			
		|||
    [Export]
 | 
			
		||||
    public Curve uvSegmentWeightsFar = null;
 | 
			
		||||
 | 
			
		||||
    [Export( PropertyHint.Range, "0,1" )]
 | 
			
		||||
    public float uvSegmentDistortion = 0.5f;
 | 
			
		||||
 | 
			
		||||
    [Export( PropertyHint.Range, "0,0.5" )]
 | 
			
		||||
    public float uvSegmentMaxRange = 0.3f;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [ExportGroup( "Blade Shape")]
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve bladeScale = MathX.Curve( 1f );
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +111,23 @@ namespace Rokojori
 | 
			
		|||
    [Export]
 | 
			
		||||
    public Curve bladeBending2 = null;
 | 
			
		||||
 | 
			
		||||
     [Export]
 | 
			
		||||
    public Curve bladeArching = MathX.Curve( 0f );
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve bladeArching2 = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve bladeTwisting = null;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve bladeTwisting2 = null;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve rolling = MathX.Curve( 0f );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    [ExportGroup( "Blade Offset & Scale")]
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +158,9 @@ namespace Rokojori
 | 
			
		|||
    [Export]
 | 
			
		||||
    public Curve normalBlending = MathX.Curve( 0.5f );
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Curve normalBlendingAmountOverY = MathX.Curve( 1f );
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public Vector3 normalBlendingDirection = Vector3.Up;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -239,6 +266,8 @@ namespace Rokojori
 | 
			
		|||
      var allBladesX = bladesX + blades;
 | 
			
		||||
      var allBladesZ = bladesZ + blades;
 | 
			
		||||
 | 
			
		||||
      var numDebugs = 0;
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < allBladesX; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var x = ( i + 0.5f ) * cellSizeX;
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +297,9 @@ namespace Rokojori
 | 
			
		|||
              worldPosition
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
          debugBlade = X_numBlades < 10;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          var bladeMG = CreateBlade( random, worldPosition );
 | 
			
		||||
          
 | 
			
		||||
          if ( filterValue > filterTreshold )
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +328,10 @@ namespace Rokojori
 | 
			
		|||
            clonedBladeMG = bladeMG.Clone();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          bladeMG.BlendNormals( normalBlendingDirection, normalBlendingAmount );        
 | 
			
		||||
          var yRange = bladeMG.GetRangeY();
 | 
			
		||||
 | 
			
		||||
          // bladeMG.BlendNormals( normalBlendingDirection, normalBlendingAmount );        
 | 
			
		||||
          bladeMG.BlendNormalsOverY( normalBlendingDirection, normalBlendingAmount, yRange.min, yRange.max, normalBlendingAmountOverY  );
 | 
			
		||||
 | 
			
		||||
          mg.Add( bladeMG );  
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -304,7 +339,8 @@ namespace Rokojori
 | 
			
		|||
          {
 | 
			
		||||
            
 | 
			
		||||
            clonedBladeMG.FlipNormalDirection();  
 | 
			
		||||
            clonedBladeMG.BlendNormals( normalBlendingDirection, normalBlendingAmount );   
 | 
			
		||||
            // clonedBladeMG.BlendNormals( normalBlendingDirection, normalBlendingAmount );   
 | 
			
		||||
            clonedBladeMG.BlendNormalsOverY( normalBlendingDirection, normalBlendingAmount, yRange.min, yRange.max, normalBlendingAmountOverY  );
 | 
			
		||||
            
 | 
			
		||||
            mg.Add( clonedBladeMG );       
 | 
			
		||||
          }          
 | 
			
		||||
| 
						 | 
				
			
			@ -318,9 +354,15 @@ namespace Rokojori
 | 
			
		|||
      output.Mesh = mg.GenerateMesh();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool debugBlade = false;
 | 
			
		||||
 | 
			
		||||
    MeshGeometry CreateBlade( RandomEngine random, Vector3 position )
 | 
			
		||||
    {
 | 
			
		||||
      // if ( debugBlade )
 | 
			
		||||
      // {
 | 
			
		||||
      //   this.LogInfo( "Blade:", X_numBlades );
 | 
			
		||||
      // }
 | 
			
		||||
 | 
			
		||||
      var bladeSegments = this.bladeSegments;
 | 
			
		||||
 | 
			
		||||
      var currentLodLevel = Mathf.Clamp( currentLODLevel, -1, lodLevels.Length - 1 );
 | 
			
		||||
| 
						 | 
				
			
			@ -407,7 +449,6 @@ namespace Rokojori
 | 
			
		|||
      }
 | 
			
		||||
     
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i <= bladeSegments; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var t = (float)i / bladeSegments;
 | 
			
		||||
| 
						 | 
				
			
			@ -421,11 +462,15 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
        var width = Mathf.Lerp( bladeWidth.Sample( v ), bw2.Sample( v ), bladeWidthLerp );
 | 
			
		||||
        width *= scaling * bladeWidthMultiplier;
 | 
			
		||||
        var bending = Mathf.Lerp( bladeBending.Sample( v ), bb2.Sample( v ), bladeBendLerp ) * Vector3.Forward.Z * scaling;
 | 
			
		||||
        var bendingNormalAngle = Mathf.LerpAngle( MathX.CurveAngle( bladeBending, v ), MathX.CurveAngle( bb2, v ), bladeBendLerp );
 | 
			
		||||
        var bendingNormal = Math3D.NormalAngle( bendingNormalAngle );
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // var bending = Mathf.Lerp( bladeBending.Sample( v ), bb2.Sample( v ), bladeBendLerp ) * Vector3.Forward.Z * scaling;
 | 
			
		||||
        // var bendingNormalAngle = Mathf.LerpAngle( MathX.CurveAngle( bladeBending, v ), MathX.CurveAngle( bb2, v ), bladeBendLerp );
 | 
			
		||||
        // var bendingNormal = Math3D.NormalAngle( bendingNormalAngle );      
 | 
			
		||||
 | 
			
		||||
        var bending = 0;
 | 
			
		||||
        var bendingNormal = Vector3.Back;
 | 
			
		||||
 | 
			
		||||
        if ( endingTriangles && width < 0.005f && ( i == 0 || ( i == bladeSegments - 1 )) )
 | 
			
		||||
        {
 | 
			
		||||
          bmg.vertices.Add( new Vector3( 0, y, bending ) );
 | 
			
		||||
| 
						 | 
				
			
			@ -443,11 +488,27 @@ namespace Rokojori
 | 
			
		|||
          bmg.normals.Add( bendingNormal );
 | 
			
		||||
          bmg.normals.Add( bendingNormal );
 | 
			
		||||
 | 
			
		||||
          bmg.uvs.Add( MapUV( new Vector2( -width / _maxWidth, v ), uvMin, uvMax ) );
 | 
			
		||||
          bmg.uvs.Add( MapUV( new Vector2(  width / _maxWidth, v ), uvMin, uvMax ) );
 | 
			
		||||
          var uvCoord = width / _maxWidth;
 | 
			
		||||
 | 
			
		||||
          uvCoord = Mathf.Lerp( uvCoord, 1f, uvSegmentDistortion );
 | 
			
		||||
 | 
			
		||||
          uvCoord *= uvSegmentMaxRange;
 | 
			
		||||
          var uvL = MapUV( new Vector2( -uvCoord + 0.5f, v ), uvMin, uvMax );
 | 
			
		||||
          var uvR = MapUV( new Vector2(  uvCoord + 0.5f, v ), uvMin, uvMax );
 | 
			
		||||
 | 
			
		||||
          bmg.uvs.Add( uvL );
 | 
			
		||||
          bmg.uvs.Add( uvR );
 | 
			
		||||
 | 
			
		||||
          // if ( debugBlade )
 | 
			
		||||
          // {
 | 
			
		||||
          //   this.LogInfo( i, ">>", uvL, uvR );
 | 
			
		||||
          // }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      for ( int i = 0; i < bladeSegments; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var index = i * 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -471,9 +532,83 @@ namespace Rokojori
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var yStart = size * 0f - inGround;
 | 
			
		||||
      var yEnd   = size * 1f - inGround;
 | 
			
		||||
 | 
			
		||||
      var startPosition = new Vector3( 0, yStart, 0 );
 | 
			
		||||
      var endPosition   = new Vector3( 0, yEnd, 0 );
 | 
			
		||||
 | 
			
		||||
      var inputList = new List<Vector3>(){ startPosition, endPosition };
 | 
			
		||||
      var inputSpline = new SplineCurveCreator().Create( inputList );
 | 
			
		||||
      inputSpline.AutoOrientateByTangents( Vector3.Back );
 | 
			
		||||
      
 | 
			
		||||
      var outputList = new List<Vector3>();
 | 
			
		||||
 | 
			
		||||
      var numPoints = Mathf.Max( 2, bladeSegments * 2 );
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < numPoints ; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var t = (float)i / ( numPoints - 1f );
 | 
			
		||||
        var y = size * t - inGround;
 | 
			
		||||
        var bb2 = bladeBending2 == null ? bladeBending : bladeBending2; 
 | 
			
		||||
        var v = 1f - t;
 | 
			
		||||
        var bending = Mathf.Lerp( bladeBending.Sample( v ), bb2.Sample( v ), bladeBendLerp ) * Vector3.Forward.Z * scaling;
 | 
			
		||||
 | 
			
		||||
        var p = new Vector3( 0, y, bending );
 | 
			
		||||
 | 
			
		||||
        outputList.Add( p );
 | 
			
		||||
      } 
 | 
			
		||||
 | 
			
		||||
      var outputSpline = new SplineCurveCreator().Create( outputList );
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      var outputPoints = outputSpline.points;
 | 
			
		||||
 | 
			
		||||
      if ( bladeTwisting != null )
 | 
			
		||||
      {     
 | 
			
		||||
        for ( int i = 0; i < outputPoints.Count; i++ )
 | 
			
		||||
        {
 | 
			
		||||
          var t = (float)i / ( numPoints - 1f );
 | 
			
		||||
          var v = 1f - t;
 | 
			
		||||
 | 
			
		||||
          var bt2 = bladeTwisting2 == null ? bladeTwisting : bladeTwisting2; 
 | 
			
		||||
          var tw = Mathf.Lerp( bladeTwisting.Sample( v ), bt2.Sample( v ), bladeBendLerp );
 | 
			
		||||
          var p = outputPoints[ i ];
 | 
			
		||||
          p.twist = tw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      outputSpline.AutoOrientateByTangents( Vector3.Back );
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < outputPoints.Count - 1; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var t = i / (float)( outputPoints.Count - 2 );
 | 
			
		||||
        var rotation = rolling.Sample( t );
 | 
			
		||||
        RollSpline( outputPoints, i, rotation );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var modifier = new SplinesDeformModifier();
 | 
			
		||||
      modifier.sourceSplines = new SplineCurve[]{ inputSpline };
 | 
			
		||||
      modifier.targetSplines = new SplineCurve[]{ outputSpline };
 | 
			
		||||
      modifier.settings = new SplinesDeformerSettings();
 | 
			
		||||
 | 
			
		||||
      bmg = modifier.Modify( bmg );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      return bmg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void RollSpline( List<SplineCurvePoint> points, int start, float amount )
 | 
			
		||||
    {
 | 
			
		||||
      var pivot = points[ start ].position;
 | 
			
		||||
      var rotation = Math3D.RotateX( MathX.DegreesToRadians * amount / (float) points.Count ).Normalized();
 | 
			
		||||
 | 
			
		||||
      for ( int i = start + 1; i < points.Count; i++ )
 | 
			
		||||
      {        
 | 
			
		||||
        points[ i ].RotateAround( rotation, pivot );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Vector2 MapUV( Vector2 uv, Vector2 min, Vector2 max )
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
// NOTE: Shader automatically converted from Godot Engine 4.3.stable.mono's StandardMaterial3D.
 | 
			
		||||
 | 
			
		||||
shader_type spatial;
 | 
			
		||||
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
 | 
			
		||||
 | 
			
		||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
 | 
			
		||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc"
 | 
			
		||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Noise.gdshaderinc"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uniform vec4 albedo : source_color;
 | 
			
		||||
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
 | 
			
		||||
 | 
			
		||||
uniform float roughness : hint_range(0.0, 1.0);
 | 
			
		||||
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable;
 | 
			
		||||
uniform vec4 metallic_texture_channel;
 | 
			
		||||
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable;
 | 
			
		||||
 | 
			
		||||
uniform float specular : hint_range(0.0, 1.0, 0.01);
 | 
			
		||||
uniform float metallic : hint_range(0.0, 1.0, 0.01);
 | 
			
		||||
 | 
			
		||||
uniform sampler2D texture_normal : hint_roughness_normal, filter_linear_mipmap, repeat_enable;
 | 
			
		||||
uniform float normal_scale : hint_range(-16.0, 16.0);
 | 
			
		||||
 | 
			
		||||
uniform sampler2D texture_ambient_occlusion : hint_default_white, filter_linear_mipmap, repeat_enable;
 | 
			
		||||
uniform vec4 ao_texture_channel;
 | 
			
		||||
uniform float ao_light_affect : hint_range(0.0, 1.0, 0.01);
 | 
			
		||||
 | 
			
		||||
uniform vec3 uv1_scale;
 | 
			
		||||
uniform vec3 uv1_offset;
 | 
			
		||||
 | 
			
		||||
uniform float windStrength = 0;
 | 
			
		||||
uniform vec2 windSpeed = vec2(1,1);
 | 
			
		||||
uniform float windScale = 1;
 | 
			
		||||
uniform sampler2D windNoise;
 | 
			
		||||
uniform vec2 windNoiseAngleOffset;
 | 
			
		||||
uniform vec2 windNoiseStrengthOffset;
 | 
			
		||||
uniform float windStart = 0;
 | 
			
		||||
uniform float windEnd = 1;
 | 
			
		||||
uniform float windWeightCurve:hint_range(0,1) = 0.5f;
 | 
			
		||||
uniform float windHeightCompensation :hint_range(0,1) = 0.5f;
 | 
			
		||||
 | 
			
		||||
void vertex() 
 | 
			
		||||
{
 | 
			
		||||
	UV = UV * uv1_scale.xy + uv1_offset.xy;
 | 
			
		||||
  
 | 
			
		||||
  float windAmount = normalizeToRange01( VERTEX.y, windStart, windEnd );
 | 
			
		||||
  float rawWindAmount = windAmount;
 | 
			
		||||
  windAmount = mix( windAmount, windAmount * windAmount, windWeightCurve );
 | 
			
		||||
  vec3 worldVertex = localToWorld( VERTEX, MODEL_MATRIX ).xyz;
 | 
			
		||||
  vec2 windUV = TIME * windSpeed + worldVertex.xz * windScale;
 | 
			
		||||
  float angle = texture( windNoise, windUV + windNoiseAngleOffset).r * PI * 2.0;
 | 
			
		||||
  float strength = texture( windNoise, windUV + windNoiseStrengthOffset ).r * windStrength;
 | 
			
		||||
  vec2 circle = onCircle( angle ) * strength;
 | 
			
		||||
  VERTEX = worldToLocal( worldVertex + vec3( circle.x, 0, circle.y ) * windAmount, MODEL_MATRIX );
 | 
			
		||||
  VERTEX.y = mix( VERTEX.y, max( 0, VERTEX.y - strength * windAmount), windHeightCompensation * 2.0f );
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fragment() 
 | 
			
		||||
{
 | 
			
		||||
	vec2 base_uv = UV;
 | 
			
		||||
 | 
			
		||||
	vec4 albedo_tex = texture(texture_albedo, base_uv);
 | 
			
		||||
	ALBEDO = albedo.rgb * albedo_tex.rgb;
 | 
			
		||||
  
 | 
			
		||||
	float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
 | 
			
		||||
	METALLIC = metallic_tex * metallic;
 | 
			
		||||
	SPECULAR = specular;
 | 
			
		||||
  
 | 
			
		||||
	vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
 | 
			
		||||
	float roughness_tex = dot(texture(texture_roughness, base_uv), roughness_texture_channel);
 | 
			
		||||
	ROUGHNESS = roughness_tex * roughness;
 | 
			
		||||
 | 
			
		||||
	NORMAL_MAP = texture(texture_normal, base_uv).rgb;
 | 
			
		||||
	NORMAL_MAP_DEPTH = normal_scale;
 | 
			
		||||
 | 
			
		||||
	AO = dot(texture(texture_ambient_occlusion, base_uv), ao_texture_channel);
 | 
			
		||||
	AO_LIGHT_AFFECT = ao_light_affect;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -181,6 +181,36 @@ namespace Rokojori
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Range GetRangeY()
 | 
			
		||||
    {
 | 
			
		||||
      var minY = float.MaxValue;
 | 
			
		||||
      var maxY = -float.MaxValue;
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < vertices.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        minY = Mathf.Min( minY, vertices[ i ].Y );
 | 
			
		||||
        maxY = Mathf.Max( maxY, vertices[ i ].Y );
 | 
			
		||||
      } 
 | 
			
		||||
 | 
			
		||||
      return new Range( minY, maxY );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void BlendNormalsOverY( Vector3 direction, float amount, float startY, float endY, Curve curve )
 | 
			
		||||
    {
 | 
			
		||||
      if ( amount <= 0 )
 | 
			
		||||
      {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < normals.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var yPositionAmount = MathX.RemapClamped( vertices[ i ].Y, startY, endY, 0, 1 );
 | 
			
		||||
        var blendAmount = curve.Sample( yPositionAmount ) * amount; 
 | 
			
		||||
        blendAmount = MathX.Clamp01( blendAmount );
 | 
			
		||||
        normals[ i ] = Math3D.BlendNormals( normals[ i ], direction, blendAmount );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Offset( Vector3 offset )
 | 
			
		||||
    {
 | 
			
		||||
      for ( int i = 0; i < vertices.Count; i++ )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Godot;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Rokojori
 | 
			
		||||
{
 | 
			
		||||
  public class MeshGeometryModifier
 | 
			
		||||
  {
 | 
			
		||||
    public MeshGeometry Modify( MeshGeometry mg ){ return mg; }
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,129 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Godot;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Rokojori
 | 
			
		||||
{
 | 
			
		||||
  public class SplinesDeformerMappingData
 | 
			
		||||
  {
 | 
			
		||||
    public Vector3 localPosition;
 | 
			
		||||
    public Vector3 localNormal;
 | 
			
		||||
    public float normalizedSplineParameter;
 | 
			
		||||
    public float weight;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public class SplinesDeformModifier
 | 
			
		||||
  {
 | 
			
		||||
    public SplineCurve[] sourceSplines;
 | 
			
		||||
    public SplineCurve[] targetSplines;
 | 
			
		||||
 | 
			
		||||
    public SplinesDeformerSettings settings;
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public MeshGeometry Modify( MeshGeometry mg )
 | 
			
		||||
    { 
 | 
			
		||||
      var mappings = CreateSourceMappings( mg );
 | 
			
		||||
      return CreateDeformed( mg, mappings ); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SplinesDeformerMappingData CreateSourceMapping( SplineCurve curve, Vector3 worldPosition, Vector3 worldNormal )
 | 
			
		||||
    {
 | 
			
		||||
      var closestParameter = curve.GetClosestParameterTo( worldPosition, settings.splineMappingResolution, settings.splineMappingDepth );
 | 
			
		||||
      var pointIndex = curve.NormalizedToPointIndex( closestParameter );
 | 
			
		||||
      var pose = curve.GetPoseByPointIndex( pointIndex );
 | 
			
		||||
      
 | 
			
		||||
      var localPosition = pose.ApplyInverse( worldPosition );
 | 
			
		||||
      var localNormal   = pose.rotation.Inverse() * worldNormal;
 | 
			
		||||
 | 
			
		||||
      var mappingData = new SplinesDeformerMappingData();
 | 
			
		||||
      
 | 
			
		||||
      mappingData.localPosition = localPosition;
 | 
			
		||||
      mappingData.localNormal   = localNormal;
 | 
			
		||||
      mappingData.normalizedSplineParameter = closestParameter;
 | 
			
		||||
      mappingData.weight = 0;
 | 
			
		||||
 | 
			
		||||
      return mappingData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SplinesDeformerMappingData[] CreateSourceMappings( MeshGeometry meshGeometry)
 | 
			
		||||
    {
 | 
			
		||||
      var mappingSize = meshGeometry.vertices.Count * sourceSplines.Length;
 | 
			
		||||
      
 | 
			
		||||
      var deformerMappings = new SplinesDeformerMappingData[ mappingSize];
 | 
			
		||||
       
 | 
			
		||||
      for ( int i = 0; i < meshGeometry.vertices.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var weights = 0f;
 | 
			
		||||
 | 
			
		||||
        for ( int j = 0; j < sourceSplines.Length; j++ )
 | 
			
		||||
        {
 | 
			
		||||
          var vertex = meshGeometry.vertices[ i ];
 | 
			
		||||
          var normal = meshGeometry.normals[ i ];
 | 
			
		||||
          var curve = sourceSplines[ j ];
 | 
			
		||||
          var mapping = CreateSourceMapping( curve, vertex, normal );
 | 
			
		||||
          
 | 
			
		||||
          var distance = curve.PositionAt( mapping.normalizedSplineParameter ) - vertex;
 | 
			
		||||
          var inverseWeight = MathX.NormalizeClamped( distance.Length(), settings.splineMinDistance, settings.splineMaxDistance );
 | 
			
		||||
          mapping.weight = 1f - inverseWeight; 
 | 
			
		||||
          weights += mapping.weight;
 | 
			
		||||
          deformerMappings[ i * sourceSplines.Length + j  ] = mapping;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ( weights > 0 && weights != 1f )
 | 
			
		||||
        {
 | 
			
		||||
          for ( int j = 0; j < sourceSplines.Length; j++ )
 | 
			
		||||
          {
 | 
			
		||||
            var mapping = deformerMappings[ i * sourceSplines.Length + j  ];
 | 
			
		||||
            mapping.weight /= weights;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return deformerMappings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MeshGeometry CreateDeformed( MeshGeometry meshGeometry,  SplinesDeformerMappingData[] mappingData )
 | 
			
		||||
    {
 | 
			
		||||
      var cloned = meshGeometry.Clone();
 | 
			
		||||
 | 
			
		||||
      for ( int i = 0; i < cloned.vertices.Count; i++ )
 | 
			
		||||
      {
 | 
			
		||||
        var vertex = Vector3.Zero;
 | 
			
		||||
        var normal = Vector3.Zero;
 | 
			
		||||
 | 
			
		||||
        for ( int j = 0; j < targetSplines.Length; j++ )
 | 
			
		||||
        {
 | 
			
		||||
          var mapping = mappingData[ i * targetSplines.Length + j  ];
 | 
			
		||||
          var curve = targetSplines[ j ];
 | 
			
		||||
 | 
			
		||||
          if ( settings.targetSmoothing > 0 )
 | 
			
		||||
          {            
 | 
			
		||||
            var pose = curve.SmoothedPoseAt( mapping.normalizedSplineParameter, settings.targetSmoothing * 0.5f, 2, settings.targetSmoothing ); 
 | 
			
		||||
            pose.ApplyTwist( curve.TwistAt( mapping.normalizedSplineParameter ) );
 | 
			
		||||
            vertex += pose.Apply( mapping.localPosition ) * mapping.weight;
 | 
			
		||||
            normal += pose.rotation * mapping.localNormal * mapping.weight;
 | 
			
		||||
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          { 
 | 
			
		||||
            var pose = curve.PoseAt( mapping.normalizedSplineParameter );
 | 
			
		||||
            pose.ApplyTwist( curve.TwistAt( mapping.normalizedSplineParameter ) );
 | 
			
		||||
            vertex += pose.Apply( mapping.localPosition ) * mapping.weight;
 | 
			
		||||
            normal += pose.rotation * mapping.localNormal * mapping.weight;
 | 
			
		||||
          } 
 | 
			
		||||
          
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cloned.vertices[ i ] = vertex;
 | 
			
		||||
        cloned.normals[ i ] = normal.Normalized();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return cloned;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Godot;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Rokojori
 | 
			
		||||
{
 | 
			
		||||
  [GlobalClass,Tool]
 | 
			
		||||
  public partial class SplinesDeformerSettings:Resource
 | 
			
		||||
  {
 | 
			
		||||
    [Export( PropertyHint.Range, "0,1")]
 | 
			
		||||
    public float targetSmoothing = 0f;
 | 
			
		||||
 | 
			
		||||
    [ExportGroup( "Spline Settings")]
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public float splineMaxDistance = 1000f;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public float splineMinDistance = 0f;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public int splineMappingResolution = 40;
 | 
			
		||||
 | 
			
		||||
    [Export]
 | 
			
		||||
    public int splineMappingDepth = 3;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ namespace Rokojori
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    public class MappingData
 | 
			
		||||
    public class DeformerMappingData
 | 
			
		||||
    {
 | 
			
		||||
      public Vector3 localPosition;
 | 
			
		||||
      public Vector3 localNormal;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,10 +72,10 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    MappingData[] deformerMappings;
 | 
			
		||||
    DeformerMappingData[] deformerMappings;
 | 
			
		||||
    MeshGeometry meshGeometry;
 | 
			
		||||
 | 
			
		||||
    MappingData CreateSourceMapping( Spline s, Vector3 worldPosition, Vector3 worldNormal )
 | 
			
		||||
    DeformerMappingData CreateSourceMapping( Spline s, Vector3 worldPosition, Vector3 worldNormal )
 | 
			
		||||
    {
 | 
			
		||||
      var curve = s.GetCurve();
 | 
			
		||||
      var closestParameter = curve.GetClosestParameterTo( worldPosition, splineMappingResolution, splineMappingDepth );
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ namespace Rokojori
 | 
			
		|||
      var localPosition = pose.ApplyInverse( worldPosition );
 | 
			
		||||
      var localNormal   = pose.rotation.Inverse() * worldNormal;
 | 
			
		||||
 | 
			
		||||
      var mappingData = new MappingData();
 | 
			
		||||
      var mappingData = new DeformerMappingData();
 | 
			
		||||
      
 | 
			
		||||
      mappingData.localPosition = localPosition;
 | 
			
		||||
      mappingData.localNormal   = localNormal;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
      if ( deformerMappings == null || deformerMappings.Length != mappingSize )
 | 
			
		||||
      {
 | 
			
		||||
        deformerMappings = new MappingData[ mappingSize];
 | 
			
		||||
        deformerMappings = new DeformerMappingData[ mappingSize];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.LogInfo( "Mappings:", deformerMappings.Length, meshGeometry );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ namespace Rokojori
 | 
			
		|||
      }
 | 
			
		||||
      else if ( node is CsgPrimitive3D )
 | 
			
		||||
      {
 | 
			
		||||
        return ReflectionHelper.GetMemberValue( node, "material" ) as M;
 | 
			
		||||
        return ReflectionHelper.GetDataMemberValue<M>( node, "material" );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      else if ( node is GpuParticles3D gp)
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
      if ( node is CsgPrimitive3D csg )
 | 
			
		||||
      {
 | 
			
		||||
        ReflectionHelper.SetMemberValue( node, "material", material );
 | 
			
		||||
        ReflectionHelper.SetDataMemberValue( node, "material", material );
 | 
			
		||||
 | 
			
		||||
        if ( csg.MaterialOverride != null )
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,7 +260,7 @@ namespace Rokojori
 | 
			
		|||
 | 
			
		||||
    void SetMemberValue( object instance, string name, object value )
 | 
			
		||||
    {
 | 
			
		||||
      ReflectionHelper.SetMemberValue( instance, name, value );
 | 
			
		||||
      ReflectionHelper.SetDataMemberValue( instance, name, value );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetListValue( IList list, int index, object value )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ namespace Rokojori
 | 
			
		|||
        } 
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          ReflectionHelper.SetMemberValue( target, name, value );
 | 
			
		||||
          ReflectionHelper.SetDataMemberValue( target, name, value );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,6 +187,7 @@ namespace Rokojori
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public static FieldInfo GetFieldInfo( object instance, string memberName )
 | 
			
		||||
    {
 | 
			
		||||
      var type = instance.GetType();
 | 
			
		||||
| 
						 | 
				
			
			@ -205,58 +206,87 @@ namespace Rokojori
 | 
			
		|||
      return index == -1 ? null : fields[ index ];
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    public static bool HasMember( object instance, string memberName )
 | 
			
		||||
    /*public static bool HasMember( object instance, string memberName )
 | 
			
		||||
    {
 | 
			
		||||
      return GetFieldInfo( instance, memberName ) != null;
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    public static MemberInfo GetDataMemberInfo( object instance, string memberName, BindingFlags flags = BindingFlags.Public | BindingFlags.Instance )
 | 
			
		||||
    {
 | 
			
		||||
      var type = instance.GetType();
 | 
			
		||||
      var fieldInfo = type.GetField( memberName, flags );
 | 
			
		||||
      
 | 
			
		||||
      if ( fieldInfo != null )
 | 
			
		||||
      {
 | 
			
		||||
        return fieldInfo;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
    public static object GetMemberValue( object instance, string memberName )
 | 
			
		||||
    {
 | 
			
		||||
      try
 | 
			
		||||
      {
 | 
			
		||||
        var field = ReflectionHelper.GetFieldInfo( instance, memberName );
 | 
			
		||||
        
 | 
			
		||||
        if ( field == null )
 | 
			
		||||
        {
 | 
			
		||||
          RJLog.Log(instance, "GetValue: member not found with name ", "'" + memberName + "'" );
 | 
			
		||||
 | 
			
		||||
          return null;
 | 
			
		||||
      return type.GetProperty( memberName, flags );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        return field.GetValue( instance );
 | 
			
		||||
    public const BindingFlags defaultBindings =  BindingFlags.Public | 
 | 
			
		||||
                                                 BindingFlags.NonPublic | 
 | 
			
		||||
                                                 BindingFlags.Instance | 
 | 
			
		||||
                                                 BindingFlags.Static;
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
      catch( System.Exception e )
 | 
			
		||||
    public static bool HasDataMember( object instance, string memberName, BindingFlags flags = ReflectionHelper.defaultBindings )
 | 
			
		||||
    {
 | 
			
		||||
        RJLog.Log(e );
 | 
			
		||||
      return GetDataMemberInfo( instance, memberName, flags ) != null;
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
      return null;      
 | 
			
		||||
    public static T GetDataMemberValue<T>( object instance, string memberName, BindingFlags flags = ReflectionHelper.defaultBindings ) 
 | 
			
		||||
    {
 | 
			
		||||
      var info = GetDataMemberInfo( instance, memberName, flags );
 | 
			
		||||
 | 
			
		||||
      if ( info == null )
 | 
			
		||||
      {
 | 
			
		||||
        return default(T);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    public static void SetMemberValue( object instance, string memberName, object value )
 | 
			
		||||
      if ( info is FieldInfo fieldInfo )
 | 
			
		||||
      {
 | 
			
		||||
      try
 | 
			
		||||
      {
 | 
			
		||||
        var field = ReflectionHelper.GetFieldInfo( instance, memberName );
 | 
			
		||||
        return (T) fieldInfo.GetValue( instance );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
        if ( field == null )
 | 
			
		||||
      if ( info is PropertyInfo propertyInfo )
 | 
			
		||||
      {
 | 
			
		||||
          RJLog.Log(instance, "SetValue: member not found with name ", "'" + memberName + "'" );
 | 
			
		||||
        return (T) propertyInfo.GetValue( instance );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return default(T);
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void SetDataMemberValue( object instance, string memberName, object value, BindingFlags flags = ReflectionHelper.defaultBindings )
 | 
			
		||||
    {
 | 
			
		||||
      var info = GetDataMemberInfo( instance, memberName, flags );
 | 
			
		||||
 | 
			
		||||
      if ( info == null )
 | 
			
		||||
      {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
        field.SetValue( instance, value );
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
      catch( System.Exception e )
 | 
			
		||||
      if ( info is FieldInfo fieldInfo )
 | 
			
		||||
      {
 | 
			
		||||
        RJLog.Log(e );
 | 
			
		||||
        fieldInfo.SetValue( instance, value );
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ( info is PropertyInfo propertyInfo )
 | 
			
		||||
      {
 | 
			
		||||
        propertyInfo.SetValue( instance, value );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void CopyDataMembersFromTo( object source, object target, List<string> dataMembers )
 | 
			
		||||
    {
 | 
			
		||||
      dataMembers.ForEach(
 | 
			
		||||
        dm =>
 | 
			
		||||
        {
 | 
			
		||||
          var value = GetDataMemberValue<object>( source, dm );
 | 
			
		||||
          SetDataMemberValue( target, dm, value );
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue