取景视角限定在 (0, 180),非法值回落到默认视角
- packages/model3d-viewer/src/framing.ts:新增 normalizeFovDegrees,fovDegrees 只在 (0, 180) 内采用,>=180 时 tan(halfFovY) 非正会把 limitY/limitX 与 fallbackDistance 算成 0 或负数,污染取景距离与 near/far - packages/model3d-viewer/src/framing.test.ts:补 180 / 360 / 0 / 负数 / NaN 回落到默认视角的用例
This commit is contained in:
@@ -146,6 +146,25 @@ describe('computeModel3dViewerFitDistance', () => {
|
||||
});
|
||||
|
||||
describe('createModel3dViewerFitSolver', () => {
|
||||
it('视角超出 (0, 180) 时回落到默认视角,不把取景距离算成非正数', () => {
|
||||
for (const fovDegrees of [180, 360, 0, -45, Number.NaN]) {
|
||||
const solver = createModel3dViewerFitSolver({
|
||||
center: { x: 0, y: 0, z: 0 },
|
||||
aspect: 1,
|
||||
fovDegrees,
|
||||
});
|
||||
|
||||
expect(solver.resolve(), String(fovDegrees)).toBeCloseTo(
|
||||
createModel3dViewerFitSolver({
|
||||
center: { x: 0, y: 0, z: 0 },
|
||||
aspect: 1,
|
||||
fovDegrees: MODEL3D_VIEWER_CAMERA_FOV_DEGREES,
|
||||
}).resolve(),
|
||||
6,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('喂包围盒角点时与包围盒口径一致', () => {
|
||||
const expected = computeModel3dViewerFitDistance({ box: CUBE, aspect: 2 });
|
||||
|
||||
|
||||
@@ -71,6 +71,19 @@ function normalizePositive(value: number, fallback: number): number {
|
||||
return Number.isFinite(value) && value > 0 ? value : fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取景视角必须落在 (0, 180):>=180 时 `tan(halfFovY)` 非正,`limitY/limitX` 与
|
||||
* `fallbackDistance` 会算出 0 或负数,取景距离跟着变成负数并污染 near/far 与轨道范围。
|
||||
*/
|
||||
function normalizeFovDegrees(value: number | null | undefined): number {
|
||||
return typeof value === 'number' &&
|
||||
Number.isFinite(value) &&
|
||||
value > 0 &&
|
||||
value < 180
|
||||
? value
|
||||
: MODEL3D_VIEWER_CAMERA_FOV_DEGREES;
|
||||
}
|
||||
|
||||
function subtract(
|
||||
left: Model3dViewerVector3,
|
||||
right: Model3dViewerVector3,
|
||||
@@ -152,10 +165,7 @@ export function createModel3dViewerFitSolver(
|
||||
input: Model3dViewerFitSolverInput,
|
||||
): Model3dViewerFitSolver {
|
||||
const aspect = normalizePositive(input.aspect, FALLBACK_ASPECT);
|
||||
const fovDegrees = normalizePositive(
|
||||
input.fovDegrees ?? MODEL3D_VIEWER_CAMERA_FOV_DEGREES,
|
||||
MODEL3D_VIEWER_CAMERA_FOV_DEGREES,
|
||||
);
|
||||
const fovDegrees = normalizeFovDegrees(input.fovDegrees);
|
||||
const fitFraction = normalizePositive(
|
||||
input.fitFraction ?? MODEL3D_VIEWER_FIT_FRACTION,
|
||||
MODEL3D_VIEWER_FIT_FRACTION,
|
||||
|
||||
Reference in New Issue
Block a user