private void HandleSelectedSegmentModifications() { if (selectedSegmentIndex < 0 || selectedSegmentIndex >= instance.Spline.Segments.Count) { return; } if (!instance.Spline.IsSegmentValid(selectedSegmentIndex)) { return; } GSplineSegment segment = instance.Spline.Segments[selectedSegmentIndex]; GSplineAnchor startAnchor = instance.Spline.Anchors[segment.StartIndex]; GSplineAnchor endAnchor = instance.Spline.Anchors[segment.EndIndex]; Vector3 worldStartTangent = startAnchor.Position + segment.StartTangent; Vector3 worldEndTangent = endAnchor.Position + segment.EndTangent; Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; worldStartTangent = Handles.PositionHandle(worldStartTangent, Quaternion.identity); worldEndTangent = Handles.PositionHandle(worldEndTangent, Quaternion.identity); segment.StartTangent = worldStartTangent - startAnchor.Position; segment.EndTangent = worldEndTangent - endAnchor.Position; Handles.color = Color.white; Handles.DrawLine(startAnchor.Position, worldStartTangent); Handles.DrawLine(endAnchor.Position, worldEndTangent); instance.transform.position = (startAnchor.Position + endAnchor.Position) * 0.5f; }
private void HandleSelectedSegmentModifications() { if (selectedSegmentIndex < 0 || selectedSegmentIndex >= splineCreator.Spline.Segments.Count) { return; } if (!splineCreator.Spline.IsSegmentValid(selectedSegmentIndex)) { return; } GSplineSegment segment = splineCreator.Spline.Segments[selectedSegmentIndex]; GSplineAnchor startAnchor = splineCreator.Spline.Anchors[segment.StartIndex]; GSplineAnchor endAnchor = splineCreator.Spline.Anchors[segment.EndIndex]; Vector3 worldStartPosition = splineCreator.transform.TransformPoint(startAnchor.Position); Vector3 worldEndPosition = splineCreator.transform.TransformPoint(endAnchor.Position); Vector3 worldStartTangent = splineCreator.transform.TransformPoint(segment.StartTangent); Vector3 worldEndTangent = splineCreator.transform.TransformPoint(segment.EndTangent); EditorGUI.BeginChangeCheck(); Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; worldStartTangent = Handles.PositionHandle(worldStartTangent, Quaternion.identity); worldEndTangent = Handles.PositionHandle(worldEndTangent, Quaternion.identity); segment.StartTangent = splineCreator.transform.InverseTransformPoint(worldStartTangent); segment.EndTangent = splineCreator.transform.InverseTransformPoint(worldEndTangent); if (EditorGUI.EndChangeCheck()) { GUI.changed = true; } Handles.color = Color.white; Handles.DrawLine(worldStartPosition, worldStartTangent); Handles.DrawLine(worldEndPosition, worldEndTangent); }
public Vector3 EvaluateScale(int segmentIndex, float t) { GSplineSegment s = Segments[segmentIndex]; GSplineAnchor startAnchor = Anchors[s.StartIndex]; GSplineAnchor endAnchor = Anchors[s.EndIndex]; return(Vector3.Lerp(startAnchor.Scale, endAnchor.Scale, t)); }
public Quaternion EvaluateRotation(int segmentIndex, float t) { GSplineSegment s = Segments[segmentIndex]; GSplineAnchor startAnchor = Anchors[s.StartIndex]; GSplineAnchor endAnchor = Anchors[s.EndIndex]; return(Quaternion.Lerp(startAnchor.Rotation, endAnchor.Rotation, t)); }
private void DrawSelectedSegmentGUI() { string label = "Selected Segment"; string id = "selectedsegment" + instance.GetInstanceID().ToString(); GEditorCommon.Foldout(label, true, id, () => { if (selectedSegmentIndex >= 0 && selectedSegmentIndex < instance.Spline.Segments.Count) { GSplineSegment s = instance.Spline.Segments[selectedSegmentIndex]; GSplineSegmentInspectorDrawer.Create(s).DrawGUI(); } else { EditorGUILayout.LabelField("No Segment selected!", GEditorCommon.ItalicLabel); } }); }
public bool IsSegmentValid(int segmentIndex) { GSplineSegment s = Segments[segmentIndex]; if (s == null) { return(false); } bool startIndexValid = s.StartIndex >= 0 && s.StartIndex < Anchors.Count && Anchors[s.StartIndex] != null; bool endIndexValid = s.EndIndex >= 0 && s.EndIndex < Anchors.Count && Anchors[s.EndIndex] != null; return(startIndexValid && endIndexValid); }
private bool CheckHasBranch() { int[] count = new int[Anchors.Count]; for (int i = 0; i < Segments.Count; ++i) { if (!IsSegmentValid(i)) { continue; } GSplineSegment s = Segments[i]; count[s.StartIndex] += 1; count[s.EndIndex] += 1; if (count[s.StartIndex] > 2 || count[s.EndIndex] > 2) { return(true); } } return(false); }
public Vector3 EvaluatePosition(int segmentIndex, float t) { GSplineSegment s = Segments[segmentIndex]; GSplineAnchor startAnchor = Anchors[s.StartIndex]; GSplineAnchor endAnchor = Anchors[s.EndIndex]; Vector3 p0 = startAnchor.Position; Vector3 p1 = s.StartTangent; Vector3 p2 = s.EndTangent; Vector3 p3 = endAnchor.Position; t = Mathf.Clamp01(t); float oneMinusT = 1 - t; Vector3 p = oneMinusT * oneMinusT * oneMinusT * p0 + 3 * oneMinusT * oneMinusT * t * p1 + 3 * oneMinusT * t * t * p2 + t * t * t * p3; return(p); }
private void DrawSelectedSegmentGUI() { string label = "Selected Segment"; string id = "selectedsegment" + instance.GetInstanceID().ToString(); GEditorCommon.Foldout(label, true, id, () => { selectedSegmentIndex = splineEditingDrawer.selectedSegmentIndex; if (selectedSegmentIndex >= 0 && selectedSegmentIndex < instance.Spline.Segments.Count) { GSplineSegment s = instance.Spline.Segments[selectedSegmentIndex]; GUI.enabled = !GEditorSettings.Instance.splineTools.autoTangent; s.StartTangent = GEditorCommon.InlineVector3Field("Start Tangent", s.StartTangent); s.EndTangent = GEditorCommon.InlineVector3Field("End Tangent", s.EndTangent); GUI.enabled = true; } else { EditorGUILayout.LabelField("No Segment selected!", GEditorCommon.ItalicLabel); } }); }
public GSplineSegment AddSegment(int startIndex, int endIndex) { GSplineSegment s = Segments.Find(s0 => (s0.StartIndex == startIndex && s0.EndIndex == endIndex) || (s0.StartIndex == endIndex && s0.EndIndex == startIndex)); if (s != null) { return(s); } GSplineSegment newSegment = new GSplineSegment(); newSegment.StartIndex = startIndex; newSegment.EndIndex = endIndex; Segments.Add(newSegment); GSplineAnchor startAnchor = Anchors[newSegment.StartIndex]; GSplineAnchor endAnchor = Anchors[newSegment.EndIndex]; newSegment.StartTangent = (endAnchor.Position - startAnchor.Position) / 3f; newSegment.EndTangent = -newSegment.StartTangent; return(newSegment); }
public GSplineSegment AddSegment(int startIndex, int endIndex) { GSplineSegment s = Segments.Find(s0 => (s0.StartIndex == startIndex && s0.EndIndex == endIndex) || (s0.StartIndex == endIndex && s0.EndIndex == startIndex)); if (s != null) { return(s); } GSplineSegment newSegment = new GSplineSegment(); newSegment.StartIndex = startIndex; newSegment.EndIndex = endIndex; Segments.Add(newSegment); GSplineAnchor startAnchor = Anchors[newSegment.StartIndex]; GSplineAnchor endAnchor = Anchors[newSegment.EndIndex]; Vector3 direction = (endAnchor.Position - startAnchor.Position).normalized; float length = (endAnchor.Position - startAnchor.Position).magnitude / 3; newSegment.StartTangent = startAnchor.Position + direction * length; newSegment.EndTangent = endAnchor.Position - direction * length; return(newSegment); }
public int[] SmoothTangents(params int[] anchorIndices) { int[] anchorRanks = new int[Anchors.Count]; Vector3[] directions = new Vector3[Anchors.Count]; float[] segmentLengths = new float[Segments.Count]; for (int i = 0; i < Segments.Count; ++i) { GSplineSegment s = Segments[i]; anchorRanks[s.StartIndex] += 1; anchorRanks[s.EndIndex] += 1; GSplineAnchor aStart = Anchors[s.StartIndex]; GSplineAnchor aEnd = Anchors[s.EndIndex]; Vector3 startToEnd = aEnd.Position - aStart.Position; Vector3 d = Vector3.Normalize(startToEnd); directions[s.StartIndex] += d; directions[s.EndIndex] += d; segmentLengths[i] = startToEnd.magnitude; } for (int i = 0; i < directions.Length; ++i) { if (anchorRanks[i] == 0) { continue; } directions[i] = Vector3.Normalize(directions[i] / anchorRanks[i]); } if (anchorIndices == null || anchorIndices.Length == 0) { anchorIndices = GUtilities.GetIndicesArray(Anchors.Count); } for (int i = 0; i < anchorIndices.Length; ++i) { int index = anchorIndices[i]; if (anchorRanks[index] > 0) { Quaternion rot = Quaternion.LookRotation(directions[index], Vector3.up); Anchors[index].Rotation = rot; } } List <int> segmentIndices = new List <int>(); for (int i = 0; i < Segments.Count; ++i) { GSplineSegment s = Segments[i]; for (int j = 0; j < anchorIndices.Length; ++j) { int anchorIndex = anchorIndices[j]; if (s.StartIndex == anchorIndex || s.EndIndex == anchorIndex) { segmentIndices.Add(i); } } } for (int i = 0; i < segmentIndices.Count; ++i) { int index = segmentIndices[i]; GSplineSegment s = Segments[index]; GSplineAnchor aStart = Anchors[s.StartIndex]; GSplineAnchor aEnd = Anchors[s.EndIndex]; float sLength = segmentLengths[index]; float tangentLength = sLength * 0.33f; Vector3 dirStart = directions[s.StartIndex]; Vector3 dirEnd = directions[s.EndIndex]; s.StartTangent = aStart.Position + dirStart * tangentLength; s.EndTangent = aEnd.Position - dirEnd * tangentLength; } return(segmentIndices.ToArray()); }
public GSplineSegmentInspectorDrawer(GSplineSegment s) { instance = s; }
public static GSplineSegmentInspectorDrawer Create(GSplineSegment s) { return(new GSplineSegmentInspectorDrawer(s)); }
public void AdjustTangent(int segmentIndex) { GSplineSegment s = Spline.Segments[segmentIndex]; int startCount = 0; Vector3 startAvgTangent = Vector3.zero; int endCount = 0; Vector3 endAvgTangent = Vector3.zero; for (int i = 0; i < Spline.Segments.Count; ++i) { GSplineSegment s0 = Spline.Segments[i]; if (s0 == s) { continue; } if (s0.StartIndex == s.StartIndex) { startAvgTangent += s0.StartTangent; startCount += 1; } if (s0.EndIndex == s.StartIndex) { startAvgTangent += s0.EndTangent; startCount += 1; } if (s0.StartIndex == s.EndIndex) { endAvgTangent += s0.StartTangent; endCount += 1; } if (s0.EndIndex == s.EndIndex) { endAvgTangent += s0.EndTangent; endCount += 1; } } if (startAvgTangent == Vector3.zero) { startCount = 0; } if (endAvgTangent == Vector3.zero) { endCount = 0; } if (startCount == 0 && endCount == 0) { GSplineAnchor startAnchor = Spline.Anchors[s.StartIndex]; GSplineAnchor endAnchor = Spline.Anchors[s.EndIndex]; s.StartTangent = (endAnchor.Position - startAnchor.Position) / 3f; s.EndTangent = -s.StartTangent; } else if (startCount == 0 && endCount > 0) { s.EndTangent = -endAvgTangent / endCount; s.StartTangent = s.EndTangent; } else if (startCount > 0 && endCount == 0) { s.StartTangent = -startAvgTangent / startCount; s.EndTangent = s.StartTangent; } else { s.StartTangent = -startAvgTangent / startCount; s.EndTangent = -endAvgTangent / endCount; } }