private void Draw() { var worldBezier = targetPath.WorldSpaceBezier; var vertexCount = DynamicBezier.GoodNumMidPoints * worldBezier.Knots.Count; vertexCount /= 2; var cPointCache = new EvaluationCache(worldBezier, vertexCount).Values; // draw bezier PathEditorUtility.DrawSplineInScene(cPointCache); // draw direction cone cap if (!settings.HideDirectionCones && targetScript.transform.lossyScale != Vector3.zero && targetPath.LocalBezier.Knots.Count > 1) // also hide cones if virtually a dot { float startConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(0f)); float endConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(1f)); Handles.color = Color.yellow; Handles.ConeCap(0, worldBezier.Evaluate(0f), Quaternion.LookRotation(worldBezier.Evaluate(0.01f) - worldBezier.Evaluate(0f)), startConeSize); Handles.color = Color.magenta; Handles.ConeCap(0, worldBezier.Evaluate(1f), Quaternion.LookRotation(worldBezier.Evaluate(1f) - worldBezier.Evaluate(1f - 0.01f)), endConeSize); } // draw tangent lines if (!settings.HideTangentLines) { Handles.color = Color.cyan; for (int i = 0; i < worldBezier.Knots.Count - 1; i++) { Handles.DrawDottedLine(worldBezier.Knots[i], worldBezier.Knots[i + 1], 7.5f); } } // Draw knot labels var knotLabelStyle = new GUIStyle(); knotLabelStyle.fontStyle = FontStyle.Bold; knotLabelStyle.fontSize = 17; knotLabelStyle.alignment = TextAnchor.UpperRight; knotLabelStyle.contentOffset = new Vector2(25f, -50f); for (int i = 0; i < worldBezier.Knots.Count; i++) { knotLabelStyle.normal.textColor = PathEditorUtility.GetTColor((float)i / worldBezier.Knots.Count); Handles.Label(worldBezier.Knots[i], i.ToString(), knotLabelStyle); } // test t if (settings.TestInterpolate) { PathEditorUtility.DrawTestInterpolate(worldBezier, settings.EditorData.T); } // draw GUI InterpolateSceneGUI(); ToolShelf(); }
private void MoveToolSceneGUI() { // Undo world transformation before writing values to Path's bezier curve Func <Vector3, Vector3> handleToLocal = (handlePoint) => { return(PathEditorUtility.HandleToLocalPosition(handlePoint, cubicBezierPath.LocalSpaceTransform)); }; Vector3 newLocalStartPosition = handleToLocal(cubicBezierPath.StartPosition); Vector3 newLocalStartTangent = handleToLocal(cubicBezierPath.StartTangent); Vector3 newLocalEndPosition = handleToLocal(cubicBezierPath.EndPosition); Vector3 newLocalEndTangent = handleToLocal(cubicBezierPath.EndTangent); // Write values to Path's bezier curve if (newLocalStartPosition != cubicBezierPath.LocalBezier.StartPosition || newLocalStartTangent != cubicBezierPath.LocalBezier.StartTangent || newLocalEndPosition != cubicBezierPath.LocalBezier.EndPosition || newLocalEndTangent != cubicBezierPath.LocalBezier.EndTangent) { Undo.RecordObject(target, "Edit Cubic Bezier"); //~ Before storing new values, prevent lossyScale from deleting values Vector3 finalStartPosition = cubicBezierPath.LocalBezier.StartPosition; Vector3 finalStartTangent = cubicBezierPath.LocalBezier.StartTangent; Vector3 finalEndPosition = cubicBezierPath.LocalBezier.EndPosition; Vector3 finalEndTangent = cubicBezierPath.LocalBezier.EndTangent; bool guardX = Mathf.Approximately(targetScript.transform.lossyScale.x, 0.0f); bool guardY = Mathf.Approximately(targetScript.transform.lossyScale.y, 0.0f); bool guardZ = Mathf.Approximately(targetScript.transform.lossyScale.z, 0.0f); if (!guardX) { finalStartPosition.x = newLocalStartPosition.x; finalStartTangent.x = newLocalStartTangent.x; finalEndPosition.x = newLocalEndPosition.x; finalEndTangent.x = newLocalEndTangent.x; } if (!guardY) { finalStartPosition.y = newLocalStartPosition.y; finalStartTangent.y = newLocalStartTangent.y; finalEndPosition.y = newLocalEndPosition.y; finalEndTangent.y = newLocalEndTangent.y; } if (!guardZ) { finalStartPosition.z = newLocalStartPosition.z; finalStartTangent.z = newLocalStartTangent.z; finalEndPosition.z = newLocalEndPosition.z; finalEndTangent.z = newLocalEndTangent.z; } cubicBezierPath.LocalBezier.StartPosition = finalStartPosition; cubicBezierPath.LocalBezier.StartTangent = finalStartTangent; cubicBezierPath.LocalBezier.EndPosition = finalEndPosition; cubicBezierPath.LocalBezier.EndTangent = finalEndTangent; EditorUtility.SetDirty(target); } }
private void OnSceneGUI() { if (!Safety()) { if (warnedTransform == false) { Debug.Log("[" + targetScript.name + "]\t" + PathEditorUtility.EditorUnavailable); warnedTransform = true; } return; } if (settings.HideHandles || Tools.current == Tool.View) { goto Draw; } if (Tools.current == Tool.Move) { Vector3 newLocalStartPosition = PathEditorUtility.HandleToLocalPosition(linePath.StartPosition, linePath.LocalSpaceTransform); Vector3 newLocalEndPosition = PathEditorUtility.HandleToLocalPosition(linePath.EndPosition, linePath.LocalSpaceTransform); bool guardX = Mathf.Approximately(linePath.LocalSpaceTransform.lossyScale.x, 0f); bool guardY = Mathf.Approximately(linePath.LocalSpaceTransform.lossyScale.y, 0f); bool guardZ = Mathf.Approximately(linePath.LocalSpaceTransform.lossyScale.z, 0f); if (newLocalStartPosition != linePath.LocalStartPosition || newLocalEndPosition != linePath.LocalEndPosition) { Undo.RecordObject(target, "Edit Line"); if (!guardX) { linePath.LocalStartPosition.x = newLocalStartPosition.x; linePath.LocalEndPosition.x = newLocalEndPosition.x; } if (!guardY) { linePath.LocalStartPosition.y = newLocalStartPosition.y; linePath.LocalEndPosition.y = newLocalEndPosition.y; } if (!guardZ) { linePath.LocalStartPosition.z = newLocalStartPosition.z; linePath.LocalEndPosition.z = newLocalEndPosition.z; } EditorUtility.SetDirty(target); } } Draw: Draw(); }
private void Draw() { CubicBezier worldBezier = cubicBezierPath.WorldSpaceBezier; // draw bezier Vector3[] cPointCache = new EvaluationCache(worldBezier, CubicBezier.GoodNumMidPoints).Values; /*Handles.color = Color.yellow; * Handles.DrawAAPolyLine(cPointCache); */ for (int i = 0; i < cPointCache.Length - 1; i++) { Handles.color = Color.Lerp(Color.yellow, Color.magenta, (float)i / cPointCache.Length); var lineSegment = new Vector3[2]; lineSegment[0] = cPointCache[i]; lineSegment[1] = cPointCache[i + 1]; Handles.DrawAAPolyLine(lineSegment); } // draw direction cone cap if (!settings.HideDirectionCones && targetScript.transform.lossyScale != Vector3.zero) //check for zero vector, since LookRotation logs messages { float startConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(0f)); float endConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(1f)); Handles.color = Color.yellow; Handles.ConeCap(0, worldBezier.Evaluate(0f), Quaternion.LookRotation(worldBezier.Tangent(0f)), startConeSize); Handles.color = Color.magenta; Handles.ConeCap(0, worldBezier.Evaluate(1f), Quaternion.LookRotation(worldBezier.Tangent(1f)), endConeSize); } // draw tangent lines if (!settings.HideTangentLines) { Handles.color = Color.cyan; Handles.DrawDottedLine(worldBezier.StartPosition, worldBezier.StartTangent, 7.5f); Handles.DrawDottedLine(worldBezier.EndPosition, worldBezier.EndTangent, 7.5f); } // test t if (settings.TestInterpolate) { PathEditorUtility.DrawTestInterpolate(worldBezier, settings.EditorData.T); } // draw GUI InterpolateSceneGUI(); ToolShelf(); }
private void Draw() { Vector3 startPoint = linePath.Evaluate(0f); Vector3 endPoint = linePath.Evaluate(1f); // draw line var cPointCache = new Vector3[32]; for (int i = 0; i < cPointCache.Length; i++) { cPointCache[i] = Vector3.Lerp(startPoint, endPoint, (float)i / (cPointCache.Length - 1)); } for (int i = 0; i < cPointCache.Length - 1; i++) { Handles.color = Color.Lerp(Color.yellow, Color.magenta, (float)i / cPointCache.Length); var lineSegment = new Vector3[2]; lineSegment[0] = cPointCache[i]; lineSegment[1] = cPointCache[i + 1]; Handles.DrawAAPolyLine(lineSegment); } // draw direction cone cap if (!settings.HideDirectionCones && linePath.LocalSpaceTransform.lossyScale != Vector3.zero && linePath.StartPosition != linePath.EndPosition) // also hide cones if virtually a dot { float startConeSize = PathEditorUtility.Nice3DHandleSize(startPoint); float endConeSize = PathEditorUtility.Nice3DHandleSize(endPoint); Handles.color = Color.yellow; Handles.ConeCap(0, startPoint, Quaternion.LookRotation(linePath.Tangent()), startConeSize); Handles.color = Color.magenta; Handles.ConeCap(0, endPoint, Quaternion.LookRotation(linePath.Tangent()), endConeSize); } // test t Handles.color = PathEditorUtility.GetTColor(settings.EditorData.T); if (settings.TestInterpolate) { Vector3 targetPoint = linePath.Evaluate(settings.EditorData.T); float sphereSize = PathEditorUtility.Nice3DHandleSize(targetPoint); Handles.SphereCap(0, targetPoint, Quaternion.identity, sphereSize); } // draw GUI InterpolateSceneGUI(); ToolShelf(); }
private void MoveToolSceneGUI() { for (int i = 0; i < targetPath.LocalBezier.Knots.Count; i++) { // Undo world transformation before writing values to Path's bezier curve Vector3 newLocalPosition; { var handlePosition = targetPath.WorldSpaceBezier.Knots[i]; newLocalPosition = PathEditorUtility.HandleToLocalPosition( handlePosition, targetPath.LocalSpaceTransform); } // Write value to Path's bezier curve //if (newLocalPosition != dynamicBezierPath.LocalBezier.Knots[i]) if (PathEditorUtility.VectorNotApproximately(newLocalPosition, targetPath.LocalBezier.Knots[i])) { Undo.RecordObject(target, "Edit Dynamic Bezier"); //~ Before storing new values, prevent lossyScale from deleting values var finalPosition = targetPath.LocalBezier.Knots[i]; bool guardX = Mathf.Approximately(targetScript.transform.lossyScale.x, 0.0f); bool guardY = Mathf.Approximately(targetScript.transform.lossyScale.y, 0.0f); bool guardZ = Mathf.Approximately(targetScript.transform.lossyScale.z, 0.0f); if (!guardX) { finalPosition.x = newLocalPosition.x; } if (!guardY) { finalPosition.y = newLocalPosition.y; } if (!guardZ) { finalPosition.z = newLocalPosition.z; } targetPath.LocalBezier.Knots[i] = finalPosition; EditorUtility.SetDirty(target); } } }
private void Draw() { QuadraticBezier worldBezier = qdrBezierPath.WorldSpaceBezier; var cPointCache = new EvaluationCache(worldBezier, QuadraticBezier.GoodNumMidPoints).Values; // draw bezier PathEditorUtility.DrawSplineInScene(cPointCache); // draw direction cone cap if (!settings.HideDirectionCones && targetScript.transform.lossyScale != Vector3.zero) // also hide cones if virtually a dot { float startConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(0f)); float endConeSize = PathEditorUtility.Nice3DHandleSize(worldBezier.Evaluate(1f)); Handles.color = Color.yellow; Handles.ConeCap(0, worldBezier.Evaluate(0f), Quaternion.LookRotation(worldBezier.Evaluate(0.01f) - worldBezier.Evaluate(0f)), startConeSize); Handles.color = Color.magenta; Handles.ConeCap(0, worldBezier.Evaluate(1f), Quaternion.LookRotation(worldBezier.Evaluate(1f) - worldBezier.Evaluate(1f - 0.01f)), endConeSize); } // draw tangent lines if (!settings.HideTangentLines) { Handles.color = Color.cyan; Handles.DrawDottedLine(worldBezier.StartPosition, worldBezier.MidTangent, 7.5f); Handles.DrawDottedLine(worldBezier.MidTangent, worldBezier.EndPosition, 7.5f); } // test t if (settings.TestInterpolate) { PathEditorUtility.DrawTestInterpolate(worldBezier, settings.EditorData.T); } // draw GUI InterpolateSceneGUI(); ToolShelf(); }
public override void OnInspectorGUI() { //base.OnInspectorGUI(); Safety(); var newStartPosition = cubicBezierPath.LocalBezier.StartPosition; var newStartTangent = cubicBezierPath.LocalBezier.StartTangent; var newEndPosition = cubicBezierPath.LocalBezier.EndPosition; var newEndTangent = cubicBezierPath.LocalBezier.EndTangent; #region Path Inspector settings.PathFoldout = EditorGUILayout.Foldout(settings.PathFoldout, "Path"); if (settings.PathFoldout) { EditorGUI.indentLevel++; //~ Knots //cubicBezierPath.LocalBezier.StartPosition = EditorGUILayout.Vector3Field("Start Position", cubicBezierPath.LocalBezier.StartPosition); //cubicBezierPath.LocalBezier.StartTangent = EditorGUILayout.Vector3Field("Start Tangent", cubicBezierPath.LocalBezier.StartTangent); //cubicBezierPath.LocalBezier.EndPosition = EditorGUILayout.Vector3Field("End Position", cubicBezierPath.LocalBezier.EndPosition); //cubicBezierPath.LocalBezier.EndTangent = EditorGUILayout.Vector3Field("End Tangent", cubicBezierPath.LocalBezier.EndTangent); newStartPosition = EditorGUILayout.Vector3Field("Start Position", cubicBezierPath.LocalBezier.StartPosition); newStartTangent = EditorGUILayout.Vector3Field("Start Tangent", cubicBezierPath.LocalBezier.StartTangent); newEndPosition = EditorGUILayout.Vector3Field("End Position", cubicBezierPath.LocalBezier.EndPosition); newEndTangent = EditorGUILayout.Vector3Field("End Tangent", cubicBezierPath.LocalBezier.EndTangent); EditorGUI.indentLevel--; } #endregion Path Inspector #region Tool Settings Inspector PathEditorUtility.Inspector(settings, 1); #endregion Tool Settings Inspector #region Advanced settings.AdvancedFoldout = EditorGUILayout.Foldout(settings.AdvancedFoldout, "Advanced"); if (settings.AdvancedFoldout) { //~ LocalSpaceTransform field cubicBezierPath.LocalSpaceTransform = (Transform)EditorGUILayout.ObjectField( "Local Space Transform", cubicBezierPath.LocalSpaceTransform, typeof(Transform), allowSceneObjects: true ); } #endregion Advanced #region Undo if (newStartPosition != cubicBezierPath.LocalBezier.StartPosition || newStartTangent != cubicBezierPath.LocalBezier.StartTangent || newEndPosition != cubicBezierPath.LocalBezier.EndPosition || newEndTangent != cubicBezierPath.LocalBezier.EndTangent) { Undo.RecordObject(target, "Edit Cubic Bezier"); cubicBezierPath.LocalBezier.StartPosition = newStartPosition; cubicBezierPath.LocalBezier.StartTangent = newStartTangent; cubicBezierPath.LocalBezier.EndPosition = newEndPosition; cubicBezierPath.LocalBezier.EndTangent = newEndTangent; EditorUtility.SetDirty(target); } #endregion Undo SceneView.RepaintAll(); }
public override void OnInspectorGUI() { //base.OnInspectorGUI(); Safety(); var newKnots = new List <Vector3>(targetPath.LocalBezier.Knots); #region Path Inspector settings.PathFoldout = EditorGUILayout.Foldout(settings.PathFoldout, "Path"); if (settings.PathFoldout) { // EditorGUI.indentLevel++; if (newKnots.Count <= 0) { if (GUILayout.Button("+")) { newKnots.Add(Vector3.right); goto UndoHistory; } } for (int i = 0; i < newKnots.Count; i++) { newKnots[i] = EditorGUILayout.Vector3Field(i.ToString(), newKnots[i]); EditorGUILayout.BeginHorizontal(EditorStyles.inspectorDefaultMargins); GUILayout.FlexibleSpace(); if (GUILayout.Button("-", GUILayout.Width(25f))) { newKnots.RemoveAt(i); goto UndoHistory; } if (GUILayout.Button("+", GUILayout.Width(25f))) { Vector3 newKnot; var currentKnot = newKnots[i]; if (i == newKnots.Count - 1) // last knot { if (newKnots.Count == 1) // this is the only knot { newKnot = newKnots[0] + Vector3.right; } else { var previousKnot = newKnots[i - 1]; newKnot = currentKnot + (currentKnot - previousKnot); } } else { var nextKnot = newKnots[i + 1]; newKnot = Vector3.Lerp(currentKnot, nextKnot, 0.5f); } newKnots.Insert(i + 1, newKnot); goto UndoHistory; } EditorGUILayout.EndHorizontal(); } //EditorGUI.indentLevel--; } #endregion Path Inspector #region Tool Settings Inspector PathEditorUtility.Inspector(settings, 1); #endregion Tool Settings Inspector #region Advanced settings.AdvancedFoldout = EditorGUILayout.Foldout(settings.AdvancedFoldout, "Advanced"); if (settings.AdvancedFoldout) { //~ LocalSpaceTransform field targetPath.LocalSpaceTransform = (Transform)EditorGUILayout.ObjectField( "Local Space Transform", targetPath.LocalSpaceTransform, typeof(Transform), allowSceneObjects: true ); } #endregion Advanced #region Undo UndoHistory: if (!targetPath.LocalBezier.Knots.SequenceEqual(newKnots) || targetPath.LocalBezier.Knots.Count != newKnots.Count) { Undo.RecordObject(target, "Edit Dynamic Bezier"); targetPath.LocalBezier.Knots = newKnots; EditorUtility.SetDirty(target); } SceneView.RepaintAll(); #endregion Undo }
public override void OnInspectorGUI() { //base.OnInspectorGUI(); Safety(); var newCenter = circlePath.LocalCircle.Center; var newRadius = circlePath.LocalCircle.Radius; var newMaxAngle = circlePath.MaxAngle; #region Path Inspector settings.PathFoldout = EditorGUILayout.Foldout(settings.PathFoldout, "Path"); if (settings.PathFoldout) { EditorGUI.indentLevel++; //~ Fields newCenter = EditorGUILayout.Vector3Field("Local Center", circlePath.LocalCircle.Center); newRadius = EditorGUILayout.FloatField("Radius", circlePath.LocalCircle.Radius); newMaxAngle = EditorGUILayout.FloatField("Max Angle (Degrees)", circlePath.MaxAngle * Mathf.Rad2Deg) * Mathf.Deg2Rad; EditorGUI.indentLevel--; } #endregion Path Inspector #region Tool Settings Inspector PathEditorUtility.Inspector(settings); #endregion Tool Settings Inspector #region Advanced settings.AdvancedFoldout = EditorGUILayout.Foldout(settings.AdvancedFoldout, "Advanced"); if (settings.AdvancedFoldout) { //~ LocalSpaceTransform field circlePath.LocalSpaceTransform = (Transform)EditorGUILayout.ObjectField( "Local Space Transform", circlePath.LocalSpaceTransform, typeof(Transform), allowSceneObjects: true ); } #endregion Advanced #region Undo if (newCenter != circlePath.LocalCircle.Center || newRadius != circlePath.LocalCircle.Radius || newMaxAngle != circlePath.MaxAngle) { Undo.RecordObject(target, "Edit Circle"); circlePath.LocalCircle.Center = newCenter; circlePath.LocalCircle.Radius = newRadius; circlePath.MaxAngle = newMaxAngle; EditorUtility.SetDirty(target); } #endregion Undo SceneView.RepaintAll(); }
private void Draw() { Vector3 startPoint = circlePath.Evaluate(0f); Vector3 endPoint = circlePath.Evaluate(1f); CirclePath reducedCirclePath = new CirclePath( circlePath.LocalSpaceTransform, new Circle(circlePath.LocalCircle.Center, circlePath.LocalCircle.Radius), circlePath.MaxAngle % Circle.TwoPI // remove loops ); if (circlePath.MaxAngle >= Circle.TwoPI) // add back a single loop if it loops { reducedCirclePath.MaxAngle += Circle.TwoPI; } else if (Mathf.Abs(circlePath.MaxAngle) >= Circle.TwoPI) // if negative maxAngle and is still at least one loop { reducedCirclePath.MaxAngle -= Circle.TwoPI; } // draw circle var cPointCache = new EvaluationCache(reducedCirclePath, 128).Values; /*Handles.color = Color.yellow; * Handles.DrawAAPolyLine(cPointCache); */ for (int i = 0; i < cPointCache.Length - 1; i++) { Handles.color = Color.Lerp(Color.yellow, Color.magenta, (float)i / cPointCache.Length); var lineSegment = new Vector3[2]; lineSegment[0] = cPointCache[i]; lineSegment[1] = cPointCache[i + 1]; Handles.DrawAAPolyLine(lineSegment); } // draw direction cone cap if (!settings.HideDirectionCones && circlePath.LocalSpaceTransform.lossyScale != Vector3.zero && circlePath.LocalCircle.Radius != 0f && Mathf.Abs(reducedCirclePath.MaxAngle * Mathf.Rad2Deg) > 10.0f) // also hide cones if virtually a dot { float startConeSize = PathEditorUtility.Nice3DHandleSize(startPoint); float endConeSize = PathEditorUtility.Nice3DHandleSize(endPoint); Handles.color = Color.yellow; Handles.ConeCap(0, startPoint, Quaternion.LookRotation(circlePath.Tangent(0f)), startConeSize); Handles.color = Color.magenta; Handles.ConeCap(0, endPoint, Quaternion.LookRotation(circlePath.Tangent(1f)), endConeSize); } // test t if (settings.TestInterpolate) { PathEditorUtility.DrawTestInterpolate(circlePath, settings.EditorData.T); } #region Scene View GUI Handles.BeginGUI(); //Note: GUILayout.BeginArea() deprecates Handles, however it behaves incorrectly (debug lines offset) { GUILayout.BeginHorizontal(GUILayout.Width(Screen.width)); { GUILayout.Space(20.0f); targetScript.EditorOnlyToolSettings.TestInterpolate = GUILayout.Toggle(targetScript.EditorOnlyToolSettings.TestInterpolate, "Test Interpolate", GUILayout.ExpandWidth(false)); if (targetScript.EditorOnlyToolSettings.TestInterpolate) { settings.EditorData.T = GUILayout.HorizontalSlider(settings.EditorData.T, 0f, 1.0f, GUILayout.Width(100.0f)); GUILayout.Label(settings.EditorData.T.ToString(), GUILayout.Width(75.0f)); GUILayout.Label("Custom: ", GUILayout.Width(60.0f)); settings.EditorData.CustomT = GUILayout.TextField(settings.EditorData.CustomT, GUILayout.Width(100.0f)); if (Event.current.keyCode == KeyCode.Return) { float tempT; if (System.Single.TryParse(settings.EditorData.CustomT, out tempT)) { settings.EditorData.T = tempT; } } } } GUILayout.EndHorizontal(); } Handles.EndGUI(); #endregion Scene View GUI ToolShelf(); }