From ac547ca2eb9ea6de855a2c44f2884f9cb5877ec6 Mon Sep 17 00:00:00 2001 From: kcz Date: Fri, 6 Dec 2024 00:14:28 -0500 Subject: [PATCH] avm2: Support matrix3D in transform copy --- .../globals/flash/display/display_object.rs | 39 +++++++++++------ core/src/avm2/globals/flash/geom/transform.rs | 2 +- tests/tests/swfs/avm2/geom_transform/Test.as | 41 ++++++++---------- .../tests/swfs/avm2/geom_transform/output.txt | 8 ++++ tests/tests/swfs/avm2/geom_transform/test.swf | Bin 2037 -> 2180 bytes 5 files changed, 54 insertions(+), 36 deletions(-) diff --git a/core/src/avm2/globals/flash/display/display_object.rs b/core/src/avm2/globals/flash/display/display_object.rs index 92f8737b269e..4b79847dfd91 100644 --- a/core/src/avm2/globals/flash/display/display_object.rs +++ b/core/src/avm2/globals/flash/display/display_object.rs @@ -750,25 +750,37 @@ pub fn set_transform<'gc>( ) -> Result, Error<'gc>> { let transform = args.get_object(activation, 0, "transform")?; - // FIXME - consider 3D matrix and pixel bounds - let matrix = transform - .get_public_property("matrix", activation)? - .as_object(); - - let Some(matrix) = matrix else { - // FP seems to not do anything when setting to a Transform with a null matrix, - // but we don't actually support setting the matrix to null anyway - // (see the comment in `flash::geom::transform::set_matrix`) - return Ok(Value::Undefined); + // FIXME - consider pixel bounds + let (matrix, mode_3d) = { + if let Some(matrix3d) = transform + .get_public_property("matrix3D", activation)? + .as_object() + { + let matrix3d = crate::avm2::globals::flash::geom::transform::object_to_matrix3d( + matrix3d, activation, + )?; + // FIXME: 3D transformation is unsupported now. + let matrix = Matrix::from(matrix3d); + (matrix, true) + } else if let Some(matrix) = transform + .get_public_property("matrix", activation)? + .as_object() + { + let matrix = + crate::avm2::globals::flash::geom::transform::object_to_matrix(matrix, activation)?; + (matrix, false) + } else { + // FP seems to not do anything when setting to a Transform with a null matrix, + // but we don't actually support setting the matrix to null anyway + // (see the comment in `flash::geom::transform::set_matrix`) + return Ok(Value::Undefined); + } }; let color_transform = transform .get_public_property("colorTransform", activation)? .as_object() .expect("colorTransform should be non-null"); - - let matrix = - crate::avm2::globals::flash::geom::transform::object_to_matrix(matrix, activation)?; let color_transform = crate::avm2::globals::flash::geom::transform::object_to_color_transform( color_transform, activation, @@ -778,6 +790,7 @@ pub fn set_transform<'gc>( let mut write = dobj.base_mut(activation.context.gc_context); write.set_matrix(matrix); write.set_color_transform(color_transform); + write.set_mode_3d(mode_3d); drop(write); if let Some(parent) = dobj.parent() { // Self-transform changes are automatically handled, diff --git a/core/src/avm2/globals/flash/geom/transform.rs b/core/src/avm2/globals/flash/geom/transform.rs index 9de88c37ffbc..9201ebd7e1b1 100644 --- a/core/src/avm2/globals/flash/geom/transform.rs +++ b/core/src/avm2/globals/flash/geom/transform.rs @@ -243,7 +243,7 @@ fn matrix3d_to_object<'gc>( Ok(object.into()) } -fn object_to_matrix3d<'gc>( +pub fn object_to_matrix3d<'gc>( object: Object<'gc>, activation: &mut Activation<'_, 'gc>, ) -> Result> { diff --git a/tests/tests/swfs/avm2/geom_transform/Test.as b/tests/tests/swfs/avm2/geom_transform/Test.as index 850b2266a0da..844db36354ed 100644 --- a/tests/tests/swfs/avm2/geom_transform/Test.as +++ b/tests/tests/swfs/avm2/geom_transform/Test.as @@ -17,9 +17,8 @@ package { testCopy2D(); trace(""); - //// FIXME: transformation copy is unsupported now. - // testCopy3D(); - // trace(""); + testCopy3D(); + trace(""); testImageComparison(); } @@ -83,26 +82,24 @@ package { trace("sprite2.transform.matrix3D", sprite2.transform.matrix3D); } - //// FIXME - // private function testCopy3D() : void { - // var sprite1 : Sprite = new Sprite(); - // var sprite2 : Sprite = new Sprite(); - // - // trace("// Copy3D"); - // var mat3D : Matrix3D = new Matrix3D(); - // mat3D.appendRotation(1, Vector3D.Z_AXIS); - // mat3D.appendScale(2, 3, 4); - // mat3D.appendTranslation(5, 6, 7); - // sprite1.transform.matrix3D = mat3D; - // sprite2.transform = sprite1.transform; - // trace("sprite1.transform.matrix", sprite1.transform.matrix); - // trace("sprite1.transform.matrix3D", sprite1.transform.matrix3D); - // trace("sprite1.transform.matrix3D.rawData", sprite1.transform.matrix3D.rawData); - // trace("sprite2.transform.matrix", sprite2.transform.matrix); - // trace("sprite2.transform.matrix3D", sprite2.transform.matrix3D); - // trace("sprite2.transform.matrix3D.rawData", sprite2.transform.matrix3D.rawData); - // } + private function testCopy3D() : void { + var sprite1 : Sprite = new Sprite(); + var sprite2 : Sprite = new Sprite(); + trace("// Copy3D"); + var mat3D : Matrix3D = new Matrix3D(); + mat3D.appendRotation(1, Vector3D.Z_AXIS); + mat3D.appendScale(2, 3, 1); // FIXME: zScale shouldn't be one (1) for test coverage. Unsupported now. + mat3D.appendTranslation(5, 6, 0); // FIXME: z shouldn't be zero (0) for test coverage. Unsupported now. + sprite1.transform.matrix3D = mat3D; + sprite2.transform = sprite1.transform; + trace("sprite1.transform.matrix", sprite1.transform.matrix); + trace("sprite1.transform.matrix3D", sprite1.transform.matrix3D); + trace("sprite1.transform.matrix3D.rawData", sprite1.transform.matrix3D.rawData); + trace("sprite2.transform.matrix", sprite2.transform.matrix); + trace("sprite2.transform.matrix3D", sprite2.transform.matrix3D); + trace("sprite2.transform.matrix3D.rawData", sprite2.transform.matrix3D.rawData); + } private function testImageComparison() : void { var m : Matrix3D = new Matrix3D(); diff --git a/tests/tests/swfs/avm2/geom_transform/output.txt b/tests/tests/swfs/avm2/geom_transform/output.txt index 2455e3e6bfa9..026a92ab726f 100644 --- a/tests/tests/swfs/avm2/geom_transform/output.txt +++ b/tests/tests/swfs/avm2/geom_transform/output.txt @@ -22,3 +22,11 @@ sprite1.transform.matrix3D null sprite2.transform.matrix (a=1, b=2, c=3, d=4, tx=5, ty=6) sprite2.transform.matrix3D null +// Copy3D +sprite1.transform.matrix null +sprite1.transform.matrix3D [object Matrix3D] +sprite1.transform.matrix3D.rawData 1.9996954202651978,0.05235721915960312,0,0,-0.03490481153130531,2.9995431900024414,0,0,0,0,1,0,5,6,0,1 +sprite2.transform.matrix null +sprite2.transform.matrix3D [object Matrix3D] +sprite2.transform.matrix3D.rawData 1.9996954202651978,0.05235721915960312,0,0,-0.03490481153130531,2.9995431900024414,0,0,0,0,1,0,5,6,0,1 + diff --git a/tests/tests/swfs/avm2/geom_transform/test.swf b/tests/tests/swfs/avm2/geom_transform/test.swf index ae49d7394ebe362c6b9eb552333f9dfe8e50b988..fafd0a4bb4b2510a0d0ec577b99d31b587fbde4a 100644 GIT binary patch literal 2180 zcmV-~2z&QKS5qdy4gdgn0fkrHQybS6zxVEHuRcHsV*>_%tg#$QV)U^Kw!tV?SIhMzO)a06L@03_oaQ)_N@<@ z(zAD00)jnd=H5N$+;h(Fch3FLu!8u1Ak_6CLcJI%o%<0&?{xhWBXp*kFN|MPGUCc& zscemdc6P96+m-QTvR11lYI4G?E+o@qV`Isbl$4}l@EEpM%eJ~QT(*u5POt=uZsn>* z#Wu{c=q6M(bICqCIOu21=UPcCOVtufna?HllD?>yZ7Z2hq#;p0H(oHSi>f`LRw^YU zr@HBqE5laN%-yf4%ldGkq*}!@$t_1W#y0GdJ~3HQb46Xul=KyGax0uUdmgTDev9XX zUu6Lz5-N*kyja9`KR2$jq?HV-s8^dfb7sM=sZ{_pm&$p@lm%`%x?#DhuG;4R4Qjf% zAtklEu%s^N6MA|6#vIGpGO-F&Tc1$$oOt56D5azkkFIMxlXN@3Z6|ySZ0-b##+LS9 znH|15IX8D}_L_p~9dH76{3)@2ac9sJ+1%W`8|Gk1fWgP^|6PVtg3wpjD~}$6^tbSJ z-LlbN_Rh5-!*39aC3tF$AKJB_BR7LQNs2JX)OL1&5_!X_l+;x?;$qWnTrBG~(eo0EswI|}N+l6u ztHz3~h-x`6E~_OY@0<2F;}Sr$Y`Moa;W>v|2EjA*Ki5@Of-Qg@R4m;VjXc~8!(R0P zh0Bae*ehT`Hy49VkHfoSSH!cToH{P9!gn-VaSKGgf5fsMn5Xt|h8!O;K%?`rmeF4>=lo{fm7&gImS-s#EL-7{5Us{_wx+w6<)@+@*qmuHid6}(8SG^gd$L`xG( z0!bp8L@XI3nP@VxMnD=N+6b{mK^i66X!sSwUQ{dYJ_()}$d$~p9#r%BsiINJi@Q4V zty|hNKfhqk+va>;FBoORedXtida1%yOp6;ib%IZijGg4A(Nk$&mgE#aB9Ep+m(68E zpDGy@VOIMtG_>RVGF%V^ZnA2_!(VOlZien!t#;QAH{5gWoG#lsyeGD?tb3O39qUsj z{F)hMy~@qq$^>dg-Y#;ZsgzLEjfJ9ppvl(V#9frrV-lAhk!b*TlkRADPcQDijRq*@ zDG5+4P)sQfQXHaOJ0+cz?4e{Y<+~~ArKFFNeo78f{s<+3Ul?;1uzpFj@e700_s0BO4eH`s%3$j-dVqZo>mkf0oWrv_`*n4nkN5LplUf zY`qXHgffH-Ifp^*a@8 z2>6Q(Wi%U`iJ`UF6X%4-_#|T-c20rIz*fm)pdQ^Sc^p)?wnDhj$#|az!wVa}avnJF zln+NfbK85tCGj0}v4My1H1wEUaxS)*O#9Lk=T*q?BI9%^8;RpMiF0v29*7Gw5n(Oz z)VU0BkD--UHb78=&Mf%93dV&?>cQglvZRO-a-Bykc>Pc3e?_PlVgg|FF z^49>=S9I$eLq-FS<5B~kCT0Vl;VKP$majGNMBqUKpA+6{;FsxpxPd2w@5B5`=mVIi z!k@sbL_UT2eA`2qGwq+ld?ES>=8GL)V8`%#@wHQGb!u@V9)_b^c0W_=+Yu{Jb5(+Bt4&h~9Eq2_1K1)LQv zaO_JA$yc=i%l@F5ov`dV!Fem&s|j9y>b&jc|NeRs!+G*H<_8*WfxV*zG|E8MaJEki zF!4Ry1PnSq#9Hv!p9vuT2qXsiK5k-i9%jh-00U^q0}VSLVh{Dl81C@4SZi+~{|eG+?F{ZS7dgVj&s)e*=hs+^dTsuVFGZb4P3U3XtGdJa!bR@zkYmo5 zKJsq?*}c48vw!!k9{hd>uRmZd*5dUQU}-T%=8rC~C=>sL;V{Fm6b_xMr{FYG9c2#| z4yLk)3WrkJ!-d1CtXL3J*&~G`sVptfRQ5pO0Gn>3gWg}UAL0Z^6Y6UHQ}HtVj{Of# G!D^JEHZ$1( literal 2037 zcmV;=B!y+d2yNLY@1jGx@XR6WvPM?H?J*eXr~J%;LuO&{ueic=E?s4{%whaBM}zgedli~ObJ47G%EMr1L-f) z4b%0|pO5`rLMS+4YBx$EVSD=vy8T~nf1lfb{R@gn5QflyF6DXVlSq}FH8XXma5q&n zH&SlBl&U+mJ1(@|yl^3KN$RfX!Bf!$uLf48sG1bm=AG)6qV)yh!W#5v-dU^aHOqA> z(I7MxY!SCwvpf^RVTcq>TxM#VO--_Bxm8==g1MGkZqstbtjnR7T-IH=vToZl#MZ1$ zRg?8fQQpvPtJpLRw&Ie&uHpu>nhc$zZG#vZh92swYLPa;Au6uv$yO0Q2g}=P0*Y4{ z6)7xW)pXV(Esv2Sv77QmSxujlx8Rvg<4wHP#~K4Y*nshv4mzi3{Dxx{n|)GQpH%I1 zJC~|W%MaiIoI@t6*6e|*9qB={nDXYDa5OH5z8i zG@nWo_=n>$&^$Rp?!?0mRIM4KJS^tufvO!p(%BFnuMs!H8O01SGQ?FtQi!1tR|QEW zhDzKCkS2&RLEJ1zSz=_RXDn|`uLdm;Ls2N$PQ{Gq#o~O~vWqde4b4h%xuDx-u8CP;#7-K}t?g zGE8}yk_6>0QSNC<<|uiFl6lH&lsrpGj*{mn!IZm3$#p8eK)Geg-Jsly6tP<_icsee ztjAy_VO@r6k082$7rzGUd01CqU44n%{Q9k1xAEdPK>H>>F%%UL=J6aN7;$rm!HuUV|crf&~4Ffwl0StqXk8qq6+ryA>XeZsk5*lvc7(U|<=fy=4ZHu4z zry#78B_08(Yqvy8ksKjoz6@$_phlT`8q{OV?@V4=l+dAGhjHo z*Hm)Afv3C_`!Hzl<$%N}T4>`z7CfqhDP z7xwAc`>_-@qzibFB`zx*Ngk>*?{;T<3Lk#m%|FtmxHr`EPXgJP2!j1W_V}rKg-oS=nP=@ne zoIhp=Onei!FeCo=un{@?Cjy{vfy7YX#w}PbgpK;|V8D%rxRU>U90LCU!J8buFzS4u=9^&;oY;?DI{T{H4Zbs%00k2Lb{t?4G ziv;e