import { ASObject } from '@awayfl/avm2'; import { DataBuffer } from '@awayjs/graphics'; import { Point } from './Point'; import { Vector3D } from './Vector3D'; import { Matrix as AwayMatrix } from '@awayjs/core'; import { SecurityDomain } from '../SecurityDomain'; export class Matrix extends ASObject { private _adaptee: AwayMatrix; static axClass: typeof Matrix; static classInitializer() { this.FROZEN_IDENTITY_MATRIX = Object.freeze(this.axConstruct([])); this.TEMP_MATRIX = this.axConstruct([]); } static classSymbols: string [] = null; // []; static instanceSymbols: string [] = null; // ["a", "b", "c", "d", "tx", "ty", "concat", // "invert", "identity", "createBox", // "createGradientBox", "rotate", "translate", // "scale", "deltaTransformPoint", "transformPoint", // "copyFrom", "setTo", "copyRowTo", "copyColumnTo", // "copyRowFrom", "copyColumnFrom", "clone", // "toString"]; public get adaptee(): AwayMatrix { return this._adaptee; } /** * The value that affects the positioning of pixels along the x axis * when scaling or rotating an image. */ public get a(): number { return this._adaptee.rawData[0]; } public set a(value: number) { this._adaptee.rawData[0] = value; } /** * The value that affects the positioning of pixels along the y axis * when rotating or skewing an image. */ public get b(): number { return this._adaptee.rawData[1]; } public set b(value: number) { this._adaptee.rawData[1] = value; } /** * The value that affects the positioning of pixels along the x axis * when rotating or skewing an image. */ public get c(): number { return this._adaptee.rawData[2]; } public set c(value: number) { this._adaptee.rawData[2] = value; } /** * The value that affects the positioning of pixels along the y axis * when scaling or rotating an image. */ public get d(): number { return this._adaptee.rawData[3]; } public set d(value: number) { this._adaptee.rawData[3] = value; } /** * The distance by which to translate each point along the x axis. */ public get tx(): number { return this._adaptee.rawData[4]; } public set tx(value: number) { this._adaptee.rawData[4] = value; } /** * The distance by which to translate each point along the y axis. */ public get ty(): number { return this._adaptee.rawData[5]; } public set ty(value: number) { this._adaptee.rawData[5] = value; } /** * Creates a new Matrix object with the specified parameters. In matrix * notation, the properties are organized like this: * *

If you do not provide any parameters to the new Matrix() * constructor, it creates an identity matrix with the following * values:

* *

In matrix notation, the identity matrix looks like this:

* * @param a The value that affects the positioning of pixels along the * x axis when scaling or rotating an image. * @param b The value that affects the positioning of pixels along the * y axis when rotating or skewing an image. * @param c The value that affects the positioning of pixels along the * x axis when rotating or skewing an image. * @param d The value that affects the positioning of pixels along the * y axis when scaling or rotating an image.. * @param tx The distance by which to translate each point along the x * axis. * @param ty The distance by which to translate each point along the y * axis. */ constructor(aAdaptee: number | AwayMatrix = 1, b: number = 0, c: number = 0, d: number = 1, tx: number = 0, ty: number = 0) { super(); this._adaptee = (aAdaptee instanceof AwayMatrix) ? aAdaptee : new AwayMatrix(+aAdaptee, +b, +c, +d, +tx, +ty); } public static FromUntyped(object: any): Matrix { return new ( this.sec).flash.geom.Matrix(object.a, object.b, object.c, object.d, object.tx, object.ty); } // Keep in sync with writeExternal below! public static FromDataBuffer(input: DataBuffer) { return new ( this.sec).flash.geom.Matrix(input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); } public static FROZEN_IDENTITY_MATRIX: Matrix; // Must only be used in cases where the members are fully initialized and then directly used. public static TEMP_MATRIX: Matrix; /** * Concatenates a matrix with the current matrix, effectively combining the * geometric effects of the two. In mathematical terms, concatenating two * matrixes is the same as combining them using matrix multiplication. * *

For example, if matrix m1 scales an object by a factor of * four, and matrix m2 rotates an object by 1.5707963267949 * radians(Math.PI/2), then m1.concat(m2) * transforms m1 into a matrix that scales an object by a factor * of four and rotates the object by Math.PI/2 radians.

* *

This method replaces the source matrix with the concatenated matrix. If * you want to concatenate two matrixes without altering either of the two * source matrixes, first copy the source matrix by using the * clone() method, as shown in the Class Examples section.

* * @param matrix The matrix to be concatenated to the source matrix. */ public concat(other: Matrix): void { this._adaptee.concat(other.adaptee); } /** * Performs the opposite transformation of the original matrix. You can apply * an inverted matrix to an object to undo the transformation performed when * applying the original matrix. */ public invert(): void { this._adaptee.invert(); } /** * Sets each matrix property to a value that causes a null transformation. An * object transformed by applying an identity matrix will be identical to the * original. * *

After calling the identity() method, the resulting matrix * has the following properties: a=1, b=0, * c=0, d=1, tx=0, * ty=0.

* *

In matrix notation, the identity matrix looks like this:

* */ public identity(): void { this._adaptee.identity(); } /** * Includes parameters for scaling, rotation, and translation. When applied * to a matrix it sets the matrix's values based on those parameters. * *

Using the createBox() method lets you obtain the same * matrix as you would if you applied the identity(), * rotate(), scale(), and translate() * methods in succession. For example, mat1.createBox(2,2,Math.PI/4, * 100, 100) has the same effect as the following:

* * @param scaleX The factor by which to scale horizontally. * @param scaleY The factor by which scale vertically. * @param rotation The amount to rotate, in radians. * @param tx The number of pixels to translate(move) to the right * along the x axis. * @param ty The number of pixels to translate(move) down along the * y axis. */ public createBox(scaleX: number, scaleY: number, rotation: number = 0, tx: number = 0, ty: number = 0): void { this._adaptee.createBox(scaleX, scaleY, rotation, tx, ty); } /** * Creates the specific style of matrix expected by the * beginGradientFill() and lineGradientStyle() * methods of the Graphics class. Width and height are scaled to a * scaleX/scaleY pair and the * tx/ty values are offset by half the width and * height. * *

For example, consider a gradient with the following * characteristics:

* * * *

The following illustrations show gradients in which the matrix was * defined using the createGradientBox() method with different * parameter settings:

* * @param width The width of the gradient box. * @param height The height of the gradient box. * @param rotation The amount to rotate, in radians. * @param tx The distance, in pixels, to translate to the right along * the x axis. This value is offset by half of the * width parameter. * @param ty The distance, in pixels, to translate down along the * y axis. This value is offset by half of the * height parameter. */ public createGradientBox(width: number, height: number, rotation: number = 0, tx: number = 0, ty: number = 0): void { this._adaptee.createGradientBox(width, height, rotation, tx, ty); } /** * Applies a rotation transformation to the Matrix object. * *

The rotate() method alters the a, * b, c, and d properties of the * Matrix object. In matrix notation, this is the same as concatenating the * current matrix with the following:

* * @param angle The rotation angle in radians. */ public rotate(angle: number): void { this._adaptee.rotate(angle); } /** * Translates the matrix along the x and y axes, as specified * by the dx and dy parameters. * * @param dx The amount of movement along the x axis to the right, in * pixels. * @param dy The amount of movement down along the y axis, in pixels. */ public translate(dx: number, dy: number): void { this._adaptee.translate(dx, dy); } /** * Applies a scaling transformation to the matrix. The x axis is * multiplied by sx, and the y axis it is multiplied by * sy. * *

The scale() method alters the a and * d properties of the Matrix object. In matrix notation, this * is the same as concatenating the current matrix with the following * matrix:

* * @param sx A multiplier used to scale the object along the x axis. * @param sy A multiplier used to scale the object along the y axis. */ public scale(sx: number, sy: number): void { this._adaptee.scale(sx, sy); } /** * Given a point in the pretransform coordinate space, returns the * coordinates of that point after the transformation occurs. Unlike the * standard transformation applied using the transformPoint() * method, the deltaTransformPoint() method's transformation * does not consider the translation parameters tx and * ty. * * @param point The point for which you want to get the result of the matrix * transformation. * @return The point resulting from applying the matrix transformation. */ public deltaTransformPoint(point: Point): Point { return new ( this.sec).flash.geom.Point(this._adaptee.deltaTransformPoint(point.adaptee)); } /** * Returns the result of applying the geometric transformation represented by * the Matrix object to the specified point. * * @param point The point for which you want to get the result of the Matrix * transformation. * @return The point resulting from applying the Matrix transformation. */ public transformPoint(point: Point): Point { return new ( this.sec).flash.geom.Point(this._adaptee.transformPoint(point.adaptee)); } /** * Copies all of the matrix data from the source Point object into the * calling Matrix object. * * @param sourceMatrix The Matrix object from which to copy the data. */ public copyFrom(sourceMatrix: Matrix): void { this._adaptee.copyFrom(sourceMatrix.adaptee); } /** * Sets the members of Matrix to the specified values. * * @param a The value that affects the positioning of pixels along the * x axis when scaling or rotating an image. * @param b The value that affects the positioning of pixels along the * y axis when rotating or skewing an image. * @param c The value that affects the positioning of pixels along the * x axis when rotating or skewing an image. * @param d The value that affects the positioning of pixels along the * y axis when scaling or rotating an image.. * @param tx The distance by which to translate each point along the x * axis. * @param ty The distance by which to translate each point along the y * axis. */ public setTo(a: number, b: number, c: number, d: number, tx: number, ty: number): void { this._adaptee.setTo(a, b, c, d, tx, ty); } /** * Copies specific row of the calling Matrix object into the Vector3D object. * The w element of the Vector3D object will not be changed. * * @param row The row from which to copy the data from. * @param vector3D The Vector3D object from which to copy the data. */ public copyRowTo(row: number, vector3D: Vector3D): void { this._adaptee.copyRowTo(row, vector3D.adaptee); } /** * Copies specific column of the calling Matrix object into the Vector3D * object. The w element of the Vector3D object will not be changed. * * @param column The column from which to copy the data from. * @param vector3D The Vector3D object from which to copy the data. */ public copyColumnTo(column: number, vector3D: Vector3D): void { this._adaptee.copyColumnTo(column, vector3D.adaptee); } /** * Copies a Vector3D object into specific row of the calling Matrix object. * * @param row The row from which to copy the data from. * @param vector3D The Vector3D object from which to copy the data. */ public copyRowFrom(row: number, vector3D: Vector3D): void { this._adaptee.copyRowFrom(row, vector3D.adaptee); } /** * Copies a Vector3D object into specific column of the calling Matrix3D * object. * * @param column The column from which to copy the data from. * @param vector3D The Vector3D object from which to copy the data. */ public copyColumnFrom(column: number, vector3D: Vector3D): void { this._adaptee.copyColumnFrom(column, vector3D.adaptee); } /** * Returns a new Matrix object that is a clone of this matrix, with an exact * copy of the contained object. * * @return A Matrix object. */ public clone(): Matrix { return new ( this.sec).flash.geom.Matrix(this._adaptee.clone()); } public toString(): string { const m = this._adaptee.rawData; return '(a=' + m[0] + ', b=' + m[1] + ', c=' + m[2] + ', d=' + m[3] + ', tx=' + m[4] + ', ty=' + m[5] + ')'; } // Keep in sync with static FromDataBuffer above! public writeExternal(output: DataBuffer) { const m = this._adaptee.rawData; output.writeFloat(m[0]); output.writeFloat(m[1]); output.writeFloat(m[2]); output.writeFloat(m[3]); output.writeFloat(m[4]); output.writeFloat(m[5]); } }