UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.

745 lines (657 loc) 22.2 kB
/** * @author Richard Davey <rich@photonstorm.com> * @copyright 2019 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** * Implements a model view projection matrices. * Pipelines can implement this for doing 2D and 3D rendering. * * @namespace Phaser.Renderer.WebGL.Pipelines.ModelViewProjection * @since 3.0.0 */ var ModelViewProjection = { /** * Dirty flag for checking if model matrix needs to be updated on GPU. * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelMatrixDirty * @type {boolean} * @since 3.0.0 */ modelMatrixDirty: false, /** * Dirty flag for checking if view matrix needs to be updated on GPU. * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewMatrixDirty * @type {boolean} * @since 3.0.0 */ viewMatrixDirty: false, /** * Dirty flag for checking if projection matrix needs to be updated on GPU. * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projectionMatrixDirty * @type {boolean} * @since 3.0.0 */ projectionMatrixDirty: false, /** * Model matrix * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelMatrix * @type {?Float32Array} * @since 3.0.0 */ modelMatrix: null, /** * View matrix * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewMatrix * @type {?Float32Array} * @since 3.0.0 */ viewMatrix: null, /** * Projection matrix * * @name Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projectionMatrix * @type {?Float32Array} * @since 3.0.0 */ projectionMatrix: null, /** * Initializes MVP matrices with an identity matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#mvpInit * @since 3.0.0 */ mvpInit: function () { this.modelMatrixDirty = true; this.viewMatrixDirty = true; this.projectionMatrixDirty = true; this.modelMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); this.viewMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); this.projectionMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); return this; }, /** * If dirty flags are set then the matrices are uploaded to the GPU. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#mvpUpdate * @since 3.0.0 */ mvpUpdate: function () { var program = this.program; if (this.modelMatrixDirty) { this.renderer.setMatrix4(program, 'uModelMatrix', false, this.modelMatrix); this.modelMatrixDirty = false; } if (this.viewMatrixDirty) { this.renderer.setMatrix4(program, 'uViewMatrix', false, this.viewMatrix); this.viewMatrixDirty = false; } if (this.projectionMatrixDirty) { this.renderer.setMatrix4(program, 'uProjectionMatrix', false, this.projectionMatrix); this.projectionMatrixDirty = false; } return this; }, /** * Loads an identity matrix to the model matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelIdentity * @since 3.0.0 */ modelIdentity: function () { var modelMatrix = this.modelMatrix; modelMatrix[0] = 1; modelMatrix[1] = 0; modelMatrix[2] = 0; modelMatrix[3] = 0; modelMatrix[4] = 0; modelMatrix[5] = 1; modelMatrix[6] = 0; modelMatrix[7] = 0; modelMatrix[8] = 0; modelMatrix[9] = 0; modelMatrix[10] = 1; modelMatrix[11] = 0; modelMatrix[12] = 0; modelMatrix[13] = 0; modelMatrix[14] = 0; modelMatrix[15] = 1; this.modelMatrixDirty = true; return this; }, /** * Scale model matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelScale * @since 3.0.0 * * @param {number} x - The x component. * @param {number} y - The y component. * @param {number} z - The z component. * * @return {this} This Model View Projection. */ modelScale: function (x, y, z) { var modelMatrix = this.modelMatrix; modelMatrix[0] = modelMatrix[0] * x; modelMatrix[1] = modelMatrix[1] * x; modelMatrix[2] = modelMatrix[2] * x; modelMatrix[3] = modelMatrix[3] * x; modelMatrix[4] = modelMatrix[4] * y; modelMatrix[5] = modelMatrix[5] * y; modelMatrix[6] = modelMatrix[6] * y; modelMatrix[7] = modelMatrix[7] * y; modelMatrix[8] = modelMatrix[8] * z; modelMatrix[9] = modelMatrix[9] * z; modelMatrix[10] = modelMatrix[10] * z; modelMatrix[11] = modelMatrix[11] * z; this.modelMatrixDirty = true; return this; }, /** * Translate model matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelTranslate * @since 3.0.0 * * @param {number} x - The x component. * @param {number} y - The y component. * @param {number} z - The z component. * * @return {this} This Model View Projection. */ modelTranslate: function (x, y, z) { var modelMatrix = this.modelMatrix; modelMatrix[12] = modelMatrix[0] * x + modelMatrix[4] * y + modelMatrix[8] * z + modelMatrix[12]; modelMatrix[13] = modelMatrix[1] * x + modelMatrix[5] * y + modelMatrix[9] * z + modelMatrix[13]; modelMatrix[14] = modelMatrix[2] * x + modelMatrix[6] * y + modelMatrix[10] * z + modelMatrix[14]; modelMatrix[15] = modelMatrix[3] * x + modelMatrix[7] * y + modelMatrix[11] * z + modelMatrix[15]; this.modelMatrixDirty = true; return this; }, /** * Rotates the model matrix in the X axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateX * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ modelRotateX: function (radians) { var modelMatrix = this.modelMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a10 = modelMatrix[4]; var a11 = modelMatrix[5]; var a12 = modelMatrix[6]; var a13 = modelMatrix[7]; var a20 = modelMatrix[8]; var a21 = modelMatrix[9]; var a22 = modelMatrix[10]; var a23 = modelMatrix[11]; modelMatrix[4] = a10 * c + a20 * s; modelMatrix[5] = a11 * c + a21 * s; modelMatrix[6] = a12 * c + a22 * s; modelMatrix[7] = a13 * c + a23 * s; modelMatrix[8] = a20 * c - a10 * s; modelMatrix[9] = a21 * c - a11 * s; modelMatrix[10] = a22 * c - a12 * s; modelMatrix[11] = a23 * c - a13 * s; this.modelMatrixDirty = true; return this; }, /** * Rotates the model matrix in the Y axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateY * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ modelRotateY: function (radians) { var modelMatrix = this.modelMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a00 = modelMatrix[0]; var a01 = modelMatrix[1]; var a02 = modelMatrix[2]; var a03 = modelMatrix[3]; var a20 = modelMatrix[8]; var a21 = modelMatrix[9]; var a22 = modelMatrix[10]; var a23 = modelMatrix[11]; modelMatrix[0] = a00 * c - a20 * s; modelMatrix[1] = a01 * c - a21 * s; modelMatrix[2] = a02 * c - a22 * s; modelMatrix[3] = a03 * c - a23 * s; modelMatrix[8] = a00 * s + a20 * c; modelMatrix[9] = a01 * s + a21 * c; modelMatrix[10] = a02 * s + a22 * c; modelMatrix[11] = a03 * s + a23 * c; this.modelMatrixDirty = true; return this; }, /** * Rotates the model matrix in the Z axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#modelRotateZ * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ modelRotateZ: function (radians) { var modelMatrix = this.modelMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a00 = modelMatrix[0]; var a01 = modelMatrix[1]; var a02 = modelMatrix[2]; var a03 = modelMatrix[3]; var a10 = modelMatrix[4]; var a11 = modelMatrix[5]; var a12 = modelMatrix[6]; var a13 = modelMatrix[7]; modelMatrix[0] = a00 * c + a10 * s; modelMatrix[1] = a01 * c + a11 * s; modelMatrix[2] = a02 * c + a12 * s; modelMatrix[3] = a03 * c + a13 * s; modelMatrix[4] = a10 * c - a00 * s; modelMatrix[5] = a11 * c - a01 * s; modelMatrix[6] = a12 * c - a02 * s; modelMatrix[7] = a13 * c - a03 * s; this.modelMatrixDirty = true; return this; }, /** * Loads identity matrix into the view matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewIdentity * @since 3.0.0 * * @return {this} This Model View Projection. */ viewIdentity: function () { var viewMatrix = this.viewMatrix; viewMatrix[0] = 1; viewMatrix[1] = 0; viewMatrix[2] = 0; viewMatrix[3] = 0; viewMatrix[4] = 0; viewMatrix[5] = 1; viewMatrix[6] = 0; viewMatrix[7] = 0; viewMatrix[8] = 0; viewMatrix[9] = 0; viewMatrix[10] = 1; viewMatrix[11] = 0; viewMatrix[12] = 0; viewMatrix[13] = 0; viewMatrix[14] = 0; viewMatrix[15] = 1; this.viewMatrixDirty = true; return this; }, /** * Scales view matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewScale * @since 3.0.0 * * @param {number} x - The x component. * @param {number} y - The y component. * @param {number} z - The z component. * * @return {this} This Model View Projection. */ viewScale: function (x, y, z) { var viewMatrix = this.viewMatrix; viewMatrix[0] = viewMatrix[0] * x; viewMatrix[1] = viewMatrix[1] * x; viewMatrix[2] = viewMatrix[2] * x; viewMatrix[3] = viewMatrix[3] * x; viewMatrix[4] = viewMatrix[4] * y; viewMatrix[5] = viewMatrix[5] * y; viewMatrix[6] = viewMatrix[6] * y; viewMatrix[7] = viewMatrix[7] * y; viewMatrix[8] = viewMatrix[8] * z; viewMatrix[9] = viewMatrix[9] * z; viewMatrix[10] = viewMatrix[10] * z; viewMatrix[11] = viewMatrix[11] * z; this.viewMatrixDirty = true; return this; }, /** * Translates view matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewTranslate * @since 3.0.0 * * @param {number} x - The x component. * @param {number} y - The y component. * @param {number} z - The z component. * * @return {this} This Model View Projection. */ viewTranslate: function (x, y, z) { var viewMatrix = this.viewMatrix; viewMatrix[12] = viewMatrix[0] * x + viewMatrix[4] * y + viewMatrix[8] * z + viewMatrix[12]; viewMatrix[13] = viewMatrix[1] * x + viewMatrix[5] * y + viewMatrix[9] * z + viewMatrix[13]; viewMatrix[14] = viewMatrix[2] * x + viewMatrix[6] * y + viewMatrix[10] * z + viewMatrix[14]; viewMatrix[15] = viewMatrix[3] * x + viewMatrix[7] * y + viewMatrix[11] * z + viewMatrix[15]; this.viewMatrixDirty = true; return this; }, /** * Rotates view matrix in the X axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateX * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ viewRotateX: function (radians) { var viewMatrix = this.viewMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a10 = viewMatrix[4]; var a11 = viewMatrix[5]; var a12 = viewMatrix[6]; var a13 = viewMatrix[7]; var a20 = viewMatrix[8]; var a21 = viewMatrix[9]; var a22 = viewMatrix[10]; var a23 = viewMatrix[11]; viewMatrix[4] = a10 * c + a20 * s; viewMatrix[5] = a11 * c + a21 * s; viewMatrix[6] = a12 * c + a22 * s; viewMatrix[7] = a13 * c + a23 * s; viewMatrix[8] = a20 * c - a10 * s; viewMatrix[9] = a21 * c - a11 * s; viewMatrix[10] = a22 * c - a12 * s; viewMatrix[11] = a23 * c - a13 * s; this.viewMatrixDirty = true; return this; }, /** * Rotates view matrix in the Y axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateY * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ viewRotateY: function (radians) { var viewMatrix = this.viewMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a00 = viewMatrix[0]; var a01 = viewMatrix[1]; var a02 = viewMatrix[2]; var a03 = viewMatrix[3]; var a20 = viewMatrix[8]; var a21 = viewMatrix[9]; var a22 = viewMatrix[10]; var a23 = viewMatrix[11]; viewMatrix[0] = a00 * c - a20 * s; viewMatrix[1] = a01 * c - a21 * s; viewMatrix[2] = a02 * c - a22 * s; viewMatrix[3] = a03 * c - a23 * s; viewMatrix[8] = a00 * s + a20 * c; viewMatrix[9] = a01 * s + a21 * c; viewMatrix[10] = a02 * s + a22 * c; viewMatrix[11] = a03 * s + a23 * c; this.viewMatrixDirty = true; return this; }, /** * Rotates view matrix in the Z axis. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewRotateZ * @since 3.0.0 * * @param {number} radians - The amount to rotate by. * * @return {this} This Model View Projection. */ viewRotateZ: function (radians) { var viewMatrix = this.viewMatrix; var s = Math.sin(radians); var c = Math.cos(radians); var a00 = viewMatrix[0]; var a01 = viewMatrix[1]; var a02 = viewMatrix[2]; var a03 = viewMatrix[3]; var a10 = viewMatrix[4]; var a11 = viewMatrix[5]; var a12 = viewMatrix[6]; var a13 = viewMatrix[7]; viewMatrix[0] = a00 * c + a10 * s; viewMatrix[1] = a01 * c + a11 * s; viewMatrix[2] = a02 * c + a12 * s; viewMatrix[3] = a03 * c + a13 * s; viewMatrix[4] = a10 * c - a00 * s; viewMatrix[5] = a11 * c - a01 * s; viewMatrix[6] = a12 * c - a02 * s; viewMatrix[7] = a13 * c - a03 * s; this.viewMatrixDirty = true; return this; }, /** * Loads a 2D view matrix (3x2 matrix) into a 4x4 view matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewLoad2D * @since 3.0.0 * * @param {Float32Array} matrix2D - The Matrix2D. * * @return {this} This Model View Projection. */ viewLoad2D: function (matrix2D) { var vm = this.viewMatrix; vm[0] = matrix2D[0]; vm[1] = matrix2D[1]; vm[2] = 0.0; vm[3] = 0.0; vm[4] = matrix2D[2]; vm[5] = matrix2D[3]; vm[6] = 0.0; vm[7] = 0.0; vm[8] = matrix2D[4]; vm[9] = matrix2D[5]; vm[10] = 1.0; vm[11] = 0.0; vm[12] = 0.0; vm[13] = 0.0; vm[14] = 0.0; vm[15] = 1.0; this.viewMatrixDirty = true; return this; }, /** * Copies a 4x4 matrix into the view matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#viewLoad * @since 3.0.0 * * @param {Float32Array} matrix - The Matrix2D. * * @return {this} This Model View Projection. */ viewLoad: function (matrix) { var vm = this.viewMatrix; vm[0] = matrix[0]; vm[1] = matrix[1]; vm[2] = matrix[2]; vm[3] = matrix[3]; vm[4] = matrix[4]; vm[5] = matrix[5]; vm[6] = matrix[6]; vm[7] = matrix[7]; vm[8] = matrix[8]; vm[9] = matrix[9]; vm[10] = matrix[10]; vm[11] = matrix[11]; vm[12] = matrix[12]; vm[13] = matrix[13]; vm[14] = matrix[14]; vm[15] = matrix[15]; this.viewMatrixDirty = true; return this; }, /** * Loads identity matrix into the projection matrix. * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projIdentity * @since 3.0.0 * * @return {this} This Model View Projection. */ projIdentity: function () { var projectionMatrix = this.projectionMatrix; projectionMatrix[0] = 1; projectionMatrix[1] = 0; projectionMatrix[2] = 0; projectionMatrix[3] = 0; projectionMatrix[4] = 0; projectionMatrix[5] = 1; projectionMatrix[6] = 0; projectionMatrix[7] = 0; projectionMatrix[8] = 0; projectionMatrix[9] = 0; projectionMatrix[10] = 1; projectionMatrix[11] = 0; projectionMatrix[12] = 0; projectionMatrix[13] = 0; projectionMatrix[14] = 0; projectionMatrix[15] = 1; this.projectionMatrixDirty = true; return this; }, /** * Sets up an orthographic projection matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projOrtho * @since 3.0.0 * * @param {number} left - The left value. * @param {number} right - The right value. * @param {number} bottom - The bottom value. * @param {number} top - The top value. * @param {number} near - The near value. * @param {number} far - The far value. * * @return {this} This Model View Projection. */ projOrtho: function (left, right, bottom, top, near, far) { var projectionMatrix = this.projectionMatrix; var leftRight = 1.0 / (left - right); var bottomTop = 1.0 / (bottom - top); var nearFar = 1.0 / (near - far); projectionMatrix[0] = -2.0 * leftRight; projectionMatrix[1] = 0.0; projectionMatrix[2] = 0.0; projectionMatrix[3] = 0.0; projectionMatrix[4] = 0.0; projectionMatrix[5] = -2.0 * bottomTop; projectionMatrix[6] = 0.0; projectionMatrix[7] = 0.0; projectionMatrix[8] = 0.0; projectionMatrix[9] = 0.0; projectionMatrix[10] = 2.0 * nearFar; projectionMatrix[11] = 0.0; projectionMatrix[12] = (left + right) * leftRight; projectionMatrix[13] = (top + bottom) * bottomTop; projectionMatrix[14] = (far + near) * nearFar; projectionMatrix[15] = 1.0; this.projectionMatrixDirty = true; return this; }, /** * Sets up a perspective projection matrix * * @method Phaser.Renderer.WebGL.Pipelines.ModelViewProjection#projPersp * @since 3.0.0 * * @param {number} fovY - The fov value. * @param {number} aspectRatio - The aspectRatio value. * @param {number} near - The near value. * @param {number} far - The far value. * * @return {this} This Model View Projection. */ projPersp: function (fovY, aspectRatio, near, far) { var projectionMatrix = this.projectionMatrix; var fov = 1.0 / Math.tan(fovY / 2.0); var nearFar = 1.0 / (near - far); projectionMatrix[0] = fov / aspectRatio; projectionMatrix[1] = 0.0; projectionMatrix[2] = 0.0; projectionMatrix[3] = 0.0; projectionMatrix[4] = 0.0; projectionMatrix[5] = fov; projectionMatrix[6] = 0.0; projectionMatrix[7] = 0.0; projectionMatrix[8] = 0.0; projectionMatrix[9] = 0.0; projectionMatrix[10] = (far + near) * nearFar; projectionMatrix[11] = -1.0; projectionMatrix[12] = 0.0; projectionMatrix[13] = 0.0; projectionMatrix[14] = (2.0 * far * near) * nearFar; projectionMatrix[15] = 0.0; this.projectionMatrixDirty = true; return this; } }; module.exports = ModelViewProjection;