void construct(Vector3 direction) { direction.Normalize(); // direction is relative to camera's look vector direction = camAngles * direction; int size = rodSize; float max = Mathf.Max(Mathf.Abs(direction.x), Mathf.Max(Mathf.Abs(direction.y), Mathf.Abs(direction.z))); if (autoDiag && max < 0.9 && size < maxRodSize) { size++; // diagonal } Vector3 origin = cursor.transform.position + direction * 10f; Vector3 target = origin + direction * rodUnits[size]; Vector3 rodC = (origin + target) / 2; UndoFrame undo = new UndoFrame(cursor, true); // existing rod? Collider[] hits = Physics.OverlapSphere(rodC, 5f, rodMask); if (hits.Length == 0) { var rod = Rod.Create(size); rod.transform.position = rodC; rod.transform.up = target - origin; undo.objs.Add(rod); if (symmetry == symMirror) { // do we need to check for duplicate rods here? rod = Rod.Create(size); rod.transform.position = Vector3.Reflect(rodC, Vector3.right); rod.transform.up = Vector3.Reflect(target - origin, Vector3.right); undo.objs.Add(rod); } else if (symmetry == sym4Rotate) { for (float theta = 90f; theta < 360; theta += 90f) { rod = Rod.Create(size); rod.transform.position = Quaternion.AngleAxis(theta, Vector3.forward) * rodC; rod.transform.up = Quaternion.AngleAxis(theta, Vector3.forward) * (target - origin); undo.objs.Add(rod); } } } else { if (Input.GetKey(KeyCode.Delete)) { undo = new UndoFrame(cursor, false); undo.objs.Add(hits[0].gameObject); undoStack.Push(undo); hits[0].gameObject.SetActive(false); deleteHandled = true; return; } } if (Input.GetKey(KeyCode.Delete)) { // not trying to create something return; } cursor.GetComponent <Node>().autoAssign(); // update old cursor for new connectors // existing node? hits = Physics.OverlapSphere(target, 5f, nodeMask); if (hits.Length == 0) { var node = Node.Create(); Vector3 pos = target + direction * 10f; node.transform.position = pos; if (!Input.GetKey(KeyCode.LeftShift)) { setCursor(node); } undo.objs.Add(node); if (symmetry == symMirror) { Vector3 symPos = Vector3.Reflect(pos, Vector3.right); if (symPos != pos) { node = Node.Create(symPos); if (node) { undo.objs.Add(node); } } } else if (symmetry == sym4Rotate) { for (float theta = 90f; theta < 360; theta += 90f) { Vector3 symPos = Quaternion.AngleAxis(theta, Vector3.forward) * pos; if (symPos != pos) { node = Node.Create(symPos); if (node) { undo.objs.Add(node); } } } } } else { if (!Input.GetKey(KeyCode.LeftShift)) { setCursor(hits[0].gameObject); } } cursor.GetComponent <Node>().autoAssign(); // update new cursor for new connectors if (undo.objs.Count > 0) { undoStack.Push(undo); } }
void Update() { ///////////////// // animate camera if (targetCursor) { Vector3 offset = new Vector3(0f, 0f, -camZoom); offset = camAngles * offset; Vector3 camPos = cursor.transform.position + offset; Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position, camPos, 5f * Time.deltaTime); Camera.main.transform.rotation = Quaternion.Slerp(Camera.main.transform.rotation, camAngles, 5f * Time.deltaTime); } //////////////////// // move camera bool ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); // mouse pan if (Input.GetMouseButtonDown(0)) { targetCursor = false; mouseStart = Input.mousePosition; } else if (Input.GetMouseButton(0)) { Vector3 delta = Input.mousePosition - mouseStart; delta.Scale(new Vector3(-0.8f, -0.8f, 0.0f)); Camera.main.transform.Translate(delta); mouseStart = Input.mousePosition; } // mouse tilt if (Input.GetMouseButtonDown(1)) { targetCursor = false; mouseStart = Input.mousePosition; camMouseLookStart = Camera.main.transform.rotation; } else if (Input.GetMouseButton(1)) { Vector3 delta = Input.mousePosition - mouseStart; delta.Scale(new Vector3(0.6f, -0.6f, 0)); // invert Y axis Quaternion x = Quaternion.AngleAxis(delta.x, Vector3.up); Quaternion y = Quaternion.AngleAxis(delta.y, Vector3.right); Camera.main.transform.rotation = camMouseLookStart * x * y; } if (Input.GetKeyDown(KeyCode.KeypadMultiply)) { targetCursor = true; // snap back to cursor } camZoom += -500 * Input.GetAxis("Mouse ScrollWheel"); if (ctrl) // camera modifier // zoom { if (Input.GetKey(KeyCode.KeypadPlus)) { camZoom -= 15; } if (Input.GetKey(KeyCode.KeypadMinus)) { camZoom += 15; } // barrel roll if (Input.GetKeyDown(KeyCode.Home)) { camAngles = camAngles * Quaternion.AngleAxis(90f, new Vector3(0f, 0f, 1f)); } if (Input.GetKeyDown(KeyCode.PageUp)) { camAngles = camAngles * Quaternion.AngleAxis(90f, new Vector3(0f, 0f, -1f)); } // rotate if (Input.GetKeyDown(KeyCode.UpArrow)) { camAngles = camAngles * Quaternion.AngleAxis(90f, new Vector3(1f, 0f, 0f)); } if (Input.GetKeyDown(KeyCode.DownArrow)) { camAngles = camAngles * Quaternion.AngleAxis(-90f, new Vector3(1f, 0f, 0f)); } if (Input.GetKeyDown(KeyCode.LeftArrow)) { camAngles = camAngles * Quaternion.AngleAxis(90f, new Vector3(0f, 1f, 0f)); } if (Input.GetKeyDown(KeyCode.RightArrow)) { camAngles = camAngles * Quaternion.AngleAxis(-90f, new Vector3(0f, 1f, 0f)); } } // save and load if (Input.GetKeyDown(KeyCode.S)) { Serial.saveFile(); } if (Input.GetKeyDown(KeyCode.L)) { Serial.loadFile(); } if (Input.GetKeyDown(KeyCode.N)) { clearStage(); loadNew(); } //////////////////// // construction if (!ctrl) { // udlr if (Input.GetKeyDown(KeyCode.RightArrow)) { construct(new Vector3(1, 0, 0)); } if (Input.GetKeyDown(KeyCode.LeftArrow)) { construct(new Vector3(-1, 0, 0)); } if (Input.GetKeyDown(KeyCode.UpArrow)) { construct(new Vector3(0, 1, 0)); } if (Input.GetKeyDown(KeyCode.DownArrow)) { construct(new Vector3(0, -1, 0)); } // diagonal if (Input.GetKeyDown(KeyCode.Home)) { construct(new Vector3(-1, 1, 0)); } if (Input.GetKeyDown(KeyCode.End)) { construct(new Vector3(-1, -1, 0)); } if (Input.GetKeyDown(KeyCode.PageUp)) { construct(new Vector3(1, 1, 0)); } if (Input.GetKeyDown(KeyCode.PageDown)) { construct(new Vector3(1, -1, 0)); } // in/out if (Input.GetKeyDown(KeyCode.KeypadPlus)) { construct(new Vector3(0, 0, 1)); } if (Input.GetKeyDown(KeyCode.KeypadMinus)) { construct(new Vector3(0, 0, -1)); } if (Input.GetKeyDown(KeyCode.Delete)) { deleteHandled = false; } if (Input.GetKeyUp(KeyCode.Delete)) { if (!deleteHandled) { GameObject newCursor = Node.nearestNotAt(cursor.transform.position); if (newCursor == null) { Debug.Log("No other nodes to set cursor to, cannot delete"); } else { UndoFrame undo = new UndoFrame(cursor, false); undo.objs.Add(cursor); undoStack.Push(undo); cursor.SetActive(false); setCursor(newCursor); } } } } // undo if (Input.GetKeyDown(KeyCode.Backspace) || (ctrl && Input.GetKeyDown(KeyCode.Z))) { if (undoStack.Count > 0) { UndoFrame undo = undoStack.Pop(); setCursor(undo.cursor); undo.Revert(); } } // rod size if (Input.GetKeyDown(KeyCode.Alpha1)) { rodSize = 0; } if (Input.GetKeyDown(KeyCode.Alpha2)) { rodSize = 1; } if (Input.GetKeyDown(KeyCode.Alpha3)) { rodSize = 2; } if (Input.GetKeyDown(KeyCode.Alpha4)) { rodSize = 3; } if (Input.GetKeyDown(KeyCode.Alpha5)) { rodSize = 4; } if (Input.GetKeyDown(KeyCode.Alpha6)) { rodSize = 5; } // toggles if (Input.GetKeyDown(KeyCode.D)) { autoDiag = !autoDiag; } if (Input.GetKeyDown(KeyCode.M)) { symmetry = (symmetry + 1) % symmetryCount; } if (Input.GetKeyDown(KeyCode.C)) { cursor.GetComponent <Node>().cycleShape(); } if (Input.GetKeyDown(KeyCode.R)) { cursor.transform.Rotate(new Vector3(0, 0, 45)); } if (Input.GetKeyDown(KeyCode.A)) { var objs = FindObjectsOfType <Node>(); foreach (var node in objs) { node.autoAssign(); } } if (Input.GetKeyDown(KeyCode.F)) { camFocus = !camFocus; Camera.main.nearClipPlane = camFocus ? camZoom - 50 : 5; Camera.main.farClipPlane = camFocus ? camZoom + 50 : 10000; } }