From 8bc4d0683180e4fef8079a9e7392eb1257e29eda Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 7 Sep 2018 14:23:25 +0100 Subject: [PATCH] Added IsoTriangle and project setting --- src/gameobjects/index.js | 2 + src/gameobjects/shape/isobox/IsoBox.js | 9 + .../shape/isobox/IsoBoxWebGLRenderer.js | 51 +++--- .../shape/isotriangle/IsoTriangle.js | 106 +++++++++++ .../isotriangle/IsoTriangleCanvasRenderer.js | 26 +++ .../shape/isotriangle/IsoTriangleFactory.js | 32 ++++ .../shape/isotriangle/IsoTriangleRender.js | 25 +++ .../isotriangle/IsoTriangleWebGLRenderer.js | 167 ++++++++++++++++++ .../webgl/pipelines/TextureTintPipeline.js | 14 +- 9 files changed, 404 insertions(+), 28 deletions(-) create mode 100644 src/gameobjects/shape/isotriangle/IsoTriangle.js create mode 100644 src/gameobjects/shape/isotriangle/IsoTriangleCanvasRenderer.js create mode 100644 src/gameobjects/shape/isotriangle/IsoTriangleFactory.js create mode 100644 src/gameobjects/shape/isotriangle/IsoTriangleRender.js create mode 100644 src/gameobjects/shape/isotriangle/IsoTriangleWebGLRenderer.js diff --git a/src/gameobjects/index.js b/src/gameobjects/index.js index ea8e51903..cad20817f 100644 --- a/src/gameobjects/index.js +++ b/src/gameobjects/index.js @@ -42,6 +42,7 @@ var GameObjects = { Arc: require('./shape/arc/Arc'), Ellipse: require('./shape/ellipse/Ellipse'), IsoBox: require('./shape/isobox/IsoBox'), + IsoTriangle: require('./shape/isotriangle/IsoTriangle'), Line: require('./shape/line/Line'), Polygon: require('./shape/polygon/Polygon'), Rectangle: require('./shape/rectangle/Rectangle'), @@ -70,6 +71,7 @@ var GameObjects = { Arc: require('./shape/arc/ArcFactory'), Ellipse: require('./shape/ellipse/EllipseFactory'), IsoBox: require('./shape/isobox/IsoBoxFactory'), + IsoTriangle: require('./shape/isotriangle/IsoTriangleFactory'), Line: require('./shape/line/LineFactory'), Polygon: require('./shape/polygon/PolygonFactory'), Rectangle: require('./shape/rectangle/RectangleFactory'), diff --git a/src/gameobjects/shape/isobox/IsoBox.js b/src/gameobjects/shape/isobox/IsoBox.js index 26bd5bc99..9165b5e2c 100644 --- a/src/gameobjects/shape/isobox/IsoBox.js +++ b/src/gameobjects/shape/isobox/IsoBox.js @@ -43,6 +43,8 @@ var IsoBox = new Class({ Shape.call(this, scene, 'IsoBox', null); + this.projection = 4; + this.fillTop = fillTop; this.fillLeft = fillLeft; this.fillRight = fillRight; @@ -59,6 +61,13 @@ var IsoBox = new Class({ this.updateDisplayOrigin(); }, + setProjection: function (value) + { + this.projection = value; + + return this; + }, + setFaces: function (showTop, showLeft, showRight) { if (showTop === undefined) { showTop = true; } diff --git a/src/gameobjects/shape/isobox/IsoBoxWebGLRenderer.js b/src/gameobjects/shape/isobox/IsoBoxWebGLRenderer.js index d564a12c4..383ac6545 100644 --- a/src/gameobjects/shape/isobox/IsoBoxWebGLRenderer.js +++ b/src/gameobjects/shape/isobox/IsoBoxWebGLRenderer.js @@ -55,6 +55,9 @@ var IsoBoxWebGLRenderer = function (renderer, src, interpolationPercentage, came var size = src.width; var height = src.height; + var sizeA = size / 2; + var sizeB = size / src.projection; + var alpha = camera.alpha * src.alpha; if (!src.isFilled) @@ -82,17 +85,17 @@ var IsoBoxWebGLRenderer = function (renderer, src, interpolationPercentage, came { tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillTop, alpha); - x0 = calcMatrix.getX(-size / 2, -height); - y0 = calcMatrix.getY(-size / 2, -height); + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); - x1 = calcMatrix.getX(0, -size / 4 - height); - y1 = calcMatrix.getY(0, -size / 4 - height); + x1 = calcMatrix.getX(0, -sizeB - height); + y1 = calcMatrix.getY(0, -sizeB - height); - x2 = calcMatrix.getX(size / 2, -height); - y2 = calcMatrix.getY(size / 2, -height); + x2 = calcMatrix.getX(sizeA, -height); + y2 = calcMatrix.getY(sizeA, -height); - x3 = calcMatrix.getX(0, size / 4 - height); - y3 = calcMatrix.getY(0, size / 4 - height); + x3 = calcMatrix.getX(0, sizeB - height); + y3 = calcMatrix.getY(0, sizeB - height); pipeline.batchQuad(x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); } @@ -103,17 +106,17 @@ var IsoBoxWebGLRenderer = function (renderer, src, interpolationPercentage, came { tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillLeft, alpha); - x0 = calcMatrix.getX(-size / 2, 0); - y0 = calcMatrix.getY(-size / 2, 0); + x0 = calcMatrix.getX(-sizeA, 0); + y0 = calcMatrix.getY(-sizeA, 0); - x1 = calcMatrix.getX(0, size / 4); - y1 = calcMatrix.getY(0, size / 4); + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - x2 = calcMatrix.getX(0, size / 4 - height); - y2 = calcMatrix.getY(0, size / 4 - height); + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); - x3 = calcMatrix.getX(-size / 2, -height); - y3 = calcMatrix.getY(-size / 2, -height); + x3 = calcMatrix.getX(-sizeA, -height); + y3 = calcMatrix.getY(-sizeA, -height); pipeline.batchQuad(x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); } @@ -124,17 +127,17 @@ var IsoBoxWebGLRenderer = function (renderer, src, interpolationPercentage, came { tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillRight, alpha); - x0 = calcMatrix.getX(size / 2, 0); - y0 = calcMatrix.getY(size / 2, 0); + x0 = calcMatrix.getX(sizeA, 0); + y0 = calcMatrix.getY(sizeA, 0); - x1 = calcMatrix.getX(0, size / 4); - y1 = calcMatrix.getY(0, size / 4); + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - x2 = calcMatrix.getX(0, size / 4 - height); - y2 = calcMatrix.getY(0, size / 4 - height); + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); - x3 = calcMatrix.getX(size / 2, -height); - y3 = calcMatrix.getY(size / 2, -height); + x3 = calcMatrix.getX(sizeA, -height); + y3 = calcMatrix.getY(sizeA, -height); pipeline.batchQuad(x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); } diff --git a/src/gameobjects/shape/isotriangle/IsoTriangle.js b/src/gameobjects/shape/isotriangle/IsoTriangle.js new file mode 100644 index 000000000..3eb2c11f8 --- /dev/null +++ b/src/gameobjects/shape/isotriangle/IsoTriangle.js @@ -0,0 +1,106 @@ +/** + * @author Richard Davey + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ + +var IsoTriangleRender = require('./IsoTriangleRender'); +var Class = require('../../../utils/Class'); +var Shape = require('../Shape'); + +/** + * @classdesc + * + * @class IsoTriangle + * @extends Phaser.GameObjects.Shape + * @memberOf Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param {number} x - The horizontal position of this Game Object in the world. + * @param {number} y - The vertical position of this Game Object in the world. + */ +var IsoTriangle = new Class({ + + Extends: Shape, + + Mixins: [ + IsoTriangleRender + ], + + initialize: + + function IsoTriangle (scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (size === undefined) { size = 48; } + if (height === undefined) { height = 32; } + if (reversed === undefined) { reversed = false; } + if (fillTop === undefined) { fillTop = 0xeeeeee; } + if (fillLeft === undefined) { fillLeft = 0x999999; } + if (fillRight === undefined) { fillRight = 0xcccccc; } + + Shape.call(this, scene, 'IsoTriangle', null); + + this.projection = 4; + + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.showTop = true; + this.showLeft = true; + this.showRight = true; + + this.isReversed = reversed; + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); + }, + + setProjection: function (value) + { + this.projection = value; + + return this; + }, + + setReversed: function (reversed) + { + this.isReversed = reversed; + + return this; + }, + + setFaces: function (showTop, showLeft, showRight) + { + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } + + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; + + return this; + }, + + setFillStyle: function (fillTop, fillLeft, fillRight) + { + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; + + this.isFilled = true; + + return this; + } + +}); + +module.exports = IsoTriangle; diff --git a/src/gameobjects/shape/isotriangle/IsoTriangleCanvasRenderer.js b/src/gameobjects/shape/isotriangle/IsoTriangleCanvasRenderer.js new file mode 100644 index 000000000..1fe51e355 --- /dev/null +++ b/src/gameobjects/shape/isotriangle/IsoTriangleCanvasRenderer.js @@ -0,0 +1,26 @@ +/** + * @author Richard Davey + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ + +/** + * Renders this Game Object with the Canvas Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.IsoTriangle#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.IsoTriangle} src - The Game Object being rendered in this call. + * @param {number} interpolationPercentage - Reserved for future use and custom pipelines. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested + */ +var IsoTriangleCanvasRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix) +{ +}; + +module.exports = IsoTriangleCanvasRenderer; diff --git a/src/gameobjects/shape/isotriangle/IsoTriangleFactory.js b/src/gameobjects/shape/isotriangle/IsoTriangleFactory.js new file mode 100644 index 000000000..2984f843f --- /dev/null +++ b/src/gameobjects/shape/isotriangle/IsoTriangleFactory.js @@ -0,0 +1,32 @@ +/** + * @author Richard Davey + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ + +var GameObjectFactory = require('../../GameObjectFactory'); +var IsoTriangle = require('./IsoTriangle'); + +/** + * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the IsoTriangle Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#isotriangle + * @since 3.13.0 + * + * @param {number} [x=0] - The horizontal position of this Game Object in the world. + * @param {number} [y=0] - The vertical position of this Game Object in the world. + * @param {number} [size=48] - The width of the iso triangle in pixels. The left and right faces will be exactly half this value. + * @param {number} [height=32] - The height of the iso triangle. The left and right faces will be this tall. The overall height of the iso triangle will be this value plus half the `size` value. + * @param {boolean} [reversed=false] - Is the iso triangle upside down? + * @param {number} [fillTop=0xeeeeee] - The fill color of the top face of the iso triangle. + * @param {number} [fillLeft=0x999999] - The fill color of the left face of the iso triangle. + * @param {number} [fillRight=0xcccccc] - The fill color of the right face of the iso triangle. + * + * @return {Phaser.GameObjects.IsoTriangle} The Game Object that was created. + */ +GameObjectFactory.register('isotriangle', function (x, y, size, height, reversed, fillTop, fillLeft, fillRight) +{ + return this.displayList.add(new IsoTriangle(this.scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight)); +}); diff --git a/src/gameobjects/shape/isotriangle/IsoTriangleRender.js b/src/gameobjects/shape/isotriangle/IsoTriangleRender.js new file mode 100644 index 000000000..ded1fc5d0 --- /dev/null +++ b/src/gameobjects/shape/isotriangle/IsoTriangleRender.js @@ -0,0 +1,25 @@ +/** + * @author Richard Davey + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ + +var renderWebGL = require('../../../utils/NOOP'); +var renderCanvas = require('../../../utils/NOOP'); + +if (typeof WEBGL_RENDERER) +{ + renderWebGL = require('./IsoTriangleWebGLRenderer'); +} + +if (typeof CANVAS_RENDERER) +{ + renderCanvas = require('./IsoTriangleCanvasRenderer'); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; diff --git a/src/gameobjects/shape/isotriangle/IsoTriangleWebGLRenderer.js b/src/gameobjects/shape/isotriangle/IsoTriangleWebGLRenderer.js new file mode 100644 index 000000000..cfaa10dc4 --- /dev/null +++ b/src/gameobjects/shape/isotriangle/IsoTriangleWebGLRenderer.js @@ -0,0 +1,167 @@ +/** + * @author Richard Davey + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ + +var Utils = require('../../../renderer/webgl/Utils'); + +/** + * Renders this Game Object with the WebGL Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.IsoTriangle#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.IsoTriangle} src - The Game Object being rendered in this call. + * @param {number} interpolationPercentage - Reserved for future use and custom pipelines. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested + */ +var IsoTriangleWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix) +{ + var pipeline = this.pipeline; + + var camMatrix = pipeline._tempMatrix1; + var shapeMatrix = pipeline._tempMatrix2; + var calcMatrix = pipeline._tempMatrix3; + + renderer.setPipeline(pipeline); + + shapeMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY); + + camMatrix.copyFrom(camera.matrix); + + if (parentMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); + + // Undo the camera scroll + shapeMatrix.e = src.x; + shapeMatrix.f = src.y; + } + else + { + shapeMatrix.e -= camera.scrollX * src.scrollFactorX; + shapeMatrix.f -= camera.scrollY * src.scrollFactorY; + } + + camMatrix.multiply(shapeMatrix, calcMatrix); + + var size = src.width; + var height = src.height; + + var sizeA = size / 2; + var sizeB = size / src.projection; + + var reversed = src.isReversed; + + var alpha = camera.alpha * src.alpha; + + if (!src.isFilled) + { + return; + } + + var tint; + + var x0; + var y0; + + var x1; + var y1; + + var x2; + var y2; + + // Top Face + + if (src.showTop && reversed) + { + tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillTop, alpha); + + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); + + x1 = calcMatrix.getX(0, -sizeB - height); + y1 = calcMatrix.getY(0, -sizeB - height); + + x2 = calcMatrix.getX(sizeA, -height); + y2 = calcMatrix.getY(sizeA, -height); + + var x3 = calcMatrix.getX(0, sizeB - height); + var y3 = calcMatrix.getY(0, sizeB - height); + + pipeline.batchQuad(x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + } + + // Left Face + + if (src.showLeft) + { + tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillLeft, alpha); + + if (reversed) + { + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); + + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); + + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } + else + { + x0 = calcMatrix.getX(-sizeA, 0); + y0 = calcMatrix.getY(-sizeA, 0); + + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); + + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } + + pipeline.batchTri(x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); + } + + // Right Face + + if (src.showRight) + { + tint = Utils.getTintAppendFloatAlphaAndSwap(src.fillRight, alpha); + + if (reversed) + { + x0 = calcMatrix.getX(sizeA, -height); + y0 = calcMatrix.getY(sizeA, -height); + + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); + + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } + else + { + x0 = calcMatrix.getX(sizeA, 0); + y0 = calcMatrix.getY(sizeA, 0); + + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); + + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } + + pipeline.batchTri(x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); + } +}; + +module.exports = IsoTriangleWebGLRenderer; diff --git a/src/renderer/webgl/pipelines/TextureTintPipeline.js b/src/renderer/webgl/pipelines/TextureTintPipeline.js index 35c2ac95e..4371d8d3c 100644 --- a/src/renderer/webgl/pipelines/TextureTintPipeline.js +++ b/src/renderer/webgl/pipelines/TextureTintPipeline.js @@ -1002,8 +1002,11 @@ var TextureTintPipeline = new Class({ var calcMatrix = this._tempMatrix3; - // Multiply and store result in calcMatrix - parentMatrix.multiply(currentMatrix, calcMatrix); + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } var tx0 = calcMatrix.getX(x0, y0); var ty0 = calcMatrix.getY(x0, y0); @@ -1086,8 +1089,11 @@ var TextureTintPipeline = new Class({ var calcMatrix = this._tempMatrix3; - // Multiply and store result in calcMatrix - parentMatrix.multiply(currentMatrix, calcMatrix); + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } var length = path.length; var polygonCache = this.polygonCache;