Overhead extended signals support
+Added overhead extended signals parsing and rendering *Cleaned up SignalExtendedRenderer *Dwarf signals now use SignalElementEnums.HeadPosition.DWARF instead of NO_POLE *Minor bugfixes and tweaks related to extended signals
This commit is contained in:
parent
fd1f3107ee
commit
6bae0a31ea
@ -5,17 +5,19 @@ export default function SignalExtendedRenderer(props) {
|
||||
const { object } = props;
|
||||
const [x, y] = object.pos.toSVGCoords();
|
||||
|
||||
const rot = AngleHelper.normalizeDegAngle(object.rot.y);
|
||||
const overheadRot = object.signal_elements.isOverhead() ? 180 : 0;
|
||||
const baseRot = object.rot.y;
|
||||
const rot = AngleHelper.normalizeDegAngle(overheadRot + baseRot);
|
||||
const upsideDown = rot >= 180;
|
||||
const upsideDownRot = upsideDown ? 90 : -90;
|
||||
const anchor = upsideDown ? "start" : "end";
|
||||
|
||||
return (
|
||||
<g className="extended-signal" transform={`translate(${x}, ${y}) rotate(${object.rot.y})`}>
|
||||
<g className="extended-signal-icon">
|
||||
<g className="extended-signal" transform={`translate(${x}, ${y}) rotate(${rot})`}>
|
||||
<g className="extended-signal-icon" transform={`rotate(${-overheadRot})`}>
|
||||
<SignalIcon object={object} />
|
||||
</g>
|
||||
<g transform={`translate(0, 1.5) rotate(${upsideDownRot})`}>
|
||||
<g transform={`translate(0, 1) rotate(${upsideDownRot})`}>
|
||||
<text x="0" y="0" textAnchor={anchor} dominantBaseline="middle">
|
||||
{object.getPrintableSignalName()}
|
||||
</text>
|
||||
@ -28,25 +30,34 @@ function SignalIcon(props) {
|
||||
const { object } = props;
|
||||
|
||||
const halfBaseWidth = getHalfBaseWidth(object);
|
||||
const headOff = getHeadOffset(object);
|
||||
const poleLength = getPoleLength(object, headOff);
|
||||
const headOffsetX = getHeadOffsetX(object);
|
||||
const poleLength = getPoleLength(object, headOffsetX);
|
||||
const headOffsetY = getHeadOffsetY(object, poleLength);
|
||||
|
||||
return (
|
||||
<g strokeWidth={0.2} strokeLinecap="round" strokeLinejoin="round">
|
||||
{ getBase(halfBaseWidth) }
|
||||
{ getPole(poleLength, headOff) }
|
||||
{ getBars(object, poleLength, headOff) }
|
||||
{ getHead(object, poleLength, headOff) }
|
||||
{ getOverheadFrame(object) }
|
||||
{ getPole(poleLength, headOffsetY, headOffsetX) }
|
||||
{ getBars(object, headOffsetY, headOffsetX) }
|
||||
{ getHead(object, headOffsetY, headOffsetX) }
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
function getHeadOffsetY(object, poleLength) {
|
||||
if(object.signal_elements.isOverhead()) {
|
||||
return object.signal_elements.units.length * 1.2 + 0.1;
|
||||
}
|
||||
|
||||
return -poleLength;
|
||||
}
|
||||
|
||||
function getHalfBaseWidth(object) {
|
||||
const isDwarf = object.signal_elements.type === SignalElementsEnums.Type.DWARF;
|
||||
const isDoubleDwarf = object.signal_elements.type === SignalElementsEnums.Type.DWARF_DOUBLE;
|
||||
const isOverhead = object.signal_elements.headPosition === SignalElementsEnums.HeadPosition.OVERHEAD;
|
||||
|
||||
if(isOverhead) return 0;
|
||||
if(object.signal_elements.isOverhead()) return 0;
|
||||
if(isDwarf) return 0.6;
|
||||
if(isDoubleDwarf) return 1.2;
|
||||
|
||||
@ -58,7 +69,13 @@ function getBase(halfBaseWidth) {
|
||||
return <path d={`M ${-halfBaseWidth} 0 L ${halfBaseWidth} 0`} />;
|
||||
}
|
||||
|
||||
function getHeadOffset(object) {
|
||||
function getOverheadFrame(object) {
|
||||
if(!object.signal_elements.isOverhead()) return null;
|
||||
|
||||
return <path d={`M -1 0 L 1 0 M -1 -.5 L -1 .5 M 1 -.5 L 1 .5`} />;
|
||||
}
|
||||
|
||||
function getHeadOffsetX(object) {
|
||||
const isTOP = object.signal_elements.type === SignalElementsEnums.Type.TOP;
|
||||
if(isTOP) return 0;
|
||||
|
||||
@ -66,8 +83,8 @@ function getHeadOffset(object) {
|
||||
|
||||
switch (headPos) {
|
||||
case SignalElementsEnums.HeadPosition.STANDARD:
|
||||
case SignalElementsEnums.HeadPosition.NO_POLE:
|
||||
case SignalElementsEnums.HeadPosition.OVERHEAD:
|
||||
case SignalElementsEnums.HeadPosition.UNKNOWN:
|
||||
case SignalElementsEnums.HeadPosition.DWARF:
|
||||
default:
|
||||
return 0;
|
||||
case SignalElementsEnums.HeadPosition.LEFT:
|
||||
@ -77,39 +94,39 @@ function getHeadOffset(object) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPoleLength(object, headOff) {
|
||||
const headPos = object.signal_elements.headPosition;
|
||||
if(headPos === SignalElementsEnums.HeadPosition.NO_POLE) return 0;
|
||||
function getPoleLength(object, headOffsetX) {
|
||||
const isOverhead = object.signal_elements.isOverhead();
|
||||
|
||||
let length = 0.8;
|
||||
let length = isOverhead ? 0 : 0.6;
|
||||
|
||||
if(headOff !== 0) {
|
||||
length += 0.4;
|
||||
if(headOffsetX !== 0) {
|
||||
length += 0.4; // zigzag offset
|
||||
}
|
||||
|
||||
switch(object.signal_elements.bar) {
|
||||
case SignalElementsEnums.BarType.YELLOW:
|
||||
case SignalElementsEnums.BarType.GREEN:
|
||||
length += 1.0;
|
||||
length += 0.7;
|
||||
break;
|
||||
case SignalElementsEnums.BarType.YELLOW_GREEN:
|
||||
length += 1.8;
|
||||
length += 1.5;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Math.max(length, 2);
|
||||
if(isOverhead) return length;
|
||||
return Math.max(length + 0.2, 2);
|
||||
}
|
||||
|
||||
function getPole(poleLength, headOff) {
|
||||
function getPole(poleLength, headOffsetY, headOffsetX) {
|
||||
if(!poleLength) return null;
|
||||
|
||||
if(headOff) {
|
||||
return <path d={`M 0 0 L 0 -${poleLength - .4} L ${headOff} -${poleLength -.4} L ${headOff} -${poleLength}`} />;
|
||||
if(headOffsetX) {
|
||||
return <path d={`M 0 ${headOffsetY+poleLength} L 0 ${headOffsetY + .4} L ${headOffsetX} ${headOffsetY + .4} L ${headOffsetX} ${headOffsetY}`} />;
|
||||
}
|
||||
|
||||
return <path d={`M 0 0 L 0 -${poleLength}`} />;
|
||||
return <path d={`M 0 ${headOffsetY+poleLength} L 0 ${headOffsetY}`} />;
|
||||
}
|
||||
|
||||
function getUnit(key, unitType, x, y) {
|
||||
@ -161,12 +178,11 @@ function getUnit(key, unitType, x, y) {
|
||||
}
|
||||
}
|
||||
|
||||
function getHead(object, poleLength, headOff) {
|
||||
function getHead(object, headOffsetY, headOffsetX) {
|
||||
if(object.signal_elements.type === SignalElementsEnums.Type.TOP) {
|
||||
return getHeadTOP(object, poleLength);
|
||||
return getHeadTOP(object, headOffsetY);
|
||||
}
|
||||
|
||||
// TODO: overhead signals
|
||||
const isDoubleDwarf = object.signal_elements.type === SignalElementsEnums.Type.DWARF_DOUBLE;
|
||||
const unitsCount = object.signal_elements.units.length;
|
||||
const units = [];
|
||||
@ -174,41 +190,41 @@ function getHead(object, poleLength, headOff) {
|
||||
|
||||
for(let i = 0; i < unitsCount; i++) {
|
||||
const unitType = object.signal_elements.units[i];
|
||||
const cx = isDoubleDwarf ? (i > 2 ? r : -r) : headOff;
|
||||
const cy = -poleLength - r - i * r * 2 + (isDoubleDwarf && i > 2 ? 6 * r : 0);
|
||||
const cx = isDoubleDwarf ? (i > 2 ? r : -r) : headOffsetX;
|
||||
const cy = headOffsetY - r - i * r * 2 + (isDoubleDwarf && i > 2 ? 6 * r : 0);
|
||||
units.push(getUnit(i, unitType, cx, cy));
|
||||
}
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
function getHeadTOP(object, poleLength) {
|
||||
function getHeadTOP(object, headOffsetY) {
|
||||
const isLeft = object.signal_elements.headPosition === SignalElementsEnums.HeadPosition.LEFT;
|
||||
const r = 0.6;
|
||||
const whiteCX = isLeft ? r*2 : -r*2;
|
||||
|
||||
return <>
|
||||
<path d={`M ${whiteCX} -${poleLength} L 0 -${poleLength}`} />
|
||||
{ getUnit(0, SignalElementsEnums.UnitType.YELLOW_LOWER, 0, -poleLength-r) }
|
||||
{ getUnit(1, SignalElementsEnums.UnitType.WHITE, 0, -poleLength-3*r) }
|
||||
{ getUnit(2, SignalElementsEnums.UnitType.WHITE, 0, -poleLength-5*r) }
|
||||
{ getUnit(3, SignalElementsEnums.UnitType.YELLOW_LOWER, whiteCX, -poleLength-r) }
|
||||
<path d={`M ${whiteCX} ${headOffsetY} L 0 ${headOffsetY}`} />
|
||||
{ getUnit(0, SignalElementsEnums.UnitType.YELLOW_LOWER, 0, headOffsetY-r) }
|
||||
{ getUnit(1, SignalElementsEnums.UnitType.WHITE, 0, headOffsetY-3*r) }
|
||||
{ getUnit(2, SignalElementsEnums.UnitType.WHITE, 0, headOffsetY-5*r) }
|
||||
{ getUnit(3, SignalElementsEnums.UnitType.YELLOW_LOWER, whiteCX, headOffsetY-r) }
|
||||
</>
|
||||
}
|
||||
|
||||
function getBar(object, headOff, y, isYellow, key = 0) {
|
||||
function getBar(object, headOffsetX, 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} />;
|
||||
<rect x={headOffsetX-0.6} y={y-0.2} width={1.2} height={0.4} className='background' />;
|
||||
<line x1={headOffsetX - yellowOff} y1={y-0.2} x2={headOffsetX + yellowOff} y2={y+0.2} />;
|
||||
</g>
|
||||
}
|
||||
|
||||
function getBars(object, poleLength, headOff) {
|
||||
function getBars(object, headOffsetY, headOffsetX) {
|
||||
const barType = object.signal_elements.bar;
|
||||
const headOffOffset = headOff !== 0 ? 0.4 : 0;
|
||||
const y = -poleLength + headOffOffset + 0.6;
|
||||
const zigzagOffset = headOffsetX !== 0 ? 0.4 : 0;
|
||||
const y = headOffsetY + zigzagOffset + 0.6;
|
||||
|
||||
if(barType === SignalElementsEnums.BarType.NONE) return null;
|
||||
|
||||
|
||||
@ -280,6 +280,33 @@ const DefinedSwitches = {
|
||||
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,
|
||||
|
||||
@ -11,8 +11,7 @@ const SignalElementsEnums = {
|
||||
STANDARD: 1,
|
||||
RIGHT: 2,
|
||||
LEFT: 3,
|
||||
NO_POLE: 4,
|
||||
OVERHEAD: 5,
|
||||
DWARF: 4,
|
||||
},
|
||||
UnitType: {
|
||||
UNKNOWN: 0,
|
||||
|
||||
@ -10,7 +10,6 @@ export default class SignalElementsParserCommon {
|
||||
|
||||
static getHeadPosition(poleString) {
|
||||
const headPosition = this.getAfterLastUnderscoreNoVersion(poleString)?.[0];
|
||||
if (!headPosition) return SignalElementsEnums.HeadPosition.UNKNOWN;
|
||||
|
||||
switch (headPosition) {
|
||||
case 'p':
|
||||
|
||||
@ -18,7 +18,7 @@ export default class SignalElementsParserEhaEriDwarfPs {
|
||||
|
||||
return new SignalElements(
|
||||
isDouble ? SignalElementsEnums.Type.DWARF_DOUBLE : SignalElementsEnums.Type.DWARF,
|
||||
SignalElementsEnums.HeadPosition.NO_POLE,
|
||||
SignalElementsEnums.HeadPosition.DWARF,
|
||||
[mainUnits, secondaryUnits].flat(),
|
||||
SignalElementsEnums.BarType.NONE,
|
||||
SignalElementsParserCommon.getSigns(entries, 15, 1, 1)
|
||||
|
||||
@ -15,7 +15,7 @@ export default class SignalElementsParserEhaEriDwarf {
|
||||
|
||||
return new SignalElements(
|
||||
SignalElementsEnums.Type.DWARF,
|
||||
SignalElementsEnums.HeadPosition.NO_POLE,
|
||||
SignalElementsEnums.HeadPosition.DWARF,
|
||||
SignalElementsParserCommon.getUnits(entries, 2, 3, 2),
|
||||
SignalElementsEnums.BarType.NONE,
|
||||
[]
|
||||
|
||||
@ -14,7 +14,7 @@ export default class SignalElementsParserSkDwarf {
|
||||
|
||||
return new SignalElements(
|
||||
SignalElementsEnums.Type.DWARF,
|
||||
SignalElementsEnums.HeadPosition.NO_POLE,
|
||||
SignalElementsEnums.HeadPosition.DWARF,
|
||||
SignalElementsParserCommon.getUnits(entries, 2, 2, 1),
|
||||
SignalElementsEnums.BarType.NONE,
|
||||
[]
|
||||
|
||||
@ -19,6 +19,10 @@ export default class SignalElements {
|
||||
});
|
||||
}
|
||||
|
||||
isOverhead() {
|
||||
return this.headPosition === SignalElementsEnums.HeadPosition.UNKNOWN;
|
||||
}
|
||||
|
||||
static fromPrefabText(id, text) {
|
||||
const prefabName = text.split(",", 2)[0].trim();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user