From 8723de8a30dc8d65547ace18c86e61cd5b095cea Mon Sep 17 00:00:00 2001 From: izawartka <59137928+izawartka@users.noreply.github.com> Date: Thu, 13 Aug 2026 21:27:58 +0200 Subject: [PATCH] Implement switch slope calculation - Implemented track slope calculation in switch tracks --- src/helpers/curveHelper.js | 19 +++++++++++++++++++ src/model/switch.js | 17 ++++++++++++++--- src/model/tracks/standard-track.js | 12 +++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/helpers/curveHelper.js b/src/helpers/curveHelper.js index 4780d22..0c9ed18 100644 --- a/src/helpers/curveHelper.js +++ b/src/helpers/curveHelper.js @@ -50,10 +50,29 @@ function transformStart(globalStart, globalRotationDeg, localStart, localRotatio }; } +function calculateSlopesFromQuaternion(rotationQuat, radius, length) { + const startTangent = new Vector3(0, 0, 1); + const endTangent = radius === 0 + ? startTangent + : Vector3.fromAngleY(-length / radius); + + const worldStart = rotationQuat.rotateVector(startTangent); + const worldEnd = rotationQuat.rotateVector(endTangent); + + const startHorizontal = Math.hypot(worldStart.x, worldStart.z); + const endHorizontal = Math.hypot(worldEnd.x, worldEnd.z); + + return { + startSlope: startHorizontal === 0 ? 0 : (worldStart.y / startHorizontal) * 1000, + endSlope: endHorizontal === 0 ? 0 : (worldEnd.y / endHorizontal) * 1000, + }; +} + const CurveHelper = { calculateCurveEnd, calculateCurveEndStandard, transformStart, + calculateSlopesFromQuaternion }; export default CurveHelper; diff --git a/src/model/switch.js b/src/model/switch.js index 259316d..57b2c90 100644 --- a/src/model/switch.js +++ b/src/model/switch.js @@ -152,7 +152,18 @@ export default class Switch extends SceneryObject { } const trackId = ids[trackDef.dataIndex][0]; const connections = this._createTrackConnections(switchDef, trackDef, ids); - const { startPos, rotationDeg } = CurveHelper.transformStart(this.pos, this.rot, trackDef.pos, trackDef.rot); + const { startPos, rotationQuat, rotationDeg } = CurveHelper.transformStart( + this.pos, + this.rot, + trackDef.pos, + trackDef.rot + ); + + const calculatedSlopes = CurveHelper.calculateSlopesFromQuaternion( + rotationQuat, + trackDef.radius, + trackDef.length + ); const track = StandardTrack.createSwitchTrack( this, @@ -162,8 +173,8 @@ export default class Switch extends SceneryObject { trackDef.length, trackDef.radius, connections, - trackDef.slope1 ?? 0, - trackDef.slope2 ?? 0, + calculatedSlopes.startSlope, + calculatedSlopes.endSlope, trackDef.speedLimit ?? 999 ); scenery.addObject(track); diff --git a/src/model/tracks/standard-track.js b/src/model/tracks/standard-track.js index e54a63c..22c9570 100644 --- a/src/model/tracks/standard-track.js +++ b/src/model/tracks/standard-track.js @@ -25,10 +25,16 @@ export default class StandardTrack extends Track { } getPointAtDist(dist, fromEnd = TrackConnectionEnd.START) { - if (fromEnd === TrackConnectionEnd.END) return this.getPointAtDist(this.len - dist, TrackConnectionEnd.START) + if (fromEnd === TrackConnectionEnd.END) { + return this.getPointAtDist(this.len - dist, TrackConnectionEnd.START); + } + const curveEnd = CurveHelper.calculateCurveEndStandard(this.r, dist).endPos; - // TODO: Verify slope logic - curveEnd.y += (this.start_slope + this.end_slope) / 2000 * dist; + + if (this.source === TrackSource.STANDARD) { + curveEnd.y += (this.start_slope + this.end_slope) / 2000 * dist; + } + return this._transformPoint(curveEnd); }