Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/MegaShapeSVG.cs
2026-02-21 16:45:37 +08:00

572 lines
17 KiB
C#

using System;
using System.Text.RegularExpressions;
using UnityEngine;
public class MegaShapeSVG
{
private int splineindex;
private char[] commaspace = new char[2] { ',', ' ' };
private const float CIRCLE_VECTOR_LENGTH = 0.5517862f;
public void LoadXML(string svgdata, MegaShape shape, bool clear, int start)
{
MegaXMLReader megaXMLReader = new MegaXMLReader();
MegaXMLNode node = megaXMLReader.read(svgdata);
if (!clear)
{
shape.splines.Clear();
}
shape.selcurve = start;
splineindex = start;
ParseXML(node, shape);
}
public void ParseXML(MegaXMLNode node, MegaShape shape)
{
foreach (MegaXMLNode child in node.children)
{
switch (child.tagName)
{
case "circle":
ParseCircle(child, shape);
break;
case "path":
ParsePath(child, shape);
break;
case "ellipse":
ParseEllipse(child, shape);
break;
case "rect":
ParseRect(child, shape);
break;
case "polygon":
ParsePolygon(child, shape);
break;
}
ParseXML(child, shape);
}
}
private MegaSpline GetSpline(MegaShape shape)
{
MegaSpline megaSpline;
if (splineindex < shape.splines.Count)
{
megaSpline = shape.splines[splineindex];
}
else
{
megaSpline = new MegaSpline();
shape.splines.Add(megaSpline);
}
splineindex++;
return megaSpline;
}
private Vector3 SwapAxis(Vector3 val, MegaAxis axis)
{
float num = 0f;
switch (axis)
{
case MegaAxis.X:
num = val.x;
val.x = val.y;
val.y = num;
break;
case MegaAxis.Z:
num = val.y;
val.y = val.z;
val.z = num;
break;
}
return val;
}
private void AddKnot(MegaSpline spline, Vector3 p, Vector3 invec, Vector3 outvec, MegaAxis axis)
{
spline.AddKnot(SwapAxis(p, axis), SwapAxis(invec, axis), SwapAxis(outvec, axis));
}
private void ParseCircle(MegaXMLNode node, MegaShape shape)
{
MegaSpline spline = GetSpline(shape);
float num = 0f;
float num2 = 0f;
float num3 = 0f;
for (int i = 0; i < node.values.Count; i++)
{
MegaXMLValue megaXMLValue = node.values[i];
switch (megaXMLValue.name)
{
case "cx":
num = float.Parse(megaXMLValue.value);
break;
case "cy":
num2 = float.Parse(megaXMLValue.value);
break;
case "r":
num3 = float.Parse(megaXMLValue.value);
break;
}
}
float num4 = 0.5517862f * num3;
spline.knots.Clear();
for (int j = 0; j < 4; j++)
{
float f = (float)Math.PI * 2f * (float)j / 4f;
float num5 = Mathf.Sin(f);
float num6 = Mathf.Cos(f);
Vector3 vector = new Vector3(num6 * num3 + num, 0f, num5 * num3 + num2);
Vector3 vector2 = new Vector3(num5 * num4, 0f, (0f - num6) * num4);
AddKnot(spline, vector, vector + vector2, vector - vector2, shape.axis);
}
spline.closed = true;
}
private void ParseEllipse(MegaXMLNode node, MegaShape shape)
{
MegaSpline spline = GetSpline(shape);
float num = 0f;
float num2 = 0f;
float value = 0f;
float value2 = 0f;
for (int i = 0; i < node.values.Count; i++)
{
MegaXMLValue megaXMLValue = node.values[i];
switch (megaXMLValue.name)
{
case "cx":
num = float.Parse(megaXMLValue.value);
break;
case "cy":
num2 = float.Parse(megaXMLValue.value);
break;
case "rx":
value = float.Parse(megaXMLValue.value);
break;
case "ry":
value2 = float.Parse(megaXMLValue.value);
break;
}
}
value2 = Mathf.Clamp(value2, 0f, float.MaxValue);
value = Mathf.Clamp(value, 0f, float.MaxValue);
float num3;
float x;
float y;
if (value2 < value)
{
num3 = value;
x = 1f;
y = value2 / value;
}
else if (value < value2)
{
num3 = value2;
x = value / value2;
y = 1f;
}
else
{
num3 = value2;
x = (y = 1f);
}
float num4 = 0.5517862f * num3;
Vector3 b = new Vector3(x, y, 1f);
for (int j = 0; j < 4; j++)
{
float f = (float)Math.PI * 2f * (float)j / 4f;
float num5 = Mathf.Sin(f);
float num6 = Mathf.Cos(f);
Vector3 vector = new Vector3(num6 * num3 + num, 0f, num5 * num3 + num2);
Vector3 vector2 = new Vector3(num5 * num4, 0f, (0f - num6) * num4);
AddKnot(spline, Vector3.Scale(vector, b), Vector3.Scale(vector + vector2, b), Vector3.Scale(vector - vector2, b), shape.axis);
}
spline.closed = true;
}
private void ParseRect(MegaXMLNode node, MegaShape shape)
{
MegaSpline spline = GetSpline(shape);
Vector3[] array = new Vector3[4];
float num = 0f;
float num2 = 0f;
float num3 = 0f;
float num4 = 0f;
for (int i = 0; i < node.values.Count; i++)
{
MegaXMLValue megaXMLValue = node.values[i];
switch (megaXMLValue.name)
{
case "x":
num3 = float.Parse(megaXMLValue.value);
break;
case "y":
num4 = float.Parse(megaXMLValue.value);
break;
case "width":
num = float.Parse(megaXMLValue.value);
break;
case "height":
num2 = float.Parse(megaXMLValue.value);
break;
case "transform":
Debug.Log("SVG Transform not implemented yet");
break;
}
}
array[0] = new Vector3(num3, 0f, num4);
array[1] = new Vector3(num3, 0f, num4 + num2);
array[2] = new Vector3(num3 + num, 0f, num4 + num2);
array[3] = new Vector3(num3 + num, 0f, num4);
spline.closed = true;
spline.knots.Clear();
AddKnot(spline, array[0], array[0], array[0], shape.axis);
AddKnot(spline, array[1], array[1], array[1], shape.axis);
AddKnot(spline, array[2], array[2], array[2], shape.axis);
AddKnot(spline, array[3], array[3], array[3], shape.axis);
}
private void ParsePolygon(MegaXMLNode node, MegaShape shape)
{
MegaSpline spline = GetSpline(shape);
spline.knots.Clear();
spline.closed = true;
char[] separator = new char[1] { ' ' };
for (int i = 0; i < node.values.Count; i++)
{
MegaXMLValue megaXMLValue = node.values[i];
string name = megaXMLValue.name;
if (name != null && name == "points")
{
string[] array = megaXMLValue.value.Split(separator, StringSplitOptions.RemoveEmptyEntries);
for (int j = 0; j < array.Length; j++)
{
Vector3 vector = ParseV2Split(array[j], 0);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = megaKnot.p;
megaKnot.outvec = megaKnot.p;
spline.knots.Add(megaKnot);
}
}
}
if (spline.closed)
{
Vector3 vector2 = spline.knots[0].outvec - spline.knots[0].p;
spline.knots[0].invec = spline.knots[0].p - vector2;
}
}
private void ParsePath(MegaXMLNode node, MegaShape shape)
{
Vector3 vector = Vector3.zero;
char[] separator = new char[2] { ',', ' ' };
MegaSpline megaSpline = null;
for (int i = 0; i < node.values.Count; i++)
{
MegaXMLValue megaXMLValue = node.values[i];
string name = megaXMLValue.name;
if (name == null || !(name == "d"))
{
continue;
}
string[] array = Regex.Split(megaXMLValue.value, "(?=[MmLlCcSsZzHhVv])");
for (int j = 0; j < array.Length; j++)
{
if (array[j].Length <= 0)
{
continue;
}
string text = array[j].Substring(1);
if (text != null && text.Length > 0)
{
text = text.Replace("-", ",-");
while (text.Length > 0 && (text[0] == ',' || text[0] == ' '))
{
text = text.Substring(1);
}
}
switch (array[j][0])
{
case 'Z':
case 'z':
if (megaSpline != null)
{
megaSpline.closed = true;
int index = megaSpline.knots.Count - 1;
megaSpline.knots[0].invec = megaSpline.knots[index].invec;
megaSpline.knots.Remove(megaSpline.knots[index]);
}
break;
case 'M':
{
megaSpline = GetSpline(shape);
megaSpline.knots.Clear();
vector = ParseV2Split(text, 0);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = megaKnot.p;
megaKnot.outvec = megaKnot.p;
megaSpline.knots.Add(megaKnot);
break;
}
case 'm':
{
megaSpline = GetSpline(shape);
megaSpline.knots.Clear();
string[] array2 = text.Split(" "[0]);
for (int num3 = 0; num3 < array2.Length - 1; num3++)
{
Vector3 vector4 = ParseV2Split(array2[num3], 0);
vector.x += vector4.x;
vector.y += vector4.y;
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = megaKnot.p;
megaKnot.outvec = megaKnot.p;
megaSpline.knots.Add(megaKnot);
}
break;
}
case 'l':
{
string[] array2 = text.Split(","[0]);
for (int num4 = 0; num4 < array2.Length; num4 += 2)
{
vector += ParseV2(array2, num4);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'c':
{
string[] array2 = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
for (int m = 0; m < array2.Length; m += 6)
{
Vector2 vector2 = vector + ParseV2(array2, m);
Vector2 vector3 = vector + ParseV2(array2, m + 2);
vector += ParseV2(array2, m + 4);
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector2.x, 0f, vector2.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector3.x, 0f, vector3.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
}
break;
}
case 'L':
{
string[] array2 = text.Split(","[0]);
for (int num6 = 0; num6 < array2.Length; num6 += 2)
{
vector = ParseV2(array2, num6);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'v':
{
string[] array2 = text.Split(","[0]);
for (int num = 0; num < array2.Length; num++)
{
vector.y += float.Parse(array2[num]);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'V':
{
string[] array2 = text.Split(","[0]);
for (int num7 = 0; num7 < array2.Length; num7++)
{
vector.y = float.Parse(array2[num7]);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'h':
{
string[] array2 = text.Split(","[0]);
for (int num5 = 0; num5 < array2.Length; num5++)
{
vector.x += float.Parse(array2[num5]);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'H':
{
string[] array2 = text.Split(","[0]);
for (int num2 = 0; num2 < array2.Length; num2++)
{
vector.x = float.Parse(array2[num2]);
}
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
break;
}
case 'S':
{
string[] array2 = text.Split(","[0]);
for (int n = 0; n < array2.Length; n += 4)
{
vector = ParseV2(array2, n + 2);
Vector2 vector2 = ParseV2(array2, n);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector2.x, 0f, vector2.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
}
break;
}
case 's':
{
string[] array2 = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
for (int l = 0; l < array2.Length; l += 4)
{
Vector2 vector2 = vector + ParseV2(array2, l);
vector += ParseV2(array2, l + 2);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector2.x, 0f, vector2.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
}
break;
}
case 'C':
{
string[] array2 = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
for (int k = 0; k < array2.Length; k += 6)
{
Vector2 vector2 = ParseV2(array2, k);
Vector2 vector3 = ParseV2(array2, k + 2);
vector = ParseV2(array2, k + 4);
megaSpline.knots[megaSpline.knots.Count - 1].outvec = SwapAxis(new Vector3(vector2.x, 0f, vector2.y), shape.axis);
MegaKnot megaKnot = new MegaKnot();
megaKnot.p = SwapAxis(new Vector3(vector.x, 0f, vector.y), shape.axis);
megaKnot.invec = SwapAxis(new Vector3(vector3.x, 0f, vector3.y), shape.axis);
megaKnot.outvec = megaKnot.p - (megaKnot.invec - megaKnot.p);
megaSpline.knots.Add(megaKnot);
}
break;
}
}
}
}
}
public void importData(string svgdata, MegaShape shape, float scale, bool clear, int start)
{
LoadXML(svgdata, shape, clear, start);
for (int i = start; i < splineindex; i++)
{
float num = shape.splines[i].Area();
if (num < 0f)
{
shape.splines[i].reverse = false;
}
else
{
shape.splines[i].reverse = true;
}
}
shape.CoordAdjust(scale, new Vector3(-1f, 1f, 1f), start);
shape.CalcLength();
}
private Vector2 ParseV2Split(string str, int i)
{
return ParseV2(str.Split(commaspace, StringSplitOptions.RemoveEmptyEntries), i);
}
private Vector3 ParseV2(string[] str, int i)
{
Vector3 result = Vector2.zero;
result.x = float.Parse(str[i]);
result.y = float.Parse(str[i + 1]);
return result;
}
public static string Export(MegaShape shape, int x, int y, float strokewidth, Color col)
{
string empty = string.Empty;
Color32 color = col;
empty += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
empty += "<!-- MegaShapes SVG Exporter v1.0 -->\n";
empty += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
empty = empty + "<svg version=\"1.1\" id=\"" + shape.name + "\" x=\"0px\" y=\"0px\" width=\"640.0px\" height=\"480.0px\">\n";
for (int i = 0; i < shape.splines.Count; i++)
{
MegaSpline megaSpline = shape.splines[i];
empty += "<path d=\"";
MegaKnot megaKnot = megaSpline.knots[0];
MegaKnot megaKnot2 = megaKnot;
string text = empty;
empty = text + "M" + megaKnot.p[x] + "," + (0f - megaKnot.p[y]);
for (int j = 1; j < megaSpline.knots.Count; j++)
{
megaKnot = megaSpline.knots[j];
Vector3 outvec = megaKnot2.outvec;
Vector3 invec = megaKnot.invec;
Vector3 p = megaKnot.p;
p[y] = 0f - p[y];
outvec[y] = 0f - outvec[y];
invec[y] = 0f - invec[y];
text = empty;
empty = text + "C" + outvec[x] + "," + outvec[y];
text = empty;
empty = text + " " + invec[x] + "," + invec[y];
text = empty;
empty = text + " " + p[x] + "," + p[y];
megaKnot2 = megaKnot;
}
if (megaSpline.closed)
{
empty += "z\"";
}
empty += " fill=\"none\"";
text = empty;
empty = text + " stroke=\"#" + color.r.ToString("x") + color.g.ToString("x") + color.b.ToString("x") + "\"";
text = empty;
empty = text + " stroke-width=\"" + strokewidth + "\"";
empty += "/>\n";
}
return empty + "</svg>\n";
}
}