Compare commits
No commits in common. "ece3b56a02180942adb1b35417667eb8b296473f" and "d75ec04876110b1f0791189e1abf7c1d6f678650" have entirely different histories.
ece3b56a02
...
d75ec04876
1
LICENSE
1
LICENSE
@ -1,7 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Josh4359
|
Copyright (c) 2023 Josh4359
|
||||||
Copyright (c) 2024 Alexander Filippov
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#if UNITY_EDITOR
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -6,13 +8,9 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Unity.AI.Navigation;
|
|
||||||
using UnityEngine.AI;
|
|
||||||
|
|
||||||
namespace FrameJosh.SplineImporter
|
namespace FrameJosh.SplineImporter
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
using static SplineImporter;
|
using static SplineImporter;
|
||||||
using static SplineData;
|
using static SplineData;
|
||||||
|
|
||||||
@ -25,98 +23,91 @@ namespace FrameJosh.SplineImporter
|
|||||||
|
|
||||||
if (GUILayout.Button("Import Spline"))
|
if (GUILayout.Button("Import Spline"))
|
||||||
{
|
{
|
||||||
var splineImporter = (SplineImporter)target;
|
SplineImporter splineImporter = target as SplineImporter;
|
||||||
|
|
||||||
splineImporter.name = splineImporter.splineData.name;
|
splineImporter.name = splineImporter.splineData.name;
|
||||||
var splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
|
||||||
var splineContainer = splineImporter.GetComponent<SplineContainer>();
|
SplineData splineData = JsonUtility.FromJson<SplineData>(splineImporter.splineData.text);
|
||||||
foreach (var thisSpline in splineContainer.Splines) splineContainer.RemoveSpline(thisSpline);
|
|
||||||
#if COM_UNITY_AI_NAVIGATION
|
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
Undo.IncrementCurrentGroup();
|
|
||||||
var children = (from Transform child in splineImporter.transform select child.gameObject).ToList();
|
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
||||||
children.ForEach(Undo.DestroyObjectImmediate);
|
splineContainer.RemoveSpline(thisSpline);
|
||||||
#endif
|
|
||||||
foreach (var thisDataSpline in splineData.splines)
|
foreach (SplineData.Spline thisDataSpline in splineData.splines)
|
||||||
{
|
{
|
||||||
var thisSpline = splineContainer.AddSpline();
|
UnityEngine.Splines.Spline thisSpline = splineContainer.AddSpline();
|
||||||
|
|
||||||
thisSpline.Closed = thisDataSpline.closed;
|
thisSpline.Closed = thisDataSpline.closed;
|
||||||
foreach (var thisControlPoint in thisDataSpline.controlPoints)
|
|
||||||
{
|
|
||||||
var position = thisControlPoint.position;
|
|
||||||
var handleL = thisControlPoint.handleL;
|
|
||||||
var handleR = thisControlPoint.handleR;
|
|
||||||
var rotation = Quaternion.LookRotation((float3)handleR - position, Vector3.up) *
|
|
||||||
Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
|
||||||
|
|
||||||
float3x3 rotationMatrix = new(rotation);
|
foreach (ControlPoint thisControlPoint in thisDataSpline.controlPoints)
|
||||||
|
|
||||||
thisSpline.Add(new BezierKnot
|
|
||||||
{
|
|
||||||
Position = position * splineImporter.scale,
|
|
||||||
Rotation = rotation,
|
|
||||||
TangentIn = math.mul((float3)handleL - position, rotationMatrix) * splineImporter.scale,
|
|
||||||
TangentOut = math.mul((float3)handleR - position, rotationMatrix) * splineImporter.scale
|
|
||||||
},
|
|
||||||
TangentMode.Broken);
|
|
||||||
}
|
|
||||||
#if COM_UNITY_AI_NAVIGATION
|
|
||||||
if (thisDataSpline.closed) continue;
|
|
||||||
var go = new GameObject
|
|
||||||
{
|
{
|
||||||
transform =
|
Vector3 position = PositionToVector(thisControlPoint.position);
|
||||||
|
|
||||||
|
Vector3 handleL = PositionToVector(thisControlPoint.handleL);
|
||||||
|
|
||||||
|
Vector3 handleR = PositionToVector(thisControlPoint.handleR);
|
||||||
|
|
||||||
|
Quaternion rotation = Quaternion.LookRotation(handleR - position, Vector3.up) * Quaternion.AngleAxis(-thisControlPoint.tilt, Vector3.forward);
|
||||||
|
|
||||||
|
float3x3 rotationMatrix = new float3x3(rotation);
|
||||||
|
|
||||||
|
thisSpline.Add(new()
|
||||||
{
|
{
|
||||||
parent = splineImporter.transform
|
Position = position * splineImporter.scale,
|
||||||
}
|
Rotation = rotation,
|
||||||
};
|
TangentIn = ((Vector3)math.mul(handleL - position, rotationMatrix)) * splineImporter.scale,
|
||||||
var link = go.AddComponent<NavMeshLink>();
|
TangentOut = ((Vector3)math.mul(handleR - position, rotationMatrix)) * splineImporter.scale
|
||||||
var startPoint = thisDataSpline.controlPoints[0].position * splineImporter.scale;
|
},
|
||||||
if (NavMesh.SamplePosition(startPoint, out var startHit, 2f, NavMesh.AllAreas))
|
TangentMode.Broken);
|
||||||
startPoint = startHit.position;
|
}
|
||||||
var endPoint = thisDataSpline.controlPoints[^1].position * splineImporter.scale;
|
|
||||||
if (NavMesh.SamplePosition(endPoint, out var endHit, 2f, NavMesh.AllAreas))
|
|
||||||
endPoint = endHit.position;
|
|
||||||
link.startPoint = startPoint;
|
|
||||||
link.endPoint = endPoint;
|
|
||||||
link.area = NavMesh.GetAreaFromName(splineImporter.area);
|
|
||||||
Undo.RegisterCreatedObjectUndo(go, $"Create link from {startPoint} to {endPoint}");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUILayout.Button("Export Spline"))
|
if (GUILayout.Button("Export Spline"))
|
||||||
{
|
{
|
||||||
var splineImporter = (SplineImporter)target;
|
SplineImporter splineImporter = target as SplineImporter;
|
||||||
|
|
||||||
if (!splineImporter.splineData)
|
if (!splineImporter.splineData)
|
||||||
{
|
{
|
||||||
var path = "Assets" +
|
string path = "Assets" + EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json").Substring(Application.dataPath.Length);
|
||||||
EditorUtility.SaveFilePanel("Save .JSON", "", "New Spline.json", "json")[
|
|
||||||
Application.dataPath.Length..];
|
|
||||||
if (path.Length > 0)
|
if (path.Length > 0)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
File.WriteAllBytes(path, Encoding.ASCII.GetBytes(""));
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
var textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
|
||||||
|
TextAsset textAsset = AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset)) as TextAsset;
|
||||||
|
|
||||||
splineImporter.splineData = textAsset;
|
splineImporter.splineData = textAsset;
|
||||||
}
|
}
|
||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var splineContainer = splineImporter.GetComponent<SplineContainer>();
|
SplineContainer splineContainer = splineImporter.GetComponent<SplineContainer>();
|
||||||
SplineData splineData = new()
|
|
||||||
{
|
SplineData splineData = new();
|
||||||
splines = new Spline[splineContainer.Splines.Count]
|
|
||||||
};
|
splineData.splines = new SplineData.Spline[splineContainer.Splines.Count];
|
||||||
List<Spline> dataSplines = new();
|
|
||||||
foreach (var thisSpline in splineContainer.Splines)
|
List<SplineData.Spline> dataSplines = new();
|
||||||
|
|
||||||
|
foreach (UnityEngine.Splines.Spline thisSpline in splineContainer.Splines)
|
||||||
{
|
{
|
||||||
List<ControlPoint> controlPoints = new();
|
List<ControlPoint> controlPoints = new();
|
||||||
foreach (var thisBezierKnot in thisSpline.Knots)
|
|
||||||
|
foreach (BezierKnot thisBezierKnot in thisSpline.Knots)
|
||||||
{
|
{
|
||||||
Position position = thisBezierKnot.Position;
|
Position position = VectorToPosition(thisBezierKnot.Position);
|
||||||
float3x3 rotationMatrix = new(Quaternion.Inverse(thisBezierKnot.Rotation));
|
|
||||||
Position handleL = math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position;
|
float3x3 rotationMatrix = new float3x3(Quaternion.Inverse(thisBezierKnot.Rotation));
|
||||||
Position handleR = math.mul(thisBezierKnot.TangentOut, rotationMatrix) +
|
|
||||||
thisBezierKnot.Position;
|
Position handleL = VectorToPosition(math.mul(thisBezierKnot.TangentIn, rotationMatrix) + thisBezierKnot.Position);
|
||||||
controlPoints.Add(new ControlPoint
|
|
||||||
|
Position handleR = VectorToPosition(math.mul(thisBezierKnot.TangentOut, rotationMatrix) + thisBezierKnot.Position);
|
||||||
|
|
||||||
|
controlPoints.Add(new()
|
||||||
{
|
{
|
||||||
position = position,
|
position = position,
|
||||||
handleL = handleL,
|
handleL = handleL,
|
||||||
@ -124,7 +115,7 @@ namespace FrameJosh.SplineImporter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSplines.Add(new Spline
|
dataSplines.Add(new()
|
||||||
{
|
{
|
||||||
controlPoints = controlPoints.ToArray(),
|
controlPoints = controlPoints.ToArray(),
|
||||||
closed = thisSpline.Closed
|
closed = thisSpline.Closed
|
||||||
@ -133,8 +124,7 @@ namespace FrameJosh.SplineImporter
|
|||||||
|
|
||||||
splineData.splines = dataSplines.ToArray();
|
splineData.splines = dataSplines.ToArray();
|
||||||
|
|
||||||
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData),
|
File.WriteAllText(AssetDatabase.GetAssetPath(splineImporter.splineData), JsonUtility.ToJson(splineData, true));
|
||||||
JsonUtility.ToJson(splineData, true));
|
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
@ -142,16 +132,28 @@ namespace FrameJosh.SplineImporter
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RequireComponent(typeof(SplineContainer))]
|
[RequireComponent(typeof(SplineContainer))]
|
||||||
#endif
|
|
||||||
public class SplineImporter : MonoBehaviour
|
public class SplineImporter : MonoBehaviour
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
public TextAsset splineData;
|
public TextAsset splineData;
|
||||||
public float3 scale = new(1f, 1f, 1f);
|
|
||||||
public string area = "Walkable";
|
public float scale = 1;
|
||||||
#endif
|
|
||||||
|
public static Vector3 PositionToVector(Position position)
|
||||||
|
{
|
||||||
|
return new(position.x, position.z, position.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Position VectorToPosition(Vector3 vector)
|
||||||
|
{
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
x = vector.x,
|
||||||
|
y = vector.z,
|
||||||
|
z = vector.y
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if UNITY_EDITOR
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class SplineData
|
public class SplineData
|
||||||
{
|
{
|
||||||
@ -159,31 +161,21 @@ namespace FrameJosh.SplineImporter
|
|||||||
public struct Position
|
public struct Position
|
||||||
{
|
{
|
||||||
public float x;
|
public float x;
|
||||||
|
|
||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
public float z;
|
public float z;
|
||||||
|
|
||||||
public static implicit operator Position(float3 vector)
|
|
||||||
{
|
|
||||||
return new Position
|
|
||||||
{
|
|
||||||
x = vector.x,
|
|
||||||
y = vector.z,
|
|
||||||
z = vector.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator float3(Position vector)
|
|
||||||
{
|
|
||||||
return new float3(vector.x, vector.z, vector.y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct ControlPoint
|
public struct ControlPoint
|
||||||
{
|
{
|
||||||
public Position position;
|
public Position position;
|
||||||
|
|
||||||
public Position handleL;
|
public Position handleL;
|
||||||
|
|
||||||
public Position handleR;
|
public Position handleR;
|
||||||
|
|
||||||
public float tilt;
|
public float tilt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +187,8 @@ namespace FrameJosh.SplineImporter
|
|||||||
public bool closed;
|
public bool closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Spline[] splines = Array.Empty<Spline>();
|
public Spline[] splines = new Spline[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
170
Runtime/SplinePlus.cs
Normal file
170
Runtime/SplinePlus.cs
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
using Unity.Mathematics;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Splines;
|
||||||
|
|
||||||
|
namespace FrameJosh.SplineImporter
|
||||||
|
{
|
||||||
|
public class SplinePlus : MonoBehaviour
|
||||||
|
{
|
||||||
|
public SplineContainer splineContainer;
|
||||||
|
|
||||||
|
public SplineContainer deformContainer;
|
||||||
|
|
||||||
|
public float resolution = 1;
|
||||||
|
|
||||||
|
public void Evaluate(int splineIndex, float anchor, float distance, out float3 position, out quaternion 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)
|
||||||
|
{
|
||||||
|
Evaluate(splineIndex, anchor, distance, out float3 position1, out quaternion rotation1);
|
||||||
|
|
||||||
|
position = position1;
|
||||||
|
|
||||||
|
rotation = rotation1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetNearestPoint(int splineIndex, float3 point, out float3 position, out quaternion rotation, out float t)
|
||||||
|
{
|
||||||
|
rotation = quaternion.identity;
|
||||||
|
|
||||||
|
if (deformContainer)
|
||||||
|
{
|
||||||
|
SplineUtility.GetNearestPoint(deformContainer.Spline, point, out _, out float t1);
|
||||||
|
|
||||||
|
deformContainer.Spline.Evaluate(t1, out float3 nearest, out float3 tangent, out float3 upVector);
|
||||||
|
|
||||||
|
float3 difference = point - nearest;
|
||||||
|
|
||||||
|
float3x3 matrix = new()
|
||||||
|
{
|
||||||
|
c0 = math.normalize(math.cross(upVector, tangent)),
|
||||||
|
c1 = math.normalize(upVector),
|
||||||
|
c2 = math.normalize(tangent),
|
||||||
|
};
|
||||||
|
|
||||||
|
float3 offset = new(math.dot(difference, matrix.c2),
|
||||||
|
math.dot(difference, matrix.c1),
|
||||||
|
-math.dot(difference, matrix.c0));
|
||||||
|
|
||||||
|
float distance = math.clamp(t1, 0, 1) * deformContainer.Spline.GetLength();
|
||||||
|
|
||||||
|
point = new float3(distance, 0, 0) + offset;
|
||||||
|
|
||||||
|
SplineUtility.GetNearestPoint(splineContainer.Splines[splineIndex], point, out position, out t);
|
||||||
|
|
||||||
|
DeformSpline(splineContainer.Spline, deformContainer.Spline, t, resolution, out position, out rotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SplineUtility.GetNearestPoint(splineContainer.Splines[splineIndex], point, out position, out t);
|
||||||
|
|
||||||
|
SplineUtility.Evaluate(splineContainer.Splines[splineIndex], t, out _, out float3 tangent, out float3 upVector);
|
||||||
|
|
||||||
|
rotation = quaternion.LookRotationSafe(tangent, upVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = math.clamp(t, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetNearestPoint(int splineIndex, Vector3 point, out Vector3 position, out Quaternion rotation, out float t)
|
||||||
|
{
|
||||||
|
GetNearestPoint(splineIndex, point, out float3 position1, out quaternion rotation1, out t);
|
||||||
|
|
||||||
|
position = position1;
|
||||||
|
|
||||||
|
rotation = rotation1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
if (deform != null)
|
||||||
|
DeformSpline(spline, deform, t, resolution, out position, out rotation);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spline.Evaluate(t, out float3 position1, out float3 tangent, out float3 upVector);
|
||||||
|
|
||||||
|
position = position1;
|
||||||
|
|
||||||
|
rotation = quaternion.LookRotation(tangent, upVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeformSpline(ISpline spline, ISpline deform, float t, float resolution, out float3 position, out quaternion rotation)
|
||||||
|
{
|
||||||
|
float resolutionScale = math.ceil(spline.GetLength() * resolution);
|
||||||
|
|
||||||
|
spline.Evaluate(t, out float3 position1, out _, out _);
|
||||||
|
|
||||||
|
position = EvaluatePoint(deform, position1);
|
||||||
|
|
||||||
|
float t1 = math.clamp(t, 0, 1 - (1 / (float)resolutionScale));
|
||||||
|
|
||||||
|
spline.Evaluate(t1, out float3 position2, out _, out _);
|
||||||
|
|
||||||
|
float3 point0 = EvaluatePoint(deform, position2);
|
||||||
|
|
||||||
|
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 deform, float3 point)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
float3 forward = math.normalize(deformTangent);
|
||||||
|
|
||||||
|
return deformPosition
|
||||||
|
+ (forward * (math.max(point.x - deform.GetLength(), 0) + math.min(point.x, 0)))
|
||||||
|
+ (right * point.z)
|
||||||
|
+ (up * point.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDrawGizmosSelected()
|
||||||
|
{
|
||||||
|
if (!splineContainer || !deformContainer) return;
|
||||||
|
|
||||||
|
Gizmos.color = Color.green;
|
||||||
|
|
||||||
|
for (int i = 0; i < splineContainer.Splines.Count; i++)
|
||||||
|
{
|
||||||
|
Evaluate(0, 0, 0, out float3 position, out _);
|
||||||
|
|
||||||
|
float3 oldPosition = position;
|
||||||
|
|
||||||
|
int gizmoResolution = (int)math.ceil(splineContainer.Splines[i].GetLength());
|
||||||
|
|
||||||
|
for (float j = 1; j <= gizmoResolution; j++)
|
||||||
|
{
|
||||||
|
Evaluate(0, j / gizmoResolution, 0, out position, out _);
|
||||||
|
|
||||||
|
Gizmos.DrawLine(oldPosition, position);
|
||||||
|
|
||||||
|
oldPosition = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
splineContainer = GetComponentInChildren<SplineContainer>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/SplinePlus.cs.meta
Normal file
11
Runtime/SplinePlus.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 41eeb6f8f41efdb4eb29d6db19d12b6c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -3,8 +3,7 @@
|
|||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"Unity.Splines",
|
"Unity.Splines",
|
||||||
"Unity.Mathematics",
|
"Unity.Mathematics"
|
||||||
"Unity.AI.Navigation"
|
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
@ -13,12 +12,6 @@
|
|||||||
"precompiledReferences": [],
|
"precompiledReferences": [],
|
||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [
|
"versionDefines": [],
|
||||||
{
|
|
||||||
"name": "com.unity.ai.navigation",
|
|
||||||
"expression": "",
|
|
||||||
"define": "COM_UNITY_AI_NAVIGATION"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"noEngineReferences": false
|
"noEngineReferences": false
|
||||||
}
|
}
|
8
Samples.meta
Normal file
8
Samples.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dad66e5ce81d3da46a6f24be534d3c90
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
21
Samples/README.txt
Normal file
21
Samples/README.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
In the Spline Debug scene, there are 6 important objects:
|
||||||
|
|
||||||
|
1. Spline
|
||||||
|
- A curved spline going from (0, 0, 0) to (10, 0, -5)
|
||||||
|
|
||||||
|
2. Deform
|
||||||
|
- A curved spline used to deform Spline
|
||||||
|
|
||||||
|
3. Spline Plus
|
||||||
|
- An object with the SplinePlus component
|
||||||
|
- This object is used to deform spline Spline along spline Deform
|
||||||
|
- The resulting spline is rendered in green with Gizmos enabled
|
||||||
|
|
||||||
|
4. Evaluate
|
||||||
|
- Renders a cube gizmo along each of the above splines at a given distance from a given anchor point
|
||||||
|
|
||||||
|
5. Nearest Point
|
||||||
|
- Renders a cube gizmo at the nearest point along the deformed spline from the Spline Plus object
|
||||||
|
|
||||||
|
6. Spline Debug
|
||||||
|
- An instantiated Blender file including a tube warped around the deformed spline using Blender's Curve modifier
|
7
Samples/README.txt.meta
Normal file
7
Samples/README.txt.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4f23fad103e2d8548be04a5c255ce66b
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Samples/Spline Debug.blend
Normal file
BIN
Samples/Spline Debug.blend
Normal file
Binary file not shown.
109
Samples/Spline Debug.blend.meta
Normal file
109
Samples/Spline Debug.blend.meta
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b93c3e7374b43344ca6fa176d935f2bd
|
||||||
|
ModelImporter:
|
||||||
|
serializedVersion: 22200
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
materials:
|
||||||
|
materialImportMode: 2
|
||||||
|
materialName: 0
|
||||||
|
materialSearch: 1
|
||||||
|
materialLocation: 1
|
||||||
|
animations:
|
||||||
|
legacyGenerateAnimations: 4
|
||||||
|
bakeSimulation: 0
|
||||||
|
resampleCurves: 1
|
||||||
|
optimizeGameObjects: 0
|
||||||
|
removeConstantScaleCurves: 0
|
||||||
|
motionNodeName:
|
||||||
|
rigImportErrors:
|
||||||
|
rigImportWarnings:
|
||||||
|
animationImportErrors:
|
||||||
|
animationImportWarnings:
|
||||||
|
animationRetargetingWarnings:
|
||||||
|
animationDoRetargetingWarnings: 0
|
||||||
|
importAnimatedCustomProperties: 0
|
||||||
|
importConstraints: 0
|
||||||
|
animationCompression: 1
|
||||||
|
animationRotationError: 0.5
|
||||||
|
animationPositionError: 0.5
|
||||||
|
animationScaleError: 0.5
|
||||||
|
animationWrapMode: 0
|
||||||
|
extraExposedTransformPaths: []
|
||||||
|
extraUserProperties: []
|
||||||
|
clipAnimations: []
|
||||||
|
isReadable: 0
|
||||||
|
meshes:
|
||||||
|
lODScreenPercentages: []
|
||||||
|
globalScale: 1
|
||||||
|
meshCompression: 0
|
||||||
|
addColliders: 0
|
||||||
|
useSRGBMaterialColor: 1
|
||||||
|
sortHierarchyByName: 1
|
||||||
|
importPhysicalCameras: 1
|
||||||
|
importVisibility: 1
|
||||||
|
importBlendShapes: 1
|
||||||
|
importCameras: 1
|
||||||
|
importLights: 1
|
||||||
|
nodeNameCollisionStrategy: 1
|
||||||
|
fileIdsGeneration: 2
|
||||||
|
swapUVChannels: 0
|
||||||
|
generateSecondaryUV: 0
|
||||||
|
useFileUnits: 1
|
||||||
|
keepQuads: 0
|
||||||
|
weldVertices: 1
|
||||||
|
bakeAxisConversion: 1
|
||||||
|
preserveHierarchy: 0
|
||||||
|
skinWeightsMode: 0
|
||||||
|
maxBonesPerVertex: 4
|
||||||
|
minBoneWeight: 0.001
|
||||||
|
optimizeBones: 1
|
||||||
|
meshOptimizationFlags: -1
|
||||||
|
indexFormat: 0
|
||||||
|
secondaryUVAngleDistortion: 8
|
||||||
|
secondaryUVAreaDistortion: 15.000001
|
||||||
|
secondaryUVHardAngle: 88
|
||||||
|
secondaryUVMarginMethod: 1
|
||||||
|
secondaryUVMinLightmapResolution: 40
|
||||||
|
secondaryUVMinObjectScale: 1
|
||||||
|
secondaryUVPackMargin: 4
|
||||||
|
useFileScale: 1
|
||||||
|
strictVertexDataChecks: 0
|
||||||
|
tangentSpace:
|
||||||
|
normalSmoothAngle: 60
|
||||||
|
normalImportMode: 0
|
||||||
|
tangentImportMode: 3
|
||||||
|
normalCalculationMode: 4
|
||||||
|
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||||
|
blendShapeNormalImportMode: 1
|
||||||
|
normalSmoothingSource: 0
|
||||||
|
referencedClips: []
|
||||||
|
importAnimation: 1
|
||||||
|
humanDescription:
|
||||||
|
serializedVersion: 3
|
||||||
|
human: []
|
||||||
|
skeleton: []
|
||||||
|
armTwist: 0.5
|
||||||
|
foreArmTwist: 0.5
|
||||||
|
upperLegTwist: 0.5
|
||||||
|
legTwist: 0.5
|
||||||
|
armStretch: 0.05
|
||||||
|
legStretch: 0.05
|
||||||
|
feetSpacing: 0
|
||||||
|
globalScale: 1
|
||||||
|
rootMotionBoneName:
|
||||||
|
hasTranslationDoF: 0
|
||||||
|
hasExtraRoot: 0
|
||||||
|
skeletonHasParents: 1
|
||||||
|
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||||
|
autoGenerateAvatarMappingIfUnspecified: 1
|
||||||
|
animationType: 2
|
||||||
|
humanoidOversampling: 1
|
||||||
|
avatarSetup: 0
|
||||||
|
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||||
|
importBlendShapeDeformPercent: 1
|
||||||
|
remapMaterialsIfMaterialImportModeIsNone: 0
|
||||||
|
additionalBone: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Samples/Spline Debug.blend1
Normal file
BIN
Samples/Spline Debug.blend1
Normal file
Binary file not shown.
7
Samples/Spline Debug.blend1.meta
Normal file
7
Samples/Spline Debug.blend1.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d3d151e577ee0984bbf49dac54834606
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
1021
Samples/Spline Debug.unity
Normal file
1021
Samples/Spline Debug.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Samples/Spline Debug.unity.meta
Normal file
7
Samples/Spline Debug.unity.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 44ea138cdbdb30745b195f3459bdf8c9
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
51
Samples/SplineEvaluateDebug.cs
Normal file
51
Samples/SplineEvaluateDebug.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using Unity.Mathematics;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace FrameJosh.SplineImporter.Samples
|
||||||
|
{
|
||||||
|
public class SplineEvaluateDebug : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] SplinePlus splinePlus;
|
||||||
|
|
||||||
|
[SerializeField] float anchor;
|
||||||
|
|
||||||
|
[SerializeField] float distance;
|
||||||
|
|
||||||
|
[SerializeField] float cubeSize;
|
||||||
|
|
||||||
|
[SerializeField] float matrixSize;
|
||||||
|
|
||||||
|
void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (!splinePlus) return;
|
||||||
|
|
||||||
|
splinePlus.Evaluate(0, anchor, distance, out float3 position, out quaternion rotation);
|
||||||
|
|
||||||
|
transform.position = position;
|
||||||
|
|
||||||
|
transform.rotation = rotation;
|
||||||
|
|
||||||
|
Gizmos.DrawCube(position, Vector3.one * cubeSize);
|
||||||
|
|
||||||
|
splinePlus.splineContainer.Evaluate(anchor + (distance / splinePlus.splineContainer.Spline.GetLength()), out float3 position1, out _, out _);
|
||||||
|
|
||||||
|
Gizmos.DrawCube(position1, Vector3.one * cubeSize);
|
||||||
|
|
||||||
|
splinePlus.deformContainer.Evaluate(position1.x / splinePlus.deformContainer.Spline.GetLength(), out float3 deformPosition, out _, out _);
|
||||||
|
|
||||||
|
Gizmos.DrawCube(deformPosition, Vector3.one * cubeSize);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Samples/SplineEvaluateDebug.cs.meta
Normal file
11
Samples/SplineEvaluateDebug.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b96504a617d74094faa656840a73e7a9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
35
Samples/SplineNearestPointDebug.cs
Normal file
35
Samples/SplineNearestPointDebug.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Unity.Mathematics;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace FrameJosh.SplineImporter.Samples
|
||||||
|
{
|
||||||
|
public class SplineNearestPointDebug : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] SplinePlus splinePlus;
|
||||||
|
|
||||||
|
[SerializeField] float cubeSize;
|
||||||
|
|
||||||
|
[SerializeField] float matrixSize;
|
||||||
|
|
||||||
|
void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (!splinePlus) return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Samples/SplineNearestPointDebug.cs.meta
Normal file
11
Samples/SplineNearestPointDebug.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0760258fbb4f0b5418d9a88014403d0e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Samples/Splines.meta
Normal file
8
Samples/Splines.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b9cd3cbddbe4e44abf819fdd6da81ee
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
45
Samples/Splines/Deform.json
Normal file
45
Samples/Splines/Deform.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"splines": [
|
||||||
|
{
|
||||||
|
"controlPoints": [
|
||||||
|
{
|
||||||
|
"position": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleL": {
|
||||||
|
"x": -9.999999046325684,
|
||||||
|
"y": -1.5099578831723193e-06,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleR": {
|
||||||
|
"x": 9.999999046325684,
|
||||||
|
"y": 1.5099578831723193e-06,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"tilt": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"position": {
|
||||||
|
"x": 10.000001907348633,
|
||||||
|
"y": -9.999998092651367,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleL": {
|
||||||
|
"x": 1.9073486328125e-06,
|
||||||
|
"y": -10.000001907348633,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleR": {
|
||||||
|
"x": 20.000001907348633,
|
||||||
|
"y": -9.999994277954102,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"tilt": 0.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"closed": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
Samples/Splines/Deform.json.meta
Normal file
7
Samples/Splines/Deform.json.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 22decb6838ce8a34a883a7ad6c7c3335
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
45
Samples/Splines/Spline.json
Normal file
45
Samples/Splines/Spline.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"splines": [
|
||||||
|
{
|
||||||
|
"controlPoints": [
|
||||||
|
{
|
||||||
|
"position": {
|
||||||
|
"x": 0.0,
|
||||||
|
"y": 0.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleL": {
|
||||||
|
"x": -1.0,
|
||||||
|
"y": -8.742277657347586e-08,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleR": {
|
||||||
|
"x": 1.0,
|
||||||
|
"y": 8.742277657347586e-08,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"tilt": -0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"position": {
|
||||||
|
"x": 10.0,
|
||||||
|
"y": -5.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleL": {
|
||||||
|
"x": 9.0,
|
||||||
|
"y": -5.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"handleR": {
|
||||||
|
"x": 11.0,
|
||||||
|
"y": -5.0,
|
||||||
|
"z": 0.0
|
||||||
|
},
|
||||||
|
"tilt": -0.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"closed": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
Samples/Splines/Spline.json.meta
Normal file
7
Samples/Splines/Spline.json.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f3719dd04e0fe40438bb9578e9d53804
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
20
package.json
20
package.json
@ -1,17 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "ru.shazbot.spline-importer",
|
"name": "com.josh.spline-importer",
|
||||||
"version": "3.1.0",
|
"version": "1.0.0",
|
||||||
"displayName": "Spline Importer",
|
"displayName": "Spline Importer",
|
||||||
"description": "Import and export splines between Blender and Unity.",
|
"description": "Import and export splines between Blender and Unity",
|
||||||
"unity": "2021.3",
|
"unity": "2022.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.modules.jsonserialize": "1.0.0",
|
"com.unity.mathematics": "1.0.0",
|
||||||
"com.unity.mathematics": "1.2.6",
|
"com.unity.splines": "1.0.0"
|
||||||
"com.unity.splines": "2.5.1"
|
},
|
||||||
},
|
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Alexander Filippov",
|
"name": "Josh",
|
||||||
"email": "alexander@shazbot.ru",
|
"url": "https://github.com/Josh4359"
|
||||||
"url": "https://shazbot.ru/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user