mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +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 "./isNumber";
|
||||
export * from "./NaNFallback";
|
||||
export * from "./normalizeAngleDeg";
|
||||
export * from "./normalizeAngleRad";
|
||||
export * from "./normalToEuler";
|
||||
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,
|
||||
TankAttributeChange_AttributeName,
|
||||
} 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";
|
||||
|
||||
export type CharacteristicOutput = number | null;
|
||||
@@ -213,23 +215,25 @@ export const characteristics = {
|
||||
},
|
||||
|
||||
gun_depression({ parameters }) {
|
||||
const pitchLimit = parameters.pitch_limits_down.find(
|
||||
(pitchLimit) => pitchLimit.angle === 0
|
||||
return radToDeg(
|
||||
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 }) {
|
||||
const pitchLimit = parameters.pitch_limits_up.find(
|
||||
(pitchLimit) => pitchLimit.angle === 0
|
||||
return radToDeg(
|
||||
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 }) {
|
||||
|
||||
@@ -50,8 +50,8 @@ export const characteristicsOrder: CharacteristicsOrder = [
|
||||
|
||||
{ name: "dispersion", decimals: 3, units: "m" },
|
||||
|
||||
{ name: "gun_depression", units: "deg" },
|
||||
{ name: "gun_elevation", units: "deg" },
|
||||
{ name: "gun_depression", decimals: 0, units: "deg" },
|
||||
{ name: "gun_elevation", decimals: 0, units: "deg" },
|
||||
|
||||
{ toy: "flexibility" },
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user