Added signal bars extended renderer

+ExtendedSignalRenderer now also draws signal bars
+ExtendedSignalRenderer  automatically adjusts pole height based on the number of bars and head offset
*Tweaked pole rendering in the ExtendedSignalRenderer
*Signals are now back higher in the rendering queue than signs
*Extended signals no longer have transparent backgrounds
*Fixed missing constants related to signs attaching
This commit is contained in:
izawartka 2025-06-27 18:17:47 +02:00
parent 2d655676c9
commit 7bf3f24fe3
4 changed files with 75 additions and 12 deletions

View File

@ -53,6 +53,10 @@
stroke: #eee; stroke: #eee;
} }
.map svg g.extended-signal-icon g path.background {
fill: #111;
}
.map svg g.route g { .map svg g.route g {
fill: #eee; fill: #eee;
} }

View File

@ -42,6 +42,13 @@ const ObjectRendererQueue = [
'renderer': DerailerRenderer, 'renderer': DerailerRenderer,
'cond': (layers) => layers['derailers'] 'cond': (layers) => layers['derailers']
}, },
{
'name': 'signs',
'category': 'track-objects',
'type': 'Sign',
'renderer': SignRenderer,
'cond': (layers) => layers['signs']
},
{ {
'name': 'nevps', 'name': 'nevps',
'category': 'track-objects', 'category': 'track-objects',
@ -56,13 +63,6 @@ const ObjectRendererQueue = [
'renderer': SignalRenderer, 'renderer': SignalRenderer,
'cond': (layers) => layers['signals'] 'cond': (layers) => layers['signals']
}, },
{
'name': 'signs',
'category': 'track-objects',
'type': 'Sign',
'renderer': SignRenderer,
'cond': (layers) => layers['signs']
},
{ {
'name': 'spawn-points', 'name': 'spawn-points',
'category': 'track-objects', 'category': 'track-objects',

View File

@ -29,12 +29,13 @@ function SignalIcon(props) {
const halfBaseWidth = getHalfBaseWidth(object); const halfBaseWidth = getHalfBaseWidth(object);
const headOff = getHeadOffset(object); const headOff = getHeadOffset(object);
const poleLength = getPoleLength(object); const poleLength = getPoleLength(object, headOff);
return ( return (
<g strokeWidth={0.2} strokeLinecap="round" strokeLinejoin="round"> <g strokeWidth={0.2} strokeLinecap="round" strokeLinejoin="round">
{ getBase(halfBaseWidth) } { getBase(halfBaseWidth) }
{ getPole(poleLength, headOff) } { getPole(poleLength, headOff) }
{ getBars(object, poleLength, headOff) }
{ getHead(object, poleLength, headOff) } { getHead(object, poleLength, headOff) }
</g> </g>
); );
@ -76,17 +77,36 @@ function getHeadOffset(object) {
} }
} }
function getPoleLength(object) { function getPoleLength(object, headOff) {
const headPos = object.signal_elements.headPosition; const headPos = object.signal_elements.headPosition;
if(headPos === SignalElementsEnums.HeadPosition.NO_POLE) return 0; if(headPos === SignalElementsEnums.HeadPosition.NO_POLE) return 0;
return 2;
let length = 0.8;
if(headOff !== 0) {
length += 0.4;
}
switch(object.signal_elements.bar) {
case SignalElementsEnums.BarType.YELLOW:
case SignalElementsEnums.BarType.GREEN:
length += 1.0;
break;
case SignalElementsEnums.BarType.YELLOW_GREEN:
length += 1.8;
break;
default:
break;
}
return Math.max(length, 2);
} }
function getPole(poleLength, headOff) { function getPole(poleLength, headOff) {
if(!poleLength) return null; if(!poleLength) return null;
if(headOff) { if(headOff) {
return <path d={`M 0 0 L 0 -${poleLength - .5} L ${headOff} -${poleLength -.5} L ${headOff} -${poleLength}`} />; return <path d={`M 0 0 L 0 -${poleLength - .4} L ${headOff} -${poleLength -.4} L ${headOff} -${poleLength}`} />;
} }
return <path d={`M 0 0 L 0 -${poleLength}`} />; return <path d={`M 0 0 L 0 -${poleLength}`} />;
@ -96,7 +116,7 @@ function getUnit(key, unitType, x, y) {
const r = 0.6; const r = 0.6;
const c = 0.4; const c = 0.4;
const baseCircle = <circle cx={x} cy={y} r={r} />; const baseCircle = <circle cx={x} cy={y} r={r} className='background' />;
switch(unitType) { switch(unitType) {
case SignalElementsEnums.UnitType.RED: case SignalElementsEnums.UnitType.RED:
@ -175,3 +195,35 @@ function getHeadTOP(object, poleLength) {
{ getUnit(3, SignalElementsEnums.UnitType.YELLOW_LOWER, whiteCX, -poleLength-r) } { getUnit(3, SignalElementsEnums.UnitType.YELLOW_LOWER, whiteCX, -poleLength-r) }
</> </>
} }
function getBar(object, headOff, y, isYellow, key = 0) {
const yellowOff = isYellow ? 0.2 : 0;
return <g key={key}>
<rect x={headOff-0.6} y={y-0.2} width={1.2} height={0.4} className='background' />;
<line x1={headOff - yellowOff} y1={y-0.2} x2={headOff + yellowOff} y2={y+0.2} />;
</g>
}
function getBars(object, poleLength, headOff) {
const barType = object.signal_elements.bar;
const headOffOffset = headOff !== 0 ? 0.4 : 0;
const y = -poleLength + headOffOffset + 0.6;
if(barType === SignalElementsEnums.BarType.NONE) return null;
switch(barType) {
case SignalElementsEnums.BarType.NONE:
default:
return null;
case SignalElementsEnums.BarType.YELLOW:
return getBar(object, 0, y, true);
case SignalElementsEnums.BarType.GREEN:
return getBar(object, 0, y, false);
case SignalElementsEnums.BarType.YELLOW_GREEN:
return <>
{ getBar(object, 0, y, false, 0) }
{ getBar(object, 0, y + 0.8, true, 1) }
</>
}
}

View File

@ -13,6 +13,12 @@ const Constants = {
runTracksConnectionTest: false, runTracksConnectionTest: false,
resolveElectrification: true, resolveElectrification: true,
maxRouteConnectionDistance: 0.2, maxRouteConnectionDistance: 0.2,
attachSigns: true,
attachSignsNeedsSameTrack: false,
attachSignsMaxDistanceZ: 1.0,
attachSignsMaxDistanceX: 0.2,
attachSignsGridSize: 10,
logAttachedSigns: true,
}, },
warnings: { warnings: {
all: false, // enable all warnings all: false, // enable all warnings
@ -38,6 +44,7 @@ const Constants = {
electrificationResolverWarnings: true, electrificationResolverWarnings: true,
signalElemsUnknownPrefab: true, signalElemsUnknownPrefab: true,
signalElemsRecognizedUnknownPrefab: true, signalElemsRecognizedUnknownPrefab: true,
attachSignsOutOfBounds: true,
}, },
errors: { errors: {
invalidSceneryInfo: true invalidSceneryInfo: true