From ef719c323ef6109dcf372b1af7aa6f670e2cace7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 13 Mar 2023 19:55:09 -0500 Subject: [PATCH] avm2: Add several more Matrix3D methods These implementations are ported from the MIT-licensed OpenFL code. --- core/src/avm2/globals/flash/geom/Matrix3D.as | 156 +++++++++++++++---- tests/tests/swfs/avm2/matrix3d/Test.as | 45 +++++- tests/tests/swfs/avm2/matrix3d/output.txt | 15 ++ tests/tests/swfs/avm2/matrix3d/test.swf | Bin 697 -> 1052 bytes 4 files changed, 182 insertions(+), 34 deletions(-) diff --git a/core/src/avm2/globals/flash/geom/Matrix3D.as b/core/src/avm2/globals/flash/geom/Matrix3D.as index 2519214be..88d8eff09 100644 --- a/core/src/avm2/globals/flash/geom/Matrix3D.as +++ b/core/src/avm2/globals/flash/geom/Matrix3D.as @@ -119,38 +119,38 @@ package flash.geom { this._rawData[14] = oRawData[11]; } public function append(lhs:Matrix3D):void { - var m111:Number = this.rawData[0], - m121:Number = this.rawData[4], - m131:Number = this.rawData[8], - m141:Number = this.rawData[12], - m112:Number = this.rawData[1], - m122:Number = this.rawData[5], - m132:Number = this.rawData[9], - m142:Number = this.rawData[13], - m113:Number = this.rawData[2], - m123:Number = this.rawData[6], - m133:Number = this.rawData[10], - m143:Number = this.rawData[14], - m114:Number = this.rawData[3], - m124:Number = this.rawData[7], - m134:Number = this.rawData[11], - m144:Number = this.rawData[15], - m211:Number = lhs.rawData[0], - m221:Number = lhs.rawData[4], - m231:Number = lhs.rawData[8], - m241:Number = lhs.rawData[12], - m212:Number = lhs.rawData[1], - m222:Number = lhs.rawData[5], - m232:Number = lhs.rawData[9], - m242:Number = lhs.rawData[13], - m213:Number = lhs.rawData[2], - m223:Number = lhs.rawData[6], - m233:Number = lhs.rawData[10], - m243:Number = lhs.rawData[14], - m214:Number = lhs.rawData[3], - m224:Number = lhs.rawData[7], - m234:Number = lhs.rawData[11], - m244:Number = lhs.rawData[15]; + var m111:Number = this._rawData[0], + m121:Number = this._rawData[4], + m131:Number = this._rawData[8], + m141:Number = this._rawData[12], + m112:Number = this._rawData[1], + m122:Number = this._rawData[5], + m132:Number = this._rawData[9], + m142:Number = this._rawData[13], + m113:Number = this._rawData[2], + m123:Number = this._rawData[6], + m133:Number = this._rawData[10], + m143:Number = this._rawData[14], + m114:Number = this._rawData[3], + m124:Number = this._rawData[7], + m134:Number = this._rawData[11], + m144:Number = this._rawData[15], + m211:Number = lhs._rawData[0], + m221:Number = lhs._rawData[4], + m231:Number = lhs._rawData[8], + m241:Number = lhs._rawData[12], + m212:Number = lhs._rawData[1], + m222:Number = lhs._rawData[5], + m232:Number = lhs._rawData[9], + m242:Number = lhs._rawData[13], + m213:Number = lhs._rawData[2], + m223:Number = lhs._rawData[6], + m233:Number = lhs._rawData[10], + m243:Number = lhs._rawData[14], + m214:Number = lhs._rawData[3], + m224:Number = lhs._rawData[7], + m234:Number = lhs._rawData[11], + m244:Number = lhs._rawData[15]; this._rawData[0] = m111 * m211 + m112 * m221 + m113 * m231 + m114 * m241; this._rawData[1] = m111 * m212 + m112 * m222 + m113 * m232 + m114 * m242; @@ -180,8 +180,98 @@ package flash.geom { ]))); } + public function prependTranslation(x:Number, y:Number, z:Number):void { + var m = new Matrix3D(); + m.position = new Vector3D(x, y, z); + this.prepend(m); + } + + public function get position():Vector3D { + return new Vector3D(_rawData[12], _rawData[13], _rawData[14]); + } + + public function set position(val:Vector3D):void { + this._rawData[12] = val.x; + this._rawData[13] = val.y; + this._rawData[14] = val.z; + } + + public function prepend(rhs:Matrix3D):void { + var m111:Number = rhs._rawData[0], + m121:Number = rhs._rawData[4], + m131:Number = rhs._rawData[8], + m141:Number = rhs._rawData[12], + m112:Number = rhs._rawData[1], + m122:Number = rhs._rawData[5], + m132:Number = rhs._rawData[9], + m142:Number = rhs._rawData[13], + m113:Number = rhs._rawData[2], + m123:Number = rhs._rawData[6], + m133:Number = rhs._rawData[10], + m143:Number = rhs._rawData[14], + m114:Number = rhs._rawData[3], + m124:Number = rhs._rawData[7], + m134:Number = rhs._rawData[11], + m144:Number = rhs._rawData[15], + m211:Number = this._rawData[0], + m221:Number = this._rawData[4], + m231:Number = this._rawData[8], + m241:Number = this._rawData[12], + m212:Number = this._rawData[1], + m222:Number = this._rawData[5], + m232:Number = this._rawData[9], + m242:Number = this._rawData[13], + m213:Number = this._rawData[2], + m223:Number = this._rawData[6], + m233:Number = this._rawData[10], + m243:Number = this._rawData[14], + m214:Number = this._rawData[3], + m224:Number = this._rawData[7], + m234:Number = this._rawData[11], + m244:Number = this._rawData[15]; + + this._rawData[0] = m111 * m211 + m112 * m221 + m113 * m231 + m114 * m241; + this._rawData[1] = m111 * m212 + m112 * m222 + m113 * m232 + m114 * m242; + this._rawData[2] = m111 * m213 + m112 * m223 + m113 * m233 + m114 * m243; + this._rawData[3] = m111 * m214 + m112 * m224 + m113 * m234 + m114 * m244; + + this._rawData[4] = m121 * m211 + m122 * m221 + m123 * m231 + m124 * m241; + this._rawData[5] = m121 * m212 + m122 * m222 + m123 * m232 + m124 * m242; + this._rawData[6] = m121 * m213 + m122 * m223 + m123 * m233 + m124 * m243; + this._rawData[7] = m121 * m214 + m122 * m224 + m123 * m234 + m124 * m244; + + this._rawData[8] = m131 * m211 + m132 * m221 + m133 * m231 + m134 * m241; + this._rawData[9] = m131 * m212 + m132 * m222 + m133 * m232 + m134 * m242; + this._rawData[10] = m131 * m213 + m132 * m223 + m133 * m233 + m134 * m243; + this._rawData[11] = m131 * m214 + m132 * m224 + m133 * m234 + m134 * m244; + + this._rawData[12] = m141 * m211 + m142 * m221 + m143 * m231 + m144 * m241; + this._rawData[13] = m141 * m212 + m142 * m222 + m143 * m232 + m144 * m242; + this._rawData[14] = m141 * m213 + m142 * m223 + m143 * m233 + m144 * m243; + this._rawData[15] = m141 * m214 + m142 * m224 + m143 * m234 + m144 * m244; + } + + public function copyFrom(other:Matrix3D):void { + // This makes a copy of other.rawData + this._rawData = other.rawData; + } + + public function copyRawDataTo(vector:Vector., index:uint = 0, transpose:Boolean = false):void { + if (transpose) { + this.transpose(); + } + + for (var i = 0; i < rawData.length; i++) { + vector[i + index] = _rawData[i]; + } + + if (transpose) { + this.transpose(); + } + } + public function clone():Matrix3D { - return new Matrix3D(this.rawData.concat()); + return new Matrix3D(this.rawData); } } diff --git a/tests/tests/swfs/avm2/matrix3d/Test.as b/tests/tests/swfs/avm2/matrix3d/Test.as index 4bb06f4b6..72bb9ff09 100644 --- a/tests/tests/swfs/avm2/matrix3d/Test.as +++ b/tests/tests/swfs/avm2/matrix3d/Test.as @@ -1,11 +1,54 @@ package { import flash.geom.Matrix3D; + import flash.geom.Vector3D; + import flash.geom.Matrix; + public class Test { public function Test() { var mat = new Matrix3D(); trace("Mat:\n" + mat.rawData); mat.appendScale(1, 2, 3); - trace("after appendScale(1, 2, 3):\n" + mat.rawData) + trace("after appendScale(1, 2, 3):\n" + mat.rawData);; + + mat = new Matrix3D(Vector.([ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + ])); + + trace("Mat:\n" + mat.rawData); + + trace("mat.position = " + mat.position); + trace("// set mat.position = new Vector3D(12, 13, 14)"); + mat.position = new Vector3D(12, 13, 14); + trace("mat.position = " + mat.position); + + trace("after mat.prependTranslation(-1, 0, 2)"); + mat.prependTranslation(-1, 0, 2); + trace("mat.position = " + mat.position); + + trace("Mat:\n" + mat.rawData); + + trace("after mat.prepend(mat):"); + mat.prepend(mat); + trace(mat.rawData); + + var other = new Matrix3D(); + other.copyFrom(mat); + + trace("Other:"); + trace(other.rawData); + + var out = new Vector.(); + out.length = 20; + mat.copyRawDataTo(out, 1, false); + + trace("Out: " + out); + + mat.copyRawDataTo(out, 2, true); + + trace("Out: " + out); } } } \ 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 99fd1d3ac..15f91d4c8 100644 --- a/tests/tests/swfs/avm2/matrix3d/output.txt +++ b/tests/tests/swfs/avm2/matrix3d/output.txt @@ -2,3 +2,18 @@ Mat: 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 after appendScale(1, 2, 3): 1,0,0,0,0,2,0,0,0,0,3,0,0,0,0,1 +Mat: +1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 +mat.position = Vector3D(13, 14, 15) +// set mat.position = new Vector3D(12, 13, 14) +mat.position = Vector3D(12, 13, 14) +after mat.prependTranslation(-1, 0, 2) +mat.position = Vector3D(29, 31, 33) +Mat: +1,2,3,4,5,6,7,8,9,10,11,12,29,31,33,36 +after mat.prepend(mat): +154,168,182,200,330,364,398,440,506,560,614,680,1525,1690,1855,2056 +Other: +154,168,182,200,330,364,398,440,506,560,614,680,1525,1690,1855,2056 +Out: 0,154,168,182,200,330,364,398,440,506,560,614,680,1525,1690,1855,2056,0,0,0 +Out: 0,154,154,330,506,1525,168,364,560,1690,182,398,614,1855,200,440,680,2056,0,0 diff --git a/tests/tests/swfs/avm2/matrix3d/test.swf b/tests/tests/swfs/avm2/matrix3d/test.swf index 7d03b44ff488f8e6e8e0fefcdfd6f7ed65206ff0..8bcccb9e9e7327c28f1cf2d9592e501b4a5ecadf 100644 GIT binary patch literal 1052 zcmV+%1mpWdS5qsB1^@tfoP|^UP8&xM-?^{7^EY5@L!daY5IcZ<#w3ayRV~4xjU{TS zMo|=D*@wN3ueE*F`3%Xwd6K+IUI7QSeGHB#pmQ9gZj&mf+ufPp{O03!=H3#yK}hri zAt@l`8I=&SFI-<=uf)a+tiTSBSikc7&j*kA>nFzZ@gx3huhM;d+AENc^FibSskQik zrwfF9j7Jm?z$Zp>-my!xBR+ES-nQ=G*68$%(xG7vj?6yqnFF5xjCO3J&kLL1U`?Zv z7gnjB{Ki|3ddCP&Gr|ary1BMF8upBL+M#u7^8KDUod0S(#V_IE>(a4jAKmVwv(D() zIPLEo_YKE3-xk|XpL&^d#z;g&wwx}vMQiK?{A_Qy)mIOFYFTz{qs3)ZO95&dXJx}N z0=M3*_~d@qafYRQ-e_AVJlC@N`Mp{(zoYAq^Cx4o=a_?_F&y$iyVf##e97oI+)hs+ znZj0jXDeOImIBI4yavk-HX0bB(a4?hmh#KEf5Po3R+$@GBhxXhLHhf&dMD@d`Sgf8 z>HpXV{4DJUE0!|_3|}bX+RdtW;D%qvjhoHAVvcNMFzOjzfXp`5q+?mx*)NUBFFZ3S zXG`=}Q(M;X-GOcOm8y5EC8fs)Z=7z}gMamJ@5qv?W2cl}zUyIbx`(CPIf@wV_JJqW zTDCcK*8Yb)t%dyd@l!r&tz@>J5PRG`uh z^?zG|_@}o-T#_#fAZP*#qNK`11{pkqNCW`@1qDP2fD*t{JlB6hmpMt2uY{|xOV4#& zFUTcChAEQCabX z)TAC}A^T;mfH|a0oy3Hd`2YQVpZ}A53D5}ui7Nmy5R_92 z0AO3VySrOVp3fS2W8c?4oIc>zN4GLQu77k7n}#Tu=WL z1Awn2$OUE@sE5>JX0W|td^>4%NNJxqy+fx| zbE{f33zqfPJUw?h%;`nQU_g7#s!cj{p0pTsvlGbc{93lKmMyN7w1tOGa+95u#?y?G zW^*U-suM&F#(DxFG@XXZ%pB66i&%lG77?NlrZ7Yp%2-se zq+vOVaT3FnIt5i7sz|_a7RTnXw1A}-SX#tV7KhJL0HFodP12@?8v8}p@+#s6LK8^!_hQC;4X!H-|QT*qtAZd%G! z1w$X-7|;+5v7(B;!in?)q4G#U3Nbyhcr3B5H3X|69D#*41S|InByw0ES-gmPV~fir&q0~8@CQ|(I>