public void CycleSpriteIndex() { ISelection selection = ShapeEditorCache.GetSelection(); if (selection.single == -1) { return; } int nextIndex = SplineUtility.NextIndex(selection.single, m_Spline.GetPointCount()); float angle = SpriteShapeHandleUtility.PosToAngle(m_Spline.GetPosition(selection.single), m_Spline.GetPosition(nextIndex), 0f); int angleRangeIndex = SpriteShapeEditorUtility.GetRangeIndexFromAngle(m_SpriteShape, angle); if (angleRangeIndex == -1) { return; } AngleRange angleRange = m_SpriteShape.angleRanges[angleRangeIndex]; int spriteIndex = (m_Spline.GetSpriteIndex(selection.single) + 1) % angleRange.sprites.Count; Undo.RecordObject(m_CurrentEditor.target, "Edit Sprite Index"); m_Spline.SetSpriteIndex(selection.single, spriteIndex); EditorUtility.SetDirty(m_CurrentEditor.target); }
private void ResetTangents(int pointIndex) { Vector3 position = GetPosition(pointIndex); Vector3 positionNext = GetPosition(SplineUtility.NextIndex(pointIndex, GetPointCount())); Vector3 positionPrev = GetPosition(SplineUtility.PreviousIndex(pointIndex, GetPointCount())); Vector3 forward = Vector3.forward; if (SplineEditorCache.IsValid() && SplineEditorCache.GetTarget() != null) { forward = SplineEditorCache.GetTarget().transform.forward; } float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f; Vector3 leftTangent = (positionPrev - position).normalized * scale; Vector3 rightTangent = (positionNext - position).normalized * scale; if (GetTangentMode(pointIndex) == TangentMode.Continuous) { SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent); } SetLeftTangent(pointIndex, leftTangent); SetRightTangent(pointIndex, rightTangent); }
public Vector2 GetEdgeWindowPosition(int edgeIndex) { int nextIndex = SplineUtility.NextIndex(edgeIndex, m_Points.Count); Vector2 start = m_Points[edgeIndex].m_Position; Vector2 startTangent = (Vector2)m_Points[edgeIndex].m_RightTangent + start; Vector2 end = m_Points[nextIndex].m_Position; Vector2 endTangent = (Vector2)m_Points[nextIndex].m_LeftTangent + end; return(BezierUtility.BezierPoint(start, startTangent, endTangent, end, 0.5f) + Vector3.up * kWindowHeaderHeight); }
private void LayoutEdges() { if (currentEvent.type != EventType.Layout) { return; } PrepareEdgePoints(); int pointCount = GetPointCount(); int edgeCount = OpenEnded() ? pointCount - 1 : pointCount; float minDistance = float.MaxValue; for (int index = 0; index < edgeCount; ++index) { int id = GUIUtility.GetControlID("Edge".GetHashCode(), FocusType.Passive); if (currentEvent.type == EventType.Layout) { int nextIndex = SplineUtility.NextIndex(index, pointCount); Vector3 position0 = GetPosition(index); Vector3 position1 = GetPosition(nextIndex); Vector3 tangent0 = GetRightTangent(index) + position0; Vector3 tangent1 = GetLeftTangent(nextIndex) + position1; float t; Vector3 closestPoint = BezierUtility.ClosestPointOnCurve(ScreenToWorld(currentEvent.mousePosition), position0, position1, tangent0, tangent1, out t); Vector2 guiPosition = HandleUtility.WorldToGUIPoint(closestPoint); float distance = (currentEvent.mousePosition - guiPosition).magnitude; if (m_HoveredPointIndex == -1) { HandleUtility.AddControl(id, distance); if (HandleUtility.nearestControl == id) { m_HoveredEdgeIndex = index; m_HoveredPointIndex = -1; m_HoveredTangentPoint = -1; } } if (distance < minDistance) { m_ClosestPoint = closestPoint; m_ClosestPointT = t; minDistance = distance; } } } }
private int GetAngleRangeLocal(int index) { var selection = SplineEditorCache.GetSelection(); var spriteShape = SplineEditorCache.GetTarget().spriteShape; var nextIndex = SplineUtility.NextIndex(selection.single, GetPointCount()); var pos1 = GetLocalPosition(selection.single); var pos2 = GetLocalPosition(nextIndex); var angle = SplineUtility.SlopeAngle(pos1, pos2) + 90; var angleRangeIndex = SpriteShapeEditorUtility.GetRangeIndexFromAngle(spriteShape, angle); return(angleRangeIndex); }
// Start is called before the first frame update private void Smoothen(SpriteShapeController sc, int pointIndex) { Vector3 position = sc.spline.GetPosition(pointIndex); Vector3 positionNext = sc.spline.GetPosition(SplineUtility.NextIndex(pointIndex, sc.spline.GetPointCount())); Vector3 positionPrev = sc.spline.GetPosition(SplineUtility.PreviousIndex(pointIndex, sc.spline.GetPointCount())); Vector3 forward = gameObject.transform.forward; float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f; Vector3 leftTangent = (positionPrev - position).normalized * scale; Vector3 rightTangent = (positionNext - position).normalized * scale; sc.spline.SetTangentMode(pointIndex, ShapeTangentMode.Continuous); SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent); sc.spline.SetLeftTangent(pointIndex, leftTangent); sc.spline.SetRightTangent(pointIndex, rightTangent); }
private void ResetTangents(int pointIndex) { Vector3 position = m_Spline.GetPosition(pointIndex); Vector3 positionNext = m_Spline.GetPosition(SplineUtility.NextIndex(pointIndex, m_Spline.GetPointCount())); Vector3 positionPrev = m_Spline.GetPosition(SplineUtility.PreviousIndex(pointIndex, m_Spline.GetPointCount())); Vector3 forward = (m_CurrentEditor.target as SpriteShapeController).transform.forward; float scale = Mathf.Min((positionNext - position).magnitude, (positionPrev - position).magnitude) * 0.33f; Vector3 leftTangent = (positionPrev - position).normalized * scale; Vector3 rightTangent = (positionNext - position).normalized * scale; if (m_Spline.GetTangentMode(pointIndex) == ShapeTangentMode.Continuous) { SplineUtility.CalculateTangents(position, positionPrev, positionNext, forward, scale, out rightTangent, out leftTangent); } m_Spline.SetLeftTangent(pointIndex, leftTangent); m_Spline.SetRightTangent(pointIndex, rightTangent); }
private void HandleDragEdge() { EventType eventType = currentEvent.GetTypeForControl(m_DragEdgeControlId); if ((m_HoveredEdgeIndex != -1 && GUIUtility.hotControl == 0 && EdgeDragModifiersActive()) || GUIUtility.hotControl == m_DragEdgeControlId) { if (eventType == EventType.MouseDown && currentEvent.button == 0) { m_ActiveEdgeIndex = m_HoveredEdgeIndex; m_SliderPosition = GetPosition(m_HoveredEdgeIndex); } if (eventType == EventType.MouseUp && currentEvent.button == 0) { m_ActiveEdgeIndex = -1; } if (eventType == EventType.Layout && GUIUtility.hotControl == 0) { HandleUtility.AddControl(m_DragEdgeControlId, 0f); } EditorGUI.BeginChangeCheck(); var newPosition = DoSlider(m_DragEdgeControlId, m_SliderPosition, GetUpVector(), GetRightVector(), GetHandleSize(m_SliderPosition), (int cid, Vector3 p, Quaternion q, float s, EventType et) => { }); if (EditorGUI.EndChangeCheck()) { RegisterUndoOnSliderChangedOnce(); var snappedDelta = Snap(newPosition) - m_SliderPosition; var nextIndex = SplineUtility.NextIndex(m_ActiveEdgeIndex, GetPointCount()); SetPosition(m_ActiveEdgeIndex, GetPosition(m_ActiveEdgeIndex) + snappedDelta); SetPosition(nextIndex, GetPosition(nextIndex) + snappedDelta); m_EdgePointsDirty = true; } m_SliderPosition = newPosition; } }
private void PrepareEdgePoints() { int pointCount = GetPointCount(); int edgeCount = OpenEnded() ? pointCount - 1 : pointCount; if (m_EdgePoints.Count != edgeCount) { m_EdgePointsDirty = true; } if (!m_EdgePointsDirty) { return; } m_EdgePoints.Clear(); for (int index = 0; index < edgeCount; ++index) { int nextIndex = SplineUtility.NextIndex(index, pointCount); Vector3 position0 = GetPosition(index); Vector3 position1 = GetPosition(nextIndex); if (GetTangentMode(index) == TangentMode.Linear && GetTangentMode(nextIndex) == TangentMode.Linear) { m_EdgePoints.Add(new Vector3[] { position0, position1 }); } else { var tangent0 = GetRightTangent(index) + position0; var tangent1 = GetLeftTangent(nextIndex) + position1; m_EdgePoints.Add(Handles.MakeBezierPoints(position0, position1, tangent0, tangent1, kBezierPatch)); } } m_EdgePointsDirty = false; }
private void GenerateSegments(SpriteShapeController sc, List <ShapeAngleRange> angleRanges) { var controlPointCount = sc.spline.GetPointCount(); var angleRangeIndices = new int[controlPointCount]; ShapeSegment activeSegment = new ShapeSegment() { start = -1, end = -1, angleRange = -1 }; m_ShapeSegments.Clear(); for (int i = 0; i < controlPointCount; ++i) { var actv = i; var next = SplineUtility.NextIndex(actv, controlPointCount); var pos1 = sc.spline.GetPosition(actv); var pos2 = sc.spline.GetPosition(next); bool continueStrip = (sc.spline.GetTangentMode(actv) == ShapeTangentMode.Continuous), edgeUpdated = false; float angle = 0; if (false == continueStrip || activeSegment.start == -1) { angle = SplineUtility.SlopeAngle(pos1, pos2) + 90.0f; } next = (!sc.spline.isOpenEnded && next == 0) ? (actv + 1) : next; int mn = (actv < next) ? actv : next; int mx = (actv > next) ? actv : next; var anglerange = RangeFromAngle(angleRanges, angle); angleRangeIndices[actv] = anglerange; if (anglerange == -1) { activeSegment = new ShapeSegment() { start = mn, end = mx, angleRange = anglerange }; m_ShapeSegments.Add(activeSegment); continue; } // Check for Segments. Also check if the Segment Start has been resolved. Otherwise simply start with the next one if (activeSegment.start != -1) { continueStrip = continueStrip && (angleRangeIndices[activeSegment.start] != -1); } bool canContinue = (actv != (controlPointCount - 1)) || (!sc.spline.isOpenEnded && (actv == (controlPointCount - 1))); if (continueStrip && canContinue) { for (int s = 0; s < m_ShapeSegments.Count; ++s) { activeSegment = m_ShapeSegments[s]; if (activeSegment.start - mn == 1) { edgeUpdated = true; activeSegment.start = mn; m_ShapeSegments[s] = activeSegment; break; } if (mx - activeSegment.end == 1) { edgeUpdated = true; activeSegment.end = mx; m_ShapeSegments[s] = activeSegment; break; } } } if (!edgeUpdated) { activeSegment.start = mn; activeSegment.end = mx; activeSegment.angleRange = anglerange; m_ShapeSegments.Add(activeSegment); } } }
private void HandleInsertPointToEdge() { EventType eventType = currentEvent.GetTypeForControl(m_DragPointControlId); if (m_HoveredPointIndex == -1 && m_HoveredEdgeIndex != -1 && GUIUtility.hotControl == 0 && eventType == EventType.MouseDown && currentEvent.button == 0 && !currentEvent.shift) { RecordUndo(); ClearSelection(); int nextIndex = SplineUtility.NextIndex(m_HoveredEdgeIndex, GetPointCount()); TangentMode leftTangentMode = GetTangentMode(m_HoveredEdgeIndex); TangentMode rightTangentMode = GetTangentMode(nextIndex); Vector3 leftStartPosition; Vector3 leftEndPosition; Vector3 leftStartTangent; Vector3 leftEndTangent; Vector3 rightStartPosition; Vector3 rightEndPosition; Vector3 rightStartTangent; Vector3 rightEndTangent; Vector3 position0 = GetPosition(m_HoveredEdgeIndex); Vector3 position1 = GetPosition(nextIndex); Vector3 tangent0 = GetRightTangent(m_HoveredEdgeIndex) + position0; Vector3 tangent1 = GetLeftTangent(nextIndex) + position1; BezierUtility.SplitBezier(m_ClosestPointT, position0, position1, tangent0, tangent1, out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent, out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent); if (leftTangentMode != TangentMode.Linear) { SetTangentMode(m_HoveredEdgeIndex, TangentMode.Broken); SetRightTangent(m_HoveredEdgeIndex, leftStartTangent - leftStartPosition); } if (rightTangentMode != TangentMode.Linear) { SetTangentMode(nextIndex, TangentMode.Broken); SetLeftTangent(nextIndex, rightEndTangent - rightEndPosition); } InsertPointAt(nextIndex, m_ClosestPoint); if (leftTangentMode != TangentMode.Linear || rightTangentMode != TangentMode.Linear) { SetTangentMode(nextIndex, TangentMode.Broken); if (m_ClosestPointT == 0.5f) { SetTangentMode(nextIndex, TangentMode.Continuous); } SetLeftTangent(nextIndex, leftEndTangent - leftEndPosition); SetRightTangent(nextIndex, rightStartTangent - rightStartPosition); } m_HoveredPointIndex = nextIndex; m_HoveredEdgeIndex = -1; HandleUtility.nearestControl = m_DragPointControlId; } }
public static void Bake(GameObject go, bool forced) { var sc = go.GetComponent <SpriteShapeController>(); var lc = go.GetComponent <LegacyCollider>(); if (sc != null) { List <IntPoint> path = new List <IntPoint>(); int splinePointCount = sc.spline.GetPointCount(); int pathPointCount = splinePointCount; ColliderCornerType cct = ColliderCornerType.Square; float co = 1.0f; if (lc != null) { int hashCode = sc.spline.GetHashCode() + lc.m_ColliderCornerType.GetHashCode() + lc.m_ColliderOffset.GetHashCode(); if (lc.m_HashCode == hashCode && !forced) { return; } lc.m_HashCode = hashCode; cct = lc.m_ColliderCornerType; co = lc.m_ColliderOffset; } if (sc.spline.isOpenEnded) { pathPointCount--; } for (int i = 0; i < pathPointCount; ++i) { int nextIndex = SplineUtility.NextIndex(i, splinePointCount); SampleCurve(sc.colliderDetail, sc.spline.GetPosition(i), sc.spline.GetRightTangent(i), sc.spline.GetPosition(nextIndex), sc.spline.GetLeftTangent(nextIndex), ref path); } if (co != 0f) { List <List <IntPoint> > solution = new List <List <IntPoint> >(); ClipperOffset clipOffset = new ClipperOffset(); EndType endType = EndType.etClosedPolygon; if (sc.spline.isOpenEnded) { endType = EndType.etOpenSquare; if (cct == ColliderCornerType.Round) { endType = EndType.etOpenRound; } } clipOffset.ArcTolerance = 200f / sc.colliderDetail; clipOffset.AddPath(path, (ExtrasClipperLib.JoinType)cct, endType); clipOffset.Execute(ref solution, s_ClipperScale * co); if (solution.Count > 0) { path = solution[0]; } } List <Vector2> pathPoints = new List <Vector2>(path.Count); for (int i = 0; i < path.Count; ++i) { IntPoint ip = path[i]; pathPoints.Add(new Vector2(ip.X / s_ClipperScale, ip.Y / s_ClipperScale)); } var pc = go.GetComponent <PolygonCollider2D>(); if (pc) { pc.pathCount = 0; pc.SetPath(0, pathPoints.ToArray()); } var ec = go.GetComponent <EdgeCollider2D>(); if (ec) { if (co > 0f || co < 0f && !sc.spline.isOpenEnded) { pathPoints.Add(pathPoints[0]); } ec.points = pathPoints.ToArray(); } } }