Refactor preProcessExtrinsic function to handle both Matrix4 and array inputs for extrinsic parameters. Add error handling for invalid inputs and update transformation sequence for camera-to-world conversion.

This commit is contained in:
2025-03-25 10:17:08 +08:00
parent 885ddd0989
commit 9fb7235d93

View File

@ -119,12 +119,14 @@ const Scene = () => {
let Rt: THREE.Matrix4 let Rt: THREE.Matrix4
if (extrinsic instanceof THREE.Matrix4) { if (extrinsic instanceof THREE.Matrix4) {
Rt = extrinsic Rt = extrinsic
} else { } else if (Array.isArray(extrinsic)) {
console.assert(extrinsic.length === 16, "extrinsic must be a 4x4 matrix")
Rt = new THREE.Matrix4() Rt = new THREE.Matrix4()
// @ts-expect-error 16 elements // @ts-expect-error 16 elements
Rt.set(...extrinsic) Rt.set(...extrinsic)
} else {
throw new Error("extrinsic must be a 4x4 matrix or an array of 16 elements")
} }
console.assert(Rt.elements.length === 16, "extrinsic must be a 4x4 matrix")
const font = new FontLoader().parse(HelvetikerRegular) const font = new FontLoader().parse(HelvetikerRegular)
const camera = new THREE.PerspectiveCamera(fov ?? 60, aspect ?? 4 / 3, near ?? DEFAULT_NEAR, far ?? DEFAULT_FAR) const camera = new THREE.PerspectiveCamera(fov ?? 60, aspect ?? 4 / 3, near ?? DEFAULT_NEAR, far ?? DEFAULT_FAR)
const helper = <cameraHelper args={[camera]} /> const helper = <cameraHelper args={[camera]} />
@ -161,17 +163,25 @@ const Scene = () => {
) )
} }
const preProcessExtrinsic = (extrinsic: number[]) => { const preProcessExtrinsic = (extrinsic: number[] | THREE.Matrix4) => {
// Create the initial world-to-camera transform let Rt: THREE.Matrix4
const worldToCamera = new THREE.Matrix4() if (extrinsic instanceof THREE.Matrix4) {
Rt = extrinsic
} else if (Array.isArray(extrinsic)) {
console.assert(extrinsic.length === 16, "extrinsic must be a 4x4 matrix")
Rt = new THREE.Matrix4()
// @ts-expect-error 16 elements // @ts-expect-error 16 elements
worldToCamera.set(...extrinsic) Rt.set(...extrinsic)
} else {
throw new Error("extrinsic must be a 4x4 matrix or an array of 16 elements")
}
// Convert from Z-up to Y-up first (this affects world coordinates)
const worldZupToYup = Z_UP_TO_Y_UP.clone()
// Then handle OpenCV to OpenGL camera convention // Then handle OpenCV to OpenGL camera convention
const cameraConversion = CV_TO_GL_MAT.clone() const cameraCvt = CV_TO_GL_MAT.clone()
// Convert from Z-up to Y-up first (this affects world coordinates)
const worldCvt = Z_UP_TO_Y_UP.clone()
// Final transformation: // Final transformation:
// 1. Convert world from Z-up to Y-up // 1. Convert world from Z-up to Y-up
@ -179,9 +189,9 @@ const Scene = () => {
// 3. Convert camera coordinates from OpenCV to OpenGL // 3. Convert camera coordinates from OpenCV to OpenGL
const final = new THREE.Matrix4() const final = new THREE.Matrix4()
final final
.multiply(cameraConversion) .multiply(cameraCvt)
.multiply(worldToCamera) .multiply(Rt)
.multiply(worldZupToYup) .multiply(worldCvt)
// Invert to get the camera-to-world transform // Invert to get the camera-to-world transform
final.invert() final.invert()