diff --git a/src/components/SettingsManager.js b/src/components/SettingsManager.js
index bac1464..98a9339 100644
--- a/src/components/SettingsManager.js
+++ b/src/components/SettingsManager.js
@@ -4,6 +4,7 @@ import Constants from "../helpers/constants";
export default function SettingsManager(props) {
const [ layers, setLayers ] = useState([]);
+ const [ trackColorMode, setTrackColorMode ] = useState(Constants.trackColorModes[0].id);
const [ settingsLoaded, setSettingsLoaded ] = useState(false);
const loadLayersSettings = useCallback(() => {
@@ -22,7 +23,8 @@ export default function SettingsManager(props) {
return (
{ props.children }
diff --git a/src/components/map/Map.css b/src/components/map/Map.css
index c32c2e8..66fe93d 100644
--- a/src/components/map/Map.css
+++ b/src/components/map/Map.css
@@ -5,7 +5,6 @@
.map svg path.track {
stroke-width: 1.44px;
- stroke: #aaa;
}
.map svg text {
diff --git a/src/components/map/object-renderers/TrackRenderer.js b/src/components/map/object-renderers/TrackRenderer.js
index a3c4666..2d0c03f 100644
--- a/src/components/map/object-renderers/TrackRenderer.js
+++ b/src/components/map/object-renderers/TrackRenderer.js
@@ -1,67 +1,101 @@
-
+import { useContext } from "react";
+import SettingsContext from "../../../contexts/SettingsContext";
import Constants from "../../../helpers/constants";
export default function TrackRenderer(props) {
- const { object } = props;
+ const { object } = props;
+ const { trackColorMode } = useContext(SettingsContext);
+ const path = getTrackPath(object);
+ const color = getTrackColor(object, trackColorMode);
+ const defs = getTrackDefs(object, trackColorMode);
+
+ return (
+
+ {defs}
+
+
+ );
+}
+
+function getTrackPath(object) {
switch (object.type) {
case "StandardTrack":
- case "PointTrack":
- return ;
+ case "PointTrack":
+ const [x1, y1] = object.points.start.toSVGCoords();
+ const [x2, y2] = object.points.end.toSVGCoords();
+ const ra = Math.abs(object.r);
+ if (object.r < 0) {
+ return `M${x1},${y1} A${ra} ${ra} 0 0 1 ${x2},${y2}`;
+ } else if (object.r > 0) {
+ return `M${x2},${y2} A${ra} ${ra} 0 0 1 ${x1},${y1}`;
+ } else {
+ return `M${x1},${y1} L${x2},${y2}`;
+ }
case "BezierTrack":
- return ;
+ const [bx1, by1] = object.points.start.toSVGCoords();
+ const [bcx1, bcy1] = object.points.control1.toSVGCoords();
+ const [bx2, by2] = object.points.end.toSVGCoords();
+ const [bcx2, bcy2] = object.points.control2.toSVGCoords();
+ return `M${bx1},${by1} C${bcx1},${bcy1} ${bcx2},${bcy2} ${bx2},${by2}`;
default:
- console.warn(`No renderer component for track type: ${object.type}`);
- return null;
+ console.warn(`TrackRenderer: Unsupported track type: ${object.type}`);
}
}
-function StandardTrackR(props) {
- const { object } = props;
+function getTrackColor(object, trackColorMode) {
+ switch (trackColorMode) {
+ case "none":
+ default:
+ return "#aaa";
+
+ case "type":
+ switch (object.type) {
+ case "StandardTrack":
+ default:
+ return "#00a";
+ case "PointTrack":
+ return "#0a0";
+ case "BezierTrack":
+ return "#aa8";
+ }
+ case "slope":
+ return `url(#track-slope-${object.id})`;
+ }
+}
+
+function getTrackDefs(object, trackColorMode) {
+ if (trackColorMode !== "slope") return null;
+
const [x1, y1] = object.points.start.toSVGCoords();
const [x2, y2] = object.points.end.toSVGCoords();
- const ra = Math.abs(object.r);
-
- let d;
- if (object.r < 0) {
- d = `M${x1},${y1} A${ra} ${ra} 0 0 1 ${x2},${y2}`;
- } else if (object.r > 0) {
- d = `M${x2},${y2} A${ra} ${ra} 0 0 1 ${x1},${y1}`;
- } else {
- d = `M${x1},${y1} L${x2},${y2}`;
- }
-
- const color = Constants.map.useTrackColors ? (
- object.r === 0 ? "rgb(0, 255, 255)" : "rgb(0, 0, 255)"
- ) : undefined;
-
+ const gradId = `track-slope-${object.id}`;
+ const startColor = getSlopeColor(object.start_slope);
+ const endColor = getSlopeColor(object.end_slope);
+
return (
-
+
+
+
+
+
+
);
}
-function BezierTrackR(props) {
- const { object } = props;
-
- const [x1, y1] = object.points.start.toSVGCoords();
- const [cx1, cy1] = object.points.control1.toSVGCoords();
- const [x2, y2] = object.points.end.toSVGCoords();
- const [cx2, cy2] = object.points.control2.toSVGCoords();
-
- const d = `M${x1},${y1} C${cx1},${cy1} ${cx2},${cy2} ${x2},${y2}`;
- const color = Constants.map.useTrackColors ? "rgb(0, 255, 0)" : undefined;
-
- return (
-
- );
-}
+function getSlopeColor(slope) {
+ const blue = Math.min(255, Math.max(0, 128 + Math.abs(slope * Constants.map.trackSlopeScale)));
+ return `rgb(128, 128, ${blue})`;
+}
\ No newline at end of file
diff --git a/src/components/sidemenu/SelTrackColorMode.js b/src/components/sidemenu/SelTrackColorMode.js
new file mode 100644
index 0000000..20eb420
--- /dev/null
+++ b/src/components/sidemenu/SelTrackColorMode.js
@@ -0,0 +1,28 @@
+import { useContext } from "react";
+import SettingsContext from "../../contexts/SettingsContext";
+import Constants from "../../helpers/constants";
+
+export default function SelTrackColorMode(props) {
+ const { trackColorMode, setTrackColorMode } = useContext(SettingsContext);
+
+ const handleColorModeChange = (event) => {
+ setTrackColorMode(event.target.value);
+ };
+
+ return (
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/sidemenu/SideMenu.js b/src/components/sidemenu/SideMenu.js
index 0416e28..a9d6c63 100644
--- a/src/components/sidemenu/SideMenu.js
+++ b/src/components/sidemenu/SideMenu.js
@@ -2,6 +2,7 @@ import {useContext} from 'react';
import MainContext from '../../contexts/MainContext';
import './SideMenu.css';
import LayersMenu from './LayersMenu';
+import SelTrackColorMode from './SelTrackColorMode';
export default function SideMenu() {
const { sideMenuOpen } = useContext(MainContext);
@@ -14,6 +15,7 @@ export default function SideMenu() {
);
diff --git a/src/helpers/constants.js b/src/helpers/constants.js
index 8e889f0..da022e1 100644
--- a/src/helpers/constants.js
+++ b/src/helpers/constants.js
@@ -1,7 +1,7 @@
const Constants = {
map: {
- useTrackColors: false,
zoomSensitivity: 0.002,
+ trackSlopeScale: 10,
},
warnings: {
all: false, // enable all warnings
@@ -41,6 +41,20 @@ const Constants = {
name: 'Routes',
default: true,
}
+ ],
+ trackColorModes: [
+ {
+ id: 'none',
+ name: 'None',
+ },
+ {
+ id: 'type',
+ name: 'Type',
+ },
+ {
+ id: 'slope',
+ name: 'Slope'
+ }
]
};
diff --git a/src/model/bezier-track.js b/src/model/bezier-track.js
index a07fd0e..c51d952 100644
--- a/src/model/bezier-track.js
+++ b/src/model/bezier-track.js
@@ -11,8 +11,8 @@ export default class BezierTrack extends Track
control2: Vector3.zero()
};
- constructor(id, start, control1, end, control2, rot, len, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed) {
- super(id, start, rot, len, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed);
+ constructor(id, start, control1, end, control2, rot, len, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed) {
+ super(id, start, rot, len, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed);
Object.assign(this.points, {
start,
@@ -37,6 +37,7 @@ export default class BezierTrack extends Track
values[15], // previd
values[16], // nextid
values[17], // id_station
+ ...Track.slopesFromText(values[18]), // start_slope, end_slope
values[21], // id_isolation
parseFloat(values[24]), // maxspeed
parseFloat(values[25]) // derailspeed
diff --git a/src/model/point-track.js b/src/model/point-track.js
index 0f8e999..6f14d2b 100644
--- a/src/model/point-track.js
+++ b/src/model/point-track.js
@@ -10,12 +10,12 @@ export default class PointTrack extends Track
end: Vector3.zero()
};
- constructor(id, start, end, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed) {
+ constructor(id, start, end, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed) {
const ry = AngleHelper.radToDeg(start.atanY(end));
const rot = new Vector3(0, ry, 0);
// TODO: fix rx and rz = 0
// TODO: calculate length
- super(id, start, rot, null, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed);
+ super(id, start, rot, null, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed);
Object.assign(this.points, {
start, end
diff --git a/src/model/standard-track.js b/src/model/standard-track.js
index 5aa654a..d523c41 100644
--- a/src/model/standard-track.js
+++ b/src/model/standard-track.js
@@ -11,8 +11,8 @@ export default class StandardTrack extends Track
circleCenter: Vector3.zero()
};
- constructor(id, start, rot, len, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed) {
- super(id, start, rot, len, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed);
+ constructor(id, start, rot, len, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed) {
+ super(id, start, rot, len, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed);
this._calcPoints();
}
@@ -27,6 +27,7 @@ export default class StandardTrack extends Track
values[11], // previd
values[12], // nextid
values[13], // id_station
+ ...Track.slopesFromText(values[14]), // start_slope, end_slope
values[17], // id_isolation
parseFloat(values[20]), // maxspeed
parseFloat(values[21]) // derailspeed
@@ -48,5 +49,13 @@ export default class StandardTrack extends Track
const endAngle = centerAngle - this.len / this.r;
this.points.end = this.points.circleCenter.add(Vector3.fromAngleY(endAngle, this.r));
}
+
+ // adjust end point by the slope
+ if (this.end_slope !== 0) {
+ const startHeightDiff = this.start_slope * this.len / 1000;
+ const endHeightDiff = this.end_slope * this.len / 1000;
+
+ this.points.end.y += startHeightDiff + (endHeightDiff - startHeightDiff) / 2;
+ }
}
}
diff --git a/src/model/switch.js b/src/model/switch.js
index 1d41187..dd83370 100644
--- a/src/model/switch.js
+++ b/src/model/switch.js
@@ -122,6 +122,8 @@ export default class Switch extends SceneryObject {
from,
to,
this.id_switch,
+ 0, // start_slope
+ 0, // end_slope
this.id_isolation,
this.maxspeed,
this.derailspeed
diff --git a/src/model/track.js b/src/model/track.js
index 8f3c619..c078dbf 100644
--- a/src/model/track.js
+++ b/src/model/track.js
@@ -9,17 +9,27 @@ export default class Track extends SceneryObject {
derailspeed;
category = "tracks";
type = "Track";
- outs = [];
+ previd;
+ nextid;
+ prevTrack = null;
+ nextTrack = null;
+ start_slope;
+ end_slope;
- constructor(id, pos, rot, len, r, previd, nextid, id_station, id_isolation, maxspeed, derailspeed) {
+ constructor(id, pos, rot, len, r, previd, nextid, id_station, start_slope, end_slope, id_isolation, maxspeed, derailspeed) {
super(id, pos, rot);
Object.assign(this, {
len, r,
- id_station, id_isolation,
+ previd, nextid,
+ id_station,
+ start_slope, end_slope,
+ id_isolation,
maxspeed, derailspeed
});
+ }
- this.outs = [previd, nextid];
+ static slopesFromText(text) {
+ return text.split(",", 2);
}
getCloserEndPos(pos) {