Extend dynamic gradients
- Generalized dynamic gradient processing - Updated max-speed gradient internal name to maxspeed - Updated "Max speed" and "Slope" gradients to be dynamic
This commit is contained in:
parent
3ed1fbe9b7
commit
3a242bb8ad
@ -186,7 +186,7 @@ function getTrackColor(object, trackColorMode, gradientDef) {
|
||||
return modeDef.options[modeDef.optionDefault][0];
|
||||
}
|
||||
|
||||
case "max-speed":
|
||||
case "maxspeed":
|
||||
if (!object.maxspeed) {
|
||||
if (object.type === 'RouteTrack') return modeDef.options['unknown'][0];
|
||||
return modeDef.options['derail'][0];
|
||||
|
||||
@ -5,28 +5,29 @@ import SceneryContext from "./SceneryContext";
|
||||
const GradientsContext = createContext();
|
||||
export default GradientsContext;
|
||||
|
||||
function getMinMax(trackColorMode, scenery) {
|
||||
if (trackColorMode === 'elevation') {
|
||||
if (!scenery) return null;
|
||||
if (scenery.trackElevationBounds.minY > scenery.trackElevationBounds.maxY) return null;
|
||||
function getMinMax(trackColorMode, scenery, gradient) {
|
||||
const sceneryGradientBounds = scenery?.dynamicGradientBounds?.[trackColorMode];
|
||||
if (!sceneryGradientBounds) return null;
|
||||
|
||||
if (sceneryGradientBounds.min > sceneryGradientBounds.max) return null;
|
||||
|
||||
const min = Math.max(sceneryGradientBounds.min, gradient.limitMin ?? -Infinity);
|
||||
const initialMax = Math.min(sceneryGradientBounds.max, gradient.limitMax ?? Infinity);
|
||||
let diff = Math.max(initialMax - min, 1);
|
||||
|
||||
const min = scenery.trackElevationBounds.minY;
|
||||
// Make sure diff > 0 even on flat sceneries
|
||||
let diff = Math.max(scenery.trackElevationBounds.maxY - scenery.trackElevationBounds.minY, 1);
|
||||
// Ensure `diff` is even so that the min, max and middle legend values are integers
|
||||
diff = Math.ceil(diff / 2)*2;
|
||||
const max = min + diff;
|
||||
|
||||
return [min, max];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function createGradientSettings(trackColorMode, scenery, def) {
|
||||
if ('gradient' in def) return def.gradient;
|
||||
if ('dynamicGradient' in def) {
|
||||
const gradient = def.dynamicGradient;
|
||||
const [minValue, maxValue] = getMinMax(trackColorMode, scenery) ?? [gradient.defaultMin, gradient.defaultMax];
|
||||
const [minValue, maxValue] = getMinMax(trackColorMode, scenery, gradient)
|
||||
?? [gradient.defaultMin, gradient.defaultMax];
|
||||
|
||||
const diff = gradient.min.map((min, i) => {
|
||||
const max = gradient.max[i];
|
||||
|
||||
@ -176,29 +176,30 @@ const Constants = {
|
||||
'slope': {
|
||||
name: 'Slope',
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
base: [128, 0, 128],
|
||||
diff: [0, 25.6, 0],
|
||||
legendMin: 0,
|
||||
legendMax: 10,
|
||||
dynamicGradient: {
|
||||
min: [128, 0, 128],
|
||||
max: [128, 255, 128],
|
||||
defaultMin: 0,
|
||||
defaultMax: 10,
|
||||
limitMax: 40,
|
||||
unit: '‰',
|
||||
startLegendAt0: false,
|
||||
}
|
||||
},
|
||||
'max-speed': {
|
||||
'maxspeed': {
|
||||
name: 'Max speed',
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
base: [128, 0, 128],
|
||||
diff: [0, 1.5, 0],
|
||||
legendMin: 0,
|
||||
legendMax: 170,
|
||||
dynamicGradient: {
|
||||
min: [128, 0, 0],
|
||||
max: [128, 255, 128],
|
||||
defaultMin: 0,
|
||||
defaultMax: 170,
|
||||
unit: 'km/h',
|
||||
startLegendAt0: false,
|
||||
},
|
||||
options: {
|
||||
'derail': ['#f22', 'Derail track'],
|
||||
'unknown': ['#aaa', 'Unknown speed'],
|
||||
'unknown': ['#f88', 'Unknown speed'],
|
||||
}
|
||||
},
|
||||
'elevation': {
|
||||
|
||||
16
src/model/dynamic-gradient-bounds-item.js
Normal file
16
src/model/dynamic-gradient-bounds-item.js
Normal file
@ -0,0 +1,16 @@
|
||||
export default class DynamicGradientBoundsItem {
|
||||
min;
|
||||
max;
|
||||
startsAtZero;
|
||||
|
||||
constructor(startsAtZero) {
|
||||
this.min = startsAtZero ? 0 : Infinity;
|
||||
this.max = -Infinity;
|
||||
this.startsAtZero = startsAtZero;
|
||||
}
|
||||
|
||||
update(value) {
|
||||
if (!this.startsAtZero && value < this.min) this.min = value;
|
||||
if (value > this.max) this.max = value;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import { ElectrificationResolutionStatus } from './electrification-status.js';
|
||||
import DynamicGradientBoundsItem from './dynamic-gradient-bounds-item.js';
|
||||
|
||||
export default class Scenery
|
||||
{
|
||||
@ -6,7 +7,11 @@ export default class Scenery
|
||||
signalBoxes = [];
|
||||
spawnPoints = [];
|
||||
bounds = { minX: Infinity, minZ: Infinity, maxX: -Infinity, maxZ: -Infinity };
|
||||
trackElevationBounds = { minY: Infinity, maxY: -Infinity };
|
||||
dynamicGradientBounds = {
|
||||
elevation: new DynamicGradientBoundsItem(),
|
||||
slope: new DynamicGradientBoundsItem(true),
|
||||
maxspeed: new DynamicGradientBoundsItem(true)
|
||||
};
|
||||
electrificationResolved = ElectrificationResolutionStatus.NOT_RESOLVED;
|
||||
|
||||
getName() {
|
||||
@ -38,7 +43,7 @@ export default class Scenery
|
||||
this._updateBounds(object.getRenderBounds());
|
||||
}
|
||||
if (object.category === 'tracks') {
|
||||
this._updateTrackElevationBounds(object);
|
||||
this._updateDynamicGradientBounds(object);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,10 +97,13 @@ export default class Scenery
|
||||
});
|
||||
}
|
||||
|
||||
_updateTrackElevationBounds(object) {
|
||||
[object.points.start, object.points.end].forEach(point => {
|
||||
if (point.y < this.trackElevationBounds.minY) this.trackElevationBounds.minY = point.y;
|
||||
if (point.y > this.trackElevationBounds.maxY) this.trackElevationBounds.maxY = point.y;
|
||||
_updateDynamicGradientBounds(trackObject) {
|
||||
[trackObject.points.start, trackObject.points.end].forEach(point => {
|
||||
this.dynamicGradientBounds.elevation.update(point.y);
|
||||
})
|
||||
|
||||
this.dynamicGradientBounds.maxspeed.update(trackObject.maxspeed);
|
||||
this.dynamicGradientBounds.slope.update(trackObject.start_slope);
|
||||
this.dynamicGradientBounds.slope.update(trackObject.end_slope);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user