diff --git a/.gitignore b/.gitignore index 34fe017..830909f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -public/sceneries/* \ No newline at end of file +public/sceneries/* + +# IDEs +.idea diff --git a/src/helpers/constants.js b/src/helpers/constants.js index 5665913..b36cca1 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -8,8 +8,6 @@ const Constants = { forcePointerEvents: false }, parser: { - forceAutoSwitches: false, - logNewAutoSwitches: true, logSceneryAfterFinished: true, sceneryInfoVersion: 29, alwaysShowLogDialog: false, @@ -35,9 +33,10 @@ const Constants = { trackAliasAlreadyExists: true, trackAliasNoTrack: true, switchUndefinedModel: true, - switchAutoDefFailed: true, switchInvalidDataFormat: true, switchNoModel: true, + switchMissingTrackId: true, + switchInvalidInternalConnection: true, signalBoxUndefinedPrefabName: true, invalidSceneryInfoVersion: true, signUndefinedPrefabName: true, @@ -175,4 +174,4 @@ const Constants = { } }; -export default Constants; \ No newline at end of file +export default Constants; diff --git a/src/model/defs/defined-switches.js b/src/model/defs/defined-switches.js index a9ea06f..f8f1c25 100644 --- a/src/model/defs/defined-switches.js +++ b/src/model/defs/defined-switches.js @@ -1,555 +1,110 @@ -import Vector3 from "../vector3"; +import SwitchPrefab from "../switch-descriptions/switch-prefab"; const DefinedSwitches = { - "Crossing": [ - 0, - 0, - [0,1], - new Vector3(-0.919, 0, -16.59), - new Vector3(0.919, 0, -16.59), - new Vector3(0.919, 0, 16.59), - new Vector3(-0.919, 0, 16.59) - ], - "Crossing4.444": [ - 0, - 0, - [0,1], - new Vector3(-1.104, 0, -9.939), - new Vector3(1.104, 0, -9.939), - new Vector3(1.104, 0, 9.939), - new Vector3(-1.104, 0, 9.939) - ], - "Rz 60E1-300-1_9 R": [ - 0, - -300, - [0, 0, 3, 4, 2, 1], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 33.231), - new Vector3(1.835, 0, 33.129) - ], - "Rz 60E1-300-1_9 L": [ - 0, - 300, - [0, 0, 3, 4, 2, 1], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 33.231), - new Vector3(-1.835, 0, 33.129) - ], - "Rz 60E1-190-1_9 R": [ - 0, - -190, - [0, 0, 5, 6, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 27.139), - new Vector3(1.835, 0, 27.037) - ], - "Rz 60E1-190-1_9 L": [ - 0, - 190, - [0, 0, 5, 6, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 27.139), - new Vector3(-1.835, 0, 27.037) - ], - "Rz 60E1-500-1_12 R": [ - 0, - -500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 41.595), - new Vector3(1.727, 0, 41.523) - ], - "Rz 60E1-500-1_12 L": [ - 0, - 500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 41.595), - new Vector3(-1.727, 0, 41.523) - ], - "Rkpd 60E1-190-1_9": [ - 0, - 0, - [0, 1, 2, 3], - new Vector3(-0.918, 0, -16.557), - new Vector3(0.917, 0, -16.557), - new Vector3(0.917, 0, 16.557), - new Vector3(-0.917, 0, 16.557) - ], - "Rkp 60E1-190-1_9 ab": [ - 0, - 0, - [0, 1, 2, 3], - new Vector3(-0.918, 0, -16.557), - new Vector3(0.917, 0, -16.556), - new Vector3(0.917, 0, 16.558), - new Vector3(-0.921, 0, 16.558) - ], - "Rkp 60E1-190-1_9 ba": [ - 0, - 0, - [0, 1, 2, 3], - new Vector3(-0.918, 0, -16.557), - new Vector3(0.917, 0, -16.556), - new Vector3(0.917, 0, 16.558), - new Vector3(-0.921, 0, 16.558) - ], - "Rz 60E1-265-1_10 R": [ - 0, - -265, - [0, 0, 5, 6], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 31.181), - new Vector3(1.789, 0, 31.094) - ], - "Rz 60E1-265-1_10 L": [ - 0, - 265, - [0, 0, 5, 6], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 31.181), - new Vector3(-1.789, 0, 31.094) - ], - "Rz 60E1-760-1_14 R": [ - 0, - -760, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 54.217), - new Vector3(1.931, 0, 54.148) - ], - "Rz 60E1-760-1_14 L": [ - 0, - 760, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 54.217), - new Vector3(-1.931, 0, 54.148) - ], - "Rz 60E1-1200-1_18.5 R": [ - 0, - -1200, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 64.817), - new Vector3(1.749, 0, 64.77) - ], - "Rz 60E1-1200-1_18.5 L": [ - 0, - 1200, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 64.817), - new Vector3(-1.75, 0, 64.77) - ], - "Rld 60E1-700_300-1_10 R": [ - 700, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.616, 0, 29.377), - new Vector3(1.438, 0, 29.339) - ], - "Rld 60E1-700_300-1_10 L": [ - -700, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.616, 0, 29.377), - new Vector3(-1.438, 0, 29.339) - ], - "Rld 60E1-1800_300-1_9 R": [ - 1800, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.307, 0, 33.228), - new Vector3(1.838, 0, 33.163) - ], - "Rld 60E1-1800_300-1_9 L": [ - -1800, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.307, 0, 33.228), - new Vector3(-1.838, 0, 33.163) - ], - "Rld 60E1-2500_1200-1_22 R": [ - 2500, - -1200, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.586, 0, 54.51), - new Vector3(1.238, 0, 54.499) - ], - "Rld 60E1-2500_1200-1_22 L": [ - -2500, - 1200, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.586, 0, 54.51), - new Vector3(-1.238, 0, 54.499) - ], - "Rld 60E1-650_450-1_15 R": [ - 650, - -450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.691, 0, 29.956), - new Vector3(0.997, 0, 29.945) - ], - "Rld 60E1-650_450-1_15 L": [ - -650, - 450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.691, 0, 29.956), - new Vector3(-0.997, 0, 29.945) - ], - "Rld 60E1-600_300-1_9 R": [ - 600, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.749, 0, 29.918), - new Vector3(1.49, 0, 29.881) - ], - "Rld 60E1-600_300-1_9 L": [ - -600, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.749, 0, 29.918), - new Vector3(-1.49, 0, 29.881) - ], - "Rz 60E1-205-1_9 R": [ - 0, - -205, - [0, 0, 5, 6], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 28.127), - new Vector3(1.853, 0, 28.025) - ], - "Rz 60E1-205-1_9 L": [ - 0, - 205, - [0, 0, 5, 6], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 28.127), - new Vector3(-1.853, 0, 28.025), - ], - "Rz 60E1-190-1_7.5 R": [ - 0, - -190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 25.221), - new Vector3(1.667, 0, 25.111) - ], - "Rz 60E1-190-1_7.5 L": [ - 0, - 190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 25.221), - new Vector3(-1.667, 0, 25.111) - ], - "Rz 60E1-2500-1_26.5 R": [ - 0, - -2500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 94.306), - new Vector3(1.778, 0, 94.273) - ], - "Rz 60E1-2500-1_26.5 L": [ - 0, - 2500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0, 0, 94.306), - new Vector3(-1.778, 0, 94.273) - ], - "Rlds 60E1-600-600-1_18.5": [ - -600, - 600, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.92, 0, 33.206), - new Vector3(-0.92, 0, 33.206) - ], - "Rlds 60E1-190-190-1_9": [ - -190, - 190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(1.184, 0, 21.186), - new Vector3(-1.185, 0, 21.186) - ], - "Rlj 60E1-650_190-1_20 R": [ - -650, - -190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.811, 0, 32.466), - new Vector3(2.77, 0, 32.332) - ], - "Rlj 60E1-650_190-1_20 L": [ - 650, - 190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.811, 0, 32.466), - new Vector3(-2.77, 0, 32.332) - ], - "Rlj 60E1-1200_300-1_7 R": [ - -1200, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.758, 0, 42.632), - new Vector3(3.025, 0, 42.498) - ], - "Rlj 60E1-1200_300-1_7 L": [ - 1200, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.758, 0, 42.632), - new Vector3(-3.025, 0, 42.498) - ], - "Rlj 60E1-750_190-1_6 R": [ - -750, - -190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.66, 0, 31.44), - new Vector3(2.597, 0, 31.306) - ], - "Rlj 60E1-750_190-1_6 L": [ - 750, - 190, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.66, 0, 31.44), - new Vector3(-2.597, 0, 31.306) - ], - "Rld 60E1-1200_600-1_15 R": [ - 1200, - -600, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.665, 0, 39.948), - new Vector3(1.33, 0, 39.926) - ], - "Rld 60E1-1200_600-1_15 L": [ - -1200, - 600, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.665, 0, 39.948), - new Vector3(-1.33, 0, 39.926) - ], - "Rld 60E1-1200_900-1_18.5 R": [ - 1200, - -900, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.984, 0, 48.6), - new Vector3(1.313, 0, 48.589) - ], - "Rld 60E1-1200_900-1_18.5 L": [ - -1200, - 900, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.984, 0, 48.6), - new Vector3(-1.313, 0, 48.589) - ], - "Rlj 60E1-900_300-1_7.5 R": [ - -900, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.881, 0, 39.81), - new Vector3(2.639, 0, 39.706) - ], - "Rlj 60E1-900_300-1_7.5 L": [ - 900, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.881, 0, 39.81), - new Vector3(-2.639, 0, 39.706) - ], - "Rlj 60E1-600_300-1_6 R": [ - -600, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(1.919, 0, 47.949), - new Vector3(3.832, 0, 47.795) - ], - "Rlj 60E1-600_300-1_6 L": [ - 600, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-1.919, 0, 47.949), - new Vector3(-3.832, 0, 47.795) - ], - "Rld 60E1-900_450-1_12 R": [ - 900, - -450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.778, 0, 37.425), - new Vector3(1.556, 0, 37.392) - ], - "Rld 60E1-900_450-1_12 L": [ - -900, - 450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.778, 0, 37.425), - new Vector3(-1.556, 0, 37.392) - ], - "Rld 60E1-700_500-1_14 R": [ - 700, - -500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.909, 0, 35.653), - new Vector3(1.272, 0, 35.639) - ], - "Rld 60E1-700_500-1_14 L": [ - -700, - 500, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.909, 0, 35.653), - new Vector3(-1.272, 0, 35.639) - ], - "Rld 60E1-2500_400-1_10.5 R": [ - 2500, - -400, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.289, 0, 38.008), - new Vector3(1.805, 0, 37.952) - ], - "Rld 60E1-2500_400-1_10.5 L": [ - -2500, - 400, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.289, 0, 38.008), - new Vector3(-1.805, 0, 37.952) - ], - "Rlj 60E1-1800_300-1_7.5 R": [ - -1800, - -300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.423, 0, 38.998), - new Vector3(2.531, 0, 38.89) - ], - "Rlj 60E1-1800_300-1_7.5 L": [ - 1800, - 300, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.423, 0, 38.998), - new Vector3(-2.531, 0, 38.89) - ], - "Rld 60E1-1800_600-1_14 R": [ - 1800, - -600, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.509, 0, 42.798), - new Vector3(1.526, 0, 42.767) - ], - "Rld 60E1-1800_600-1_14 L": [ - -1800, - 600, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.509, 0, 42.798), - new Vector3(-1.526, 0, 42.767) - ], - "Rlj 60E1-1800_450-1_9 R": [ - -1800, - -450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(0.69, 0, 49.84), - new Vector3(2.758, 0, 49.744) - ], - "Rlj 60E1-1800_450-1_9 L": [ - 1800, - 450, - [0, 0, 3, 4], - new Vector3(0, 0, 0), - new Vector3(0, 0, 0), - new Vector3(-0.69, 0, 49.84), - new Vector3(-2.758, 0, 49.745) - ] -} + // "Crossing": [ + // 0, + // 0, + // [0,1], + // new Vector3(-0.919, 0, -16.59), + // new Vector3(0.919, 0, -16.59), + // new Vector3(0.919, 0, 16.59), + // new Vector3(-0.919, 0, 16.59) + // ], + // "Crossing4.444": [ + // 0, + // 0, + // [0,1], + // new Vector3(-1.104, 0, -9.939), + // new Vector3(1.104, 0, -9.939), + // new Vector3(1.104, 0, 9.939), + // new Vector3(-1.104, 0, 9.939) + // ], + // Rkp 60E1-190-1_9 ab + // Rkp 60E1-190-1_9 ba + // Rkpd 60E1-190-1_9 + "Rld 60E1-1200_600-1_15 L": SwitchPrefab.fork(600.0, -1200.0, 39.95566, 0.0), + "Rld 60E1-1200_600-1_15 R": SwitchPrefab.fork(-600.0, 1200.0, 39.95566, 0.0), + "Rld 60E1-1200_900-1_18.5 L": SwitchPrefab.fork(900.0, -1200.0, 48.61317, 0.0), + "Rld 60E1-1200_900-1_18.5 R": SwitchPrefab.fork(-900.0, 1200.0, 48.61317, 0.0), + "Rld 60E1-1800_300-1_9 L": SwitchPrefab.fork(300.0, -1800.0, 33.23108, 0.0), + "Rld 60E1-1800_300-1_9 R": SwitchPrefab.fork(-300.0, 1800.0, 33.23108, 0.0), + "Rld 60E1-1800_600-1_14 L": SwitchPrefab.fork(600.0, -1800.0, 42.80262, 0.0), + "Rld 60E1-1800_600-1_14 R": SwitchPrefab.fork(-600.0, 1800.0, 42.80262, 0.0), + "Rld 60E1-1800_900-1_18.5 L": SwitchPrefab.fork(900.0, -1800.0, 48.61317, 0.0), + "Rld 60E1-1800_900-1_18.5 R": SwitchPrefab.fork(-900.0, 1800.0, 48.61317, 0.0), + "Rld 60E1-2500_1200-1_22 L": SwitchPrefab.fork(1200.0, -2500.0, 54.51731, 0.0), + "Rld 60E1-2500_1200-1_22 R": SwitchPrefab.fork(-1200.0, 2500.0, 54.51731, 0.0), + "Rld 60E1-2500_250-1_8.5 L": SwitchPrefab.fork(250.0, -2500.0, 29.31069, 0.0), + "Rld 60E1-2500_250-1_8.5 R": SwitchPrefab.fork(-250.0, 2500.0, 29.31069, 0.0), + "Rld 60E1-2500_400-1_10.5 L": SwitchPrefab.fork(400.0, -2500.0, 38.00925, 0.0), + "Rld 60E1-2500_400-1_10.5 R": SwitchPrefab.fork(-400.0, 2500.0, 38.00925, 0.0), + "Rld 60E1-2500_600-1_14 L": SwitchPrefab.fork(600.0, -2500.0, 42.80262, 0.0), + "Rld 60E1-2500_600-1_14 R": SwitchPrefab.fork(-600.0, 2500.0, 42.80262, 0.0), + "Rld 60E1-2500_900-1_17 L": SwitchPrefab.fork(900.0, -2500.0, 52.14928, 0.0), + "Rld 60E1-2500_900-1_17 R": SwitchPrefab.fork(-900.0, 2500.0, 52.14928, 0.0), + "Rld 60E1-600_300-1_9 L": SwitchPrefab.fork(300.0, -600.0, 29.92537, 0.0), + "Rld 60E1-600_300-1_9 R": SwitchPrefab.fork(-300.0, 600.0, 29.92537, 0.0), + "Rld 60E1-650_450-1_15 L": SwitchPrefab.fork(450.0, -650.0, 29.96674, 0.0), + "Rld 60E1-650_450-1_15 R": SwitchPrefab.fork(-450.0, 650.0, 29.96674, 0.0), + "Rld 60E1-700_190-1_7.5 L": SwitchPrefab.fork(190.0, -700.0, 25.22173, 0.0), + "Rld 60E1-700_190-1_7.5 R": SwitchPrefab.fork(-190.0, 700.0, 25.22173, 0.0), + "Rld 60E1-700_300-1_10 L": SwitchPrefab.fork(300.0, -700.0, 29.38637, 0.0), + "Rld 60E1-700_300-1_10 R": SwitchPrefab.fork(-300.0, 700.0, 29.38637, 0.0), + "Rld 60E1-700_500-1_14 L": SwitchPrefab.fork(500.0, -700.0, 35.66885, 0.0), + "Rld 60E1-700_500-1_14 R": SwitchPrefab.fork(-500.0, 700.0, 35.66885, 0.0), + "Rld 60E1-900_300-1_9 L": SwitchPrefab.fork(300.0, -900.0, 33.23108, 0.0), + "Rld 60E1-900_300-1_9 R": SwitchPrefab.fork(-300.0, 900.0, 33.23108, 0.0), + "Rld 60E1-900_450-1_12 L": SwitchPrefab.fork(450.0, -900.0, 37.43512, 0.0), + "Rld 60E1-900_450-1_12 R": SwitchPrefab.fork(-450.0, 900.0, 37.43512, 0.0), + "Rld 60E1-900_600-1_15 L": SwitchPrefab.fork(600.0, -900.0, 39.95566, 0.0), + "Rld 60E1-900_600-1_15 R": SwitchPrefab.fork(-600.0, 900.0, 39.95566, 0.0), + "Rlds 60E1-1000-1000-1_23": SwitchPrefab.fork(1000.0, -1000.0, 43.45773, 0.0), + "Rlds 60E1-190-190-1_9": SwitchPrefab.fork(190.0, -190.0, 21.23, 0.0), + "Rlds 60E1-600-600-1_18.5": SwitchPrefab.fork(599.9205, -600.0, 33.22262, 0.0), + "Rlj 60E1-1200_300-1_7 L": SwitchPrefab.fork(300.0, 1200.0, 42.64069, 0.0), + "Rlj 60E1-1200_300-1_7 R": SwitchPrefab.fork(-300.0, -1200.0, 42.64069, 0.0), + "Rlj 60E1-1200_600-1_9 L": SwitchPrefab.fork(600.0, 1200.0, 68.0, 0.0), + "Rlj 60E1-1200_600-1_9 R": SwitchPrefab.fork(-600.0, -1200.0, 68.0, 0.0), + "Rlj 60E1-1500_450-1_9 L": SwitchPrefab.fork(450.0, 1500.0, 49.84663, 0.0), + "Rlj 60E1-1500_450-1_9 R": SwitchPrefab.fork(-450.0, -1500.0, 49.84663, 0.0), + "Rlj 60E1-1800_300-1_7.5 L": SwitchPrefab.fork(300.0, 1800.0, 39.0, 0.0), + "Rlj 60E1-1800_300-1_7.5 R": SwitchPrefab.fork(-300.0, -1800.0, 39.0, 0.0), + "Rlj 60E1-1800_450-1_9 L": SwitchPrefab.fork(450.0, 1800.0, 49.84663, 0.0), + "Rlj 60E1-1800_450-1_9 R": SwitchPrefab.fork(-450.0, -1800.0, 49.84663, 0.0), + "Rlj 60E1-1800_600-1_10 L": SwitchPrefab.fork(599.48096, 1800.0, 59.85075, 0.0), + "Rlj 60E1-1800_600-1_10 R": SwitchPrefab.fork(-599.48096, -1800.0, 59.85075, 0.0), + "Rlj 60E1-600_300-1_6 L": SwitchPrefab.fork(300.0, 600.0, 48.0, 0.0), + "Rlj 60E1-600_300-1_6 R": SwitchPrefab.fork(-300.0, -600.0, 48.0, 0.0), + "Rlj 60E1-650_190-1_20 L": SwitchPrefab.fork(190.0, 650.0, 32.47971, 0.0), + "Rlj 60E1-650_190-1_20 R": SwitchPrefab.fork(-190.0, -650.0, 32.47971, 0.0), + "Rlj 60E1-750_190-1_6 L": SwitchPrefab.fork(190.0, 750.0, 31.44976, 0.0), + "Rlj 60E1-750_190-1_6 R": SwitchPrefab.fork(-190.0, -750.0, 31.44976, 0.0), + "Rlj 60E1-800_250-1_6.5 L": SwitchPrefab.fork(250.0, 800.0, 38.23661, 0.0), + "Rlj 60E1-800_250-1_6.5 R": SwitchPrefab.fork(-250.0, -800.0, 38.23661, 0.0), + "Rlj 60E1-900_300-1_7.5 L": SwitchPrefab.fork(300.0, 900.0, 39.82378, 0.0), + "Rlj 60E1-900_300-1_7.5 R": SwitchPrefab.fork(-300.0, -900.0, 39.82378, 0.0), + "Rlj 60E1-900_300-1_9 L": SwitchPrefab.fork(300.0, 900.0, 49.84663, 0.0), + "Rlj 60E1-900_300-1_9 R": SwitchPrefab.fork(-300.0, -900.0, 49.84663, 0.0), + "Rlj 60E1-900_450-1_7.5 L": SwitchPrefab.fork(450.0, 900.0, 59.0, 0.0), + "Rlj 60E1-900_450-1_7.5 R": SwitchPrefab.fork(-450.0, -900.0, 59.0, 0.0), + "Rz 60E1-1200-1_18.5 L": SwitchPrefab.fork(1200.0, 0.0, 64.81756, 0.0), + "Rz 60E1-1200-1_18.5 R": SwitchPrefab.fork(-1200.0, 0.0, 64.81756, 0.0), + "Rz 60E1-190-1_7.5 L": SwitchPrefab.fork(190.0, 0.0, 25.221731, 0.0), + "Rz 60E1-190-1_7.5 R": SwitchPrefab.fork(-190.0, 0.0, 25.221731, 0.0), + "Rz 60E1-190-1_9 L": SwitchPrefab.fork(0.0, 190.0, 21.046352, 6.0923653), + "Rz 60E1-190-1_9 R": SwitchPrefab.fork(0.0, -190.0, 21.046352, 6.0923653), + "Rz 60E1-205-1_9 L": SwitchPrefab.fork(205.0, 0.0, 22.707907, 5.42 /* added manually */), + "Rz 60E1-205-1_9 R": SwitchPrefab.fork(-205.0, 0.0, 22.707907, 5.42 /* added manually */), + "Rz 60E1-2500-1_26.5 L": SwitchPrefab.fork(2500.0, 0.0, 94.30607, 0.0), + "Rz 60E1-2500-1_26.5 R": SwitchPrefab.fork(-2500.0, 0.0, 94.30607, 0.0), + "Rz 60E1-265-1_10 L": SwitchPrefab.fork(0.0, 265.0, 26.434078, 4.75 /* added manually */), + "Rz 60E1-265-1_10 R": SwitchPrefab.fork(0.0, -265.0, 26.434078, 4.75 /* added manually */), + "Rz 60E1-300-1_9 L": SwitchPrefab.fork(300.0, 0.0, 33.231083, 0.0), + "Rz 60E1-300-1_9 R": SwitchPrefab.fork(-300.0, 0.0, 33.231083, 0.0), + "Rz 60E1-500-1_12 L": SwitchPrefab.fork(500.0, 0.0, 41.59458, 0.0), + "Rz 60E1-500-1_12 R": SwitchPrefab.fork(-500.0, 0.0, 41.59458, 0.0), + "Rz 60E1-760-1_14 L": SwitchPrefab.fork(760.0, 0.0, 54.21665, 0.0), + "Rz 60E1-760-1_14 R": SwitchPrefab.fork(-760.0, 0.0, 54.21665, 0.0), +}; -export default DefinedSwitches; \ No newline at end of file +export default DefinedSwitches; diff --git a/src/model/switch-descriptions/switch-prefab-track.js b/src/model/switch-descriptions/switch-prefab-track.js new file mode 100644 index 0000000..61808be --- /dev/null +++ b/src/model/switch-descriptions/switch-prefab-track.js @@ -0,0 +1,37 @@ +export const SwitchTrackConnectionEnd = { + PREV: Symbol('SwitchTrackConnectionEnd.PREV'), + NEXT: Symbol('SwitchTrackConnectionEnd.NEXT'), +}; + +export const SwitchTrackConnectionType = { + INTERNAL: Symbol('SwitchTrackConnectionType.INTERNAL'), + EXTERNAL: Symbol('SwitchTrackConnectionType.EXTERNAL'), +}; + +export default class SwitchPrefabTrack { + startPos; + endPos; + radius; + dataIndex; + connections; + + constructor(startPos, endPos, radius, dataIndex, connections = []) { + Object.assign(this, { + startPos, + endPos, + radius, + dataIndex, + connections, + }); + } + + static point(pos, dataIndex, connections = []) { + return new SwitchPrefabTrack( + pos, + pos, + 0, + dataIndex, + connections, + ); + } +} diff --git a/src/model/switch-descriptions/switch-prefab.js b/src/model/switch-descriptions/switch-prefab.js new file mode 100644 index 0000000..0791b76 --- /dev/null +++ b/src/model/switch-descriptions/switch-prefab.js @@ -0,0 +1,176 @@ +import Vector3 from "../vector3"; +import SwitchPrefabTrack, {SwitchTrackConnectionEnd, SwitchTrackConnectionType} from "./switch-prefab-track"; +import SceneryParserLog from "../scenery-parser-log"; + +export default class SwitchPrefab { + tracks = {}; + + constructor(tracks) { + Object.assign(this, { + tracks, + }); + this._verifyConnections(); + } + + _verifyConnections() { + // TODO: Should SceneryParserLog be used here? + Object.entries(this.tracks).forEach(([internalId, track]) => { + track.connections.forEach((connection) => { + if (connection.type === SwitchTrackConnectionType.INTERNAL) { + const otherTrack = this.tracks[connection.internalId]; + if (!otherTrack) { + SceneryParserLog.warn( + 'switchInvalidInternalConnection', + `In a switch prefab the referenced internal track ${connection.internalId} in a connection of track ${internalId} not found`, + ); + return; + } + + const reverseConnection = otherTrack.connections.find( + (otherConnection) => otherConnection.type === SwitchTrackConnectionType.INTERNAL && otherConnection.internalId === internalId, + ); + if (!reverseConnection) { + SceneryParserLog.warn( + 'switchInvalidInternalConnection', + `In a switch prefab the internal track ${internalId} is connected to ${connection.internalId} but there is not reverse connection`, + ); + return; + } + + if (reverseConnection.end !== connection.otherEnd) { + SceneryParserLog.warn( + 'switchInvalidInternalConnection', + `In a switch prefab the connection between tracks internal tracks ${internalId} and ${connection.internalId} has mismatched ends`, + ); + } + } + }); + }); + } + + static fork(radiusA, radiusB, curveLength, addedLength) { + const tracks = { + start: new SwitchPrefabTrack( + Vector3.zero(), + Vector3.zero(), + radiusA, + 0, + [ + { + type: SwitchTrackConnectionType.EXTERNAL, + end: SwitchTrackConnectionEnd.PREV, + }, + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.NEXT, + otherEnd: SwitchTrackConnectionEnd.PREV, + internalId: 'curve_a', + }, + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.NEXT, + otherEnd: SwitchTrackConnectionEnd.PREV, + internalId: 'curve_b', + }, + ], + ), + ...SwitchPrefab._createSwitchTracks( + radiusA, + curveLength, + addedLength, + 'a', + ), + ...SwitchPrefab._createSwitchTracks( + radiusB, + curveLength, + addedLength, + 'b', + ), + }; + + return new SwitchPrefab(tracks); + } + + static _createSwitchTracks(radius, curveLength, addedLength, side) { + let curveEnd; + let endAngle; + if (radius === 0) { + curveEnd = new Vector3(0, 0, curveLength); + endAngle = 0; + } else { + const circleCenter = new Vector3(-radius, 0, 0); + endAngle = -curveLength / radius; + const centerToEnd = Vector3.fromAngleY(endAngle + Math.sign(radius) * Math.PI / 2, Math.abs(radius)); + curveEnd = circleCenter.add(centerToEnd); + } + + const tracks = { + [`curve_${side}`]: new SwitchPrefabTrack( + Vector3.zero(), + curveEnd, + radius, + side === 'a' ? 1 : 2, + [ + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.PREV, + otherEnd: SwitchTrackConnectionEnd.NEXT, + internalId: 'start', + }, + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.NEXT, + otherEnd: SwitchTrackConnectionEnd.PREV, + internalId: addedLength > 0 ? `added_${side}` : `end_${side}`, + }, + ], + ), + }; + + let end = curveEnd; + if (addedLength > 0) { + end = end.add(Vector3.fromAngleY(endAngle, addedLength)); + tracks[`added_${side}`] = new SwitchPrefabTrack( + curveEnd, + end, + 0, + side === 'a' ? 3 : 4, + [ + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.PREV, + otherEnd: SwitchTrackConnectionEnd.NEXT, + internalId: `curve_${side}`, + }, + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.NEXT, + otherEnd: SwitchTrackConnectionEnd.PREV, + internalId: `end_${side}`, + }, + ], + ); + } + + tracks[`end_${side}`] = SwitchPrefabTrack.point( + end, + addedLength > 0 ? + (side === 'a' ? 5 : 6) : + (side === 'a' ? 3 : 4), + [ + { + type: SwitchTrackConnectionType.INTERNAL, + end: SwitchTrackConnectionEnd.PREV, + otherEnd: SwitchTrackConnectionEnd.NEXT, + internalId: addedLength > 0 ? `added_${side}` : `curve_${side}`, + }, + { + type: SwitchTrackConnectionType.EXTERNAL, + end: SwitchTrackConnectionEnd.NEXT, + }, + ] + ); + + return tracks; + } +} diff --git a/src/model/switch.js b/src/model/switch.js index b19cc39..22c8797 100644 --- a/src/model/switch.js +++ b/src/model/switch.js @@ -3,7 +3,7 @@ import SceneryObject from "./scenery-object.js"; import SceneryParserLog from "./scenery-parser-log.js"; import Vector3 from "./vector3.js"; import DefinedSwitches from "./defs/defined-switches.js"; -import Constants from "../helpers/constants.js"; +import {SwitchTrackConnectionEnd, SwitchTrackConnectionType} from "./switch-descriptions/switch-prefab-track"; export default class Switch extends SceneryObject { model; @@ -17,8 +17,7 @@ export default class Switch extends SceneryObject { type = "Switch"; applied = false; track_prefab_name; - trackA; - trackB; + tracks = []; def = null; constructor(id, model, pos, rot, data, id_isolation, id_switch, maxspeed, derailspeed, track_prefab_name) { @@ -64,188 +63,105 @@ export default class Switch extends SceneryObject { let def = DefinedSwitches[this.bare_model] || null; - if(!def && !Constants.parser.forceAutoSwitches) { - SceneryParserLog.warn('switchUndefinedModel', `Switch ${this.id} has an undefined model "${this.bare_model}", trying to generate auto model definition`); + if (!def) { + SceneryParserLog.warn('switchUndefinedModel', `Switch ${this.id} has an undefined model "${this.bare_model}"`); + return; } - if(!def || Constants.parser.forceAutoSwitches) { - def = this._tryGetAutoDef(scenery); - } - - if(def) { - this._applySwitchFromDef(scenery, def); - } else { - SceneryParserLog.warn('switchAutoDefFailed', `Could not generate auto definition for switch ${this.id} with model "${this.bare_model}"`); - } + this._applySwitchFromDef(scenery, def); } _applySwitchFromDef(scenery, def) { - const ids = this._getTrackIds(def[2]); - if(!ids) return; - + const trackIds = this._getTrackIds(); + if (!trackIds) return; + + const tracks = Object.entries(def.tracks).map(([key, track]) => { + return this._createSwitchTrackFromDef(scenery, def, track, trackIds) + }); + + if (tracks.some(track => !track)) return; + + this.tracks = tracks; this.def = def; - - const trackAAliases = this._getTrackAliases(ids); - this.trackA = this._createSwitchTrackFromDef(scenery, this.id+"A", def[0], ids[0][1], ids[2][1], def[3], def[5], trackAAliases); - - const trackBAliases = this._getTrackAliases(ids, 1, trackAAliases); - this.trackB = this._createSwitchTrackFromDef(scenery, this.id+"B", def[1], ids[1][1], ids[3][1], def[4], def[6], trackBAliases); - this.trackB.hide_isolation = true; // hide isolation for the second track } - _getTrackAliases(ids, startingId = 0, exclude = []) { - const aliases = new Set(); - for(let i = startingId; i < ids.length; i+=2) { - aliases.add(ids[i][0]); + _getTrackIds() { + const ids = this.data + .split(",") + .filter(part => part.trim() !== '') + .map( + (value) => value.split(":").map((part) => part.trim()), + ); + if (ids.some((part) => part.length !== 3)) { + SceneryParserLog.warn('switchInvalidDataFormat', `Switch ${this.id} has invalid data: ${this.data}`); } - - exclude.forEach(alias => { - aliases.delete(alias); - }); - - return Array.from(aliases); + return ids; } - _getTrackIds(outs) { - const dataValues = this.data.split(","); - const isCrossing = outs.length === 2; - if(isCrossing) outs = [outs[0], outs[1], outs[0], outs[1]]; - - return outs.map((out, index) => { - const parts = dataValues[out]?.split(":"); - if(parts.length !== 3) { - SceneryParserLog.warn('switchInvalidDataFormat', `Switch ${this.id} has invalid data: ${this.data}`); - return null; - } - const trackId = parts[0].trim(); - let connectedId = parts[1].trim() || parts[2].trim() || null; - if(isCrossing) connectedId = parts[~~(index / 2) + 1].trim(); - - return [trackId, connectedId]; - }); - } - - _createSwitchTrackFromDef(scenery, id, r, previd, nextid, startPos, endPos, aliases = []) { + _createSwitchTrackFromDef(scenery, switchDef, trackDef, ids) { const rotRad = this.rot.multiply(Math.PI / 180); + if (trackDef.dataIndex >= ids.length) { + SceneryParserLog.warn( + 'switchMissingTrackId', + `Switch ${this.id} with model ${this.bare_model} is missing an id for the track at index ${trackDef.dataIndex}`, + ); + return null; + } + const [trackId, prevId, nextId] = ids[trackDef.dataIndex]; + + const endIds = { + [SwitchTrackConnectionEnd.PREV]: [], + [SwitchTrackConnectionEnd.NEXT]: [], + }; + trackDef.connections.forEach((connection) => { + if (connection.type === SwitchTrackConnectionType.INTERNAL) { + const otherTrackDef = switchDef.tracks[connection.internalId]; + if (!otherTrackDef) { + SceneryParserLog.warn( + 'switchMissingTrackId', + `Switch prefab for model with model ${this.bare_model} of track ${this.id} does not have the internal track ${connection.internalId}`, + ); + return; + } + if (otherTrackDef.dataIndex >= ids.length) { + SceneryParserLog.warn( + 'switchMissingTrackId', + `Switch ${this.id} with model ${this.bare_model} is missing an id for the track at index ${otherTrackDef.dataIndex}`, + ); + return; + } + const otherTrackId = ids[otherTrackDef.dataIndex][0]; + if (otherTrackId) { + endIds[connection.end].push(otherTrackId); + } + } else if (connection.type === SwitchTrackConnectionType.EXTERNAL) { + const otherTrackId = connection.end === SwitchTrackConnectionEnd.PREV ? prevId : nextId; + if (otherTrackId) { + endIds[connection.end].push(otherTrackId); + } + } + }); const trackObj = new PointTrack( - id, - this.pos.add(startPos.rotate(rotRad)), - this.pos.add(endPos.rotate(rotRad)), - r, - nextid, - previd, - this.id_switch, + trackId, + this.pos.add(trackDef.startPos.rotate(rotRad)), + this.pos.add(trackDef.endPos.rotate(rotRad)), + trackDef.radius, + endIds[SwitchTrackConnectionEnd.PREV][0], // TODO: Pass the array + endIds[SwitchTrackConnectionEnd.NEXT][0], // TODO: --||-- + this.id_switch, 0, // start_slope 0, // end_slope - this.id_isolation, + this.id_isolation, this.track_prefab_name, - this.maxspeed, + this.maxspeed, this.derailspeed ); trackObj.switch = this; scenery.addObject(trackObj); - aliases.forEach(alias => { - scenery.addTrackAlias(id, alias); - }); + scenery.addTrackAlias(trackId, trackId); return trackObj; } - - _tryGetAutoDef(scenery) { - const outs = Switch.autoGetOutsFromData(this.data); - if(!outs) return null; - - const radiuses = Switch.autoGetRadiusesFromModel(this.bare_model); - if(!radiuses) return null; - const [ra, rb] = radiuses; - - const ids = this._getTrackIds(outs); - if(!ids) return null; - - const trackPoints = ids.map(idsVal => - this._autoFindClosestTrackEnd(scenery, idsVal[1]) - ); - - if(trackPoints.length !== 4 || trackPoints.some(point => !point)) return null; - - const rotRadNeg = this.rot.multiply(-Math.PI / 180); - const transformedPoints = trackPoints.map(point => point.sub(this.pos).rotate(rotRadNeg).toPrecision(3)); - - const newDef = [ - ra, - rb, - outs, - ...transformedPoints - ]; - - if(!DefinedSwitches[this.bare_model]) DefinedSwitches[this.bare_model] = newDef; - if(Constants.parser.logNewAutoSwitches) console.log(this.bare_model, newDef); - return newDef; - } - - static autoGetOutsFromData(data) { - const tracks = data.split(","); - - if(tracks.length === 3) return [0, 1]; // Crossing - - if(tracks.length < 4) { - SceneryParserLog.warn('switchInvalidDataFormat', `Switch data "${data}" is invalid, expected at least 4 tracks`); - return null; - } - - const outs = []; - tracks.forEach((ct, i) => { - const ctv = ct.split(":"); - outs.push(ctv[1] || ctv[2]); - }); - - return [ - 0, - outs[1] ? 1 : 0, // if no second track, use first track - outs[2] ? 2 : (outs[3] ? 3 : 5), // if no third track, use fourth or sixth track - outs[4] ? 4 : (outs[6] ? 6 : 3) // if no fourth track, use sixth or third track - ]; - } - - static autoGetRadiusesFromModel(model) { - const bareModel = (model.split(',')[0] || model).trim(); - if(/Rkp|Crossing/.test(bareModel)) return [0, 0]; - const right = bareModel.at(-1) === "R"; - const [prefix, rText, rldsR2Text] = bareModel.split("-"); - const r = parseFloat(rText) || 0; - const [r1, r2] = rText.split('_').map(value => parseFloat(value) || 0); - - switch(prefix) { - case 'Rz 60E1': - return [0, right ? -r : r]; - case 'Rld 60E1': - return right ? [r1, -r2] : [-r1, r2]; - case 'Rlds 60E1': - const rldsR2 = parseFloat(rldsR2Text) || 0; - return [-r1, rldsR2]; - case 'Rlj 60E1': - return right ? [-r1, -r2] : [r1, r2]; - default: - SceneryParserLog.warn('switchCannotResolveModel', `Switch model ${model} cannot be auto-resolved to radiuses`); - return null; - } - } - - _autoFindClosestTrackEnd(scenery, trackId) { - if(!trackId) { - SceneryParserLog.warn('switchInvalidTrackConnection', `Switch ${this.id}, trackId of one of the required connections is empty`); - return null; - } - - const track = scenery.getObject("tracks", trackId); - - if(!track) { - SceneryParserLog.warn('switchInvalidTrackConnection', `Switch ${this.id}, track ${trackId} that the switch connects to not found`); - return null; - } - - return track.getCloserEndPos(this.pos); - } }