ai-chatbot/lib/ai/runtime/angle-edit-options.ts

83 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export interface DirectAgentAngleEditOptions {
horizontalAngle: number;
verticalAngle: number;
zoom: number;
loraScale?: number;
}
export function clampAngleEditNumber(
value: number | undefined,
min: number,
max: number,
fallback: number,
) {
if (!Number.isFinite(value)) return fallback;
return Math.min(max, Math.max(min, Number(value)));
}
function parseFirstNumberMatch(text: string, patterns: RegExp[]) {
for (const pattern of patterns) {
const match = text.match(pattern);
const value = Number(match?.[1]);
if (Number.isFinite(value)) return value;
}
return undefined;
}
export function inferAngleEditOptionsFromText(text: string): DirectAgentAngleEditOptions {
const normalizedText = String(text || "").toLowerCase().replace(/\s+/g, "");
const explicitHorizontal = parseFirstNumberMatch(normalizedText, [
/(?:水平角|水平|环绕|左右|horizontal|h)[::]?(-?\d{1,3})(?:度|°)?/,
/(?:旋转|转|转到|换成|改成)(-?\d{1,3})(?:度|°)/,
]);
const explicitVertical = parseFirstNumberMatch(normalizedText, [
/(?:垂直角|垂直|俯仰|上下|vertical|v)[::]?(-?\d{1,3})(?:度|°)?/,
]);
const explicitZoom = parseFirstNumberMatch(normalizedText, [
/(?:zoom|缩放|景别)[::]?(\d{1,2})(?:倍|x)?/,
]);
let horizontalAngle = explicitHorizontal ?? 45;
if (explicitHorizontal === undefined) {
if (/背面|背后|背视|后视|back/.test(normalizedText)) {
horizontalAngle = 180;
} else if (/左侧|左边|左视|left/.test(normalizedText)) {
horizontalAngle = 270;
} else if (/右侧|右边|右视|侧面|侧视|profile|side/.test(normalizedText)) {
horizontalAngle = 90;
} else if (/正面|正视|front/.test(normalizedText)) {
horizontalAngle = 0;
} else if (/三分之四|四分之三|斜侧|45度|45°/.test(normalizedText)) {
horizontalAngle = 45;
}
}
let verticalAngle = explicitVertical ?? 0;
if (explicitVertical === undefined) {
if (/俯视|俯拍|鸟瞰|高机位|top|overhead/.test(normalizedText)) {
verticalAngle = 45;
} else if (/仰视|仰拍|低机位|lowangle/.test(normalizedText)) {
verticalAngle = -20;
} else if (/平视|eyelevel/.test(normalizedText)) {
verticalAngle = 0;
}
}
let zoom = explicitZoom ?? 5;
if (explicitZoom === undefined) {
if (/特写|近景|拉近|推近|zoomin/.test(normalizedText)) {
zoom = 7;
} else if (/远景|全身|拉远|zoomout/.test(normalizedText)) {
zoom = 3;
} else if (/中景/.test(normalizedText)) {
zoom = 5;
}
}
return {
horizontalAngle: clampAngleEditNumber(horizontalAngle, 0, 360, 45),
verticalAngle: clampAngleEditNumber(verticalAngle, -30, 90, 0),
zoom: clampAngleEditNumber(zoom, 0, 10, 5),
};
}