diff options
| author | yum <yum.food.vr@gmail.com> | 2026-01-12 19:31:54 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-01-12 19:31:54 -0800 |
| commit | 6d86c9663bab3ec1ef95ba455dfa7281415b7f44 (patch) | |
| tree | cda255c2dfd0ef2c96334fb7ecf2182d4950086e /Scripts/Fold/Editor/VertexDeformationBuilder.cs | |
| parent | cbc299f489d6bdc38cce30d74040c54197efe125 (diff) | |
Fold: move from visual programming to fluent builder
Diffstat (limited to 'Scripts/Fold/Editor/VertexDeformationBuilder.cs')
| -rw-r--r-- | Scripts/Fold/Editor/VertexDeformationBuilder.cs | 339 |
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"); + } +} |
