T Out Parameter for Get Nearest Point
This commit is contained in:
parent
56e460a95b
commit
5fba9784c2
@ -4,187 +4,191 @@ using System;
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Splines;
|
using UnityEngine.Splines;
|
||||||
using static SplineImporter;
|
|
||||||
using static SplineData;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
[CustomEditor(typeof(SplineImporter))]
|
namespace FrameJosh.SplineImporter
|
||||||
public class SplineImporterEditor : Editor
|
|
||||||
{
|
{
|
||||||
public override void OnInspectorGUI()
|
using static SplineImporter;
|
||||||
|
using static SplineData;
|
||||||
|
|
||||||
|
[CustomEditor(typeof(SplineImporter))]
|
||||||
|
public class SplineImporterEditor : Editor
|
||||||
{
|
{
|
||||||
DrawDefaultInspector();
|
public override void OnInspectorGUI()
|
||||||
|
|
||||||
if (GUILayout.Button("Import Spline"))
|
|
||||||
{
|
{
|
||||||
SplineImporter splineImporter = target as SplineImporter;
|
DrawDefaultInspector();
|
||||||
|
|
||||||
splineImporter.name = splineImporter.splineData.name;
|
if (GUILayout.Button("Import Spline"))
|
||||||
|
|
||||||
SplineData splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
|
||||||
|
|
||||||
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
|
||||||
|
|
||||||
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
|
||||||
splineContainer.RemoveSpline(thisSpline);
|
|
||||||
|
|
||||||
foreach (SplineData.Spline thisDataSpline in splineData.splines)
|
|
||||||
{
|
{
|
||||||
UnityEngine.Splines.Spline thisSpline = splineContainer.AddSpline();
|
SplineImporter splineImporter = target as SplineImporter;
|
||||||
|
|
||||||
thisSpline.Closed = thisDataSpline.closed;
|
splineImporter.name = splineImporter.splineData.name;
|
||||||
|
|
||||||
foreach (ControlPoint thisControlPoint in thisDataSpline.controlPoints)
|
SplineData splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
||||||
|
|
||||||
|
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
|
|
||||||
|
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
||||||
|
splineContainer.RemoveSpline(thisSpline);
|
||||||
|
|
||||||
|
foreach (SplineData.Spline thisDataSpline in splineData.splines)
|
||||||
{
|
{
|
||||||
Vector3 position = PositionToVector(thisControlPoint.position);
|
UnityEngine.Splines.Spline thisSpline = splineContainer.AddSpline();
|
||||||
|
|
||||||
Vector3 handleL = PositionToVector(thisControlPoint.handleL);
|
thisSpline.Closed = thisDataSpline.closed;
|
||||||
|
|
||||||
Vector3 handleR = PositionToVector(thisControlPoint.handleR);
|
foreach (ControlPoint thisControlPoint in thisDataSpline.controlPoints)
|
||||||
|
|
||||||
Quaternion rotation = Quaternion.LookRotation(handleR - position, Vector3.up) * Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
|
||||||
|
|
||||||
float3x3 rotationMatrix = new float3x3(rotation);
|
|
||||||
|
|
||||||
thisSpline.Add(new()
|
|
||||||
{
|
{
|
||||||
Position = position * splineImporter.scale,
|
Vector3 position = PositionToVector(thisControlPoint.position);
|
||||||
Rotation = rotation,
|
|
||||||
TangentIn = ((Vector3)math.mul(handleL - position, rotationMatrix)) * splineImporter.scale,
|
Vector3 handleL = PositionToVector(thisControlPoint.handleL);
|
||||||
TangentOut = ((Vector3)math.mul(handleR - position, rotationMatrix)) * splineImporter.scale
|
|
||||||
},
|
Vector3 handleR = PositionToVector(thisControlPoint.handleR);
|
||||||
TangentMode.Broken);
|
|
||||||
|
Quaternion rotation = Quaternion.LookRotation(handleR - position, Vector3.up) * Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
||||||
|
|
||||||
|
float3x3 rotationMatrix = new float3x3(rotation);
|
||||||
|
|
||||||
|
thisSpline.Add(new()
|
||||||
|
{
|
||||||
|
Position = position * splineImporter.scale,
|
||||||
|
Rotation = rotation,
|
||||||
|
TangentIn = ((Vector3)math.mul(handleL - position, rotationMatrix)) * splineImporter.scale,
|
||||||
|
TangentOut = ((Vector3)math.mul(handleR - position, rotationMatrix)) * splineImporter.scale
|
||||||
|
},
|
||||||
|
TangentMode.Broken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (GUILayout.Button("Export Spline"))
|
if (GUILayout.Button("Export Spline"))
|
||||||
{
|
|
||||||
SplineImporter splineImporter = target as SplineImporter;
|
|
||||||
|
|
||||||
if (!splineImporter.splineData)
|
|
||||||
{
|
{
|
||||||
string path = "Assets" + EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json").Substring(Application.dataPath.Length);
|
SplineImporter splineImporter = target as SplineImporter;
|
||||||
|
|
||||||
if (path.Length > 0)
|
if (!splineImporter.splineData)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
string path = "Assets" + EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json").Substring(Application.dataPath.Length);
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
if (path.Length > 0)
|
||||||
|
|
||||||
TextAsset textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
|
||||||
|
|
||||||
splineImporter.splineData = textAsset;
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
|
||||||
|
|
||||||
SplineData splineData = new();
|
|
||||||
|
|
||||||
splineData.splines = new SplineData.Spline[splineContainer.Splines.Count];
|
|
||||||
|
|
||||||
List<SplineData.Spline> dataSplines = new();
|
|
||||||
|
|
||||||
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
|
||||||
{
|
|
||||||
List<ControlPoint> controlPoints = new();
|
|
||||||
|
|
||||||
foreach (BezierKnot thisBezierKnot in thisSpline.Knots)
|
|
||||||
{
|
|
||||||
Position position = VectorToPosition(thisBezierKnot.Position);
|
|
||||||
|
|
||||||
float3x3 rotationMatrix = new float3x3(Quaternion.Inverse(thisBezierKnot.Rotation));
|
|
||||||
|
|
||||||
Position handleL = VectorToPosition(math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position);
|
|
||||||
|
|
||||||
Position handleR = VectorToPosition(math.mul(thisBezierKnot.TangentOut, rotationMatrix) + thisBezierKnot.Position);
|
|
||||||
|
|
||||||
controlPoints.Add(new()
|
|
||||||
{
|
{
|
||||||
position = position,
|
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
||||||
handleL = handleL,
|
|
||||||
handleR = handleR
|
AssetDatabase.Refresh();
|
||||||
|
|
||||||
|
TextAsset textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
||||||
|
|
||||||
|
splineImporter.splineData = textAsset;
|
||||||
|
}
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
|
|
||||||
|
SplineData splineData = new();
|
||||||
|
|
||||||
|
splineData.splines = new SplineData.Spline[splineContainer.Splines.Count];
|
||||||
|
|
||||||
|
List<SplineData.Spline> dataSplines = new();
|
||||||
|
|
||||||
|
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
||||||
|
{
|
||||||
|
List<ControlPoint> controlPoints = new();
|
||||||
|
|
||||||
|
foreach (BezierKnot thisBezierKnot in thisSpline.Knots)
|
||||||
|
{
|
||||||
|
Position position = VectorToPosition(thisBezierKnot.Position);
|
||||||
|
|
||||||
|
float3x3 rotationMatrix = new float3x3(Quaternion.Inverse(thisBezierKnot.Rotation));
|
||||||
|
|
||||||
|
Position handleL = VectorToPosition(math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position);
|
||||||
|
|
||||||
|
Position handleR = VectorToPosition(math.mul(thisBezierKnot.TangentOut, rotationMatrix) + thisBezierKnot.Position);
|
||||||
|
|
||||||
|
controlPoints.Add(new()
|
||||||
|
{
|
||||||
|
position = position,
|
||||||
|
handleL = handleL,
|
||||||
|
handleR = handleR
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSplines.Add(new()
|
||||||
|
{
|
||||||
|
controlPoints = controlPoints.ToArray(),
|
||||||
|
closed = thisSpline.Closed
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSplines.Add(new()
|
splineData.splines = dataSplines.ToArray();
|
||||||
{
|
|
||||||
controlPoints = controlPoints.ToArray(),
|
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData), JsonUtility.ToJson(splineData, true));
|
||||||
closed = thisSpline.Closed
|
|
||||||
});
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
splineData.splines = dataSplines.ToArray();
|
|
||||||
|
|
||||||
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData), JsonUtility.ToJson(splineData, true));
|
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[RequireComponent(typeof(SplineContainer))]
|
[RequireComponent(typeof(SplineContainer))]
|
||||||
public class SplineImporter : MonoBehaviour
|
public class SplineImporter : MonoBehaviour
|
||||||
{
|
|
||||||
public TextAsset splineData;
|
|
||||||
|
|
||||||
public float scale = 1;
|
|
||||||
|
|
||||||
public static Vector3 PositionToVector(Position position)
|
|
||||||
{
|
{
|
||||||
return new(position.x, position.z, position.y);
|
public TextAsset splineData;
|
||||||
}
|
|
||||||
|
|
||||||
public static Position VectorToPosition(Vector3 vector)
|
public float scale = 1;
|
||||||
{
|
|
||||||
return new()
|
public static Vector3 PositionToVector(Position position)
|
||||||
{
|
{
|
||||||
x = vector.x,
|
return new(position.x, position.z, position.y);
|
||||||
y = vector.z,
|
}
|
||||||
z = vector.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
public static Position VectorToPosition(Vector3 vector)
|
||||||
public class SplineData
|
{
|
||||||
{
|
return new()
|
||||||
[Serializable]
|
{
|
||||||
public struct Position
|
x = vector.x,
|
||||||
{
|
y = vector.z,
|
||||||
public float x;
|
z = vector.y
|
||||||
|
};
|
||||||
public float y;
|
}
|
||||||
|
|
||||||
public float z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct ControlPoint
|
public class SplineData
|
||||||
{
|
{
|
||||||
public Position position;
|
[Serializable]
|
||||||
|
public struct Position
|
||||||
|
{
|
||||||
|
public float x;
|
||||||
|
|
||||||
public Position handleL;
|
public float y;
|
||||||
|
|
||||||
public Position handleR;
|
public float z;
|
||||||
|
}
|
||||||
|
|
||||||
public float tilt;
|
[Serializable]
|
||||||
|
public struct ControlPoint
|
||||||
|
{
|
||||||
|
public Position position;
|
||||||
|
|
||||||
|
public Position handleL;
|
||||||
|
|
||||||
|
public Position handleR;
|
||||||
|
|
||||||
|
public float tilt;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct Spline
|
||||||
|
{
|
||||||
|
public ControlPoint[] controlPoints;
|
||||||
|
|
||||||
|
public bool closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Spline[] splines = new Spline[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public struct Spline
|
|
||||||
{
|
|
||||||
public ControlPoint[] controlPoints;
|
|
||||||
|
|
||||||
public bool closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Spline[] splines = new Spline[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
@ -2,194 +2,231 @@ using Unity.Mathematics;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Splines;
|
using UnityEngine.Splines;
|
||||||
|
|
||||||
public class SplinePlus : MonoBehaviour
|
namespace FrameJosh.SplineImporter
|
||||||
{
|
{
|
||||||
public SplineContainer splineContainer;
|
public class SplinePlus : MonoBehaviour
|
||||||
|
|
||||||
public SplineContainer deformContainer;
|
|
||||||
|
|
||||||
public int resolution;
|
|
||||||
|
|
||||||
public void Evaluate(int splineIndex, float anchor, float distance, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
{
|
||||||
float t = anchor + (distance / splineContainer.Spline.GetLength());
|
public SplineContainer splineContainer;
|
||||||
|
|
||||||
if (deformContainer)
|
public SplineContainer deformContainer;
|
||||||
DeformSpline(splineIndex, t, out position, out rotation);
|
|
||||||
else
|
|
||||||
EvaluateSpline(splineIndex, t, out position, out rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Evaluate(float anchor, float distance, out Vector3 position, out Quaternion rotation)
|
public int resolution = 1;
|
||||||
{
|
|
||||||
float t = anchor + (distance / splineContainer.Spline.GetLength());
|
|
||||||
|
|
||||||
if (deformContainer)
|
public void Evaluate(int splineIndex, float anchor, float distance, out Vector3 position, out Quaternion rotation)
|
||||||
DeformSpline(t, out position, out rotation);
|
|
||||||
else
|
|
||||||
EvaluateSpline(t, out position, out rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetNearestPoint(Vector3 point, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
|
||||||
position = Vector3.zero;
|
|
||||||
|
|
||||||
rotation = Quaternion.identity;
|
|
||||||
|
|
||||||
float nearestDistance = Mathf.Infinity;
|
|
||||||
|
|
||||||
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
|
||||||
{
|
{
|
||||||
int resolutionScale = Mathf.CeilToInt(splineContainer.Splines[i].GetLength()) * resolution;
|
float t = anchor + (distance / splineContainer.Spline.GetLength());
|
||||||
|
|
||||||
for (float j = 0; j <= resolutionScale; j++)
|
if (deformContainer)
|
||||||
|
DeformSpline(splineIndex, t, out position, out rotation);
|
||||||
|
else
|
||||||
|
EvaluateSpline(splineIndex, t, out position, out rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Evaluate(float anchor, float distance, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
float t = anchor + (distance / splineContainer.Spline.GetLength());
|
||||||
|
|
||||||
|
if (deformContainer)
|
||||||
|
DeformSpline(t, out position, out rotation);
|
||||||
|
else
|
||||||
|
EvaluateSpline(t, out position, out rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetNearestPoint(int splineIndex, Vector3 point, out Vector3 position, out Quaternion rotation, out float t)
|
||||||
|
{
|
||||||
|
position = Vector3.zero;
|
||||||
|
|
||||||
|
rotation = Quaternion.identity;
|
||||||
|
|
||||||
|
t = 0;
|
||||||
|
|
||||||
|
float nearestDistance = Mathf.Infinity;
|
||||||
|
|
||||||
|
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
||||||
{
|
{
|
||||||
Evaluate(i, j / resolutionScale, 0, out Vector3 thisPosition, out Quaternion thisRotation);
|
int resolutionScale = Mathf.CeilToInt(splineContainer.Splines[i].GetLength()) * resolution;
|
||||||
|
|
||||||
float thisDistance = Vector3.Distance(point, thisPosition);
|
for (float j = 0; j <= resolutionScale; j++)
|
||||||
|
|
||||||
if (thisDistance < nearestDistance)
|
|
||||||
{
|
{
|
||||||
position = thisPosition;
|
Evaluate(i, j / resolutionScale, 0, out Vector3 thisPosition, out Quaternion thisRotation);
|
||||||
|
|
||||||
rotation = thisRotation;
|
float thisDistance = Vector3.Distance(point, thisPosition);
|
||||||
|
|
||||||
nearestDistance = thisDistance;
|
if (thisDistance < nearestDistance)
|
||||||
|
{
|
||||||
|
position = thisPosition;
|
||||||
|
|
||||||
|
rotation = thisRotation;
|
||||||
|
|
||||||
|
t = j / resolutionScale;
|
||||||
|
|
||||||
|
nearestDistance = thisDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetNearestPoint(Vector3 point, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
position = Vector3.zero;
|
||||||
|
|
||||||
|
rotation = Quaternion.identity;
|
||||||
|
|
||||||
|
float nearestDistance = Mathf.Infinity;
|
||||||
|
|
||||||
|
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
||||||
|
{
|
||||||
|
int resolutionScale = Mathf.CeilToInt(splineContainer.Splines[i].GetLength()) * resolution;
|
||||||
|
|
||||||
|
for (float j = 0; j <= resolutionScale; j++)
|
||||||
|
{
|
||||||
|
Evaluate(i, j / resolutionScale, 0, out Vector3 thisPosition, out Quaternion thisRotation);
|
||||||
|
|
||||||
|
float thisDistance = Vector3.Distance(point, thisPosition);
|
||||||
|
|
||||||
|
if (thisDistance < nearestDistance)
|
||||||
|
{
|
||||||
|
position = thisPosition;
|
||||||
|
|
||||||
|
rotation = thisRotation;
|
||||||
|
|
||||||
|
nearestDistance = thisDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvaluateSpline(int splineIndex, float t, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
ScaledEvaluate(splineContainer, splineIndex, t, out float3 position1, out float3 tangent, out float3 upVector);
|
||||||
|
|
||||||
|
position = position1;
|
||||||
|
|
||||||
|
rotation = Quaternion.LookRotation(tangent, upVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvaluateSpline(float t, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
splineContainer.Evaluate(t, out float3 position1, out float3 tangent, out float3 upVector);
|
||||||
|
|
||||||
|
position = position1;
|
||||||
|
|
||||||
|
rotation = Quaternion.LookRotation(tangent, upVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeformSpline(int splineIndex, float t, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
int resolutionScale = Mathf.CeilToInt(splineContainer.Splines[splineIndex].GetLength()) * resolution;
|
||||||
|
|
||||||
|
position = EvaluatePoint(splineIndex, t);
|
||||||
|
|
||||||
|
float t1 = Mathf.Clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
||||||
|
|
||||||
|
Vector3 position0 = EvaluatePoint(splineIndex, t1);
|
||||||
|
|
||||||
|
Vector3 position1 = EvaluatePoint(splineIndex, t1 + (1 / (float)resolutionScale));
|
||||||
|
|
||||||
|
Vector3 difference = position1 - position0;
|
||||||
|
|
||||||
|
rotation = Mathf.Abs(Vector3.Dot(difference, Vector3.up)) > 0
|
||||||
|
? Quaternion.LookRotation(difference, Vector3.up)
|
||||||
|
: Quaternion.FromToRotation(Vector3.forward, difference);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeformSpline(float t, out Vector3 position, out Quaternion rotation)
|
||||||
|
{
|
||||||
|
int resolutionScale = Mathf.CeilToInt(splineContainer.CalculateLength()) * resolution;
|
||||||
|
|
||||||
|
position = EvaluatePoint(t);
|
||||||
|
|
||||||
|
float t1 = Mathf.Clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
||||||
|
|
||||||
|
Vector3 position0 = EvaluatePoint(t1);
|
||||||
|
|
||||||
|
Vector3 position1 = EvaluatePoint(t1 + (1 / (float)resolutionScale));
|
||||||
|
|
||||||
|
Vector3 difference = position1 - position0;
|
||||||
|
|
||||||
|
rotation = Mathf.Abs(Vector3.Dot(difference, Vector3.up)) > 0
|
||||||
|
? Quaternion.LookRotation(difference, Vector3.up)
|
||||||
|
: Quaternion.FromToRotation(Vector3.forward, difference);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 EvaluatePoint(int splineIndex, float t)
|
||||||
|
{
|
||||||
|
ScaledEvaluate(splineContainer, splineIndex, t, out float3 position, out _, out _);
|
||||||
|
|
||||||
|
ScaledEvaluate(deformContainer, 0, position.x / deformContainer.Spline.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
||||||
|
|
||||||
|
float3x3 deformMatrix = new()
|
||||||
|
{
|
||||||
|
c0 = (float3)Vector3.Normalize(Vector3.Cross(deformTangent, deformUpVector)),
|
||||||
|
c1 = (float3)Vector3.Normalize(deformUpVector),
|
||||||
|
c2 = (float3)Vector3.Normalize(deformTangent)
|
||||||
|
};
|
||||||
|
|
||||||
|
return deformPosition + (deformMatrix.c0 * position.z) + (deformMatrix.c1 * position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 EvaluatePoint(float t)
|
||||||
|
{
|
||||||
|
splineContainer.Evaluate(t, out float3 position, out _, out _);
|
||||||
|
|
||||||
|
ScaledEvaluate(deformContainer, 0, position.x / deformContainer.Spline.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
||||||
|
|
||||||
|
float3x3 deformMatrix = new()
|
||||||
|
{
|
||||||
|
c0 = (float3)Vector3.Normalize(Vector3.Cross(deformTangent, deformUpVector)),
|
||||||
|
c1 = (float3)Vector3.Normalize(deformUpVector),
|
||||||
|
c2 = (float3)Vector3.Normalize(deformTangent)
|
||||||
|
};
|
||||||
|
|
||||||
|
return deformPosition + (deformMatrix.c0 * position.z) + (deformMatrix.c1 * position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaledEvaluate(SplineContainer splineContainer, int splineIndex, float t, out float3 position, out float3 tangent, out float3 upVector)
|
||||||
|
{
|
||||||
|
Spline spline = splineContainer.Splines[splineIndex];
|
||||||
|
|
||||||
|
if (spline == null)
|
||||||
|
{
|
||||||
|
splineContainer.Evaluate(t, out position, out tangent, out upVector);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SplineUtility.Evaluate(splineContainer.Splines[splineIndex], t, out position, out tangent, out upVector);
|
||||||
|
|
||||||
|
position = splineContainer.transform.TransformPoint(position);
|
||||||
|
|
||||||
|
tangent = splineContainer.transform.TransformVector(tangent);
|
||||||
|
|
||||||
|
upVector = splineContainer.transform.TransformDirection(upVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
if (!splineContainer || !deformContainer) return;
|
||||||
|
|
||||||
|
Gizmos.color = Color.green;
|
||||||
|
|
||||||
|
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
||||||
|
{
|
||||||
|
Evaluate(i, 0, 0, out Vector3 position, out _);
|
||||||
|
|
||||||
|
Vector3 oldPosition = position;
|
||||||
|
|
||||||
|
int gizmoResolution = Mathf.CeilToInt(splineContainer.Splines[i].GetLength());
|
||||||
|
|
||||||
|
for (float j = 1; j <= gizmoResolution; j++)
|
||||||
|
{
|
||||||
|
Evaluate(i, j / gizmoResolution, 0, out position, out _);
|
||||||
|
|
||||||
|
Gizmos.DrawLine(oldPosition, position);
|
||||||
|
|
||||||
|
oldPosition = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvaluateSpline(int splineIndex, float t, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
|
||||||
ScaledEvaluate(splineContainer, splineIndex, t, out float3 position1, out float3 tangent, out float3 upVector);
|
|
||||||
|
|
||||||
position = position1;
|
|
||||||
|
|
||||||
rotation = Quaternion.LookRotation(tangent, upVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvaluateSpline(float t, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
|
||||||
splineContainer.Evaluate(t, out float3 position1, out float3 tangent, out float3 upVector);
|
|
||||||
|
|
||||||
position = position1;
|
|
||||||
|
|
||||||
rotation = Quaternion.LookRotation(tangent, upVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeformSpline(int splineIndex, float t, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
|
||||||
int resolutionScale = Mathf.CeilToInt(splineContainer.Splines[splineIndex].GetLength()) * resolution;
|
|
||||||
|
|
||||||
position = EvaluatePoint(splineIndex, t);
|
|
||||||
|
|
||||||
float t1 = Mathf.Clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
|
||||||
|
|
||||||
Vector3 position0 = EvaluatePoint(splineIndex, t1);
|
|
||||||
|
|
||||||
Vector3 position1 = EvaluatePoint(splineIndex, t1 + (1 / (float)resolutionScale));
|
|
||||||
|
|
||||||
Vector3 difference = position1 - position0;
|
|
||||||
|
|
||||||
rotation = Mathf.Abs(Vector3.Dot(difference, Vector3.up)) > 0
|
|
||||||
? Quaternion.LookRotation(difference, Vector3.up)
|
|
||||||
: Quaternion.FromToRotation(Vector3.forward, difference);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeformSpline(float t, out Vector3 position, out Quaternion rotation)
|
|
||||||
{
|
|
||||||
int resolutionScale = Mathf.CeilToInt(splineContainer.CalculateLength()) * resolution;
|
|
||||||
|
|
||||||
position = EvaluatePoint(t);
|
|
||||||
|
|
||||||
float t1 = Mathf.Clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
|
||||||
|
|
||||||
Vector3 position0 = EvaluatePoint(t1);
|
|
||||||
|
|
||||||
Vector3 position1 = EvaluatePoint(t1 + (1 / (float)resolutionScale));
|
|
||||||
|
|
||||||
Vector3 difference = position1 - position0;
|
|
||||||
|
|
||||||
rotation = Mathf.Abs(Vector3.Dot(difference, Vector3.up)) > 0
|
|
||||||
? Quaternion.LookRotation(difference, Vector3.up)
|
|
||||||
: Quaternion.FromToRotation(Vector3.forward, difference);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 EvaluatePoint(int splineIndex, float t)
|
|
||||||
{
|
|
||||||
ScaledEvaluate(splineContainer, splineIndex, t, out float3 position, out _, out _);
|
|
||||||
|
|
||||||
ScaledEvaluate(deformContainer, 0, position.x / deformContainer.Spline.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
|
||||||
|
|
||||||
float3x3 deformMatrix = new()
|
|
||||||
{
|
|
||||||
c0 = (float3)Vector3.Normalize(Vector3.Cross(deformTangent, deformUpVector)),
|
|
||||||
c1 = (float3)Vector3.Normalize(deformUpVector),
|
|
||||||
c2 = (float3)Vector3.Normalize(deformTangent)
|
|
||||||
};
|
|
||||||
|
|
||||||
return deformPosition + (deformMatrix.c0 * position.z) + (deformMatrix.c1 * position.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 EvaluatePoint(float t)
|
|
||||||
{
|
|
||||||
splineContainer.Evaluate(t, out float3 position, out _, out _);
|
|
||||||
|
|
||||||
ScaledEvaluate(deformContainer, 0, position.x / deformContainer.Spline.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
|
||||||
|
|
||||||
float3x3 deformMatrix = new()
|
|
||||||
{
|
|
||||||
c0 = (float3)Vector3.Normalize(Vector3.Cross(deformTangent, deformUpVector)),
|
|
||||||
c1 = (float3)Vector3.Normalize(deformUpVector),
|
|
||||||
c2 = (float3)Vector3.Normalize(deformTangent)
|
|
||||||
};
|
|
||||||
|
|
||||||
return deformPosition + (deformMatrix.c0 * position.z) + (deformMatrix.c1 * position.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScaledEvaluate(SplineContainer splineContainer, int splineIndex, float t, out float3 position, out float3 tangent, out float3 upVector)
|
|
||||||
{
|
|
||||||
Spline spline = splineContainer.Splines[splineIndex];
|
|
||||||
|
|
||||||
if (spline == null)
|
|
||||||
{
|
|
||||||
splineContainer.Evaluate(t, out position, out tangent, out upVector);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SplineUtility.Evaluate(splineContainer.Splines[splineIndex], t, out position, out tangent, out upVector);
|
|
||||||
|
|
||||||
position = splineContainer.transform.TransformPoint(position);
|
|
||||||
|
|
||||||
tangent = splineContainer.transform.TransformVector(tangent);
|
|
||||||
|
|
||||||
upVector = splineContainer.transform.TransformDirection(upVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDrawGizmos()
|
|
||||||
{
|
|
||||||
if (!splineContainer || !deformContainer) return;
|
|
||||||
|
|
||||||
Gizmos.color = Color.green;
|
|
||||||
|
|
||||||
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
|
||||||
{
|
|
||||||
Evaluate(i, 0, 0, out Vector3 position, out _);
|
|
||||||
|
|
||||||
Vector3 oldPosition = position;
|
|
||||||
|
|
||||||
int gizmoResolution = Mathf.CeilToInt(splineContainer.Splines[i].GetLength());
|
|
||||||
|
|
||||||
for (float j = 1; j <= gizmoResolution; j++)
|
|
||||||
{
|
|
||||||
Evaluate(i, j / gizmoResolution, 0, out position, out _);
|
|
||||||
|
|
||||||
Gizmos.DrawLine(oldPosition, position);
|
|
||||||
|
|
||||||
oldPosition = position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,51 @@
|
|||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class SplineEvaluateDebug : MonoBehaviour
|
namespace FrameJosh.SplineImporter.Samples
|
||||||
{
|
{
|
||||||
[SerializeField] SplinePlus splinePlus;
|
public class SplineEvaluateDebug : MonoBehaviour
|
||||||
|
|
||||||
[SerializeField] float anchor;
|
|
||||||
|
|
||||||
[SerializeField] float distance;
|
|
||||||
|
|
||||||
[SerializeField] float cubeSize;
|
|
||||||
|
|
||||||
[SerializeField] float matrixSize;
|
|
||||||
|
|
||||||
void OnDrawGizmos()
|
|
||||||
{
|
{
|
||||||
if (!splinePlus) return;
|
[SerializeField] SplinePlus splinePlus;
|
||||||
|
|
||||||
splinePlus.Evaluate(anchor, distance, out Vector3 position, out Quaternion rotation);
|
[SerializeField] float anchor;
|
||||||
|
|
||||||
transform.position = position;
|
[SerializeField] float distance;
|
||||||
|
|
||||||
transform.rotation = rotation;
|
[SerializeField] float cubeSize;
|
||||||
|
|
||||||
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
[SerializeField] float matrixSize;
|
||||||
|
|
||||||
splinePlus.splineContainer.Evaluate(anchor + (distance / splinePlus.splineContainer.Spline.GetLength()), out float3 position1, out _, out _);
|
void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (!splinePlus) return;
|
||||||
|
|
||||||
Gizmos.DrawCube(position1, Vector3.one * cubeSize);
|
splinePlus.Evaluate(anchor, distance, out Vector3 position, out Quaternion rotation);
|
||||||
|
|
||||||
splinePlus.deformContainer.Evaluate(position1.x / splinePlus.deformContainer.Spline.GetLength(), out float3 deformPosition, out _, out _);
|
transform.position = position;
|
||||||
|
|
||||||
Gizmos.DrawCube(deformPosition, Vector3.one * cubeSize);
|
transform.rotation = rotation;
|
||||||
|
|
||||||
Gizmos.color = Color.green;
|
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
||||||
|
|
||||||
Gizmos.DrawRay(position, transform.up * matrixSize);
|
splinePlus.splineContainer.Evaluate(anchor + (distance / splinePlus.splineContainer.Spline.GetLength()), out float3 position1, out _, out _);
|
||||||
|
|
||||||
Gizmos.color = Color.red;
|
Gizmos.DrawCube(position1, Vector3.one * cubeSize);
|
||||||
|
|
||||||
Gizmos.DrawRay(position, transform.right * matrixSize);
|
splinePlus.deformContainer.Evaluate(position1.x / splinePlus.deformContainer.Spline.GetLength(), out float3 deformPosition, out _, out _);
|
||||||
|
|
||||||
Gizmos.color = Color.blue;
|
Gizmos.DrawCube(deformPosition, Vector3.one * cubeSize);
|
||||||
|
|
||||||
Gizmos.DrawRay(position, transform.forward * matrixSize);
|
Gizmos.color = Color.green;
|
||||||
|
|
||||||
|
Gizmos.DrawRay(position, transform.up * matrixSize);
|
||||||
|
|
||||||
|
Gizmos.color = Color.red;
|
||||||
|
|
||||||
|
Gizmos.DrawRay(position, transform.right * matrixSize);
|
||||||
|
|
||||||
|
Gizmos.color = Color.blue;
|
||||||
|
|
||||||
|
Gizmos.DrawRay(position, transform.forward * matrixSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class SplineNearestPointDebug : MonoBehaviour
|
namespace FrameJosh.SplineImporter.Samples
|
||||||
{
|
{
|
||||||
[SerializeField] SplinePlus splinePlus;
|
public class SplineNearestPointDebug : MonoBehaviour
|
||||||
|
|
||||||
[SerializeField] float cubeSize;
|
|
||||||
|
|
||||||
void OnDrawGizmos()
|
|
||||||
{
|
{
|
||||||
if (!splinePlus) return;
|
[SerializeField] SplinePlus splinePlus;
|
||||||
|
|
||||||
splinePlus.GetNearestPoint(transform.position, out Vector3 position, out _);
|
[SerializeField] float cubeSize;
|
||||||
|
|
||||||
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (!splinePlus) return;
|
||||||
|
|
||||||
|
splinePlus.GetNearestPoint(transform.position, out Vector3 position, out _);
|
||||||
|
|
||||||
|
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user