mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: start of pitch yaw limits
This commit is contained in:
1 parent
57702d8a43
commit
ad9f2d8609
5 files changed
+127
-14
No files matched your search
@@ -3,6 +3,7 @@ export * from "./fisherYates";
|
|||||||
export * from "./formatCompact";
|
export * from "./formatCompact";
|
||||||
export * from "./isNumber";
|
export * from "./isNumber";
|
||||||
export * from "./NaNFallback";
|
export * from "./NaNFallback";
|
||||||
|
export * from "./normalizeAngleDeg";
|
||||||
export * from "./normalizeAngleRad";
|
export * from "./normalizeAngleRad";
|
||||||
export * from "./normalToEuler";
|
export * from "./normalToEuler";
|
||||||
export * from "./numberToRomanNumeral";
|
export * from "./numberToRomanNumeral";
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export function normalizeAngleDeg(angle: number) {
|
||||||
|
const newAngle = angle % 360;
|
||||||
|
if (newAngle > 360) return newAngle - 360;
|
||||||
|
if (newAngle < -360) return newAngle + 360;
|
||||||
|
return newAngle;
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import { normalizeAngleDeg } from "@blitzkit/core";
|
||||||
|
import type { PitchLimit } from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||||
|
import { clamp, degToRad, lerp, radToDeg } from "three/src/math/MathUtils.js";
|
||||||
|
|
||||||
|
export function applyPitchYawLimits(
|
||||||
|
givenPitch: number,
|
||||||
|
givenYaw: number,
|
||||||
|
pitchLimitsUp: PitchLimit[],
|
||||||
|
pitchLimitsDown: PitchLimit[]
|
||||||
|
) {
|
||||||
|
const givenYawDeg = normalizeAngleDeg(radToDeg(givenYaw));
|
||||||
|
const givenPitchDeg = normalizeAngleDeg(radToDeg(givenPitch));
|
||||||
|
|
||||||
|
const yawDeg = givenYawDeg;
|
||||||
|
const yaw = degToRad(givenYawDeg);
|
||||||
|
|
||||||
|
let leftLimitUp: PitchLimit | undefined;
|
||||||
|
let rightLimitUp: PitchLimit | undefined;
|
||||||
|
let leftLimitDown: PitchLimit | undefined;
|
||||||
|
let rightLimitDown: PitchLimit | undefined;
|
||||||
|
|
||||||
|
for (const limit of pitchLimitsUp) {
|
||||||
|
const normalizedAngle = normalizeAngleDeg(limit.angle);
|
||||||
|
|
||||||
|
if (normalizedAngle <= yawDeg) {
|
||||||
|
if (
|
||||||
|
!leftLimitUp ||
|
||||||
|
normalizeAngleDeg(yawDeg - normalizedAngle) <
|
||||||
|
normalizeAngleDeg(yawDeg - leftLimitUp.angle)
|
||||||
|
) {
|
||||||
|
leftLimitUp = limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedAngle >= yawDeg) {
|
||||||
|
if (
|
||||||
|
!rightLimitUp ||
|
||||||
|
normalizeAngleDeg(normalizedAngle - yawDeg) <
|
||||||
|
normalizeAngleDeg(rightLimitUp.angle - yawDeg)
|
||||||
|
) {
|
||||||
|
rightLimitUp = limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const limit of pitchLimitsDown) {
|
||||||
|
const normalizedAngle = normalizeAngleDeg(limit.angle);
|
||||||
|
|
||||||
|
if (normalizedAngle <= yawDeg) {
|
||||||
|
if (
|
||||||
|
!leftLimitDown ||
|
||||||
|
normalizeAngleDeg(yawDeg - normalizedAngle) <
|
||||||
|
normalizeAngleDeg(yawDeg - leftLimitDown.angle)
|
||||||
|
) {
|
||||||
|
leftLimitDown = limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedAngle >= yawDeg) {
|
||||||
|
if (
|
||||||
|
!rightLimitDown ||
|
||||||
|
normalizeAngleDeg(normalizedAngle - yawDeg) <
|
||||||
|
normalizeAngleDeg(rightLimitDown.angle - yawDeg)
|
||||||
|
) {
|
||||||
|
rightLimitDown = limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!leftLimitUp || !rightLimitUp || !leftLimitDown || !rightLimitDown) {
|
||||||
|
throw new Error("Pitch limits not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const spanUp = normalizeAngleDeg(rightLimitUp.angle - leftLimitUp.angle);
|
||||||
|
const spanDown = normalizeAngleDeg(
|
||||||
|
rightLimitDown.angle - leftLimitDown.angle
|
||||||
|
);
|
||||||
|
|
||||||
|
let limitUp: number;
|
||||||
|
let limitDown: number;
|
||||||
|
|
||||||
|
if (spanUp === 0) {
|
||||||
|
limitUp = leftLimitUp.limit;
|
||||||
|
} else {
|
||||||
|
const delta = normalizeAngleDeg(givenYawDeg - leftLimitUp.angle);
|
||||||
|
const t = delta / spanUp;
|
||||||
|
limitUp = lerp(leftLimitUp.limit, rightLimitUp.limit, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spanDown === 0) {
|
||||||
|
limitDown = leftLimitDown.limit;
|
||||||
|
} else {
|
||||||
|
const delta = normalizeAngleDeg(givenYawDeg - leftLimitDown.angle);
|
||||||
|
const t = delta / spanDown;
|
||||||
|
limitDown = lerp(leftLimitDown.limit, rightLimitDown.limit, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
const pitchDeg = clamp(givenPitchDeg, limitUp, -limitDown);
|
||||||
|
const pitch = degToRad(pitchDeg);
|
||||||
|
|
||||||
|
return { pitch, yaw };
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
StageParameters,
|
StageParameters,
|
||||||
TankAttributeChange_AttributeName,
|
TankAttributeChange_AttributeName,
|
||||||
} from "@protos/blitz_static_tank_upgrade_single_stage";
|
} from "@protos/blitz_static_tank_upgrade_single_stage";
|
||||||
|
import { radToDeg } from "three/src/math/MathUtils.js";
|
||||||
|
import { applyPitchYawLimits } from "./applyPitchYawLimits";
|
||||||
import type { TankState } from "./tankState";
|
import type { TankState } from "./tankState";
|
||||||
|
|
||||||
export type CharacteristicOutput = number | null;
|
export type CharacteristicOutput = number | null;
|
||||||
@@ -213,23 +215,25 @@ export const characteristics = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
gun_depression({ parameters }) {
|
gun_depression({ parameters }) {
|
||||||
const pitchLimit = parameters.pitch_limits_down.find(
|
return radToDeg(
|
||||||
(pitchLimit) => pitchLimit.angle === 0
|
applyPitchYawLimits(
|
||||||
|
-Math.PI / 2,
|
||||||
|
0,
|
||||||
|
parameters.pitch_limits_up,
|
||||||
|
parameters.pitch_limits_down
|
||||||
|
).pitch
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!pitchLimit) throw new Error("No angle 0 depression pitch limit found");
|
|
||||||
|
|
||||||
return pitchLimit.limit;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gun_elevation({ parameters }) {
|
gun_elevation({ parameters }) {
|
||||||
const pitchLimit = parameters.pitch_limits_up.find(
|
return radToDeg(
|
||||||
(pitchLimit) => pitchLimit.angle === 0
|
applyPitchYawLimits(
|
||||||
|
Math.PI / 2,
|
||||||
|
0,
|
||||||
|
parameters.pitch_limits_up,
|
||||||
|
parameters.pitch_limits_down
|
||||||
|
).pitch
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!pitchLimit) throw new Error("No angle 0 elevation pitch limit found");
|
|
||||||
|
|
||||||
return pitchLimit.limit;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
engine_power({ attribute }) {
|
engine_power({ attribute }) {
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ export const characteristicsOrder: CharacteristicsOrder = [
|
|||||||
|
|
||||||
{ name: "dispersion", decimals: 3, units: "m" },
|
{ name: "dispersion", decimals: 3, units: "m" },
|
||||||
|
|
||||||
{ name: "gun_depression", units: "deg" },
|
{ name: "gun_depression", decimals: 0, units: "deg" },
|
||||||
{ name: "gun_elevation", units: "deg" },
|
{ name: "gun_elevation", decimals: 0, units: "deg" },
|
||||||
|
|
||||||
{ toy: "flexibility" },
|
{ toy: "flexibility" },
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in new issue
Block a user