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
This commit is contained in:
parent
3befb69f51
commit
968867c5d9
52
bundle.js
52
bundle.js
@ -1,7 +1,7 @@
|
||||
(() => {
|
||||
// lib/context.ts
|
||||
var contextStack = [];
|
||||
var defaultContext = {};
|
||||
var contextStack = [defaultContext];
|
||||
var debug = JSON.parse(localStorage.getItem("debug") || "false");
|
||||
function setDefaultContext(context) {
|
||||
Object.assign(defaultContext, context);
|
||||
@ -1350,8 +1350,8 @@
|
||||
}
|
||||
calculateEvenlySpacedPoints(spacing, resolution = 1, targetLength) {
|
||||
const points = [];
|
||||
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;
|
||||
const div = Math.ceil(this.length * resolution * 10);
|
||||
@ -1366,7 +1366,7 @@
|
||||
Vector.sub(point, prev).normalize().mult(overshoot)
|
||||
);
|
||||
distSinceLastEvenPoint = overshoot;
|
||||
points.push(evenPoint);
|
||||
points.push([evenPoint, this.tangent(t).heading()]);
|
||||
prev = evenPoint;
|
||||
}
|
||||
prev = point;
|
||||
@ -1383,7 +1383,7 @@
|
||||
Vector.sub(point, prev).normalize().mult(overshoot)
|
||||
);
|
||||
distSinceLastEvenPoint = overshoot;
|
||||
points.push(evenPoint);
|
||||
points.push([evenPoint, this.tangent(t).heading()]);
|
||||
prev = evenPoint;
|
||||
}
|
||||
prev = point;
|
||||
@ -1403,7 +1403,7 @@
|
||||
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]);
|
||||
}
|
||||
}
|
||||
draw() {
|
||||
@ -1437,6 +1437,12 @@
|
||||
segment.recalculateRailPoints(Math.round(percent * 100 / 4));
|
||||
}
|
||||
}
|
||||
recalculateAll() {
|
||||
for (const segment of this.segments.values()) {
|
||||
segment.recalculateRailPoints();
|
||||
segment.length = segment.calculateApproxLength();
|
||||
}
|
||||
}
|
||||
registerSegment(segment) {
|
||||
segment.setTrack(this);
|
||||
this.segments.set(segment.id, segment);
|
||||
@ -1447,6 +1453,9 @@
|
||||
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) {
|
||||
for (const [i, segment] of this.segments.entries()) {
|
||||
@ -1642,7 +1651,7 @@
|
||||
setTrack(t) {
|
||||
this.track = t;
|
||||
}
|
||||
draw(showControls = false) {
|
||||
draw(showControls = false, recalculateRailPoints = false) {
|
||||
if (showControls) {
|
||||
this.doodler.deferDrawing(() => {
|
||||
this.doodler.fillCircle(this.points[0], 1, {
|
||||
@ -1659,11 +1668,11 @@
|
||||
});
|
||||
});
|
||||
}
|
||||
const ties = Math.ceil(this.length / 10);
|
||||
for (let i = 0; i < ties; i++) {
|
||||
const t = i / ties;
|
||||
const p = this.getPointAtT(t);
|
||||
this.doodler.drawRotated(p, this.tangent(t).heading(), () => {
|
||||
const spacing = Math.ceil(this.length / 10);
|
||||
const points = this.calculateEvenlySpacedPoints(this.length / spacing);
|
||||
for (let i = 0; i < points.length - 1; i++) {
|
||||
const [p, t] = points[i];
|
||||
this.doodler.drawRotated(p, t, () => {
|
||||
this.doodler.line(p, p.copy().add(0, 10), {
|
||||
color: "#291b17",
|
||||
weight: 4
|
||||
@ -1674,6 +1683,9 @@
|
||||
});
|
||||
});
|
||||
}
|
||||
if (recalculateRailPoints) {
|
||||
this.recalculateRailPoints();
|
||||
}
|
||||
this.doodler.deferDrawing(
|
||||
() => {
|
||||
this.doodler.drawLine(this.normalPoints, {
|
||||
@ -2044,18 +2056,20 @@
|
||||
);
|
||||
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.ghostRotated && this.ghostSegment.rotateAboutPoint(
|
||||
this.closestEnd.tangent.heading(),
|
||||
this.closestEnd.tangent.heading() - ghostEndTangent.heading(),
|
||||
this.ghostSegment.points[3]
|
||||
);
|
||||
this.ghostRotated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!this.closestEnd || !closestEnd) {
|
||||
this.ghostSegment = void 0;
|
||||
this.ghostRotated = false;
|
||||
@ -2082,11 +2096,11 @@
|
||||
const doodler2 = getContextItem("doodler");
|
||||
this.layers.push(
|
||||
doodler2.createLayer(() => {
|
||||
this.selectedSegment?.draw();
|
||||
this.selectedSegment?.draw(false, true);
|
||||
if (this.ghostSegment) {
|
||||
doodler2.drawWithAlpha(0.5, () => {
|
||||
if (!this.ghostSegment) return;
|
||||
this.ghostSegment.draw();
|
||||
this.ghostSegment.draw(false, true);
|
||||
if (getContextItemOrDefault("debug", false)) {
|
||||
const colors2 = getContextItem("colors");
|
||||
for (const [i, point] of this.ghostSegment.points.entries() ?? []) {
|
||||
@ -2182,6 +2196,8 @@
|
||||
for (const layer of this.layers) {
|
||||
getContextItem("doodler").deleteLayer(layer);
|
||||
}
|
||||
const track = getContextItem("track");
|
||||
track.recalculateAll();
|
||||
const inputManager2 = getContextItem("inputManager");
|
||||
inputManager2.offKey("e");
|
||||
inputManager2.offKey("w");
|
||||
@ -2830,10 +2846,6 @@
|
||||
fpsEl.id = "fps";
|
||||
document.body.appendChild(fpsEl);
|
||||
}
|
||||
const fPerc = frameRate / 60;
|
||||
if (fPerc < 0.6) {
|
||||
state.optimizePerformance(fPerc);
|
||||
}
|
||||
fpsEl.textContent = frameRate.toFixed(1) + " fps";
|
||||
}, 1e3);
|
||||
var gameLoop = new GameLoop();
|
||||
|
@ -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");
|
||||
|
||||
|
8
main.ts
8
main.ts
@ -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);
|
||||
|
||||
|
12
math/path.ts
12
math/path.ts
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,19 +121,21 @@ 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;
|
||||
} else if (!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");
|
||||
|
@ -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, {
|
||||
|
Loading…
x
Reference in New Issue
Block a user