From acfed9eda62bec51a644b66a4b955ed4fde4db64 Mon Sep 17 00:00:00 2001 From: Josef Date: Fri, 10 Jan 2025 11:45:38 +0100 Subject: [PATCH] Spline Deformer Fix --- Runtime/Math/Geometry/Pose.cs | 2 +- Runtime/Math/Math3D.cs | 7 +++- .../Parametric/Deformer/Deformer.cs | 36 +++++++++++-------- .../Procedural/Parametric/Spline/Spline.cs | 19 ++++++---- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/Runtime/Math/Geometry/Pose.cs b/Runtime/Math/Geometry/Pose.cs index 9e109ed..93c6b30 100644 --- a/Runtime/Math/Geometry/Pose.cs +++ b/Runtime/Math/Geometry/Pose.cs @@ -167,7 +167,7 @@ namespace Rokojori public Vector3 ApplyInverse( Vector3 p ) { p -= position; - p = rotation.Inverse() * p; + p = rotation.Inverse() * p; return p; } diff --git a/Runtime/Math/Math3D.cs b/Runtime/Math/Math3D.cs index e254b32..8734ca9 100644 --- a/Runtime/Math/Math3D.cs +++ b/Runtime/Math/Math3D.cs @@ -446,8 +446,13 @@ namespace Rokojori node.SetGlobalQuaternion( node.GetGlobalQuaternion() * rotation ); } - public static void LookTowards( this Node3D node, Vector3 forward, Vector3 up ) + public static void LookTowards( this Node3D node, Vector3 forward, Vector3 up, Vector3? up2 = null ) { + if ( forward == up ) + { + up = up2 == null ? Vector3.Back : (Vector3)up2; + } + node.LookAt( forward + node.GlobalPosition, up ); } diff --git a/Runtime/Procedural/Parametric/Deformer/Deformer.cs b/Runtime/Procedural/Parametric/Deformer/Deformer.cs index a617439..c68dd7f 100644 --- a/Runtime/Procedural/Parametric/Deformer/Deformer.cs +++ b/Runtime/Procedural/Parametric/Deformer/Deformer.cs @@ -5,11 +5,7 @@ using System.Collections.Generic; namespace Rokojori { - - - - [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Spline.svg") ] public partial class Deformer : Node3D @@ -21,7 +17,7 @@ namespace Rokojori public class MappingData { public Vector3 localPosition; - public float parameter; + public float normalizedSplineParameter; public float weight; } @@ -30,6 +26,14 @@ namespace Rokojori Max_Distance } + [Export] + public bool update = false; + + [Export] + public bool updateAlways = false; + + [ExportGroup( "Input")] + [Export] public Spline[] sourceSplines; @@ -39,6 +43,7 @@ namespace Rokojori [Export] public bool updateSourceMesh; + [ExportGroup( "Output")] [Export] public Spline[] deformerSplines; @@ -48,6 +53,9 @@ namespace Rokojori [Export( PropertyHint.Range, "0,1")] public float targetSmoothing = 0f; + + [ExportGroup( "Spline Settings")] + [Export] public float splineMaxDistance = 1000f; @@ -60,11 +68,7 @@ namespace Rokojori [Export] public int splineMappingDepth = 3; - [Export] - public bool update = false; - [Export] - public bool updateAlways = false; MappingData[] deformerMappings; @@ -74,14 +78,15 @@ namespace Rokojori { var curve = s.GetCurve(); var closestParameter = curve.GetClosestParameterTo( worldPosition, splineMappingResolution, splineMappingDepth ); - var pose = curve.GetPoseByPointIndex( closestParameter ); + var pointIndex = curve.NormalizedToPointIndex( closestParameter ); + var pose = curve.GetPoseByPointIndex( pointIndex ); var localPosition = pose.ApplyInverse( worldPosition ); var mappingData = new MappingData(); mappingData.localPosition = localPosition; - mappingData.parameter = closestParameter; + mappingData.normalizedSplineParameter = closestParameter; mappingData.weight = 0; return mappingData; @@ -109,7 +114,7 @@ namespace Rokojori var vertex = meshGeometry.vertices[ i ]; var mapping = CreateSourceMapping( sourceSplines[ j ], vertex ); var curve = sourceSplines[ j ].GetCurve(); - var distance = curve.PositionAt( mapping.parameter ) - vertex; + var distance = curve.PositionAt( mapping.normalizedSplineParameter ) - vertex; var inverseWeight = MathX.NormalizeClamped( distance.Length(), splineMinDistance, splineMaxDistance ); mapping.weight = 1f - inverseWeight; weights += mapping.weight; @@ -144,14 +149,15 @@ namespace Rokojori if ( targetSmoothing > 0 ) { - var pose = curve.SmoothedPoseAt( mapping.parameter, targetSmoothing * 0.5f, 2, targetSmoothing ); + var pose = curve.SmoothedPoseAt( mapping.normalizedSplineParameter, targetSmoothing * 0.5f, 2, targetSmoothing ); + pose.ApplyTwist( curve.TwistAt( mapping.normalizedSplineParameter ) ); vertexPosition += pose.Apply( mapping.localPosition ) * mapping.weight; } else { - var pose = curve.PoseAt( mapping.parameter ); - pose.ApplyTwist( curve.TwistAt( mapping.parameter ) ); + var pose = curve.PoseAt( mapping.normalizedSplineParameter ); + pose.ApplyTwist( curve.TwistAt( mapping.normalizedSplineParameter ) ); vertexPosition += pose.Apply( mapping.localPosition ) * mapping.weight; } diff --git a/Runtime/Procedural/Parametric/Spline/Spline.cs b/Runtime/Procedural/Parametric/Spline/Spline.cs index 4fc37e4..2d64717 100644 --- a/Runtime/Procedural/Parametric/Spline/Spline.cs +++ b/Runtime/Procedural/Parametric/Spline/Spline.cs @@ -37,7 +37,6 @@ namespace Rokojori [Export] public Vector3 autoOrientationUp = Vector3.Up; - [Export] public bool updateAlways = false; @@ -238,25 +237,33 @@ namespace Rokojori return; } + var up = autoOrientationUp.Normalized(); + if ( SplineAutoOrientationMode.Next_Neighbor == autoOrientationMode ) { + + for ( int i = 0; i < list.Count; i++ ) { - var sp = list[ i ]; + var point = list[ i ]; if ( i == ( list.Count - 1 ) ) { if ( closed ) { var first = list[ 0 ]; - sp.LookAt( first.GlobalPosition, autoOrientationUp ); + var firstDirection = ( first.GlobalPosition - point.GlobalPosition ).Normalized(); + point.LookTowards( firstDirection, up); } continue; } var next = list[ i + 1 ]; - sp.LookAt( next.GlobalPosition, autoOrientationUp ); + + var direction = ( next.GlobalPosition - point.GlobalPosition ).Normalized(); + + point.LookTowards( direction, up ); } } else if ( SplineAutoOrientationMode.Tangent == autoOrientationMode ) @@ -264,7 +271,7 @@ namespace Rokojori for ( int i = 0; i < list.Count; i++ ) { - var sp = list[ i ]; + var point = list[ i ]; var tangentForward = Vector3.Zero; @@ -282,7 +289,7 @@ namespace Rokojori continue; } - sp.LookAt( sp.GlobalPosition + tangentForward, autoOrientationUp ); + point.LookTowards( tangentForward, up ); } }