public SomeCurveData(MyCurveData referenceCurve, string name, Vector3 position, BGCurveBaseMath.Config config) : base(new GameObject(name), referenceCurve.LineRendererMaterial, Color.magenta) { this.referenceCurve = referenceCurve; //game object GameObject.transform.parent = referenceCurve.GameObject.transform.parent; GameObject.transform.localScale = localScale; GameObject.transform.position = position; origin = position; //curve Curve = GameObject.AddComponent <BGCurve>(); Curve.Closed = referenceCurve.Curve.Closed; //add points for (var i = 0; i < referenceCurve.Curve.PointsCount; i++) { Curve.AddPoint(referenceCurve.Curve[i].CloneTo(Curve)); } //init math after points are added Math = new BGCurveBaseMath(Curve, config); AddObjects(ObjectsCount, referenceCurve.ObjectToMove, referenceCurve.Curve.transform.parent); }
public static int CountStraightLines(BGCurveBaseMath math, bool[] straight) { var curve = math.Curve; var points = curve.Points; var sections = math.SectionInfos; var sectionsCount = sections.Length; var straightLinesCount = 0; var previousControlAbsent = points[0].ControlType == BGCurvePoint.ControlTypeEnum.Absent; for (var i = 0; i < sectionsCount; i++) { var nextPoint = curve.Closed && i == sectionsCount - 1 ? points[0] : points[i + 1]; var nextControlAbsent = nextPoint.ControlType == BGCurvePoint.ControlTypeEnum.Absent; if (previousControlAbsent && nextControlAbsent) { straight[i] = true; straightLinesCount++; } previousControlAbsent = nextControlAbsent; } return(straightLinesCount); }
public virtual void Init(BGCcVisualizationLineRenderer cc) { this.cc = cc; doNotOptimizeStraightLines = cc.doNotOptimizeStraightLines; Math = cc.Math.Math; straightBits = cc.straightBits; }
// Use this for initialization void Start() { BGCurveBaseMath.Config cfg = new BGCurveBaseMath.Config(BGCurveBaseMath.Fields.PositionAndTangent); cMath = new BGCurveBaseMath(curve, cfg); //curveDistance = 1f; curveTotal = cMath.GetDistance(); }
public BGCurvePainterGizmo(BGCurveBaseMath math, bool monitorTransform = false) { Math = math; if (monitorTransform) { transformMonitor = new BGTransformMonitor(math.Curve); } }
private static void AdjustMath(BGCurveSettings settings, BGCurveBaseMath math) { if (settings.Sections != math.Configuration.Parts || (settings.ShowTangents && !math.IsCalculated(BGCurveBaseMath.Field.Tangent)) || (!settings.ShowTangents && math.IsCalculated(BGCurveBaseMath.Field.Tangent))) { math.Init(NewConfig(settings)); } }
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); }
//check if delay is over private bool CheckIfDelayIsOver(BGCurveBaseMath math, BGCcCursor cursor) { var pointsCountMinusOne = Curve.PointsCount - 1; if (adjustByTotalLength) { oldLength = math.GetDistance(); } //curve is not closed and delayed at last point var delayAtLastPoint = !Curve.Closed && currentSectionIndex == pointsCountMinusOne; //curve may be changing, so we need to adjust a position anyway cursor.Distance = delayAtLastPoint ? math.GetDistance() : math[currentSectionIndex].DistanceFromStartToOrigin; var delayValue = GetDelayAtPoint(currentSectionIndex); // we are still delayed if (!(Time.time - delayStarted > delayValue)) { return(false); } var currentSpeed = speed; if (speedField != null) { //we need to retrieve speed from a field value currentSpeed = Curve[currentSectionIndex].GetFloat(speedField.FieldName); } // delay is over, start moving delayStarted = -1; if (speedWasPositiveWhileDelayed) { // if (delayAtLastPoint) cursor.Distance = 0; // else cursor.Distance += BGCurve.Epsilon; cursor.Distance += Mathf.Abs(currentSpeed * Time.deltaTime); } else { if (currentSectionIndex > 0) { currentSectionIndex--; cursor.Distance -= Mathf.Abs(currentSpeed * Time.deltaTime); } else { if (!skipZeroPoint) { currentSectionIndex = pointsCountMinusOne; cursor.Distance = math.GetDistance() - Mathf.Abs(currentSpeed * Time.deltaTime); } } } return(true); }
private void Dispose() { // CurrentCurve = null; CurrentGizmoPainter = null; AllCurves = null; Undo.undoRedoPerformed -= InternalOnUndoRedo; if (Math != null) Math.Dispose(); Math = null; }
//Unity callback private void Start() { curve = GetComponent <BGCurve>(); var ccMath = GetComponent <BGCcMath>(); math = ccMath.Math; curve = ccMath.Curve; //init arrays oldPos = new Vector3[PointsCount]; newPos = new Vector3[PointsCount]; speed = new float[ObjectsCount]; distances = new float[ObjectsCount]; objects = new GameObject[ObjectsCount]; //--------------------------- init from points for (var i = 0; i < PointsCount; i++) { var controlTypeEnum = BGCurvePoint.ControlTypeEnum.BezierIndependant; switch (ControlType) { case ControlTypeForNewPoints.Absent: controlTypeEnum = BGCurvePoint.ControlTypeEnum.Absent; break; case ControlTypeForNewPoints.Random: controlTypeEnum = (BGCurvePoint.ControlTypeEnum)Random.Range(0, 3); break; } curve.AddPoint(new BGCurvePoint(curve, RandomVector(), controlTypeEnum, RandomVector(), RandomVector())); } //Recalculate manually after points were added (normally you would not do it) math.Recalculate(); //---------------------------- init objects if (ObjectToMove != null) { var totalDistance = oldDistance = math.GetDistance(); for (var i = 0; i < ObjectsCount; i++) { var obj = Instantiate(ObjectToMove, Vector3.zero, Quaternion.identity) as GameObject; obj.transform.parent = transform; objects[i] = obj; distances[i] = Random.Range(0, totalDistance); } ObjectToMove.SetActive(false); //--------------------------- init speed for (var i = 0; i < ObjectsCount; i++) { speed[i] = Random.Range(0, 2) == 0 ? Random.Range(-SpeedRange, -SpeedRange * 0.3f) : Random.Range(SpeedRange * 0.3f, SpeedRange); } } }
// Use this for initialization private void Start() { curve = GetComponent <BGCurve>(); lineRenderer = GetComponent <LineRenderer>(); // curveBaseMath = new BGCurveBaseMath(curve, false, 30); curveBaseMath = new BGCurveBaseMath(curve); started = Time.time; ResetLineRenderer(); }
protected override bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message) { if (BGCurveSettingsForEditor.DisableSceneViewPointMenu) { return(false); } var minDistanceToCamera = float.MaxValue; var mousePosition = @event.mousePosition; var cameraPos = SceneView.currentDrawingSceneView.camera.transform.position; var index = -1; var pointsCount = math.Curve.PointsCount; for (var i = 0; i < pointsCount; i++) { var pointPos = math.GetPosition(i); var sqrMagnitude = (mousePosition - BGEditorUtility.GetSceneViewPosition(pointPos, sceneViewHeight)).sqrMagnitude; if (sqrMagnitude > DistanceTolerance) { continue; } var sqrtMagnitude = Vector3.SqrMagnitude(cameraPos - pointPos); if (minDistanceToCamera < sqrtMagnitude) { continue; } //found a target minDistanceToCamera = sqrMagnitude; index = i; } if (index < 0) { return(false); } //menu active var point = math.Curve[index]; position = math.GetPosition(index); message = SuccessMessage("Point " + index); menu.On(point, index); //============== Ok return(true); }
// Use this for initialization private void Start() { curve = GetComponent <BGCurve>(); // curve.TraceChanges = true; lineRenderer = GetComponent <LineRenderer>(); // curveBaseMath = new BGCurveBaseMath(curve, true); curveBaseMath = new BGCurveBaseMath(curve); started = Time.time; ResetLineRenderer(); curve.Changed += (sender, args) => ResetLineRenderer(); }
public CurveData(TestCurves testCurves, string name, string description, Vector3 position, BGCurveBaseMath.Config config, MathTypeEnum mathType) : base(new GameObject(name), testCurves.LineRendererMaterial, Color.magenta) { this.testCurves = testCurves; this.description = description; //game object GameObject.transform.position = position; origin = position; //curve Curve = GameObject.AddComponent <BGCurve>(); Curve.Closed = testCurves.Curve.Closed; //add points for (var i = 0; i < testCurves.Curve.PointsCount; i++) { var point = testCurves.Curve[i]; var clonePoint = new BGCurvePoint(Curve, point.PositionLocal, point.ControlType, point.ControlFirstLocal, point.ControlSecondLocal); Curve.AddPoint(clonePoint); } //init math after points are added switch (mathType) { case MathTypeEnum.Base: Math = new BGCurveBaseMath(Curve, config); break; case MathTypeEnum.Formula: #pragma warning disable 0618 Math = new BGCurveFormulaMath(Curve, config); #pragma warning restore 0618 break; case MathTypeEnum.Adaptive: Math = new BGCurveAdaptiveMath(Curve, (BGCurveAdaptiveMath.ConfigAdaptive)config); break; default: throw new ArgumentOutOfRangeException("mathType", mathType, null); } AddObjects(ObjectsCount, testCurves.ObjectToMove, GameObject.transform); //scale down GameObject.transform.localScale = originalScale; }
private void InitMath(object sender, EventArgs e) { //New math var config = new BGCurveBaseMath.Config(fields) { Parts = sectionParts, UsePointPositionsToCalcTangents = usePositionToCalculateTangents, OptimizeStraightLines = optimizeStraightLines, Fields = fields }; if (updateMode != UpdateModeEnum.Always && Application.isPlaying) { switch (updateMode) { case UpdateModeEnum.AabbVisible: InitAabbVisibleBefore(config); break; case UpdateModeEnum.RendererVisible: InitRendererVisible(config); break; } } if (math == null) { /* * math = mathType == MathTypeEnum.Base * ? new BGCurveBaseMath(Curve, config) * : new BGCurveAdaptiveSplitMath(Curve, config); */ math = new BGCurveBaseMath(Curve, config); ChangedParams += InitMath; math.Changed += MathWasChanged; } else { math.ChangeRequested -= MathOnChangeRequested; math.Init(config); } if (updateMode == UpdateModeEnum.AabbVisible) { InitAabbVisibleAfter(config); } }
//points was passed and we check if delay is required at this point private bool CheckDelayAtPoint(BGCurveBaseMath math, BGCcCursor cursor, int pointIndex, bool speedPositive) { if (IsDelayRequired(pointIndex)) { //we gotta delay at this point currentSectionIndex = pointIndex; //move cursor straight to the point cursor.Distance = Curve.PointsCount - 1 == pointIndex && !Curve.Closed ? math.GetDistance() : math[pointIndex].DistanceFromStartToOrigin; // !!!!!!! start delay StartDelay(speedPositive); //we does not need to process movement (it will be ignored at any rate, cause we stick to the particular point) return(true); } return(false); }
private void Dispose() { // CurrentCurve = null; if (CurrentGizmoPainter != null && CurrentGizmoPainter.Math.Curve == Curve) { CurrentGizmoPainter = null; } AllCurves = null; Undo.undoRedoPerformed -= InternalOnUndoRedo; if (Math != null) { Math.Dispose(); } Math = null; }
public TestCurves(BGCurve curve, BGCurveBaseMath.Config config, MeshRenderer objectToMove, Material lineRendererMaterial) : base(curve.gameObject, lineRendererMaterial, Color.green) { Curve = curve; Math = new BGCurveBaseMath(curve, config); ObjectToMove = objectToMove; AddObject(objectToMove.gameObject); AddObjects(ObjectsCount - 1, objectToMove, curve.transform); const float offset = 1 / (float)ObjectsCount; for (var i = 0; i < ObjectsCount; i++) { DistanceRatios.Add(i * offset); } }
// Use this for initialization void Start() { hp = maxHp; BGCurveBaseMath.Config cfg = new BGCurveBaseMath.Config(BGCurveBaseMath.Fields.PositionAndTangent); cMath = new BGCurveBaseMath(curve, cfg); curveDistance = 1f; curveTotal = cMath.GetDistance(); animator = GetComponentInChildren <Animator>(); rbs = transform.GetComponentsInChildren <Rigidbody>(); rbRends = new List <Renderer>(); foreach (Rigidbody r in rbs) { rbRends.Add(r.gameObject.GetComponent <Renderer>()); } }
//checks if cursor passed a point (current section is changed) and if new delay occured. Also fires events if needed private bool CheckForNewDelay(BGCurveBaseMath math, float distance, ref int newSectionIndex, bool checkDelay, bool firingEvents) { if (currentSectionIndex == 0 && skipZeroPoint) { return(false); } if (!math.Curve.Closed && currentSectionIndex == math.Curve.PointsCount - 1) { return(false); } newSectionIndex = math.CalcSectionIndexByDistance(distance); if (currentSectionIndex != newSectionIndex) { //section is changed (there could be several points between) //if speed was positive or negative? bool speedPositive; if (speedField == null) { speedPositive = speed > 0; } else { speedPositive = Curve[currentSectionIndex].GetFloat(speedField.FieldName) > 0; if (speedReversed) { speedPositive = !speedPositive; } } if (CheckDelayAtSectionChanged(newSectionIndex, checkDelay, firingEvents, speedPositive)) { return(true); } } //no delay delayStarted = -1; return(false); }
public BGCurveCalculatorClosestPoint(BGCurveBaseMath math) { this.math = math; }
protected abstract bool Process(Event @event, BGCurveBaseMath math, float sceneViewHeight, ref Vector3 position, ref string message);
protected void OnEnable() { Curve = (BGCurve)target; //wth if (Curve == null) { return; } CurrentCurve = Curve; transformMonitor = BGTransformMonitor.GetMonitor(Curve); var settings = BGPrivateField.GetSettings(Curve); //painter and math if (curve2Painter.ContainsKey(Curve)) { curve2Painter[Curve].Dispose(); curve2Painter.Remove(Curve); } Math = NewMath(Curve, settings); CurrentGizmoPainter = new BGCurvePainterGizmo(Math); AllCurves = FindObjectsOfType <BGCurve>(); //overlay BGEditorUtility.Assign(ref OverlayMessage, () => new BGOverlayMessage()); //probably we do not need it for play mode.. probably if (!Application.isPlaying) { //they are not persistent Curve.ImmediateChangeEvents = true; Curve.BeforeChange += BeforeCurveChange; Curve.Changed += CurveChanged; } if (!settings.Existing) { //newly created settings.Existing = true; var defaultSettings = BGCurveSettingsOperations.LoadDefault(); if (defaultSettings != null) { BGPrivateField.SetSettings(Curve, defaultSettings); } } //load textures BGEditorUtility.Assign(ref headerTexture, () => BGEditorUtility.LoadTexture2D(BGEditorUtility.Image.BGCurveLogo123)); stickerTextureOk = BGEditorUtility.Texture1X1(new Color32(46, 143, 168, 255)); stickerTextureError = BGEditorUtility.Texture1X1(new Color32(255, 0, 0, 255)); stickerTextureWarning = BGEditorUtility.Texture1X1(new Color32(255, 206, 92, 255)); stickerTextureActive = BGEditorUtility.Texture1X1(new Color32(44, 160, 90, 255)); //selection editorSelection = new BGCurveEditorPointsSelection(Curve, this); // editors editors = new BGCurveEditorTab[] { new BGCurveEditorPoints(this, serializedObject, editorSelection), new BGCurveEditorComponents(this, serializedObject), new BGCurveEditorFields(this, serializedObject, editorSelection), new BGCurveEditorSettings(this, serializedObject) }; headers = editors.Select(editor => editor.Header2D).ToArray(); foreach (var editor in editors) { editor.OnEnable(); } //do it every frame EditorApplication.update -= OverlayMessage.Check; EditorApplication.update += OverlayMessage.Check; Undo.undoRedoPerformed -= InternalOnUndoRedo; Undo.undoRedoPerformed += InternalOnUndoRedo; }
// overflow occurred private void Overflow(BGCurveBaseMath math, ref float newDistance, bool currentSpeedPositive, bool checkDelay, bool firingEvents) { var lessThanZero = newDistance < 0; var totalDistance = math.GetDistance(); var lastPointIndex = Curve.PointsCount - 1; //we need to check delays. (all points up to boundary point) if (checkDelay || firingEvents) { if (currentSpeedPositive) { //process all passed points // var lastPointIndexToCheck = Curve.Closed ? lastPointIndex : lastPointIndex - 1; var lastPointIndexToCheck = lastPointIndex; if (currentSectionIndex != lastPointIndexToCheck) { if (CheckDelayAtSectionChanged(lastPointIndexToCheck, checkDelay, firingEvents, true)) { return; } } } else { if (currentSectionIndex > 0) { if (CheckDelayAtSectionChanged(0, checkDelay, firingEvents, false)) { return; } } //this needs to be refactored if (!skipZeroPoint) { if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, false)) { if (firingEvents) { FirePointReachedEvent(0); } skipZeroPoint = true; return; } } } } //overflow switch (overflowControl) { case OverflowControlEnum.Stop: newDistance = lessThanZero ? 0 : totalDistance; Stopped = true; break; case OverflowControlEnum.Cycle: newDistance = lessThanZero ? totalDistance + newDistance : newDistance - totalDistance; break; case OverflowControlEnum.PingPong: if (speedField == null) { speed = -speed; } speedReversed = !speedReversed; currentSpeedPositive = !currentSpeedPositive; newDistance = lessThanZero ? -newDistance : totalDistance * 2 - newDistance; break; } if (newDistance < 0) { newDistance = 0; } else if (newDistance > totalDistance) { newDistance = totalDistance; } //ok, we need to check delays.. once again. (single boundary point) if (checkDelay || firingEvents) { if (Curve.Closed) { if (skipZeroPoint) { skipZeroPoint = false; } else { if (firingEvents) { FirePointReachedEvent(0); } currentSectionIndex = currentSpeedPositive ? 0 : lastPointIndex; if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive)) { return; } } } else { if (lessThanZero) { //original speed was negative if (skipZeroPoint) { skipZeroPoint = false; } else { currentSectionIndex = 0; if (firingEvents) { FirePointReachedEvent(0); } if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive)) { return; } } } else { //original speed was positive if (!Curve.Closed) { if (currentSpeedPositive) { //last->first currentSectionIndex = 0; if (firingEvents) { FirePointReachedEvent(0); } if (checkDelay && CheckDelayAtPoint(math, Cursor, 0, currentSpeedPositive)) { return; } } else { //last->last (pingpong) currentSectionIndex = lastPointIndex - 1; } } } } } }
public BGCurvePainterHandles(BGCurveBaseMath math) : base(math) { }
//init math with current params private void InitMath(object sender, EventArgs e) { //new config var config = mathType == MathTypeEnum.Adaptive ? new BGCurveAdaptiveMath.ConfigAdaptive(fields) { Tolerance = tolerance } : new BGCurveBaseMath.Config(fields) { Parts = sectionParts }; config.UsePointPositionsToCalcTangents = usePositionToCalculateTangents; config.OptimizeStraightLines = optimizeStraightLines; config.Fields = fields; if (updateMode != UpdateModeEnum.Always && Application.isPlaying) { switch (updateMode) { case UpdateModeEnum.AabbVisible: InitAabbVisibleBefore(config); break; case UpdateModeEnum.RendererVisible: InitRendererVisible(config); break; } } if (NewMathRequired) { //we need to create new math object var mathWasNull = math == null; if (mathWasNull) { ChangedParams += InitMath; } else { math.ChangeRequested -= MathOnChangeRequested; math.Changed -= MathWasChanged; math.Dispose(); } switch (MathType) { case MathTypeEnum.Base: math = new BGCurveBaseMath(Curve, config); break; default: // case MathTypeEnum.Adaptive: math = new BGCurveAdaptiveMath(Curve, (BGCurveAdaptiveMath.ConfigAdaptive)config); break; } math.Changed += MathWasChanged; if (!mathWasNull) { MathWasChanged(this, null); } } else { //we can reuse existing math object math.ChangeRequested -= MathOnChangeRequested; //reinit math with new params (it will be recalculated as result) math.Init(config); } //init AABB if (updateMode == UpdateModeEnum.AabbVisible) { InitAabbVisibleAfter(); } }