From 8f0a43f9d97a5729787f9d87938891b6eca00ead Mon Sep 17 00:00:00 2001 From: Fancy2209 <64917206+Fancy2209@users.noreply.github.com> Date: Fri, 30 Jun 2023 18:31:08 +0000 Subject: [PATCH] Add prependRotation, copyRowTo and copyRowFrom (#11698) Co-authored-by: Aaron Hill --- core/src/avm2/globals/flash/geom/Matrix3D.as | 76 ++++++++++++++++++- tests/tests/swfs/avm2/matrix3d/Test.as | 32 ++++++++ tests/tests/swfs/avm2/matrix3d/output.txt | 8 ++ tests/tests/swfs/avm2/matrix3d/test.swf | Bin 1580 -> 1950 bytes tests/tests/swfs/avm2/matrix3d/test.toml | 5 ++ 5 files changed, 120 insertions(+), 1 deletion(-) diff --git a/core/src/avm2/globals/flash/geom/Matrix3D.as b/core/src/avm2/globals/flash/geom/Matrix3D.as index 8f537eb7d..b6d3c4616 100644 --- a/core/src/avm2/globals/flash/geom/Matrix3D.as +++ b/core/src/avm2/globals/flash/geom/Matrix3D.as @@ -106,6 +106,74 @@ package flash.geom { } } + // Based on https://github.com/openfl/openfl/blob/develop/src/openfl/geom/Matrix3D.hx#L542C1-L573 + public function copyRowTo(row:uint, vector3D:Vector3D):void { + if (row > 3) { + throw new ArgumentError("Error #2004: One of the parameters is invalid.", 2004); + } + + switch (row) { + case 0: + vector3D.x = rawData[0]; + vector3D.y = rawData[4]; + vector3D.z = rawData[8]; + vector3D.w = rawData[12]; + break; + case 1: + vector3D.x = rawData[1]; + vector3D.y = rawData[5]; + vector3D.z = rawData[9]; + vector3D.w = rawData[13]; + break; + case 2: + vector3D.x = rawData[2]; + vector3D.y = rawData[6]; + vector3D.z = rawData[10]; + vector3D.w = rawData[14]; + break; + case 3: + vector3D.x = rawData[3]; + vector3D.y = rawData[7]; + vector3D.z = rawData[11]; + vector3D.w = rawData[15]; + break; + } + } + + // Based on https://github.com/openfl/openfl/blob/develop/src/openfl/geom/Matrix3D.hx#L504-L534 + public function copyRowFrom(row:uint, vector3D:Vector3D):void { + if (row > 3) { + throw new ArgumentError("Error #2004: One of the parameters is invalid.", 2004); + } + + switch (row) { + case 0: + _rawData[0] = vector3D.x; + _rawData[4] = vector3D.y; + _rawData[8] = vector3D.z; + _rawData[12] = vector3D.w; + break; + case 1: + _rawData[1] = vector3D.x; + _rawData[5] = vector3D.y; + _rawData[9] = vector3D.z; + _rawData[13] = vector3D.w; + break; + case 2: + _rawData[2] = vector3D.x; + _rawData[6] = vector3D.y; + _rawData[10] = vector3D.z; + _rawData[14] = vector3D.w; + break; + case 3: + _rawData[3] = vector3D.x; + _rawData[7] = vector3D.y; + _rawData[11] = vector3D.z; + _rawData[15] = vector3D.w; + break; + } + } + public function deltaTransformVector(v:Vector3D):Vector3D { var x:Number = this._rawData[0] * v.x + this._rawData[4] * v.y + this._rawData[8] * v.z; var y:Number = this._rawData[1] * v.x + this._rawData[5] * v.y + this._rawData[9] * v.z; @@ -206,6 +274,12 @@ package flash.geom { this.prepend(m); } + public function prependRotation(degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null):void { + var m = new Matrix3D(); + m.appendRotation(degrees, axis, pivotPoint); + this.prepend(m); + } + public function get position():Vector3D { return new Vector3D(_rawData[12], _rawData[13], _rawData[14]); } @@ -593,6 +667,6 @@ import flash.geom.Orientation3D; function checkOrientation(orientationStyle:String) { if (!(orientationStyle == Orientation3D.AXIS_ANGLE || orientationStyle == Orientation3D.EULER_ANGLES || orientationStyle == Orientation3D.QUATERNION)) { - throw new Error("Error #2187: Invalid orientation style " + orientationStyle + ". Value must be one of 'Orientation3D.EULER_ANGLES', 'Orientation3D.AXIS_ANGLE', or 'Orientation3D.QUATERNION'.", 2187); + throw new Error("Error #2187: Invalid orientation style " + orientationStyle + ". Value must be one of 'Orientation3D.EULER_ANGLES', 'Orientation3D.AXIS_ANGLE', or 'Orientation3D.QUATERNION'.", 2187); } } \ No newline at end of file diff --git a/tests/tests/swfs/avm2/matrix3d/Test.as b/tests/tests/swfs/avm2/matrix3d/Test.as index 1f2edecfb..598f66e38 100644 --- a/tests/tests/swfs/avm2/matrix3d/Test.as +++ b/tests/tests/swfs/avm2/matrix3d/Test.as @@ -83,6 +83,38 @@ } catch (e) { trace("Column 4: " + e); } + + var row = new Vector3D(); + for each (var i in [0, 1, 2, 3]) { + newMat.copyRowTo(i, row); + trace("Row: " + row + " w=" + row.w); + } + try { + newMat.copyRowTo(4, row); + } catch (e) { + trace("Row 4: " + e); + } + + var row0 = new Vector3D(100, 200, 300, 400); + var row1 = new Vector3D(500, 600, 700, 800); + var row2 = new Vector3D(900, 1000, 1100, 1200); + var row3 = new Vector3D(1300, 1400, 1500, 1600); + + newMat.copyRowFrom(0, row0); + newMat.copyRowFrom(1, row1); + newMat.copyRowFrom(2, row2); + newMat.copyRowFrom(3, row3); + + try { + newMat.copyRowFrom(4, row3) + } catch (e) { + trace("Copy from row 4: " + e); + } + + trace("After row copies: " + newMat.rawData); + + newMat.prependRotation(90, Vector3D.X_AXIS); + trace("After prependRotation: " + newMat.rawData); } } } \ No newline at end of file diff --git a/tests/tests/swfs/avm2/matrix3d/output.txt b/tests/tests/swfs/avm2/matrix3d/output.txt index fe6fd6831..c0bbf41e4 100644 --- a/tests/tests/swfs/avm2/matrix3d/output.txt +++ b/tests/tests/swfs/avm2/matrix3d/output.txt @@ -30,3 +30,11 @@ Column: Vector3D(5, 6, 7) w=8 Column: Vector3D(9, 10, 11) w=12 Column: Vector3D(13, 14, 15) w=16 Column 4: ArgumentError: Error #2004: One of the parameters is invalid. +Row: Vector3D(1, 5, 9) w=13 +Row: Vector3D(2, 6, 10) w=14 +Row: Vector3D(3, 7, 11) w=15 +Row: Vector3D(4, 8, 12) w=16 +Row 4: ArgumentError: Error #2004: One of the parameters is invalid. +Copy from row 4: ArgumentError: Error #2004: One of the parameters is invalid. +After row copies: 100,500,900,1300,200,600,1000,1400,300,700,1100,1500,400,800,1200,1600 +After prependRotation: 100,500,900,1300,300,700,1100,1500,-200,-600,-1000,-1400,400,800,1200,1600 diff --git a/tests/tests/swfs/avm2/matrix3d/test.swf b/tests/tests/swfs/avm2/matrix3d/test.swf index 3edb075a8c552a2685526ad0c4c02b24074734b0..e8bf1be7c4831fc21c9c794ed8b6a19d324e4291 100644 GIT binary patch literal 1950 zcmV;P2VwX_S5qrp4FCXmoUK>SPaD}Ce{X)hnX!#c0*3q`8N!(G+hd#r*4Z>65E9rB zZ(|nN)D#c)bL_3{q2s}Xo+{L9r9D)=mOr3}_FifC(yE6ZXsd2}s8m%|rQZ5d^{_Yk zeKR(4NV=;^wRqq8{(hhDcis=?6_R%liXJ00h|yB7iV#{9PESv-$M!FoDf4jNT-p8T zNp9}&!@2r*TbtiWt!+IkExbyh&-z2)i&3sf8`MZ4^jY6u!(0Ks7@9%CPkyK%ltefm;t&-jSgcd!u;}P!mh=8J5 znJHD9do}w|TXR}fx>&33^}jQp51U;cer)7Bk1yYFR;0iML; zsmqRA4`7b9#xv1#I{XSB;_u;utK7dtYmnjXpuTq*LhFuWG%Jn^v+10#IgOVYqyHfV zA8OQ{Qng$y`gLWDzJ;K&HF_f*Hg{_rbwB5_+ju-Si@I0r@7?_IC64~L6 z7M*<$x1<(yR`nbw$BQPwJcWwYpe9;UU_HS46^l*{S4Egvf?;uz;$)VS^iXF5&UA0U zO#2Y%u}h_8&gF`3bj|KIZSJ>2G(w1Z3Jrxtc_xA z91}c2@Fc-g1W#*8d)p^k+oR68%G>e^Zl1f^(#2gGif1+9J}&M0!Dj!(R}BCm$jVDc}VxXaX>z zq{>LfGUf&myfFqw!J>pQK^UImiS-yl`X#yN$D!8|Moz5Fi9cBX#65^mY@u;M|fxmyMAuYVUUM8bAv1S$VM?6*;WG| zZb_UqNMNI&7JRQ5W@8X*a*uJ}T?pJKDGpll5F$i21s2ilvwPWedj`?OH?tQ+mW1$| zT=s#a&aA>Hx2E5)-ln|%c7s?(=ECPvbrv z$f^>%3!yVS^!={T!65YBSBKv3dg&a|hR}YY3VQ%qE$~#@&3$;zm4olBjn2yGtP8Vu zqqm)iutiA38$#NN9(8*9wQ2bBI;yK|nNJNFR6nD}9z(`ikhONkC){SDX>4C&D_~1^ z**^FmV4p2#jXmY>XjOr?uCp~0eF00*58jZD{urA@2zK4?e>cMS-7`KJj1UYxds$#v zKyaH2$5VHX`Lle*N3u363cbHPJyk_jV9$A!DRp9Uv1yT!S z3N_4whahD03{seFeI=xiyC8+LR|WP0a=pieHl%PH(pER5?K4Pz%(u@V;SQu7NR#P? zwCk_rQsUP*@lzr3sR)bts2*WOu1@@0O#Deo{6bC~E55#mm3;jVNa7zP@f$VqGtJjW z8TIu)(i30mi9d%DpND;YjJ@;`A)t}$kiaUw$d`8y7puO=H*l1TpZKB(G{(jHSv9`c zIIBkJRO3K3?{`<@g5qA+(((KhFA7TeTK2lY_QCw1%iMY_o{+zgzY}EqP5qbprHYK7 z>!0ht(vcAx=4bs41b4s)KmAQ4DJX$t1&t#38n}tzk{Cnqkui=mgeH)V&?JKIh$#f0 z4$~-t;KQK@p(KhTWWi^Ie?N!=Cl=fT%66(CSOsAV4OKA665J9ZhC4F2FyQ{sLs9U2 z&hR!~#b}%fpq52Y$4@M{B(`T?uQP0-ld_zh6@04#>9xrdiz1#nZ53`=h1*u)j#Zem k3KINn;i2GH5nq3c4MNEMil7H42Br1 z)=G3uTYf|QPx6#^lGJ7&_i3Ng{srXpjO3EBcU`NZyU*o2 zm+n4&m={FfCnWWnkTD>uLna|)ML9V+xtu;Y#}-)b0bBp>(UY%oi#Pt!>QrkB-)=mv zEe9(u`DG-5SRmVF-sH{#A-@by+EReOG|3U==bsEh9uaGYcf!1!u7)`6SLR@+{KFU)=f)i2egTch~w8(t309%7&$kwihKmaF)kR^5APZ3TxuU#a`8 zkq`Pa;uL1SEVETssc)oCgha7n2Fv zORMHq3|`g4wpZplvIU#Ay`xnx^z5!ZTe>+>3&U0+pZ6-kGoC94jr{WVQhw2OZ{(jH z`1R0lCcIXQH!Is^ug))e)sVNHKFRdLoU=IREM*I}5ywvK@1u+T{oElh8;=ee&v-k9 znde$T#}ECW>D+eA9-YhQoemG3Q~D-9a(Ww?UO@K?OE|7)r{eGty3J({J8iGose96H zdLC18F`Mj}_m!jXSxzIJEzmA!mV?&IwRX@jieZhn3r3wcpNF-i6hDp+Z70x+2Vub( zl}Ua(Zl;j!yi&4c7nj^)Pgofvn5>*n$HW) z$UTl2?lgjmU-iq;z6#Fpa=f#5gab0~m7spmXzm1NOcWf|Il67fjB~x<09P?JJ&+q# zgM$zbwL{#Y83w_&3{H`Fh>^|MH?J6YFIY!vIjDm_-mBqUe+?J9?`Y7gRMsT5U2glW zaPq%^`?-O*iuoaLhMm-Xxvb*D@xn6Zmt2kCQ2g44Hk!C+uN?Y^JeFkM(XRx}5Iys@ zvE6F>A;0p`C-pRyfiXQpGuBvQlx9-8u8)j@nK`d#&S%y&YJz1almWB5CIRvkbP5Jl zO{&?{7@#yw=@5l8)-YJ3V4YJaT(HK$a=^L*)+AV0!I}aq3lwH3%u<-6FmL7I0$A6< znn&?XYJW!U0<~{Z`*UjFruG-qzC-Q1)Ly3cJ!-F5x=P_b9ehBw4XSNY?MtdXq;cO< zlz5dx#i7Nt0*a*|p=zd1bkIR6R73+HVSuUuPy)EB$L>0sjA*+3qxmK&=&}3N%s<_~ zV31G_&JRXI=P>cAVMTKS^&3Q(9QNoYC9fJFtUYt?EQdN&t=B~pge_?XOkrx#Rz(8U zV}0tRG%Y1c1KUs$gE5Y2BE@uOFv?7kW)`zqf(?ivmSlr0#nQX!W!R)3qYa;mmO=hv z#3v(u6!}Y%h+^&;Y(P5MG*mAs&Yi+uK>o5MA|X3rgek>ARg9m)T|O0a0{IC^T#-UK ziYXA2duEK0nyYUQND)&gRw7gy#5CG6iO5E9C5F#(h>zqRTBu?UH7XnShQxd~g391p z@r)|+XnsxdQ6dX(waS##F1@4ugv4-Sp=nNk5i%6q;xc5#$W%9k+ z=v79qF4)lSP}dO^E9gib2<Aes$q&X85%v9kw;6cqsK+$t**xhQpdX!O+U;ZCyzb$7=Jd}5|Y2dBfVvCVKu>>RIUG3Gs(u;)PtNY{kN%`&`$zV7V zIPBtiMHDfEPbBkt?#64mRxd=EY%QwF(61*arfMqUv9w}Z&t^M)iI8LWH}`8Y^XH5^ ziw|lC-F(WGI!NPjG}&E;WBPCUA4)DJ#$_+LM6kzPmfgi6nn5OrZjdVkKeQ$ZHX%mv z`|T>R2$>@IEq0A0NYrN3(PJ0eiLp0bQrwdAgpAh!c@3M53fNEMzJqPZPNWdIDqs&b zfn*6gv%iF7^VmS)}3oLicAOF6fs;olP& ekAF4w&6XHLlRIb6cbnt~|0j{VsQDXQjJ7F7CKGx9 diff --git a/tests/tests/swfs/avm2/matrix3d/test.toml b/tests/tests/swfs/avm2/matrix3d/test.toml index dbee897f5..aa1397abe 100644 --- a/tests/tests/swfs/avm2/matrix3d/test.toml +++ b/tests/tests/swfs/avm2/matrix3d/test.toml @@ -1 +1,6 @@ num_frames = 1 + +[approximations] +epsilon = 0.001 +# Based on https://stackoverflow.com/questions/12643009/regular-expression-for-floating-point-numbers#comment101152072_12643009 +number_patterns = ['([-+]?(?:[0-9]*[.])?[0-9]+(?:[eE][-+]?\d+)?|(?:NaN))'] \ No newline at end of file