From e50a6a04be0130114a9843127a072ce3884afbd0 Mon Sep 17 00:00:00 2001 From: Misode Date: Wed, 8 Mar 2023 22:09:04 +0100 Subject: [PATCH] Apply svdDecompose fixes from 1.19.4-pre4 --- src/app/Utils.ts | 42 +++++++++++++------------------- src/app/pages/Transformation.tsx | 17 +++++-------- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/app/Utils.ts b/src/app/Utils.ts index 57a34b96..869323fe 100644 --- a/src/app/Utils.ts +++ b/src/app/Utils.ts @@ -396,7 +396,7 @@ function approxGivensQuat(a: number, b: number, c: number): [number, number] { } } -function qrGivensQuat(a: number, b: number) { +function qrGivensQuat(a: number, b: number): [number, number] { const c = Math.hypot(a, b) let d = c > 1e-6 ? b : 0 let e = Math.abs(a) + Math.max(c, 1e-6) @@ -407,22 +407,20 @@ function qrGivensQuat(a: number, b: number) { return [d * f, e * f] } -// modifies the passed mat3 +// modifies the passed matrix function stepJacobi(m: Matrix3): quat { - const n = new Matrix3() const q = quat.create() if (m.m01 * m.m01 + m.m10 * m.m10 > 1e-6) { const [a, b] = approxGivensQuat(m.m00, 0.5 * (m.m01 + m.m10), m.m11) const r = quat.fromValues(0, 0, a, b) const c = b * b - a * a const d = -2 * a * b - const e = b * b + a * a quat.mul(q, q, r) + const n = new Matrix3() n.m00 = c n.m11 = c n.m01 = -d n.m10 = d - n.m22 = e m.mul(n) n.transpose().mul(m) m.copy(n) @@ -434,13 +432,12 @@ function stepJacobi(m: Matrix3): quat { const r = quat.fromValues(0, a, 0, b) const c = b * b - a * a const d = -2 * a * b - const e = b * b + a * a quat.mul(q, q, r) + const n = new Matrix3() n.m00 = c n.m22 = c n.m02 = d n.m20 = -d - n.m11 = e m.mul(n) n.transpose().mul(m) m.copy(n) @@ -450,13 +447,12 @@ function stepJacobi(m: Matrix3): quat { const r = quat.fromValues(a, 0, 0, b) const c = b * b - a * a const d = -2 * a * b - const e = b * b + a * a quat.mul(q, q, r) + const n = new Matrix3() n.m11 = c n.m22 = c n.m12 = -d n.m21 = d - n.m00 = e m.mul(n) n.transpose().mul(m) m.copy(n) @@ -477,12 +473,12 @@ export function svdDecompose(m: Matrix3): [quat, Vector, quat] { quat.normalize(r, r) const p0 = m.clone() .mul(Matrix3.fromQuat(r)) - let f = 1 - const [a1, b1] = qrGivensQuat(p0.m00, p0.m01) + const [a1, b1] = m.m00 < 1e-6 + ? qrGivensQuat(p0.m11, -p0.m10) + : qrGivensQuat(p0.m00, p0.m01) const c1 = b1 * b1 - a1 * a1 const d1 = -2 * a1 * b1 - const e1 = b1 * b1 + a1 * a1 const s1 = quat.fromValues(0, 0, a1, b1) quat.mul(q, q, s1) const p1 = new Matrix3() @@ -490,16 +486,15 @@ export function svdDecompose(m: Matrix3): [quat, Vector, quat] { p1.m11 = c1 p1.m01 = d1 p1.m10 = -d1 - p1.m22 = e1 - f *= e1 p1.mul(p0) - const pair = qrGivensQuat(p1.m00, p1.m02) + const pair = m.m00 < 1e-6 + ? qrGivensQuat(p1.m22, -p1.m20) + : qrGivensQuat(p1.m00, p1.m02) const a2 = -pair[0] const b2 = pair[1] const c2 = b2 * b2 - a2 * a2 const d2 = -2 * a2 * b2 - const e2 = b2 * b2 + a2 * a2 const s2 = quat.fromValues(0, a2, 0, b2) quat.mul(q, q, s2) const p2 = new Matrix3() @@ -507,14 +502,13 @@ export function svdDecompose(m: Matrix3): [quat, Vector, quat] { p2.m22 = c2 p2.m02 = -d2 p2.m20 = d2 - p2.m11 = e2 - f *= e2 p2.mul(p1) - const [a3, b3] = qrGivensQuat(p2.m11, p2.m12) + const [a3, b3] = m.m11 < 1e-6 + ? qrGivensQuat(p2.m22, -p2.m21) + : qrGivensQuat(p2.m11, p2.m12) const c3 = b3 * b3 - a3 * a3 const d3 = -2 * a3 * b3 - const e3 = b3 * b3 + a3 * a3 const s3 = quat.fromValues(a3, 0, 0, b3) quat.mul(q, q, s3) const p3 = new Matrix3() @@ -522,13 +516,11 @@ export function svdDecompose(m: Matrix3): [quat, Vector, quat] { p3.m22 = c3 p3.m12 = d3 p3.m21 = -d3 - p3.m00 = e3 - f *= e3 p3.mul(p2) - f = 1 / f - quat.scale(q, q, Math.sqrt(f)) - const scale = new Vector(p3.m00 * f, p3.m11 * f, p3.m22 * f) + quat.scale(q, q, Math.sqrt(1)) + const scale = new Vector(p3.m00, p3.m11, p3.m22) + quat.conjugate(r, r) return [q, scale, r] } diff --git a/src/app/pages/Transformation.tsx b/src/app/pages/Transformation.tsx index 5593cb13..e09f7831 100644 --- a/src/app/pages/Transformation.tsx +++ b/src/app/pages/Transformation.tsx @@ -44,14 +44,9 @@ export function Transformation({}: Props) { const [normalizeLeft, setNormalizeLeft] = useState(true) const [normalizeRight, setNormalizeRight] = useState(true) - const [useMatrixOverride, setUseMatrixOverride] = useState(false) - const usedMatrix = useMemo(() => { - if (matrix !== undefined && useMatrixOverride) { - return matrix - } return composeMatrix(translation, leftRotation, scale, rightRotation) - }, [matrix, useMatrixOverride]) + }, [translation, leftRotation, scale, rightRotation]) const updateMatrix = useCallback((m: Matrix4) => { const affine = m.clone().affine() @@ -233,10 +228,9 @@ export function Transformation({}: Props) { {locale('transformation.matrix')} - {Array(16).fill(0).map((_, i) => - changeMatrix(i, v)} /> + changeMatrix(i, v)} disabled={i % 4 === 3} /> )} @@ -256,12 +250,13 @@ interface SliderProps { onChange?: (value: number) => void min?: number max?: number + disabled?: boolean } -function Slider({ label, value, onChange, min, max }: SliderProps) { +function Slider({ label, value, onChange, min, max, disabled }: SliderProps) { return
{label && } - - + +
}