diff --git a/src/helpers/constants.js b/src/helpers/constants.js index a193a63..0c535d9 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -23,6 +23,7 @@ const Constants = { attachSignsMaxDistanceX: 0.2, attachSignsGridSize: 10, logAttachedSigns: false, + connectTracks: true, }, warnings: { all: false, // enable all warnings @@ -51,7 +52,7 @@ const Constants = { attachSignsOutOfBounds: true, signalElemsUnknownSign: true, signalElemsUnknownSignText: true, - + connectTracksFailed: true, }, errors: { invalidSceneryInfo: true diff --git a/src/model/connect-tracks.js b/src/model/connect-tracks.js new file mode 100644 index 0000000..477da55 --- /dev/null +++ b/src/model/connect-tracks.js @@ -0,0 +1,70 @@ +import SceneryParserLog from "./scenery-parser-log"; +import TrackConnection, { TrackConnectionType } from "./track-connection"; + +export function connectTracks(scenery) { + const tracks = scenery.objects['tracks'] || {}; + + Object.values(tracks).forEach(track => { + connectTrack(scenery, track, false); + connectTrack(scenery, track, true); + }); +} + +function connectTrack(scenery, track, isPrev) { + const vNext = isPrev ? track.previd : track.nextid; + if (!vNext) return; + + const vNextTrackId = scenery.getTrackIdByAlias(vNext); + const vNextTrack = scenery.getObject('tracks', vNextTrackId); + + if (!vNextTrack) { + SceneryParserLog.warn('connectTracks', `Track ${track.id} has non-existing ${isPrev ? 'previous' : 'next'} track: ${isPrev ? track.previd : track.nextid} (${vNextTrackId})`); + return; + } + + const vNextTrackNextId = scenery.getTrackIdByAlias(vNextTrack.nextid); + const vNextTrackPrevId = scenery.getTrackIdByAlias(vNextTrack.previd); + const isConnectedAsNext = vNextTrackPrevId === track.id || track.aliases.includes(vNextTrackPrevId); + const isConnectedAsPrev = vNextTrackNextId === track.id || track.aliases.includes(vNextTrackNextId); + + let otherConnectionType = isConnectedAsNext ? TrackConnectionType.START : TrackConnectionType.END; + let addReverseConnection = false; + + if (!isConnectedAsNext && !isConnectedAsPrev) { + // switch connection + if(!track.switch) { + SceneryParserLog.warn('connectTracksFailed', `${isPrev ? 'Previous' : 'Next'} track ${vNextTrackId} is not connected back to track ${track.id} (${track.previd} / ${track.nextid}). Cannot connect tracks`); + return; + } + + const switchId = track.switch.id; + const isConnectedAsSwitchNext = vNextTrackNextId.slice(0, -1) === switchId; + const isConnectedAsSwitchPrev = vNextTrackPrevId.slice(0, -1) === switchId; + + if(!isConnectedAsSwitchNext && !isConnectedAsSwitchPrev) { + SceneryParserLog.warn('connectTracksFailed', `${isPrev ? 'Previous' : 'Next'} track ${vNextTrackId} is not connected back to switch track ${track.id} (${track.previd} / ${track.nextid}). Cannot connect tracks`); + return; + } + + otherConnectionType = isConnectedAsSwitchNext ? TrackConnectionType.START : TrackConnectionType.END; + addReverseConnection = true; + } + + const mainConnectionType = isPrev ? TrackConnectionType.START : TrackConnectionType.END; + + track.connections.push(new TrackConnection( + track, + vNextTrack, + mainConnectionType, + otherConnectionType + )); + + if(!addReverseConnection) return; + + vNextTrack.connections.push(new TrackConnection( + vNextTrack, + track, + otherConnectionType, + mainConnectionType + )); +} \ No newline at end of file diff --git a/src/model/scenery-parser.js b/src/model/scenery-parser.js index 27ef58a..51292a0 100644 --- a/src/model/scenery-parser.js +++ b/src/model/scenery-parser.js @@ -19,6 +19,7 @@ import NEVP from './track-objects/nevp'; import Derailer from './track-objects/derailer'; import SpawnPoint from './track-objects/spawn-point'; import { attachSigns } from './attach-signs'; +import { connectTracks } from './connect-tracks'; /* TODO: add support for WorldRotation and WorldTranslation @@ -44,8 +45,9 @@ export default class SceneryParser { scenery.applyObjects(); - if(Constants.parser.resolveElectrification) ElectrificationResolver.resolveScenery(scenery); if(Constants.parser.runTracksConnectionTest) tracksConnectionTest(scenery); + if(Constants.parser.connectTracks) connectTracks(scenery); + if(Constants.parser.resolveElectrification) ElectrificationResolver.resolveScenery(scenery); if(Constants.parser.attachSigns) attachSigns(scenery); if(Constants.parser.logSceneryAfterFinished) console.log(scenery); diff --git a/src/model/track-connection.js b/src/model/track-connection.js new file mode 100644 index 0000000..7aab742 --- /dev/null +++ b/src/model/track-connection.js @@ -0,0 +1,20 @@ +export const TrackConnectionType = { + END: 0, + START: 1, +} + +export default class TrackConnection { + tracks; + otherTrack; + type; + otherType; + + constructor(track, otherTrack, type, otherType) { + Object.assign(this, { + track, + otherTrack, + type, + otherType + }); + } +} diff --git a/src/model/tracks/track.js b/src/model/tracks/track.js index fff70bb..b209c29 100644 --- a/src/model/tracks/track.js +++ b/src/model/tracks/track.js @@ -20,6 +20,7 @@ export default class Track extends SceneryObject { switch = null; electrificationStatus = ElectrificationStatus.NOT_CHECKED; hasNEVP = false; + connections = []; constructor(id, pos, rot, len, r, nextid, previd, id_station, start_slope, end_slope, id_isolation, prefab_name, maxspeed, derailspeed) { super(id, pos, rot);