/* * Creating new Limit Points * */ private void AddPoint(int p) { RotationLimitPolygonal.LimitPoint[] newPoints = new RotationLimitPolygonal.LimitPoint[script.points.Length + 1]; for (int i = 0; i < p + 1; i++) { newPoints[i] = script.points[i]; } newPoints[p + 1] = new RotationLimitPolygonal.LimitPoint(); Vector3 nextPoint = Vector3.forward; if (p < script.points.Length - 1) { nextPoint = script.points[p + 1].point; } else { nextPoint = script.points[0].point; } newPoints[p + 1].point = Vector3.Lerp(script.points[p].point, nextPoint, 0.5f); for (int i = p + 2; i < newPoints.Length; i++) { newPoints[i] = script.points[i - 1]; } script.points = newPoints; script.BuildReachCones(); }
/* * Removing Limit Points * */ private void DeletePoint(int p) { RotationLimitPolygonal.LimitPoint[] newPoints = new RotationLimitPolygonal.LimitPoint[0]; for (int i = 0; i < script.points.Length; i++) { if (i != p) { Array.Resize(ref newPoints, newPoints.Length + 1); newPoints[newPoints.Length - 1] = script.points[i]; } } script.points = newPoints; script.BuildReachCones(); }
/* * Returns closest point to a position. Used for symmetric editing * */ private RotationLimitPolygonal.LimitPoint GetClosestPoint(Vector3 v) { float closestDistace = Mathf.Infinity; RotationLimitPolygonal.LimitPoint closestPoint = null; foreach (RotationLimitPolygonal.LimitPoint limitPoint in script.points) { if (limitPoint.point == v) { return(limitPoint); } float d = Vector3.Distance(limitPoint.point, v); if (d < closestDistace) { closestPoint = limitPoint; closestDistace = d; } } return(closestPoint); }
public void OnSceneGUI() { GUI.changed = false; // Set defaultLocalRotation so that the initial local rotation will be the zero point for the rotation limit if (!Application.isPlaying) { script.defaultLocalRotation = script.transform.localRotation; } if (script.axis == Vector3.zero) { return; } // Quick Editing Tools Handles.BeginGUI(); GUILayout.BeginArea(new Rect(10, Screen.height - 180, 550, 130), "Rotation Limit Polygonal", "Window"); // Cloning values from another RotationLimitPolygonal EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Clone From", "Make this rotation limit identical to another", script, GUILayout.Width(220))) { CloneLimit(); } clone = (RotationLimitPolygonal)EditorGUILayout.ObjectField("", clone, typeof(RotationLimitPolygonal), true); EditorGUILayout.EndHorizontal(); // Symmetry symmetry = (Symmetry)EditorGUILayout.EnumPopup("Symmetry", symmetry, GUILayout.Width(220)); // Flipping EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Flip X", "Flip points along local X axis", script, GUILayout.Width(100))) { FlipLimit(0); } if (Inspector.Button("Flip Y", "Flip points along local Y axis", script, GUILayout.Width(100))) { FlipLimit(1); } if (Inspector.Button("Flip Z", "Flip points along local Z axis", script, GUILayout.Width(100))) { FlipLimit(2); } GUILayout.Label("Flip everything along axis"); EditorGUILayout.EndHorizontal(); // Rotating EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Rotate X", "Rotate points along X axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.right); } if (Inspector.Button("Rotate Y", "Rotate points along Y axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.up); } if (Inspector.Button("Rotate Z", "Rotate points along Z axis by Degrees", script, GUILayout.Width(100))) { RotatePoints(degrees, Vector3.forward); } degrees = EditorGUILayout.FloatField("Degrees", degrees, GUILayout.Width(200)); EditorGUILayout.EndHorizontal(); // Smooth/Optimize EditorGUILayout.BeginHorizontal(); if (Inspector.Button("Smooth", "Double the points", script)) { Smooth(); } if (Inspector.Button("Optimize", "Delete every second point", script)) { Optimize(); } EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); Handles.EndGUI(); // Rebuild reach cones script.BuildReachCones(); // Draw a white transparent sphere DrawRotationSphere(script.transform.position); // Draw Axis DrawArrow(script.transform.position, Direction(script.axis), colorDefault, "Axis", 0.02f); // Display limit points for (int i = 0; i < script.points.Length; i++) { Color color = GetColor(i); // Paint the point in green or red if it belongs to an invalid reach cone Handles.color = color; GUI.color = color; // Line from the center to the point and the label Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.points[i].point)); Handles.Label(script.transform.position + Direction(script.points[i].point + new Vector3(-0.02f, 0, 0)), " " + i.ToString()); // Selecting points Handles.color = colorHandles; if (Inspector.DotButton(script.transform.position + Direction(script.points[i].point), script.transform.rotation, 0.02f, 0.02f)) { selectedPoint = i; } Handles.color = Color.white; GUI.color = Color.white; // Limit point GUI if (i == selectedPoint) { Handles.BeginGUI(); GUILayout.BeginArea(new Rect(Screen.width - 240, Screen.height - 180, 230, 130), "Limit Point " + i.ToString(), "Window"); if (Inspector.Button("Delete", "Delete this point", script)) { if (script.points.Length > 3) { // Using the deletePoint index here because we dont want to delete points from the array that we are iterating deletePoint = i; } else if (!Warning.logged) { script.LogWarning("Polygonal Rotation Limit should have at least 3 limit points"); } } if (Inspector.Button("Add Point", "Add a new point next to this one", script)) { addPoint = i; } // Store point for undo Vector3 oldPoint = script.points[i].point; // Manual input for the point position Inspector.AddVector3(ref script.points[i].point, "Point", script, GUILayout.Width(210)); EditorGUILayout.Space(); // Tangent weight Inspector.AddFloat(ref script.points[i].tangentWeight, "Tangent Weight", "Weight of this point's tangent. Used in smoothing.", script, -Mathf.Infinity, Mathf.Infinity, GUILayout.Width(150)); GUILayout.EndArea(); Handles.EndGUI(); // Moving Points Vector3 pointWorld = Handles.PositionHandle(script.transform.position + Direction(script.points[i].point), Quaternion.identity); Vector3 newPoint = InverseDirection(pointWorld - script.transform.position); if (newPoint != script.points[i].point) { if (!Application.isPlaying) { Undo.RecordObject(script, "Move Limit Point"); } script.points[i].point = newPoint; } // Symmetry if (symmetry != Symmetry.Off && script.points.Length > 3 && oldPoint != script.points[i].point) { RotationLimitPolygonal.LimitPoint symmetryPoint = GetClosestPoint(Symmetrize(oldPoint, symmetry)); if (symmetryPoint != script.points[i]) { symmetryPoint.point = Symmetrize(script.points[i].point, symmetry); } } } // Normalize the point script.points[i].point = script.points[i].point.normalized; } // Display smoothed polygon for (int i = 0; i < script.P.Length; i++) { Color color = GetColor(i); // Smoothed triangles are transparent Handles.color = new Color(color.r, color.g, color.b, 0.25f); Handles.DrawLine(script.transform.position, script.transform.position + Direction(script.P[i])); Handles.color = color; if (i < script.P.Length - 1) { Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[i + 1])); } else { Handles.DrawLine(script.transform.position + Direction(script.P[i]), script.transform.position + Direction(script.P[0])); } Handles.color = Color.white; } // Deleting points if (deletePoint != -1) { DeletePoint(deletePoint); selectedPoint = -1; deletePoint = -1; } // Adding points if (addPoint != -1) { AddPoint(addPoint); addPoint = -1; } if (GUI.changed) { EditorUtility.SetDirty(script); } }
/* * Removing Limit Points * */ private void DeletePoint(int p) { RotationLimitPolygonal.LimitPoint[] newPoints = new RotationLimitPolygonal.LimitPoint[0]; for (int i = 0; i < script.points.Length; i++) { if (i != p) { Array.Resize(ref newPoints, newPoints.Length + 1); newPoints[newPoints.Length - 1] = script.points[i]; } } script.points = newPoints; script.BuildReachCones(); }
/* * Creating new Limit Points * */ private void AddPoint(int p) { RotationLimitPolygonal.LimitPoint[] newPoints = new RotationLimitPolygonal.LimitPoint[script.points.Length + 1]; for (int i = 0; i < p + 1; i++) newPoints[i] = script.points[i]; newPoints[p + 1] = new RotationLimitPolygonal.LimitPoint(); Vector3 nextPoint = Vector3.forward; if (p < script.points.Length - 1) nextPoint = script.points[p + 1].point; else nextPoint = script.points[0].point; newPoints[p + 1].point = Vector3.Lerp(script.points[p].point, nextPoint, 0.5f); for (int i = p + 2; i < newPoints.Length; i++) newPoints[i] = script.points[i - 1]; script.points = newPoints; script.BuildReachCones(); }