mirror of
https://github.com/servo/servo.git
synced 2025-06-29 11:33:39 +01:00
style: Cleanup and add references to decompose_3d_matrix.
Same, no functional change, but I basically rewrote this two times so... Bug: 1459403 Reviewed-by: hiro MozReview-Commit-ID: FXOnJDPyPu5
This commit is contained in:
parent
6ddb04a483
commit
875c4ff621
1 changed files with 49 additions and 43 deletions
|
@ -1908,7 +1908,8 @@ impl ComputeSquaredDistance for Quaternion {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decompose a 3D matrix.
|
/// Decompose a 3D matrix.
|
||||||
/// <https://drafts.csswg.org/css-transforms/#decomposing-a-3d-matrix>
|
/// https://drafts.csswg.org/css-transforms-2/#decomposing-a-3d-matrix
|
||||||
|
/// http://www.realtimerendering.com/resources/GraphicsGems/gemsii/unmatrix.c
|
||||||
fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
// Normalize the matrix.
|
// Normalize the matrix.
|
||||||
if matrix.m44 == 0.0 {
|
if matrix.m44 == 0.0 {
|
||||||
|
@ -1916,6 +1917,8 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let scaling_factor = matrix.m44;
|
let scaling_factor = matrix.m44;
|
||||||
|
|
||||||
|
// Normalize the matrix.
|
||||||
% for i in range(1, 5):
|
% for i in range(1, 5):
|
||||||
% for j in range(1, 5):
|
% for j in range(1, 5):
|
||||||
matrix.m${i}${j} /= scaling_factor;
|
matrix.m${i}${j} /= scaling_factor;
|
||||||
|
@ -1926,9 +1929,9 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
// an easy way to test for singularity of the upper 3x3 component.
|
// an easy way to test for singularity of the upper 3x3 component.
|
||||||
let mut perspective_matrix = matrix;
|
let mut perspective_matrix = matrix;
|
||||||
|
|
||||||
% for i in range(1, 4):
|
perspective_matrix.m14 = 0.0;
|
||||||
perspective_matrix.m${i}4 = 0.0;
|
perspective_matrix.m24 = 0.0;
|
||||||
% endfor
|
perspective_matrix.m34 = 0.0;
|
||||||
perspective_matrix.m44 = 1.0;
|
perspective_matrix.m44 = 1.0;
|
||||||
|
|
||||||
if perspective_matrix.determinant() == 0.0 {
|
if perspective_matrix.determinant() == 0.0 {
|
||||||
|
@ -1944,37 +1947,18 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
matrix.m44
|
matrix.m44
|
||||||
];
|
];
|
||||||
|
|
||||||
perspective_matrix = perspective_matrix.inverse().unwrap();
|
perspective_matrix = perspective_matrix.inverse().unwrap().transpose();
|
||||||
|
let perspective = perspective_matrix.pre_mul_point4(&right_hand_side);
|
||||||
// Transpose perspective_matrix
|
// NOTE(emilio): Even though the reference algorithm clears the
|
||||||
perspective_matrix = Matrix3D {
|
// fourth column here (matrix.m14..matrix.m44), they're not used below
|
||||||
% for i in range(1, 5):
|
// so it's not really needed.
|
||||||
% for j in range(1, 5):
|
Perspective(perspective[0], perspective[1], perspective[2], perspective[3])
|
||||||
m${i}${j}: perspective_matrix.m${j}${i},
|
|
||||||
% endfor
|
|
||||||
% endfor
|
|
||||||
};
|
|
||||||
|
|
||||||
// Multiply right_hand_side with perspective_matrix
|
|
||||||
let mut tmp: [f32; 4] = [0.0; 4];
|
|
||||||
% for i in range(1, 5):
|
|
||||||
tmp[${i - 1}] = (right_hand_side[0] * perspective_matrix.m1${i}) +
|
|
||||||
(right_hand_side[1] * perspective_matrix.m2${i}) +
|
|
||||||
(right_hand_side[2] * perspective_matrix.m3${i}) +
|
|
||||||
(right_hand_side[3] * perspective_matrix.m4${i});
|
|
||||||
% endfor
|
|
||||||
|
|
||||||
Perspective(tmp[0], tmp[1], tmp[2], tmp[3])
|
|
||||||
} else {
|
} else {
|
||||||
Perspective(0.0, 0.0, 0.0, 1.0)
|
Perspective(0.0, 0.0, 0.0, 1.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next take care of translation
|
// Next take care of translation (easy).
|
||||||
let translate = Translate3D (
|
let translate = Translate3D(matrix.m41, matrix.m42, matrix.m43);
|
||||||
matrix.m41,
|
|
||||||
matrix.m42,
|
|
||||||
matrix.m43
|
|
||||||
);
|
|
||||||
|
|
||||||
// Now get scale and shear. 'row' is a 3 element array of 3 component vectors
|
// Now get scale and shear. 'row' is a 3 element array of 3 component vectors
|
||||||
let mut row: [[f32; 3]; 3] = [[0.0; 3]; 3];
|
let mut row: [[f32; 3]; 3] = [[0.0; 3]; 3];
|
||||||
|
@ -2015,8 +1999,7 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
// At this point, the matrix (in rows) is orthonormal.
|
// At this point, the matrix (in rows) is orthonormal.
|
||||||
// Check for a coordinate system flip. If the determinant
|
// Check for a coordinate system flip. If the determinant
|
||||||
// is -1, then negate the matrix and the scaling factors.
|
// is -1, then negate the matrix and the scaling factors.
|
||||||
let pdum3 = cross(row[1], row[2]);
|
if dot(row[0], cross(row[1], row[2])) < 0.0 {
|
||||||
if dot(row[0], pdum3) < 0.0 {
|
|
||||||
% for i in range(3):
|
% for i in range(3):
|
||||||
scale.${i} *= -1.0;
|
scale.${i} *= -1.0;
|
||||||
row[${i}][0] *= -1.0;
|
row[${i}][0] *= -1.0;
|
||||||
|
@ -2025,8 +2008,8 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, get the rotations out
|
// Now, get the rotations out.
|
||||||
let mut quaternion = Quaternion (
|
let mut quaternion = Quaternion(
|
||||||
0.5 * ((1.0 + row[0][0] - row[1][1] - row[2][2]).max(0.0) as f64).sqrt(),
|
0.5 * ((1.0 + row[0][0] - row[1][1] - row[2][2]).max(0.0) as f64).sqrt(),
|
||||||
0.5 * ((1.0 - row[0][0] + row[1][1] - row[2][2]).max(0.0) as f64).sqrt(),
|
0.5 * ((1.0 - row[0][0] + row[1][1] - row[2][2]).max(0.0) as f64).sqrt(),
|
||||||
0.5 * ((1.0 - row[0][0] - row[1][1] + row[2][2]).max(0.0) as f64).sqrt(),
|
0.5 * ((1.0 - row[0][0] - row[1][1] + row[2][2]).max(0.0) as f64).sqrt(),
|
||||||
|
@ -2044,11 +2027,11 @@ fn decompose_3d_matrix(mut matrix: Matrix3D) -> Result<MatrixDecomposed3D, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(MatrixDecomposed3D {
|
Ok(MatrixDecomposed3D {
|
||||||
translate: translate,
|
translate,
|
||||||
scale: scale,
|
scale,
|
||||||
skew: skew,
|
skew,
|
||||||
perspective: perspective,
|
perspective,
|
||||||
quaternion: quaternion
|
quaternion,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,11 +2260,22 @@ impl Matrix3D {
|
||||||
self.m11 * self.m22 * self.m33 * self.m44
|
self.m11 * self.m22 * self.m33 * self.m44
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inverse(&self) -> Option<Matrix3D> {
|
/// Transpose a matrix.
|
||||||
|
fn transpose(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
% for i in range(1, 5):
|
||||||
|
% for j in range(1, 5):
|
||||||
|
m${i}${j}: self.m${j}${i},
|
||||||
|
% endfor
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inverse(&self) -> Result<Matrix3D, ()> {
|
||||||
let mut det = self.determinant();
|
let mut det = self.determinant();
|
||||||
|
|
||||||
if det == 0.0 {
|
if det == 0.0 {
|
||||||
return None;
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
det = 1.0 / det;
|
det = 1.0 / det;
|
||||||
|
@ -2352,7 +2346,19 @@ impl Matrix3D {
|
||||||
self.m12*self.m21*self.m33 + self.m11*self.m22*self.m33),
|
self.m12*self.m21*self.m33 + self.m11*self.m22*self.m33),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(x)
|
Ok(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Multiplies `pin * self`.
|
||||||
|
fn pre_mul_point4(&self, pin: &[f32; 4]) -> [f32; 4] {
|
||||||
|
[
|
||||||
|
% for i in range(1, 5):
|
||||||
|
pin[0] * self.m1${i} +
|
||||||
|
pin[1] * self.m2${i} +
|
||||||
|
pin[2] * self.m3${i} +
|
||||||
|
pin[3] * self.m4${i},
|
||||||
|
% endfor
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue