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];
|
return modeDef.options[modeDef.optionDefault][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
case "max-speed":
|
case "maxspeed":
|
||||||
if (!object.maxspeed) {
|
if (!object.maxspeed) {
|
||||||
if (object.type === 'RouteTrack') return modeDef.options['unknown'][0];
|
if (object.type === 'RouteTrack') return modeDef.options['unknown'][0];
|
||||||
return modeDef.options['derail'][0];
|
return modeDef.options['derail'][0];
|
||||||
|
|||||||
@ -5,28 +5,29 @@ import SceneryContext from "./SceneryContext";
|
|||||||
const GradientsContext = createContext();
|
const GradientsContext = createContext();
|
||||||
export default GradientsContext;
|
export default GradientsContext;
|
||||||
|
|
||||||
function getMinMax(trackColorMode, scenery) {
|
function getMinMax(trackColorMode, scenery, gradient) {
|
||||||
if (trackColorMode === 'elevation') {
|
const sceneryGradientBounds = scenery?.dynamicGradientBounds?.[trackColorMode];
|
||||||
if (!scenery) return null;
|
if (!sceneryGradientBounds) return null;
|
||||||
if (scenery.trackElevationBounds.minY > scenery.trackElevationBounds.maxY) return null;
|
|
||||||
|
|
||||||
const min = scenery.trackElevationBounds.minY;
|
if (sceneryGradientBounds.min > sceneryGradientBounds.max) return null;
|
||||||
// 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];
|
const min = Math.max(sceneryGradientBounds.min, gradient.limitMin ?? -Infinity);
|
||||||
}
|
const initialMax = Math.min(sceneryGradientBounds.max, gradient.limitMax ?? Infinity);
|
||||||
return null;
|
let diff = Math.max(initialMax - min, 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGradientSettings(trackColorMode, scenery, def) {
|
function createGradientSettings(trackColorMode, scenery, def) {
|
||||||
if ('gradient' in def) return def.gradient;
|
if ('gradient' in def) return def.gradient;
|
||||||
if ('dynamicGradient' in def) {
|
if ('dynamicGradient' in def) {
|
||||||
const gradient = def.dynamicGradient;
|
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 diff = gradient.min.map((min, i) => {
|
||||||
const max = gradient.max[i];
|
const max = gradient.max[i];
|
||||||
|
|||||||
@ -176,29 +176,30 @@ const Constants = {
|
|||||||
'slope': {
|
'slope': {
|
||||||
name: 'Slope',
|
name: 'Slope',
|
||||||
type: 'gradient',
|
type: 'gradient',
|
||||||
gradient: {
|
dynamicGradient: {
|
||||||
base: [128, 0, 128],
|
min: [128, 0, 128],
|
||||||
diff: [0, 25.6, 0],
|
max: [128, 255, 128],
|
||||||
legendMin: 0,
|
defaultMin: 0,
|
||||||
legendMax: 10,
|
defaultMax: 10,
|
||||||
|
limitMax: 40,
|
||||||
unit: '‰',
|
unit: '‰',
|
||||||
startLegendAt0: false,
|
startLegendAt0: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'max-speed': {
|
'maxspeed': {
|
||||||
name: 'Max speed',
|
name: 'Max speed',
|
||||||
type: 'gradient',
|
type: 'gradient',
|
||||||
gradient: {
|
dynamicGradient: {
|
||||||
base: [128, 0, 128],
|
min: [128, 0, 0],
|
||||||
diff: [0, 1.5, 0],
|
max: [128, 255, 128],
|
||||||
legendMin: 0,
|
defaultMin: 0,
|
||||||
legendMax: 170,
|
defaultMax: 170,
|
||||||
unit: 'km/h',
|
unit: 'km/h',
|
||||||
startLegendAt0: false,
|
startLegendAt0: false,
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
'derail': ['#f22', 'Derail track'],
|
'derail': ['#f22', 'Derail track'],
|
||||||
'unknown': ['#aaa', 'Unknown speed'],
|
'unknown': ['#f88', 'Unknown speed'],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'elevation': {
|
'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 { ElectrificationResolutionStatus } from './electrification-status.js';
|
||||||
|
import DynamicGradientBoundsItem from './dynamic-gradient-bounds-item.js';
|
||||||
|
|
||||||
export default class Scenery
|
export default class Scenery
|
||||||
{
|
{
|
||||||
@ -6,7 +7,11 @@ export default class Scenery
|
|||||||
signalBoxes = [];
|
signalBoxes = [];
|
||||||
spawnPoints = [];
|
spawnPoints = [];
|
||||||
bounds = { minX: Infinity, minZ: Infinity, maxX: -Infinity, maxZ: -Infinity };
|
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;
|
electrificationResolved = ElectrificationResolutionStatus.NOT_RESOLVED;
|
||||||
|
|
||||||
getName() {
|
getName() {
|
||||||
@ -38,7 +43,7 @@ export default class Scenery
|
|||||||
this._updateBounds(object.getRenderBounds());
|
this._updateBounds(object.getRenderBounds());
|
||||||
}
|
}
|
||||||
if (object.category === 'tracks') {
|
if (object.category === 'tracks') {
|
||||||
this._updateTrackElevationBounds(object);
|
this._updateDynamicGradientBounds(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,10 +97,13 @@ export default class Scenery
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateTrackElevationBounds(object) {
|
_updateDynamicGradientBounds(trackObject) {
|
||||||
[object.points.start, object.points.end].forEach(point => {
|
[trackObject.points.start, trackObject.points.end].forEach(point => {
|
||||||
if (point.y < this.trackElevationBounds.minY) this.trackElevationBounds.minY = point.y;
|
this.dynamicGradientBounds.elevation.update(point.y);
|
||||||
if (point.y > this.trackElevationBounds.maxY) this.trackElevationBounds.maxY = 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