Implement switch slope calculation

- Implemented track slope calculation in switch tracks
This commit is contained in:
izawartka 2026-08-13 21:27:58 +02:00
parent 0bedd56cc8
commit 20a46f7bba
3 changed files with 42 additions and 6 deletions

View File

@ -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 = { const CurveHelper = {
calculateCurveEnd, calculateCurveEnd,
calculateCurveEndStandard, calculateCurveEndStandard,
transformStart, transformStart,
calculateSlopesFromQuaternion
}; };
export default CurveHelper; export default CurveHelper;

View File

@ -152,7 +152,18 @@ export default class Switch extends SceneryObject {
} }
const trackId = ids[trackDef.dataIndex][0]; const trackId = ids[trackDef.dataIndex][0];
const connections = this._createTrackConnections(switchDef, trackDef, ids); 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( const track = StandardTrack.createSwitchTrack(
this, this,
@ -162,8 +173,8 @@ export default class Switch extends SceneryObject {
trackDef.length, trackDef.length,
trackDef.radius, trackDef.radius,
connections, connections,
trackDef.slope1 ?? 0, calculatedSlopes.startSlope,
trackDef.slope2 ?? 0, calculatedSlopes.endSlope,
trackDef.speedLimit ?? 999 trackDef.speedLimit ?? 999
); );
scenery.addObject(track); scenery.addObject(track);

View File

@ -25,10 +25,16 @@ export default class StandardTrack extends Track {
} }
getPointAtDist(dist, fromEnd = TrackConnectionEnd.START) { 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; 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); return this._transformPoint(curveEnd);
} }