From df08de1339143c9505e935575263f76abcd81c47 Mon Sep 17 00:00:00 2001 From: Jennifer Taylor Date: Mon, 21 Nov 2022 02:04:55 +0000 Subject: [PATCH] Fix transform update tracking for affine transforms, fix special case where an animation wants to specify a transform but also wants to use the identity matrix. Fixes an issue with Cinder BG. --- bemani/format/afp/render.py | 11 +++- bemani/format/afp/swf.py | 7 +-- bemani/format/afp/types/generic.py | 98 ++++++++++++++++++++++++------ 3 files changed, 89 insertions(+), 27 deletions(-) diff --git a/bemani/format/afp/render.py b/bemani/format/afp/render.py index c330ced..1258f3f 100644 --- a/bemani/format/afp/render.py +++ b/bemani/format/afp/render.py @@ -1092,8 +1092,15 @@ class AFPRenderer(VerboseOutput): new_add_color = tag.add_color or obj.add_color new_hsl_shift = tag.hsl_shift or obj.hsl_shift new_transform = ( - obj.transform.update(tag.transform) - if tag.transform is not None + obj.transform.update( + tag.transform, + tag.projection + == AP2PlaceObjectTag.PROJECTION_PERSPECTIVE, + ) + if ( + tag.transform is not None + and tag.projection != AP2PlaceObjectTag.PROJECTION_NONE + ) else obj.transform ) new_rotation_origin = tag.rotation_origin or obj.rotation_origin diff --git a/bemani/format/afp/swf.py b/bemani/format/afp/swf.py index a55a696..ab0e637 100644 --- a/bemani/format/afp/swf.py +++ b/bemani/format/afp/swf.py @@ -2174,12 +2174,7 @@ class SWF(VerboseOutput, TrackedCoverage): # Unset any previously set 3D transforms. Files shouldn't include both 3D # transforms AND the old 2D transform flag, but let's respect that bit. rotation_origin.z = 0.0 - transform.a13 = 0.0 - transform.a23 = 0.0 - transform.a31 = 0.0 - transform.a32 = 0.0 - transform.a33 = 1.0 - transform.a43 = 0.0 + transform = transform.to_affine() self.vprint(f"{prefix} Final transform: {transform}", component="tags") diff --git a/bemani/format/afp/types/generic.py b/bemani/format/afp/types/generic.py index c410d3d..8edeefe 100644 --- a/bemani/format/afp/types/generic.py +++ b/bemani/format/afp/types/generic.py @@ -273,6 +273,33 @@ class Matrix: a43=0.0, ) + def to_affine(self) -> "Matrix": + # Copy over just the affine bits. + new = Matrix( + a11=self.a11, + a12=self.a12, + a13=0.0, + a21=self.a21, + a22=self.a22, + a23=0.0, + a31=0.0, + a32=0.0, + a33=1.0, + a41=self.a41, + a42=self.a42, + a43=0.0, + ) + + # Copy over tracking flags for affine, but unset the perspective ones. + new.__scale_set = self.__scale_set + new.__rotate_set = self.__rotate_set + new.__translate_xy_set = self.__translate_xy_set + new.__3d_grid_set = False + new.__translate_z_set = False + + # Now return the new affine transform. + return new + @property def __is_affine(self) -> bool: return ( @@ -310,7 +337,7 @@ class Matrix: "tz": self.__a43, } - def update(self, other: "Matrix") -> "Matrix": + def update(self, other: "Matrix", is_perspective: bool) -> "Matrix": new = Matrix( a11=self.__a11, a12=self.__a12, @@ -326,29 +353,62 @@ class Matrix: a43=self.__a43, ) - if other.__3d_grid_set: - new.__a11 = other.__a11 - new.__a12 = other.__a12 - new.__a13 = other.__a13 - new.__a21 = other.__a21 - new.__a22 = other.__a22 - new.__a23 = other.__a23 - new.__a31 = other.__a31 - new.__a32 = other.__a32 - new.__a33 = other.__a33 - else: - if other.__scale_set: + if not ( + other.__scale_set + or other.__rotate_set + or other.__3d_grid_set + or other.__translate_xy_set + or other.__translate_z_set + ): + # Special case for uninitialized matrix that might need updating. + if is_perspective: + # Full perspective copy-over. + new.__a11 = other.__a11 + new.__a12 = other.__a12 + new.__a13 = other.__a13 + new.__a21 = other.__a21 + new.__a22 = other.__a22 + new.__a23 = other.__a23 + new.__a31 = other.__a31 + new.__a32 = other.__a32 + new.__a33 = other.__a33 + new.__a41 = other.__a41 + new.__a42 = other.__a42 + new.__a43 = other.__a43 + else: + # Simple affine copy-over. new.__a11 = other.__a11 new.__a22 = other.__a22 - if other.__rotate_set: new.__a12 = other.__a12 new.__a21 = other.__a21 + new.__a41 = other.__a41 + new.__a42 = other.__a42 - if other.__translate_xy_set: - new.__a41 = other.__a41 - new.__a42 = other.__a42 - if other.__translate_z_set: - new.__a43 = other.__a43 + else: + # Use object tracking to set only what changed. + if other.__3d_grid_set and is_perspective: + new.__a11 = other.__a11 + new.__a12 = other.__a12 + new.__a13 = other.__a13 + new.__a21 = other.__a21 + new.__a22 = other.__a22 + new.__a23 = other.__a23 + new.__a31 = other.__a31 + new.__a32 = other.__a32 + new.__a33 = other.__a33 + else: + if other.__scale_set: + new.__a11 = other.__a11 + new.__a22 = other.__a22 + if other.__rotate_set: + new.__a12 = other.__a12 + new.__a21 = other.__a21 + + if other.__translate_xy_set: + new.__a41 = other.__a41 + new.__a42 = other.__a42 + if other.__translate_z_set and is_perspective: + new.__a43 = other.__a43 return new