public static BGCurvePoint CreatePoint(Vector3 position, BGCurve curve, BGCurvePoint.ControlTypeEnum controlType, int parts, bool ensureNew) { float distanceToPreviousPoint; float distanceToNextPoint; return(CreatePoint(position, curve, controlType, parts, out distanceToPreviousPoint, out distanceToNextPoint, ensureNew)); }
/// <summary>Curve's point creation</summary> public BGCurvePoint CreatePointFromWorldPosition(Vector3 worldPos, BGCurvePoint.ControlTypeEnum controlType, Vector3 control1WorldPos, Vector3 control2WorldPos) { return new BGCurvePoint(this, transform.InverseTransformPoint(worldPos), controlType, transform.InverseTransformDirection(control1WorldPos - worldPos), transform.InverseTransformDirection(control2WorldPos - worldPos)); }
public void SetControlTypeForSelected(BGCurvePoint.ControlTypeEnum controlType) { curve.Transaction(() => { foreach (var point in points) { point.ControlType = controlType; } }); }
protected override bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message) { if (BGCurveSettingsForEditor.DisableSceneViewSelectionMenu || !menu.EditorSelection.HasSelected()) { return(false); } var selectedPos = menu.EditorSelection.GetAveragePosition(); if (!(DistanceTolerance > (@event.mousePosition - BGEditorUtility.GetSceneViewPosition(selectedPos, sceneViewHeight)).sqrMagnitude)) { return(false); } //out params position = selectedPos; message = SuccessMessage("Selected " + menu.EditorSelection.CountSelected + " point(s)."); //turn on the menu menu.On(position); //check if all points share the same control type BGCurvePoint.ControlTypeEnum singleType = BGCurvePoint.ControlTypeEnum.Absent; bool first = true, single = true; menu.EditorSelection.ForEach(point => { if (first) { first = false; singleType = point.ControlType; } else if (singleType != point.ControlType) { single = false; return(true); } return(false); }); if (single) { menu.Get(0).Current = singleType == BGCurvePoint.ControlTypeEnum.Absent; menu.Get(1).Current = singleType == BGCurvePoint.ControlTypeEnum.BezierSymmetrical; menu.Get(2).Current = singleType == BGCurvePoint.ControlTypeEnum.BezierIndependant; } else { menu.Get(0).Current = menu.Get(1).Current = menu.Get(2).Current = false; } return(true); }
public void Copy(BGCurvePointI point) { controlType = point.ControlType; positionLocal = point.PositionLocal; control1LocalTransformed = point.ControlFirstLocalTransformed; control2LocalTransformed = point.ControlSecondLocalTransformed; pointTransform = point.PointTransform; InitPasteTooltip(); }
private static BGCurvePoint InsertNoData(BGCurve curve, BGCurvePoint.ControlTypeEnum controlType, Vector3 tangent, Vector3 control, Vector3 positionWorld, bool inverseTangent) { var controlMagnitude = control.magnitude; if (controlMagnitude < 1) { controlMagnitude = 1; } var pos = positionWorld - tangent * controlMagnitude * DistanceToTangentNoDataMultiplier * (inverseTangent ? -1 : 1); return(curve.CreatePointFromWorldPosition(pos, controlType, pos - tangent, pos + tangent)); }
private static BGCurvePoint CreatePointByPointsCount(BGCurve curve, BGCurvePoint.ControlTypeEnum controlType) { var pointsCount = curve.PointsCount; switch (pointsCount) { case 0: throw new UnityException("You can not use this method with no points on the curve. pointsCount==0"); case 1: return(curve.CreatePointFromLocalPosition(Vector3.forward, controlType, Vector3.right, Vector3.left)); } return(null); }
public static BGCurvePoint InsertBefore(BGCurve curve, int index, BGCurvePoint.ControlTypeEnum controlType, int parts) { var newPoint = CreatePointByPointsCount(curve, controlType); if (newPoint != null) { return(newPoint); } if (index == 0 && !curve.Closed) { return(InsertNoData(curve, controlType, BGEditorUtility.CalculateTangent(curve[0], curve[1], 0f), curve[0].ControlFirstLocal, curve[0].PositionWorld, false)); } return(CreatePointBetween(curve, index == 0 ? curve[curve.PointsCount - 1] : curve[index - 1], curve[index], parts, controlType)); }
public static BGCurvePoint InsertAfter(BGCurve curve, int index, BGCurvePoint.ControlTypeEnum controlType, int parts) { var newPoint = CreatePointByPointsCount(curve, controlType); if (newPoint != null) { return(newPoint); } var pointsCount = curve.PointsCount; if (index == pointsCount - 1 && !curve.Closed) { var lastPoint = curve[pointsCount - 1]; return(InsertNoData(curve, controlType, BGEditorUtility.CalculateTangent(curve[pointsCount - 2], lastPoint, 1f), lastPoint.ControlSecondLocal, lastPoint.PositionWorld, true)); } return(CreatePointBetween(curve, curve[index], index == pointsCount - 1 ? curve[0] : curve[index + 1], parts, controlType)); }
public static BGCurvePoint CreatePointBetween(BGCurve curve, BGCurvePointI previousPoint, BGCurvePointI nextPoint, int parts, BGCurvePoint.ControlTypeEnum controlType, Vector3 position, Vector3 tangent) { var scaledTangent = tangent * DistanceToTangentMultiplier * BGEditorUtility.CalculateDistance(previousPoint, nextPoint, parts); return(curve.CreatePointFromLocalPosition(curve.ToLocal(position), controlType, curve.ToLocalDirection(-scaledTangent), curve.ToLocalDirection(scaledTangent))); }
protected abstract void SetControl(BGCurvePoint.ControlTypeEnum controlType);
protected override void SetControl(BGCurvePoint.ControlTypeEnum type) { point.ControlType = type; }
protected override void SetControl(BGCurvePoint.ControlTypeEnum type) { EditorSelection.SetControlTypeForSelected(type); }
//OnInspectorGui for selection public void InspectorSelectionOperations() { BGEditorUtility.VerticalBox(() => { // ================================================ Global operations BGEditorUtility.HorizontalBox(() => { BGEditorUtility.SwapLabelWidth(80, () => EditorGUILayout.LabelField("Selected (" + points.Count + ")")); if (BGEditorUtility.ButtonWithIcon(deleteTexture, "Delete selected points")) { if (!DeleteSelected()) { return; } } GUILayout.Space(4); if (BGEditorUtility.ButtonWithIcon(selectAllTexture, "Select all points", 35)) { Changed = Changed || points.Count != curve.PointsCount; points.Clear(); foreach (var point1 in curve.Points) { points.Add(point1); } } GUILayout.Space(4); if (BGEditorUtility.ButtonWithIcon(deselectAllTexture, "Deselect all points", 35)) { Clear(); } }); // ================================================ Selections operations // skip mouse buttons events which change selection if (Changed) { return; } GUILayout.Space(5); if (HasSelected()) { BGEditorUtility.SwapGuiBackgroundColor(SelectedBackgroundColor, () => { BGEditorUtility.VerticalBox(() => { var averagePositionSelected = GetAveragePosition(); // ===================================================== Control handles BGEditorUtility.Horizontal(() => { controlType = (BGCurvePoint.ControlTypeEnum)EditorGUILayout.EnumPopup("Controls", controlType); if (!BGEditorUtility.ButtonWithIcon(convertAll2D, "Set control type for all selected points", 44)) { return; } SetControlTypeForSelected(controlType); }); // ===================================================== Average positions & delete BGEditorUtility.Vector3Field("Average position", "Average points position. Change several points positions at once, keeping distance difference intact", averagePositionSelected, newAverage => { var delta = newAverage - averagePositionSelected; curve.Transaction(() => { foreach (var point in points) { point.PositionWorld += delta; } }); }); // ===================================================== Set position directly BGEditorUtility.Vector3Field("Set position", "Set points position directly", averagePositionSelected, newPosition => { curve.Transaction(() => { if (BGEditorUtility.AnyChange(averagePositionSelected.x, newPosition.x)) { SetX(newPosition.x); } if (BGEditorUtility.AnyChange(averagePositionSelected.y, newPosition.y)) { SetY(newPosition.y); } if (BGEditorUtility.AnyChange(averagePositionSelected.z, newPosition.z)) { SetZ(newPosition.z); } }); }); // ===================================================== Set control positions directly var count = 0; var averageControl1Sum = Vector3.zero; var averageControl2Sum = Vector3.zero; foreach (var point in points.Where(point => point.ControlType != BGCurvePoint.ControlTypeEnum.Absent)) { count++; averageControl1Sum += point.ControlFirstLocal; averageControl2Sum += point.ControlSecondLocal; } if (count == 0) { return; } //has points with bezier controls BGEditorUtility.Vector3Field("Set Control 1", "Set 1st control position directly", averageControl1Sum / count, newPosition => { curve.Transaction( () => { foreach (var point in points.Where(point => point.ControlType != BGCurvePoint.ControlTypeEnum.Absent)) { point.ControlFirstLocal = newPosition; } }); }); BGEditorUtility.Vector3Field("Set Control 2", "Set 2nd control position directly", averageControl2Sum / count, newPosition => { curve.Transaction( () => { foreach (var point in points.Where(point => point.ControlType != BGCurvePoint.ControlTypeEnum.Absent)) { point.ControlSecondLocal = newPosition; } }); }); }); }); } else { BGEditorUtility.HelpBox("Hold shift to use rectangular selection\r\nClick or click+drag over tick icons to (de)select points", MessageType.Info, curve.PointsCount > 0); } }); }
public static BGCurvePoint CreatePoint(Vector3 position, BGCurve curve, BGCurvePoint.ControlTypeEnum controlType, int parts, out float distanceToPreviousPoint, out float distanceToNextPoint, bool ensureNew) { distanceToPreviousPoint = -1; distanceToNextPoint = -1; if (curve.PointsCount == 0) { //first point Vector3 control; switch (curve.Mode2D) { case BGCurve.Mode2DEnum.YZ: control = Vector3.forward; break; default: // BGCurve.Mode2DEnum.XY: // BGCurve.Mode2DEnum.Off: // BGCurve.Mode2DEnum.XZ: control = Vector3.right; break; } return(curve.CreatePointFromLocalPosition(curve.ToLocal(position), controlType, control, -control)); } parts = Mathf.Clamp(parts, 1, 50); //we no need no events (maybe check if point was actually added to a curve for events firing?) var oldSuppress = curve.SupressEvents; curve.SupressEvents = true; //create a point with no controls first BGCurvePoint newPoint; if (ensureNew) { newPoint = curve.CreatePointFromWorldPosition(position, BGCurvePoint.ControlTypeEnum.Absent); } else { if (point == null || point.Curve != curve) { point = curve.CreatePointFromWorldPosition(position, BGCurvePoint.ControlTypeEnum.Absent); } newPoint = point; newPoint.PositionWorld = position; newPoint.ControlFirstLocal = Vector3.zero; newPoint.ControlSecondLocal = Vector3.zero; } if (curve.Mode2DOn) { curve.Apply2D(newPoint); } //adjacent points var previousPoint = curve[curve.PointsCount - 1]; var nextPoint = curve.Closed ? curve[0] : null; //direction var tangent = BGEditorUtility.CalculateTangent(newPoint, previousPoint, nextPoint, 1 / (float)parts); if (tangent.sqrMagnitude < 0.0001f) { //whatever switch (curve.Mode2D) { case BGCurve.Mode2DEnum.Off: case BGCurve.Mode2DEnum.XY: case BGCurve.Mode2DEnum.XZ: tangent = Vector3.right; break; case BGCurve.Mode2DEnum.YZ: tangent = Vector3.up; break; } } //length distanceToPreviousPoint = BGEditorUtility.CalculateDistance(previousPoint, newPoint, parts); float minDistance; if (nextPoint != null) { distanceToNextPoint = BGEditorUtility.CalculateDistance(newPoint, nextPoint, parts); minDistance = Math.Min(distanceToPreviousPoint, distanceToNextPoint); } else { minDistance = distanceToPreviousPoint; } var length = minDistance * DistanceToControlMultiplier; //we need local tangent for controls tangent = curve.ToLocalDirection(tangent); newPoint.ControlSecondLocal = tangent * length; newPoint.ControlFirstLocal = -newPoint.ControlSecondLocal; newPoint.ControlType = controlType; curve.SupressEvents = oldSuppress; return(newPoint); }
private static BGCurvePoint CreatePointBetween(BGCurve curve, BGCurvePointI previousPoint, BGCurvePointI nextPoint, int parts, BGCurvePoint.ControlTypeEnum controlType) { var newPos = BGEditorUtility.CalculatePosition(previousPoint, nextPoint, .5f); var tangent = BGEditorUtility.CalculateTangent(previousPoint, nextPoint, .5f); var scaledTangent = tangent * DistanceToTangentMultiplier * BGEditorUtility.CalculateDistance(previousPoint, nextPoint, parts); return(curve.CreatePointFromLocalPosition(curve.ToLocal(newPos), controlType, curve.ToLocalDirection(-scaledTangent), curve.ToLocalDirection(scaledTangent))); }
//================================================================================= // This is not copy/pasted part //================================================================================= /// <summary>all methods, prefixed with Private, are not meant to be called from outside of BGCurve package </summary> //Init with data. No events are fired. point==null for pointsMode switching. public void PrivateInit(BGCurvePoint point, BGCurve.PointsModeEnum pointsMode) { if (point != null) { // init from new point curve = point.Curve; controlType = point.ControlType; pointTransform = point.PointTransform; switch (pointsMode) { case BGCurve.PointsModeEnum.GameObjectsNoTransform: positionLocal = point.PositionLocal; controlFirstLocal = point.ControlFirstLocal; controlSecondLocal = point.ControlSecondLocal; break; case BGCurve.PointsModeEnum.GameObjectsTransform: transform.localPosition = point.PositionLocal; //transformed locals are always the same var targetTransform = pointTransform != null ? pointTransform : transform; controlFirstLocal = targetTransform.InverseTransformVector(point.ControlFirstLocalTransformed); controlSecondLocal = targetTransform.InverseTransformVector(point.ControlSecondLocalTransformed); break; default: throw new ArgumentOutOfRangeException("pointsMode", pointsMode, null); } } else { // change pointsMode Transform targetTransform; switch (pointsMode) { case BGCurve.PointsModeEnum.GameObjectsNoTransform: { if (Curve.PointsMode != BGCurve.PointsModeEnum.GameObjectsTransform) { throw new ArgumentOutOfRangeException("Curve.PointsMode", "Curve points mode should be equal to GameObjectsTransform"); } positionLocal = transform.localPosition; //transformed locals are always the same targetTransform = pointTransform != null ? pointTransform : curve.transform; break; } case BGCurve.PointsModeEnum.GameObjectsTransform: { if (Curve.PointsMode != BGCurve.PointsModeEnum.GameObjectsNoTransform) { throw new ArgumentOutOfRangeException("Curve.PointsMode", "Curve points mode should be equal to GameObjectsNoTransform"); } transform.position = PositionWorld; //transformed locals are always the same targetTransform = pointTransform != null ? pointTransform : transform; break; } default: throw new ArgumentOutOfRangeException("pointsMode", pointsMode, null); } controlFirstLocal = targetTransform.InverseTransformVector(ControlFirstLocalTransformed); controlSecondLocal = targetTransform.InverseTransformVector(ControlSecondLocalTransformed); } }
// ============================================== Public functions (only required ones- no math. to use math use BGCurveBaseMath or your own extension with BGCurveBaseMath as an example) /// <summary>Curve's point creation</summary> public BGCurvePoint CreatePointFromWorldPosition(Vector3 worldPos, BGCurvePoint.ControlTypeEnum controlType) { return new BGCurvePoint(this, transform.InverseTransformPoint(worldPos), controlType); }
private static BGCurvePoint CreatePointBetween(BGCurve curve, BGCurvePointI previousPoint, BGCurvePointI nextPoint, int parts, BGCurvePoint.ControlTypeEnum controlType) { var newPos = BGEditorUtility.CalculatePosition(previousPoint, nextPoint, .5f); var tangent = BGEditorUtility.CalculateTangent(previousPoint, nextPoint, .5f); return(CreatePointBetween(curve, previousPoint, nextPoint, parts, controlType, newPos, tangent)); }
/// <summary>Curve's point creation</summary> public BGCurvePoint CreatePointFromLocalPosition(Vector3 localPos, BGCurvePoint.ControlTypeEnum controlType, Vector3 control1LocalPos, Vector3 control2LocalPos) { return new BGCurvePoint(this, localPos, controlType, control1LocalPos, control2LocalPos); }