Compare commits

2 Commits

Author SHA1 Message Date
10f6d92b7f removes bundle from output 2025-02-15 06:42:13 -07:00
968867c5d9 Fixed ghost track rotation on rear ends
Recalculation on track edit end
Changes rendering of ties to be evenly spaced
Fixes ghost and held track rendering
2025-02-15 06:40:39 -07:00
6 changed files with 41 additions and 2862 deletions

2841
bundle.js

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
type ContextStore = Record<string, any>;
const contextStack: ContextStore[] = [];
const defaultContext: ContextStore = {};
const contextStack: ContextStore[] = [defaultContext];
const debug = JSON.parse(localStorage.getItem("debug") || "false");

View File

@@ -74,10 +74,10 @@ setInterval(() => {
fpsEl.id = "fps";
document.body.appendChild(fpsEl);
}
const fPerc = frameRate / 60;
if (fPerc < 0.6) {
state.optimizePerformance(fPerc);
}
// const fPerc = frameRate / 60;
// if (fPerc < 0.6) {
// state.optimizePerformance(fPerc);
// }
fpsEl.textContent = frameRate.toFixed(1) + " fps";
}, 1000);

View File

@@ -237,10 +237,10 @@ export class PathSegment {
resolution = 1,
targetLength?: number,
) {
const points: Vector[] = [];
const points: [Vector, number][] = [];
points.push(this.points[0]);
let prev = points[0];
points.push([this.points[0], this.tangent(0).heading()]);
let [prev] = points[0];
let distSinceLastEvenPoint = 0;
let t = 0;
@@ -258,7 +258,7 @@ export class PathSegment {
Vector.sub(point, prev).normalize().mult(overshoot),
);
distSinceLastEvenPoint = overshoot;
points.push(evenPoint);
points.push([evenPoint, this.tangent(t).heading()]);
prev = evenPoint;
}
@@ -278,7 +278,7 @@ export class PathSegment {
Vector.sub(point, prev).normalize().mult(overshoot),
);
distSinceLastEvenPoint = overshoot;
points.push(evenPoint);
points.push([evenPoint, this.tangent(t).heading()]);
prev = evenPoint;
}
@@ -304,7 +304,7 @@ export class PathSegment {
const curveLength = this.startingLength;
const points = this.calculateEvenlySpacedPoints(1, 1, curveLength + 1);
if (points.length >= curveLength) {
this.points[3].set(points[curveLength]);
this.points[3].set(points[curveLength][0]);
}
}

View File

@@ -121,18 +121,20 @@ export class EditTrackState extends State<States> {
);
this.ghostRotated = true;
break;
case "back":
case "back": {
this.ghostSegment.setPositionByPoint(
this.closestEnd.pos,
this.ghostSegment.points[3],
);
const ghostEndTangent = this.ghostSegment.tangent(1);
// this.ghostSegment.points[3] = this.closestEnd.pos;
!this.ghostRotated && this.ghostSegment.rotateAboutPoint(
this.closestEnd.tangent.heading(),
this.closestEnd.tangent.heading() - ghostEndTangent.heading(),
this.ghostSegment.points[3],
);
this.ghostRotated = true;
break;
}
}
// } else if (closestEnd) {
// this.closestEnd = closestEnd;
@@ -258,11 +260,11 @@ export class EditTrackState extends State<States> {
const doodler = getContextItem<Doodler>("doodler");
this.layers.push(
doodler.createLayer(() => {
this.selectedSegment?.draw();
this.selectedSegment?.draw(false, true);
if (this.ghostSegment) {
doodler.drawWithAlpha(0.5, () => {
if (!this.ghostSegment) return;
this.ghostSegment.draw();
this.ghostSegment.draw(false, true);
if (getContextItemOrDefault("debug", false)) {
const colors = getContextItem<string[]>("colors");
for (
@@ -396,6 +398,9 @@ export class EditTrackState extends State<States> {
getContextItem<Doodler>("doodler").deleteLayer(layer);
}
const track = getContextItem<TrackSystem>("track");
track.recalculateAll();
const inputManager = getContextItem<InputManager>("inputManager");
inputManager.offKey("e");
inputManager.offKey("w");

View File

@@ -29,6 +29,13 @@ export class TrackSystem {
}
}
recalculateAll() {
for (const segment of this.segments.values()) {
segment.recalculateRailPoints();
segment.length = segment.calculateApproxLength();
}
}
registerSegment(segment: TrackSegment) {
segment.setTrack(this);
this.segments.set(segment.id, segment);
@@ -39,6 +46,9 @@ export class TrackSystem {
s.backNeighbours = s.backNeighbours.filter((n) => n !== segment);
s.frontNeighbours = s.frontNeighbours.filter((n) => n !== segment);
}
const ends = this.ends.get(segment);
this.ends.delete(segment);
this.endArray = this.endArray.filter((e) => !ends?.includes(e));
}
draw(showControls = false) {
@@ -291,7 +301,7 @@ export class TrackSegment extends PathSegment {
this.track = t;
}
override draw(showControls = false) {
override draw(showControls = false, recalculateRailPoints = false) {
// if (showControls) {
// this.doodler.drawBezier(
// this.points[0],
@@ -320,15 +330,17 @@ export class TrackSegment extends PathSegment {
});
}
const ties = Math.ceil(this.length / 10);
for (let i = 0; i < ties; i++) {
const t = i / ties;
const p = this.getPointAtT(t);
const spacing = Math.ceil(this.length / 10);
const points = this.calculateEvenlySpacedPoints(this.length / spacing);
for (let i = 0; i < points.length - 1; i++) {
// const t = i / ties;
// const p = this.getPointAtT(t);
const [p, t] = points[i];
// this.doodler.drawCircle(p, 2, {
// color: "red",
// weight: 3,
// });
this.doodler.drawRotated(p, this.tangent(t).heading(), () => {
this.doodler.drawRotated(p, t, () => {
this.doodler.line(p, p.copy().add(0, 10), {
color: "#291b17",
weight: 4,
@@ -348,6 +360,9 @@ export class TrackSegment extends PathSegment {
});
}
if (recalculateRailPoints) {
this.recalculateRailPoints();
}
this.doodler.deferDrawing(
() => {
this.doodler.drawLine(this.normalPoints, {