protected IEnumerable <MarkupStyleDash> CalculateDashed(Bezier3 trajectory, float dashLength, float spaceLength, Func <Bezier3, float, float, IEnumerable <MarkupStyleDash> > calculateDashes) { var dashesT = new List <float[]>(); var startSpace = spaceLength / 2; for (var i = 0; i < 3; i += 1) { dashesT.Clear(); var isDash = false; var prevT = 0f; var currentT = 0f; var nextT = trajectory.Travel(currentT, startSpace); while (nextT < 1) { if (isDash) { dashesT.Add(new float[] { currentT, nextT }); } isDash = !isDash; prevT = currentT; currentT = nextT; nextT = trajectory.Travel(currentT, isDash ? dashLength : spaceLength); } float endSpace; if (isDash || ((trajectory.Position(1) - trajectory.Position(currentT)).magnitude is float tempLength && tempLength < spaceLength / 2)) { endSpace = (trajectory.Position(1) - trajectory.Position(prevT)).magnitude; }
private static ushort CheckOverlap(ushort ignoreParked, ref Bezier3 bezier, Vector3 pos, Vector3 dir, float offset, float length, ushort otherID, ref VehicleParked otherData, ref bool overlap, ref float minPos, ref float maxPos) { if (otherID != ignoreParked) { VehicleInfo info = otherData.Info; Vector3 otherPos = otherData.m_position; Vector3 diff = otherPos - pos; float carLength = info.m_generatedInfo.m_size.z; float lengthAvr = (length + carLength) * 0.5f + 1f; float diffLength = diff.magnitude; if (diffLength < lengthAvr - 0.5f) { overlap = true; float l1; float l2; if (Vector3.Dot(diff, dir) >= 0f) { l1 = lengthAvr + diffLength; l2 = lengthAvr - diffLength; } else { l1 = lengthAvr - diffLength; l2 = lengthAvr + diffLength; } maxPos = Mathf.Max(maxPos, bezier.Travel(offset, l1)); minPos = Mathf.Min(minPos, bezier.Travel(offset, -l2)); } } return(otherData.m_nextGridParked); }
//used to calculate t in non-fence Curved and Freeform modes //for each individual item /// <summary> /// Solves for t-value which would be a length of *distance* along the curve from original point at t = *tStart*. /// </summary> /// <param name="bezier"></param> /// <param name="tStart"></param> /// <param name="distance"></param> /// <param name="tolerance"></param> /// <param name="tEnd"></param> public static void StepDistanceCurve(Bezier3 bezier, float tStart, float distance, float tolerance, out float tEnd) { float _tCurrent = 0f; _tCurrent = bezier.Travel(tStart, distance); float _tStepInitial = _tCurrent - tStart; Vector3 _posCurrent = bezier.Position(_tCurrent); float _distCurrent = CubicBezierArcLengthXZGauss04(bezier, tStart, _tCurrent); float _toleranceSqr = tolerance * tolerance; if (Mathf.Pow(distance - _distCurrent, 2f) >= _toleranceSqr) { float _localSpeed = CubicSpeedXZ(bezier, _tCurrent); float _distDifference = distance - _distCurrent; int _counter = 0; while (_counter < 12 && (Mathf.Pow(_distDifference, 2f) > _toleranceSqr)) { _distCurrent = CubicBezierArcLengthXZGauss04(bezier, tStart, _tCurrent); _distDifference = distance - _distCurrent; _localSpeed = CubicSpeedXZ(bezier, _tCurrent); _tCurrent = _tCurrent + _distDifference / _localSpeed; _counter++; } } tEnd = _tCurrent; }
/// <summary> /// Travels some distance on bezier and calculates the point and tangent at that distance. /// </summary> /// <param name="distance">distance to travel on the arc in meters</param> /// <param name="tangent">normalized tangent on the curve toward the end of the bezier.</param> /// <returns>point on the curve at the given distance.</returns> public static Vector3 Travel2(this Bezier3 beizer, float distance, out Vector3 tangent) { float t = beizer.Travel(0, distance); tangent = beizer.Tangent(t).normalized; return(beizer.Position(t)); }
public static float Travel(this Bezier3 bezier, float distance, int depth = 5) { var length = (bezier.b - bezier.a).magnitude + (bezier.c - bezier.b).magnitude + (bezier.d - bezier.c).magnitude; if (distance > length) { return(1f); } else { bezier.Travel(distance, depth, out _, out var t); return(t); } }
void MakeRoad(Vector3 start, Vector3 end, Vector3 startDirection, Vector3 endDirection, bool flip, uint prefabId) { DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "making bezier road"); if (flip) { Vector3 temp = start; start = end; end = temp; temp = -startDirection; startDirection = -endDirection; endDirection = temp; } float length = (end - start).magnitude; var curve = new Bezier3(start, start + startDirection * length / 3, end + endDirection * length / 3, end); Vector3 priorPos = curve.Position(0); Vector3 priorDir = curve.Tangent(0).normalized; float t = curve.Travel(0, pitch); DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString()); while (t < .9999) { Vector3 pos = curve.Position(t); Vector3 dir = curve.Tangent(t); MakeSegment(priorPos, pos, priorDir, -dir, prefabId); t = curve.Travel(t, pitch); DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString()); priorPos = pos; priorDir = dir; } { Vector3 pos = curve.Position(1); Vector3 dir = curve.Tangent(1).normalized; MakeSegment(priorPos, pos, priorDir, -dir, prefabId); } }