using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using NaughtyAttributes; public enum Scene { AssetSpace, Pixelgon, StretchSilo } public class Monolith : MonoBehaviour { public Input input; // INPUT public Pixelgon pixelgon; // DATA public AssetSpace assetSpace; [Button] public void Save() { assetSpace.Save(pixelgon); } [Button] public void Load() { pixelgon = assetSpace.Load(); } // Tools/Systems public ToolNewVector toolNewVector; public ToolEditVector toolEditVector; public ToolNewQuad toolNewQuad; // public ToolEditQuad toolEditQuad; public ToolEraser toolEraser; // stretch-silo public StretchSilo stretchSilo; public Render render; // VIEW void Start() { assetSpace.Init(render.polyVector); } public Scene scene; int toolIndex = 0; void Update() { input.Frame(); switch (scene) { case Scene.AssetSpace: assetSpace.Frame(input, render); break; case Scene.Pixelgon: // toolNewQuad.Frame(input, pixelgon); // render.ToolNewQuad(toolNewQuad); if (input.offCon.two.down) { toolNewVector.Reset(); toolEditVector.Reset(); toolNewQuad.Reset(); toolEraser.Reset(); if (toolIndex < 3) { toolIndex++; } else { toolIndex = 0; } } switch (toolIndex) { case 0: toolNewVector.Frame(input, pixelgon); render.ToolNewVector(toolNewVector); break; case 1: toolEditVector.Frame(input, pixelgon); render.ToolEditVector(toolEditVector); break; case 2: toolNewQuad.Frame(input, pixelgon); render.ToolNewQuad(toolNewQuad, pixelgon); break; case 3: toolEraser.Frame(input, pixelgon); render.ToolEraser(toolEraser); break; } render.Pixelgon(pixelgon); break; case Scene.StretchSilo: render.StretchSilo(stretchSilo, assetSpace); break; } render.Frame(input); } } public static class StaticMethods { public static List DeleteLoose(List vectors) { int length = 0; for (int i = vectors.Count - 1; i >= 0; i--) { if (vectors[i] != Vector3.zero) { length++; } else { if (length == 1) { vectors.RemoveAt(i + 1); } length = 0; } } return vectors; } public static bool Inside(float from, float to, float x) { if (from < to) { return x > from && x < to; } else { return x > to && x < from; } } static Vector3[] snappingDir = new Vector3[] { Vector3.right, Vector3.up, Vector3.forward }; public static Vector3 DirSnap(Vector3 a, Vector3 c) { for (int i = 0; i < snappingDir.Length; i++) { for (int j = 0; j < 2; j++) { Vector3 snapDir = snappingDir[i]; if (j == 1) { snapDir = snappingDir[i] * -1f; // right -> left etc. } Vector3 dir = (c - a).normalized; if (Vector3.Angle(snapDir, dir) < 8f) // dir snapping margin { return a + snapDir * Vector3.Distance(a, c); } } } return c; } public static Vector3 EdgeSnap(Vector3 a, Vector3 b, Vector3 c) { Quaternion perspective = Quaternion.LookRotation(b - a); Vector3 pA = Quaternion.Inverse(perspective) * a; Vector3 pB = Quaternion.Inverse(perspective) * b; Vector3 pC = Quaternion.Inverse(perspective) * c; // XY float dist = Vector2.Distance(pC, pA); // pA & pB interchangeable // Z if (pC.z < pA.z || pC.z > pB.z) // outside { dist += Mathf.Min(Mathf.Abs(pC.z - pA.z), Mathf.Abs(pC.z - pB.z)); } // snapping margin, where is this variable? // idk becuase this snapping system will be reused in tools and quads // scalable 0-1 * design (0 == no snapping) set parameter in ORIEL UI pC.x = pA.x; pC.y = pA.y; pC.z = Mathf.Clamp(pC.z, pA.z, pB.z); return perspective * pC; // min distance to handle 2+ conflicting snaps ? } public static Vector3 Snap(List> lists, Vector3 cursorPos) { Vector3 closestJoint = Vector3.one * 1000; Vector3 closestEdge = Vector3.one * 1000; Vector3 closestMirrorJoint = Vector3.one * 1000; for (int l = 0; l < lists.Count; l++) { int length = 0; for (int i = 0; i < lists[l].Count; i++) { if (lists[l][i] == Vector3.zero) { length = 0; continue; } if (Vector3.Distance(cursorPos, lists[l][i]) < Vector3.Distance(cursorPos, closestJoint)) { closestJoint = lists[l][i]; } if (length > 0) { Vector3 edgeSnapPos = StaticMethods.EdgeSnap(lists[l][i - 1], lists[l][i], cursorPos); if (Vector3.Distance(cursorPos, edgeSnapPos) < Vector3.Distance(cursorPos, closestEdge)) { closestEdge = edgeSnapPos; } } Vector3 xMirrorJoint = lists[l][i]; xMirrorJoint.x *= -1; if (Vector3.Distance(cursorPos, xMirrorJoint) < Vector3.Distance(cursorPos, closestMirrorJoint)) { closestMirrorJoint = xMirrorJoint; } Vector3 yMirrorJoint = lists[l][i]; yMirrorJoint.y *= -1; if (Vector3.Distance(cursorPos, yMirrorJoint) < Vector3.Distance(cursorPos, closestMirrorJoint)) { closestMirrorJoint = yMirrorJoint; } Vector3 zMirrorJoint = lists[l][i]; zMirrorJoint.z *= -1; if (Vector3.Distance(cursorPos, zMirrorJoint) < Vector3.Distance(cursorPos, closestMirrorJoint)) { closestMirrorJoint = zMirrorJoint; } length++; } } Vector3 xMiddleJoint = cursorPos; xMiddleJoint.x = 0; if (Vector3.Distance(cursorPos, xMiddleJoint) < Vector3.Distance(cursorPos, closestMirrorJoint)) { closestMirrorJoint = xMiddleJoint; } Vector3 snapPos = cursorPos; if (Vector3.Distance(cursorPos, closestJoint) < 0.015f) // snap dist { snapPos = closestJoint; } else if (Vector3.Distance(cursorPos, closestEdge) < 0.015f) { snapPos = closestEdge; } else if (Vector3.Distance(cursorPos, closestMirrorJoint) < 0.015f) { snapPos = closestMirrorJoint; } // else if (vector.Count > 1) //weird // { // snapPos = StaticMethods.DirSnap(vector[vector.Count - 2], cursorPos); // } return snapPos; } }