Last active
July 28, 2024 11:43
-
-
Save andybak/07d372884fec99f6d8785ba677d2fa2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Unity.Mathematics; | |
using Unity.VectorGraphics; | |
using UnityEngine; | |
using UnityEngine.Splines; | |
public class SplineTest : MonoBehaviour | |
{ | |
public string svgPath; | |
[Multiline(16)] | |
public string rawSvg; | |
public string Id; | |
public List<int> childIndices; | |
public Vector3 translation = Vector3.zero; | |
public Vector3 rotation = Vector3.zero; | |
public Vector3 scale = new (1, -1, 1); | |
public Vector3 translateEach = Vector3.zero; | |
public Vector3 rotateEach = Vector3.zero; | |
public Vector3 scaleEach = new (1, 1, 1); | |
void Start() | |
{ | |
Generate(); | |
} | |
private string _GetNodeInfo(SceneNode node) | |
{ | |
return $"{node.Children?.Count ?? 0} children. {node.Shapes?.Count ?? 0} shapes."; | |
} | |
[ContextMenu("Generate")] | |
void Generate() | |
{ | |
var importer = new RuntimeSVGImporter(); | |
string svg; | |
if (!string.IsNullOrEmpty(svgPath)) | |
{ | |
svg = System.IO.File.ReadAllText(svgPath); | |
} | |
else | |
{ | |
svg = rawSvg; | |
} | |
SVGParser.SceneInfo sceneInfo = importer.ParseToSceneInfo(svg); | |
if (!string.IsNullOrEmpty(Id)) | |
{ | |
// Extract a node by it's id | |
sceneInfo = sceneInfo.FromNodeId(Id); | |
} | |
else if (childIndices != null && childIndices.Count > 0) | |
{ | |
foreach (var index in childIndices) | |
{ | |
sceneInfo = sceneInfo.FromChildIndex(index); | |
} | |
} | |
var scene = sceneInfo.Scene; | |
int numChildren = scene.Root.Children?.Count ?? 0; | |
// // Some useful debugging info | |
// for (var i = 0; i < numChildren; i++) | |
// { | |
// var child = scene.Root.Children[i]; | |
// Debug.Log($"Child {i}: {_GetNodeInfo(child)}"); | |
// } | |
// foreach (var id in sceneInfo.NodeIDs) | |
// { | |
// Debug.Log($"NodeIDs: {id.Key}: {_GetNodeInfo(id.Value)}"); | |
// } | |
// foreach (var opacity in sceneInfo.NodeOpacity) | |
// { | |
// Debug.Log($"NodeOpacity: {opacity.Key}: {opacity.Value}"); | |
// } | |
int numShapes = scene.Root.Shapes?.Count ?? 0; | |
bool singleNode = numChildren == 0 && numShapes > 0; | |
int numMeshes = singleNode ? 1 : numChildren; | |
CombineInstance[] combine = new CombineInstance[numMeshes]; | |
var tr = Matrix4x4.TRS( | |
translation, | |
Quaternion.Euler(rotation), | |
scale | |
); | |
var splineContainer = gameObject.GetComponent<SplineContainer>(); | |
for (var i = 0; i < splineContainer.Splines.Count; i++) | |
{ | |
splineContainer.RemoveSplineAt(i); | |
} | |
for (var i = 0; i < numMeshes; i++) | |
{ | |
tr *= Matrix4x4.TRS( | |
translateEach, | |
Quaternion.Euler(rotateEach), | |
scaleEach | |
); | |
// Edge case - a single node with shapes but no children | |
SVGParser.SceneInfo newSceneInfo = sceneInfo; | |
// Common case - a node with children | |
if (!singleNode) | |
{ | |
newSceneInfo = sceneInfo.FromChildIndex(i); | |
} | |
var shapes = newSceneInfo.Scene.Root.Shapes; | |
if (shapes != null) | |
{ | |
foreach (var shape in shapes) | |
{ | |
foreach (var contour in shape.Contours) | |
{ | |
var spline = new Spline(); | |
spline.Closed = contour.Closed; | |
int numSegments = contour.Segments.Length; | |
for (int idx = 0; idx < numSegments; idx++) | |
{ | |
int prevIdx = (int)Mathf.Repeat(idx - 1, numSegments); | |
Debug.Log($"m: {numSegments} i: {idx} i-1: {prevIdx}"); | |
var prevSeg = contour.Segments[prevIdx]; | |
var seg = contour.Segments[idx]; | |
float3 p0 = tr.MultiplyPoint3x4(new float3(seg.P0.x, seg.P0.y, 0)); | |
float3 p1 = tr.MultiplyPoint3x4(new float3(prevSeg.P2.x, prevSeg.P2.y, 0)); | |
float3 p2 = tr.MultiplyPoint3x4(new float3(seg.P1.x, seg.P1.y, 0)); | |
BezierKnot knot = new BezierKnot(p0, p1 - p0, p2 - p0); | |
spline.Add(knot); | |
} | |
splineContainer.AddSpline(spline); | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment