Skip to content

Commit ac42b16

Browse files
committed
transform3d: Introduce Transform3D::project_to_2d to flatten a transform.
Need to use this for servo/webrender#3394. The normalization of perspective is not necessary bug Gecko does it as a performance optimization, and ScaleOffset in WR wouldn't handle this. See: https://bugzilla.mozilla.org/show_bug.cgi?id=1241161 But in any case I'm happy to teach ScaleOffset about that case instead if you think it's better.
1 parent 0b810d5 commit ac42b16

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

src/transform3d.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,42 @@ where T: Copy + Clone +
520520
self.post_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
521521
}
522522

523+
/// Returns a projection of this transform in 2d space.
524+
pub fn project_to_2d(&self) -> Self {
525+
let (_0, _1): (T, T) = (Zero::zero(), One::one());
526+
527+
let mut result = self.clone();
528+
529+
result.m31 = _0;
530+
result.m32 = _0;
531+
result.m13 = _0;
532+
result.m23 = _0;
533+
result.m33 = _1;
534+
result.m43 = _0;
535+
result.m34 = _0;
536+
537+
// Try to normalize perspective when possible to convert to a 2d matrix.
538+
// Some matrices, such as those derived from perspective transforms, can
539+
// modify m44 from 1, while leaving the rest of the fourth column
540+
// (m14, m24) at 0. In this case, after resetting the third row and
541+
// third column above, the value of m44 functions only to scale the
542+
// coordinate transform divide by W. The matrix can be converted to
543+
// a true 2D matrix by normalizing out the scaling effect of m44 on
544+
// the remaining components ahead of time.
545+
if self.m14 == _0 && self.m24 == _0 && self.m44 != _0 && self.m44 != _1 {
546+
let scale = _1 / self.m44;
547+
result.m11 = result.m11 * scale;
548+
result.m12 = result.m12 * scale;
549+
result.m21 = result.m21 * scale;
550+
result.m22 = result.m22 * scale;
551+
result.m41 = result.m41 * scale;
552+
result.m42 = result.m42 * scale;
553+
result.m44 = _1;
554+
}
555+
556+
result
557+
}
558+
523559
/// Create a 3d scale transform
524560
pub fn create_scale(x: T, y: T, z: T) -> Self {
525561
let (_0, _1): (T, T) = (Zero::zero(), One::one());

0 commit comments

Comments
 (0)