private float ShowMidpointControls(Ferr2DPath aPath, int i, PathEditorUtil.Selection aSelection, Matrix4x4 aTransform, SerializedProperty aPathProp, float aCurrDistance) { EventType eType = Event.current.type; // calculate distance data for finding the midpoint float segmentDistance = aPath.GetDistanceBetween(i, PathUtil.WrapIndex(i + 1, aPath.Count, aPath.Closed)); float nextDistance = aCurrDistance + segmentDistance; float midDist = aCurrDistance + (segmentDistance) / 2; // if we have no segment on the control vert, skip this midpoint if (aPath.Count <= 1 || (i == aPath.Count - 1 && !aPath.Closed)) { return(nextDistance); } // find the midpoint of this line Vector2 midPoint = aPath.GetPointAtDistance(midDist); Vector2 midNormal = aPath.GetNormalAtDistance(midDist); Vector3 midWorldPoint = aTransform.MultiplyPoint(midPoint); Vector3 midWorldNormal = aTransform.MultiplyVector(midNormal); float midSize = eType == EventType.Layout || eType == EventType.Repaint ? HandleUtility.GetHandleSize(midWorldPoint) : 0; // edge override button int direction = aPath.GetData(i).directionOverride; if (terrain.EdgeMode != Ferr2D_SectionMode.None && (i == activeSegment || aSelection.IsSegmentSelected(i, aPath.Count, aPath.Closed) || direction != (int)Ferr2DT_TerrainDirection.None)) { if (Event.current.alt) { if (direction != (int)Ferr2DT_TerrainDirection.None && Handles.Button(midWorldPoint + midWorldNormal * midSize * sizeLargeHandle * 2, Quaternion.identity, midSize * sizeSmallHandle, midSize * sizeSmallHandle, Ferr2DT_Caps.CapDotReset)) { aSelection.EachSegment(i, aPath.Count, aPath.Closed, id => { SerializedProperty overrideProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("directionOverride"); overrideProp.intValue = (int)Ferr2DT_TerrainDirection.None; }); } } else { if (Handles.Button(midWorldPoint + midWorldNormal * midSize * sizeLargeHandle * 2, Quaternion.identity, midSize * sizeSmallHandle, midSize * sizeSmallHandle, Ferr2DT_Caps.GetEdgeCap(direction))) { CycleEdgeOverride(aPathProp, i); SerializedProperty cycledOverride = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(i).FindPropertyRelative("directionOverride"); aSelection.EachSegment(i, aPath.Count, aPath.Closed, id => { SerializedProperty overrideProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("directionOverride"); overrideProp.intValue = cycledOverride.intValue; }); } } } // new point button if (!Event.current.alt && i == activeSegment && Handles.Button(midWorldPoint, Quaternion.identity, midSize * sizeLargeHandle, midSize * sizeLargeHandle, Ferr2DT_Caps.CapDotPlus)) { PathEditorUtil.AddPoint(aPathProp, midPoint, i + 1); ProcessNewPoint(aPathProp, i + 1); } return(nextDistance); }
private void ShowPathGUI(Transform aTransform, Ferr2DPath aPath, SerializedProperty aPathProp) { EventType eType = Event.current.type; Matrix4x4 mat = aTransform.localToWorldMatrix; // show the path and all its standard controls PathEditorUtil.OnSceneGUI(aTransform.localToWorldMatrix, aTransform.worldToLocalMatrix, aPathProp, aPath, true, ProcessNewPoint, ProcessRemovePoint, Path2D.Plane.XY, Ferr2DT_Menu.PathSnapMode, Ferr2DT_Menu.SmartSnap?Ferr2DT_Menu.SmartSnapDist:0, KeyCode.C, visuals); PathEditorUtil.Selection selection = PathEditorUtil.GetSelection(aPath); // find which segments and points are active FindActiveControls(aPath, mat, aTransform.worldToLocalMatrix); if (Ferr2DT_SceneOverlay.segmentLockMode) { ShowTexSegmentSelect(aPath, aPathProp, mat); } else { float currDistance = 0; for (int i = 0; i < aPath.Count; i++) { // show all the data at the control points ShowPointControls(aPath, i, selection, mat, aPathProp); // show midpoint controls currDistance = ShowMidpointControls(aPath, i, selection, mat, aPathProp, currDistance); } } // drag select has to happen last, otherwise it steals control ahead of the other handles ShowDragSelect(aPath, mat); }
private void ShowPointControls(Ferr2DPath aPath, int i, PathEditorUtil.Selection aSelection, Matrix4x4 aTransform, SerializedProperty aPathProp) { EventType eType = Event.current.type; Ferr2D_PointData pointData = aPath.GetData(i); Vector2 point = aPath[i]; Vector2 pointNormal = aPath.GetNormal(i); Vector3 pointWorld = aTransform.MultiplyPoint(point); Vector3 pointWorldNormal = aTransform.MultiplyVector(pointNormal); float pointSize = eType == EventType.Layout || eType == EventType.Repaint ? HandleUtility.GetHandleSize(pointWorld) : 0; // point scale button if (terrain.EdgeMode != Ferr2D_SectionMode.None && (i == activePoint || aSelection.IsSelected(i) || pointData.scale != 1)) { Vector3 scaleStart = pointWorld + pointWorldNormal * (visuals.sizeVertex + sizeSmallHandle) * pointSize; Vector3 scalePos = scaleStart + ((pointData.scale - 0.5f) * 3f) * pointWorldNormal; if (Event.current.alt) { // reset scale if (pointData.scale != 1 && Handles.Button(scalePos, Quaternion.identity, pointSize * sizeSmallHandle, pointSize * sizeSmallHandle, Ferr2DT_Caps.CapDotReset)) { aSelection.Each(i, id => { SerializedProperty scaleProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("scale"); scaleProp.floatValue = 1; }); } } else { Vector2 screenNormal = HandleUtility.WorldToGUIPoint(pointWorld + pointWorldNormal) - HandleUtility.WorldToGUIPoint(pointWorld); screenNormal.Normalize(); Vector3 move = Handles.FreeMoveHandle(scalePos, Quaternion.identity, pointSize * sizeSmallHandle, Vector3.zero, Ferr2DT_Caps.GetScaleCap(screenNormal)); if (move != scalePos) { move = PathUtil.GetClosetPointOnLine(scaleStart, scaleStart + pointWorldNormal * 3, move, true); float finalScale = 0.5f + (scaleStart - move).magnitude / 3f; float delta = finalScale - pointData.scale; aSelection.Each(i, id => { SerializedProperty scaleProp = aPathProp.FindPropertyRelative("_data").GetArrayElementAtIndex(id).FindPropertyRelative("scale"); scaleProp.floatValue += delta; }); } } } // show index numbers if (Ferr2DT_SceneOverlay.showIndices) { Vector2 pt = HandleUtility.WorldToGUIPoint(pointWorld - pointWorldNormal * pointSize * sizeLargeHandle * 2); Rect r = new Rect(pt.x - 15, pt.y - EditorGUIUtility.singleLineHeight * 0.5f, 30, EditorGUIUtility.singleLineHeight); Handles.BeginGUI(); GUI.Label(r, i.ToString(), PathEditorUtil.CenteredShadowStyle); GUI.Label(r, i.ToString(), PathEditorUtil.CenteredLabelStyle); Handles.EndGUI(); } }