Fixed GetNearestPoint
This commit is contained in:
parent
30e2fe07c5
commit
51d9f90227
@ -10,11 +10,15 @@ namespace FrameJosh.SplineImporter
|
||||
|
||||
public SplineContainer deformContainer;
|
||||
|
||||
public int resolution = 1;
|
||||
public float resolution = 1;
|
||||
|
||||
public void Evaluate(int splineIndex, float anchor, float distance, out float3 position, out quaternion rotation)
|
||||
{
|
||||
EvaluateSpline(splineContainer.Splines[splineIndex], deformContainer.Spline, anchor, distance, resolution, out position, out rotation);
|
||||
EvaluateSpline(splineContainer.Splines[splineIndex], deformContainer ? deformContainer.Spline : null, anchor, distance, resolution, out position, out rotation);
|
||||
|
||||
position = splineContainer.transform.TransformPoint(position);
|
||||
|
||||
rotation *= splineContainer.transform.rotation;
|
||||
}
|
||||
|
||||
public void Evaluate(int splineIndex, float anchor, float distance, out Vector3 position, out Quaternion rotation)
|
||||
@ -28,37 +32,43 @@ namespace FrameJosh.SplineImporter
|
||||
|
||||
public void GetNearestPoint(int splineIndex, float3 point, out float3 position, out quaternion rotation, out float t)
|
||||
{
|
||||
position = float3.zero;
|
||||
|
||||
rotation = quaternion.identity;
|
||||
|
||||
t = 0;
|
||||
|
||||
ISpline spline = splineContainer.Splines[splineIndex];
|
||||
|
||||
ISpline deform = deformContainer.Spline;
|
||||
|
||||
float nearestDistance = float.PositiveInfinity;
|
||||
|
||||
int resolutionScale = (int)math.ceil(spline.GetLength()) * resolution;
|
||||
|
||||
for (float i = 0; i <= resolutionScale; i++)
|
||||
if (deformContainer)
|
||||
{
|
||||
EvaluateSpline(spline, deform, i / resolutionScale, 0, resolution, out float3 thisPosition, out quaternion thisRotation);
|
||||
SplineUtility.GetNearestPoint(deformContainer.Spline, point, out _, out float t1);
|
||||
|
||||
float thisDistance = math.distance(point, thisPosition);
|
||||
deformContainer.Spline.Evaluate(t1, out float3 nearest, out float3 tangent, out float3 upVector);
|
||||
|
||||
if (thisDistance < nearestDistance)
|
||||
float3 difference = point - nearest;
|
||||
|
||||
float3x3 matrix = new()
|
||||
{
|
||||
position = thisPosition;
|
||||
c0 = math.normalize(math.cross(upVector, tangent)),
|
||||
c1 = math.normalize(upVector),
|
||||
c2 = math.normalize(tangent),
|
||||
};
|
||||
|
||||
rotation = thisRotation;
|
||||
float3 offset = new(math.dot(difference, matrix.c2),
|
||||
math.dot(difference, matrix.c1),
|
||||
-math.dot(difference, matrix.c0));
|
||||
|
||||
t = i / resolutionScale;
|
||||
point = new float3(t1 * deformContainer.Spline.GetLength(), 0, 0) + offset;
|
||||
|
||||
nearestDistance = thisDistance;
|
||||
}
|
||||
SplineUtility.GetNearestPoint(splineContainer.Splines[splineIndex], point, out position, out t);
|
||||
|
||||
position = EvaluatePoint(deformContainer.Spline, position);
|
||||
|
||||
float3 point1 = new float3((t1 * deformContainer.Spline.GetLength()) + (1 / resolution), 0, 0) + offset;
|
||||
|
||||
SplineUtility.GetNearestPoint(splineContainer.Splines[splineIndex], point1, out float3 position1, out _);
|
||||
|
||||
position1 = EvaluatePoint(deformContainer.Spline, position1);
|
||||
|
||||
rotation = quaternion.LookRotationSafe(position1 - position, Vector3.up);
|
||||
}
|
||||
else
|
||||
SplineUtility.GetNearestPoint(splineContainer.Splines[splineIndex], point, out position, out t);
|
||||
}
|
||||
|
||||
public void GetNearestPoint(int splineIndex, Vector3 point, out Vector3 position, out Quaternion rotation, out float t)
|
||||
@ -70,7 +80,7 @@ namespace FrameJosh.SplineImporter
|
||||
rotation = rotation1;
|
||||
}
|
||||
|
||||
static void EvaluateSpline(ISpline spline, ISpline deform, float anchor, float distance, int resolution, out float3 position, out quaternion rotation)
|
||||
static void EvaluateSpline(ISpline spline, ISpline deform, float anchor, float distance, float resolution, out float3 position, out quaternion rotation)
|
||||
{
|
||||
float t = anchor + (distance / spline.GetLength());
|
||||
|
||||
@ -86,34 +96,38 @@ namespace FrameJosh.SplineImporter
|
||||
}
|
||||
}
|
||||
|
||||
static void DeformSpline(ISpline spline, ISpline deform, float t, int resolution, out float3 position, out quaternion rotation)
|
||||
static void DeformSpline(ISpline spline, ISpline deform, float t, float resolution, out float3 position, out quaternion rotation)
|
||||
{
|
||||
int resolutionScale = (int)math.ceil(spline.GetLength()) * resolution;
|
||||
float resolutionScale = math.ceil(spline.GetLength() * resolution);
|
||||
|
||||
position = EvaluatePoint(spline, deform, t);
|
||||
spline.Evaluate(t, out float3 position1, out _, out _);
|
||||
|
||||
position = EvaluatePoint(deform, position1);
|
||||
|
||||
float t1 = math.clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
||||
|
||||
float3 position0 = EvaluatePoint(spline, deform, t1);
|
||||
spline.Evaluate(t1, out float3 position2, out _, out _);
|
||||
|
||||
float3 position1 = EvaluatePoint(spline, deform, t1 + (1 / (float)resolutionScale));
|
||||
float3 point0 = EvaluatePoint(deform, position2);
|
||||
|
||||
float3 difference = position1 - position0;
|
||||
spline.Evaluate(t1 + (1 / resolutionScale), out float3 position3, out _, out _);
|
||||
|
||||
float3 point1 = EvaluatePoint(deform, position3);
|
||||
|
||||
float3 difference = point1 - point0;
|
||||
|
||||
rotation = quaternion.LookRotationSafe(difference, math.up());
|
||||
}
|
||||
|
||||
static float3 EvaluatePoint(ISpline spline, ISpline deform, float t)
|
||||
static float3 EvaluatePoint(ISpline deform, float3 point)
|
||||
{
|
||||
spline.Evaluate(t, out float3 position, out _, out _);
|
||||
|
||||
deform.Evaluate(position.x / deform.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
||||
deform.Evaluate(point.x / deform.GetLength(), out float3 deformPosition, out float3 deformTangent, out float3 deformUpVector);
|
||||
|
||||
float3 right = math.normalize(math.cross(deformTangent, deformUpVector));
|
||||
|
||||
float3 up = math.normalize(deformUpVector);
|
||||
|
||||
return deformPosition + (right * position.z) + (up * position.y);
|
||||
return deformPosition + (right * point.z) + (up * point.y);
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
|
@ -864,6 +864,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
splinePlus: {fileID: 1797524873}
|
||||
cubeSize: 0.5
|
||||
matrixSize: 1
|
||||
--- !u!4 &1220459428
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -872,7 +873,7 @@ Transform:
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1220459424}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 10, y: 0, z: -5}
|
||||
m_LocalPosition: {x: 2, y: 0, z: -5}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
|
@ -9,13 +9,27 @@ namespace FrameJosh.SplineImporter.Samples
|
||||
|
||||
[SerializeField] float cubeSize;
|
||||
|
||||
[SerializeField] float matrixSize;
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (!splinePlus) return;
|
||||
|
||||
splinePlus.GetNearestPoint(0, transform.position, out float3 position, out _, out _);
|
||||
splinePlus.GetNearestPoint(0, transform.position, out float3 position, out quaternion rotation, out _);
|
||||
|
||||
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
||||
|
||||
Gizmos.color = Color.green;
|
||||
|
||||
Gizmos.DrawRay(position, (Quaternion)rotation * Vector3.up * matrixSize);
|
||||
|
||||
Gizmos.color = Color.red;
|
||||
|
||||
Gizmos.DrawRay(position, (Quaternion)rotation * Vector3.right * matrixSize);
|
||||
|
||||
Gizmos.color = Color.blue;
|
||||
|
||||
Gizmos.DrawRay(position, (Quaternion)rotation * Vector3.forward * matrixSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user