summaryrefslogtreecommitdiffstats
path: root/Scripts/Fold/Editor/VertexDeformationBuilder.cs
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-01-12 19:31:54 -0800
committeryum <yum.food.vr@gmail.com>2026-01-12 19:31:54 -0800
commit6d86c9663bab3ec1ef95ba455dfa7281415b7f44 (patch)
treecda255c2dfd0ef2c96334fb7ecf2182d4950086e /Scripts/Fold/Editor/VertexDeformationBuilder.cs
parentcbc299f489d6bdc38cce30d74040c54197efe125 (diff)
Fold: move from visual programming to fluent builder
Diffstat (limited to 'Scripts/Fold/Editor/VertexDeformationBuilder.cs')
-rw-r--r--Scripts/Fold/Editor/VertexDeformationBuilder.cs339
1 files changed, 339 insertions, 0 deletions
diff --git a/Scripts/Fold/Editor/VertexDeformationBuilder.cs b/Scripts/Fold/Editor/VertexDeformationBuilder.cs
new file mode 100644
index 0000000..c04a66a
--- /dev/null
+++ b/Scripts/Fold/Editor/VertexDeformationBuilder.cs
@@ -0,0 +1,339 @@
+using System;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+public class VertexDeformationSlot
+{
+ public int opcode;
+ public float float0, float1, float2, float3;
+ public Vector4 vec0, vec1, vec2, vec3;
+
+ public void ApplyToMaterial(Material mat, int slotIndex)
+ {
+ var prefix = $"_Vertex_Deformation_Slot_{slotIndex}_";
+ mat.SetFloat(prefix + "Enabled", 1f);
+ mat.SetInt(prefix + "Opcode", opcode);
+ mat.SetFloat(prefix + "Float_0", float0);
+ mat.SetFloat(prefix + "Float_1", float1);
+ mat.SetFloat(prefix + "Float_2", float2);
+ mat.SetFloat(prefix + "Float_3", float3);
+ mat.SetVector(prefix + "Vector_0", vec0);
+ mat.SetVector(prefix + "Vector_1", vec1);
+ mat.SetVector(prefix + "Vector_2", vec2);
+ mat.SetVector(prefix + "Vector_3", vec3);
+ }
+}
+
+public class VertexDeformationBuilder
+{
+ readonly List<VertexDeformationSlot> slots = new();
+ Material targetMaterial;
+
+ public static class Opcodes
+ {
+ public const int None = 0;
+ public const int TubeToPlane = 1;
+ public const int PlaneToTube = 2;
+ public const int PointAlign = 3;
+ public const int AxisAlign = 4;
+ public const int NormConversion = 5;
+ public const int Seal = 6;
+ public const int SineWaves = 7;
+ public const int FBM = 8;
+ }
+
+ VertexDeformationBuilder() { }
+
+ public static VertexDeformationBuilder Create() => new();
+
+ public VertexDeformationBuilder For(Material material)
+ {
+ targetMaterial = material;
+ return this;
+ }
+
+ public VertexDeformationBuilder TubeToPlane(Vector3 p, Vector3 r, Vector3 s, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.TubeToPlane,
+ vec0 = p,
+ vec1 = r,
+ vec2 = s,
+ float0 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder PlaneToTube(Vector3 p, Vector3 r, Vector3 s, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.PlaneToTube,
+ vec0 = p,
+ vec1 = r,
+ vec2 = s,
+ float0 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder PointAlign(Vector3 po, Vector3 pp, Vector3 r, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.PointAlign,
+ vec0 = po,
+ vec1 = pp,
+ vec2 = r,
+ float0 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder AxisAlign(Vector3 po, Vector3 pp, Vector3 r, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.AxisAlign,
+ vec0 = po,
+ vec1 = pp,
+ vec2 = r,
+ float0 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder NormConversion(float inputK, float outputK, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.NormConversion,
+ float0 = inputK,
+ float1 = outputK,
+ float2 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder Seal(float A, float k, float st, float t)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = Opcodes.Seal,
+ float0 = A,
+ float1 = k,
+ float2 = st,
+ float3 = t
+ });
+ return this;
+ }
+
+ public VertexDeformationBuilder SineWaves()
+ {
+ slots.Add(new VertexDeformationSlot { opcode = Opcodes.SineWaves });
+ return this;
+ }
+
+ public VertexDeformationBuilder FBM()
+ {
+ slots.Add(new VertexDeformationSlot { opcode = Opcodes.FBM });
+ return this;
+ }
+
+ public VertexDeformationBuilder Custom(int opcode,
+ float f0 = 0, float f1 = 0, float f2 = 0, float f3 = 0,
+ Vector4? v0 = null, Vector4? v1 = null, Vector4? v2 = null, Vector4? v3 = null)
+ {
+ slots.Add(new VertexDeformationSlot
+ {
+ opcode = opcode,
+ float0 = f0, float1 = f1, float2 = f2, float3 = f3,
+ vec0 = v0 ?? Vector4.zero,
+ vec1 = v1 ?? Vector4.zero,
+ vec2 = v2 ?? Vector4.zero,
+ vec3 = v3 ?? Vector4.zero
+ });
+ return this;
+ }
+
+ public void Apply()
+ {
+ if (targetMaterial == null)
+ {
+ Debug.LogError("No target material set. Use .For(material) before .Apply()");
+ return;
+ }
+
+ if (slots.Count > 16)
+ {
+ Debug.LogWarning($"Too many operations ({slots.Count}). Only the first 16 will be applied.");
+ }
+
+ Undo.RecordObject(targetMaterial, "Apply Vertex Deformation");
+
+ targetMaterial.SetFloat("_Vertex_Deformation_Enabled", 1f);
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (i < slots.Count)
+ {
+ slots[i].ApplyToMaterial(targetMaterial, i);
+ }
+ else
+ {
+ var prefix = $"_Vertex_Deformation_Slot_{i}_";
+ targetMaterial.SetFloat(prefix + "Enabled", 0f);
+ }
+ }
+
+ EditorUtility.SetDirty(targetMaterial);
+ }
+
+ public void Clear()
+ {
+ slots.Clear();
+ }
+
+ public int Count => slots.Count;
+}
+
+public static class VertexDeformationPresets
+{
+ public static void TubeToPlaneFull(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .TubeToPlane(Vector3.zero, Vector3.right, Vector3.forward, 1f)
+ .Apply();
+
+ public static void PlaneToTubeFull(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .PlaneToTube(Vector3.zero, Vector3.right, Vector3.forward, 1f)
+ .Apply();
+
+ public static void TubeToPlaneThenNormConv(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .TubeToPlane(Vector3.zero, Vector3.right, Vector3.forward, 1f)
+ .NormConversion(2f, 1f, 1f)
+ .Apply();
+
+ public static void NormConvL1ToL2(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .NormConversion(1f, 2f, 1f)
+ .Apply();
+
+ public static void NormConvL2ToL1(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .NormConversion(2f, 1f, 1f)
+ .Apply();
+
+ public static void NormConvL2ToLinf(Material mat) =>
+ VertexDeformationBuilder.Create()
+ .For(mat)
+ .NormConversion(2f, float.PositiveInfinity, 1f)
+ .Apply();
+}
+
+public class VertexDeformationEditorWindow : EditorWindow
+{
+ Material targetMaterial;
+ Vector2 scrollPos;
+
+ [MenuItem("Window/Vertex Deformation Presets")]
+ static void ShowWindow()
+ {
+ GetWindow<VertexDeformationEditorWindow>("Vertex Deformation");
+ }
+
+ void OnGUI()
+ {
+ GUILayout.Label("Vertex Deformation Builder", EditorStyles.boldLabel);
+
+ targetMaterial = EditorGUILayout.ObjectField("Target Material", targetMaterial, typeof(Material), false) as Material;
+
+ if (targetMaterial == null)
+ {
+ EditorGUILayout.HelpBox("Select a material to apply vertex deformations", MessageType.Info);
+ return;
+ }
+
+ scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
+
+ DrawSection("Basic Operations", () =>
+ {
+ if (GUILayout.Button("Tube to Plane"))
+ VertexDeformationPresets.TubeToPlaneFull(targetMaterial);
+
+ if (GUILayout.Button("Plane to Tube"))
+ VertexDeformationPresets.PlaneToTubeFull(targetMaterial);
+ });
+
+ DrawSection("Norm Conversions", () =>
+ {
+ if (GUILayout.Button("L1 to L2"))
+ VertexDeformationPresets.NormConvL1ToL2(targetMaterial);
+
+ if (GUILayout.Button("L2 to L1"))
+ VertexDeformationPresets.NormConvL2ToL1(targetMaterial);
+
+ if (GUILayout.Button("L2 to L∞"))
+ VertexDeformationPresets.NormConvL2ToLinf(targetMaterial);
+ });
+
+ DrawSection("Complex Pipelines", () =>
+ {
+ if (GUILayout.Button("Tube to Plane + Norm Conv (L2→L1)"))
+ VertexDeformationPresets.TubeToPlaneThenNormConv(targetMaterial);
+ });
+
+ DrawSection("Utilities", () =>
+ {
+ if (GUILayout.Button("Clear All Deformations"))
+ {
+ Undo.RecordObject(targetMaterial, "Clear Vertex Deformations");
+ targetMaterial.SetFloat("_Vertex_Deformation_Enabled", 0f);
+ for (int i = 0; i < 16; i++)
+ {
+ var prefix = $"_Vertex_Deformation_Slot_{i}_";
+ targetMaterial.SetFloat(prefix + "Enabled", 0f);
+ }
+ EditorUtility.SetDirty(targetMaterial);
+ }
+
+ if (GUILayout.Button("Show Code Example"))
+ {
+ ShowCodeExample();
+ }
+ });
+
+ EditorGUILayout.EndScrollView();
+ }
+
+ void DrawSection(string title, Action content)
+ {
+ GUILayout.Space(10);
+ GUILayout.Label(title, EditorStyles.boldLabel);
+ content();
+ }
+
+ void ShowCodeExample()
+ {
+ EditorUtility.DisplayDialog("Code Example",
+ "// Quick preset:\n" +
+ "VertexDeformationPresets.TubeToPlaneFull(material);\n\n" +
+ "// Custom pipeline:\n" +
+ "VertexDeformationBuilder.Create()\n" +
+ " .For(material)\n" +
+ " .TubeToPlane(Vector3.zero, Vector3.right, Vector3.forward, 1f)\n" +
+ " .NormConversion(2f, 1f, 1f)\n" +
+ " .PlaneToTube(Vector3.zero, Vector3.right, Vector3.forward, 1f)\n" +
+ " .Apply();\n\n" +
+ "// Add your own presets in VertexDeformationPresets class!",
+ "OK");
+ }
+}