diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/display/src/DisplayObject.js b/packages/display/src/DisplayObject.js index ebcd232..1d6d7d8 100644 --- a/packages/display/src/DisplayObject.js +++ b/packages/display/src/DisplayObject.js @@ -205,10 +205,10 @@ /** * Retrieves the bounds of the displayObject as a rectangle object. * - * @param {boolean} skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from * being updated. This means the calculation returned MAY be out of date BUT will give you a * nice performance boost. - * @param {PIXI.Rectangle} rect - Optional rectangle to store the result of the bounds calculation. + * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. * @return {PIXI.Rectangle} The rectangular bounding area. */ getBounds(skipUpdate, rect) diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/display/src/DisplayObject.js b/packages/display/src/DisplayObject.js index ebcd232..1d6d7d8 100644 --- a/packages/display/src/DisplayObject.js +++ b/packages/display/src/DisplayObject.js @@ -205,10 +205,10 @@ /** * Retrieves the bounds of the displayObject as a rectangle object. * - * @param {boolean} skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from * being updated. This means the calculation returned MAY be out of date BUT will give you a * nice performance boost. - * @param {PIXI.Rectangle} rect - Optional rectangle to store the result of the bounds calculation. + * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. * @return {PIXI.Rectangle} The rectangular bounding area. */ getBounds(skipUpdate, rect) diff --git a/packages/mesh/src/Mesh.js b/packages/mesh/src/Mesh.js index 742870e..35667e2 100644 --- a/packages/mesh/src/Mesh.js +++ b/packages/mesh/src/Mesh.js @@ -3,6 +3,7 @@ import { BLEND_MODES, DRAW_MODES } from '@pixi/constants'; import { Container } from '@pixi/display'; import { settings } from '@pixi/settings'; +import MeshBatchUvs from './MeshBatchUvs'; const tempPoint = new Point(); const tempPolygon = new Polygon(); @@ -121,6 +122,32 @@ * @private */ this._roundPixels = settings.ROUND_PIXELS; + + /** + * Batched UV's are cached for atlas textures + * @member {PIXI.MeshBatchUvs} + * @private + */ + this.batchUvs = null; + } + + /** + * To change mesh uv's, change its uvBuffer data and increment its _updateID. + * @returns {PIXI.Buffer} + */ + get uvBuffer() + { + return this.geometry.buffers[1].data; + } + + /** + * To change mesh vertices, change its uvBuffer data and increment its _updateID. + * Incrementing _updateID is optional because most of Mesh objects do it anyway. + * @returns {PIXI.Buffer} + */ + get verticesBuffer() + { + return this.geometry.buffers[0].data; } /** @@ -220,12 +247,6 @@ // TODO could use a different way to grab verts? const vertices = this.geometry.buffers[0].data; - if (this.geometry.update && this.geometry._updateId !== renderer.tick) - { - this.geometry._updateId = renderer.tick; - this.geometry.update(); - } - // TODO benchmark check for attribute size.. if (this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < Mesh.BATCHABLE_SIZE * 2) { @@ -246,6 +267,7 @@ { const shader = this.shader; + shader.alpha = this.worldAlpha; if (shader.update) { shader.update(); @@ -280,56 +302,94 @@ { const geometry = this.geometry; - // set properties for batching.. - const vertices = geometry.buffers[0].data; - - if (geometry.vertexDirtyId !== this.vertexDirty || this._transformID !== this.transform._worldID) + if (this.shader.uvMatrix) { - this._transformID = this.transform._worldID; - - if (this.vertexData.length !== vertices.length) - { - this.vertexData = new Float32Array(vertices.length); - } - - const wt = this.transform.worldTransform; - const a = wt.a; - const b = wt.b; - const c = wt.c; - const d = wt.d; - const tx = wt.tx; - const ty = wt.ty; - - const vertexData = this.vertexData; - - for (let i = 0; i < vertexData.length / 2; i++) - { - const x = vertices[(i * 2)]; - const y = vertices[(i * 2) + 1]; - - vertexData[(i * 2)] = (a * x) + (c * y) + tx; - vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; - } - - if (this._roundPixels) - { - for (let i = 0; i < vertexData.length; i++) - { - vertexData[i] = Math.round(vertexData[i]); - } - } - - this.vertexDirty = geometry.vertexDirtyId; + this.shader.uvMatrix.update(); + this.calculateUvs(); } - // set batchable bits.. - this.uvs = geometry.buffers[1].data; + // set properties for batching.. + this.calculateVertices(); this.indices = geometry.indexBuffer.data; this._tintRGB = this.shader._tintRGB; this._texture = this.shader.texture; - renderer.batch.setObjectRenderer(renderer.plugins.batch); - renderer.plugins.batch.render(this); + const pluginName = this.material.pluginName; + + renderer.batch.setObjectRenderer(renderer.plugins[pluginName]); + renderer.plugins[pluginName].render(this); + } + + /** + * Updates vertexData field based on transform and vertices + */ + calculateVertices() + { + const geometry = this.geometry; + const vertices = geometry.buffers[0].data; + + if (geometry.vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) + { + return; + } + + this._transformID = this.transform._worldID; + + if (this.vertexData.length !== vertices.length) + { + this.vertexData = new Float32Array(vertices.length); + } + + const wt = this.transform.worldTransform; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + + const vertexData = this.vertexData; + + for (let i = 0; i < vertexData.length / 2; i++) + { + const x = vertices[(i * 2)]; + const y = vertices[(i * 2) + 1]; + + vertexData[(i * 2)] = (a * x) + (c * y) + tx; + vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; + } + + if (this._roundPixels) + { + for (let i = 0; i < vertexData.length; i++) + { + vertexData[i] = Math.round(vertexData[i]); + } + } + + this.vertexDirty = geometry.vertexDirtyId; + } + + /** + * Updates uv field based on from geometry uv's or batchUvs + */ + calculateUvs() + { + const geomUvs = this.geometry.buffers[1]; + + if (!this.shader.uvMatrix.isSimple) + { + if (!this.batchUvs) + { + this.batchUvs = new MeshBatchUvs(geomUvs, this.shader.uvMatrix); + } + this.batchUvs.update(); + this.uvs = this.batchUvs.data; + } + else + { + this.uvs = geomUvs.data; + } } /** @@ -340,14 +400,9 @@ */ _calculateBounds() { - // The position property could be set manually? - if (this.geometry.attributes.aVertexPosition) - { - const vertices = this.geometry.getAttribute('aVertexPosition').data; + this.calculateVertices(); - // TODO - we can cache local bounds and use them if they are dirty (like graphics) - this._bounds.addVertices(this.transform, vertices, 0, vertices.length); - } + this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); } /** diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/display/src/DisplayObject.js b/packages/display/src/DisplayObject.js index ebcd232..1d6d7d8 100644 --- a/packages/display/src/DisplayObject.js +++ b/packages/display/src/DisplayObject.js @@ -205,10 +205,10 @@ /** * Retrieves the bounds of the displayObject as a rectangle object. * - * @param {boolean} skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from * being updated. This means the calculation returned MAY be out of date BUT will give you a * nice performance boost. - * @param {PIXI.Rectangle} rect - Optional rectangle to store the result of the bounds calculation. + * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. * @return {PIXI.Rectangle} The rectangular bounding area. */ getBounds(skipUpdate, rect) diff --git a/packages/mesh/src/Mesh.js b/packages/mesh/src/Mesh.js index 742870e..35667e2 100644 --- a/packages/mesh/src/Mesh.js +++ b/packages/mesh/src/Mesh.js @@ -3,6 +3,7 @@ import { BLEND_MODES, DRAW_MODES } from '@pixi/constants'; import { Container } from '@pixi/display'; import { settings } from '@pixi/settings'; +import MeshBatchUvs from './MeshBatchUvs'; const tempPoint = new Point(); const tempPolygon = new Polygon(); @@ -121,6 +122,32 @@ * @private */ this._roundPixels = settings.ROUND_PIXELS; + + /** + * Batched UV's are cached for atlas textures + * @member {PIXI.MeshBatchUvs} + * @private + */ + this.batchUvs = null; + } + + /** + * To change mesh uv's, change its uvBuffer data and increment its _updateID. + * @returns {PIXI.Buffer} + */ + get uvBuffer() + { + return this.geometry.buffers[1].data; + } + + /** + * To change mesh vertices, change its uvBuffer data and increment its _updateID. + * Incrementing _updateID is optional because most of Mesh objects do it anyway. + * @returns {PIXI.Buffer} + */ + get verticesBuffer() + { + return this.geometry.buffers[0].data; } /** @@ -220,12 +247,6 @@ // TODO could use a different way to grab verts? const vertices = this.geometry.buffers[0].data; - if (this.geometry.update && this.geometry._updateId !== renderer.tick) - { - this.geometry._updateId = renderer.tick; - this.geometry.update(); - } - // TODO benchmark check for attribute size.. if (this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < Mesh.BATCHABLE_SIZE * 2) { @@ -246,6 +267,7 @@ { const shader = this.shader; + shader.alpha = this.worldAlpha; if (shader.update) { shader.update(); @@ -280,56 +302,94 @@ { const geometry = this.geometry; - // set properties for batching.. - const vertices = geometry.buffers[0].data; - - if (geometry.vertexDirtyId !== this.vertexDirty || this._transformID !== this.transform._worldID) + if (this.shader.uvMatrix) { - this._transformID = this.transform._worldID; - - if (this.vertexData.length !== vertices.length) - { - this.vertexData = new Float32Array(vertices.length); - } - - const wt = this.transform.worldTransform; - const a = wt.a; - const b = wt.b; - const c = wt.c; - const d = wt.d; - const tx = wt.tx; - const ty = wt.ty; - - const vertexData = this.vertexData; - - for (let i = 0; i < vertexData.length / 2; i++) - { - const x = vertices[(i * 2)]; - const y = vertices[(i * 2) + 1]; - - vertexData[(i * 2)] = (a * x) + (c * y) + tx; - vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; - } - - if (this._roundPixels) - { - for (let i = 0; i < vertexData.length; i++) - { - vertexData[i] = Math.round(vertexData[i]); - } - } - - this.vertexDirty = geometry.vertexDirtyId; + this.shader.uvMatrix.update(); + this.calculateUvs(); } - // set batchable bits.. - this.uvs = geometry.buffers[1].data; + // set properties for batching.. + this.calculateVertices(); this.indices = geometry.indexBuffer.data; this._tintRGB = this.shader._tintRGB; this._texture = this.shader.texture; - renderer.batch.setObjectRenderer(renderer.plugins.batch); - renderer.plugins.batch.render(this); + const pluginName = this.material.pluginName; + + renderer.batch.setObjectRenderer(renderer.plugins[pluginName]); + renderer.plugins[pluginName].render(this); + } + + /** + * Updates vertexData field based on transform and vertices + */ + calculateVertices() + { + const geometry = this.geometry; + const vertices = geometry.buffers[0].data; + + if (geometry.vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) + { + return; + } + + this._transformID = this.transform._worldID; + + if (this.vertexData.length !== vertices.length) + { + this.vertexData = new Float32Array(vertices.length); + } + + const wt = this.transform.worldTransform; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + + const vertexData = this.vertexData; + + for (let i = 0; i < vertexData.length / 2; i++) + { + const x = vertices[(i * 2)]; + const y = vertices[(i * 2) + 1]; + + vertexData[(i * 2)] = (a * x) + (c * y) + tx; + vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; + } + + if (this._roundPixels) + { + for (let i = 0; i < vertexData.length; i++) + { + vertexData[i] = Math.round(vertexData[i]); + } + } + + this.vertexDirty = geometry.vertexDirtyId; + } + + /** + * Updates uv field based on from geometry uv's or batchUvs + */ + calculateUvs() + { + const geomUvs = this.geometry.buffers[1]; + + if (!this.shader.uvMatrix.isSimple) + { + if (!this.batchUvs) + { + this.batchUvs = new MeshBatchUvs(geomUvs, this.shader.uvMatrix); + } + this.batchUvs.update(); + this.uvs = this.batchUvs.data; + } + else + { + this.uvs = geomUvs.data; + } } /** @@ -340,14 +400,9 @@ */ _calculateBounds() { - // The position property could be set manually? - if (this.geometry.attributes.aVertexPosition) - { - const vertices = this.geometry.getAttribute('aVertexPosition').data; + this.calculateVertices(); - // TODO - we can cache local bounds and use them if they are dirty (like graphics) - this._bounds.addVertices(this.transform, vertices, 0, vertices.length); - } + this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); } /** diff --git a/packages/mesh/src/MeshBatchUvs.js b/packages/mesh/src/MeshBatchUvs.js new file mode 100644 index 0000000..4fce153 --- /dev/null +++ b/packages/mesh/src/MeshBatchUvs.js @@ -0,0 +1,69 @@ +/** + * Class controls cache for UV mapping from Texture normal space to BaseTexture normal space. + * + * @class + * @memberof PIXI + */ +export default class MeshBatchUvs +{ + /** + * @param {PIXI.Buffer} uvBuffer - Buffer with normalized uv's + * @param {PIXI.TextureMatrix} uvMatrix - Material UV matrix + */ + constructor(uvBuffer, uvMatrix) + { + /** + * Buffer with normalized UV's + * @member {PIXI.Buffer} + */ + this.uvBuffer = uvBuffer; + + /** + * Material UV matrix + * @member {PIXI.TextureMatrix} + */ + this.uvMatrix = uvMatrix; + + /** + * UV Buffer data + * @member {Float32Array} + * @readonly + */ + this.data = null; + + this._bufferUpdateId = -1; + + this._textureUpdateId = -1; + + this._updateID = 0; + } + + /** + * updates + * + * @param {boolean} forceUpdate - force the update + */ + update(forceUpdate) + { + if (!forceUpdate + && this._bufferUpdateId === this.uvBuffer._updateID + && this._textureUpdateId === this.uvMatrix._updateID) + { + return; + } + + this._bufferUpdateId = this.uvBuffer._updateID; + this._textureUpdateId = this.uvMatrix._updateID; + + const data = this.uvBuffer.data; + + if (!this.data || this.data.length !== data.length) + { + this.data = new Float32Array(data.length); + } + + this.uvMatrix.multiplyUvs(data, this.data); + + this._updateID++; + } +} diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/display/src/DisplayObject.js b/packages/display/src/DisplayObject.js index ebcd232..1d6d7d8 100644 --- a/packages/display/src/DisplayObject.js +++ b/packages/display/src/DisplayObject.js @@ -205,10 +205,10 @@ /** * Retrieves the bounds of the displayObject as a rectangle object. * - * @param {boolean} skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from * being updated. This means the calculation returned MAY be out of date BUT will give you a * nice performance boost. - * @param {PIXI.Rectangle} rect - Optional rectangle to store the result of the bounds calculation. + * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. * @return {PIXI.Rectangle} The rectangular bounding area. */ getBounds(skipUpdate, rect) diff --git a/packages/mesh/src/Mesh.js b/packages/mesh/src/Mesh.js index 742870e..35667e2 100644 --- a/packages/mesh/src/Mesh.js +++ b/packages/mesh/src/Mesh.js @@ -3,6 +3,7 @@ import { BLEND_MODES, DRAW_MODES } from '@pixi/constants'; import { Container } from '@pixi/display'; import { settings } from '@pixi/settings'; +import MeshBatchUvs from './MeshBatchUvs'; const tempPoint = new Point(); const tempPolygon = new Polygon(); @@ -121,6 +122,32 @@ * @private */ this._roundPixels = settings.ROUND_PIXELS; + + /** + * Batched UV's are cached for atlas textures + * @member {PIXI.MeshBatchUvs} + * @private + */ + this.batchUvs = null; + } + + /** + * To change mesh uv's, change its uvBuffer data and increment its _updateID. + * @returns {PIXI.Buffer} + */ + get uvBuffer() + { + return this.geometry.buffers[1].data; + } + + /** + * To change mesh vertices, change its uvBuffer data and increment its _updateID. + * Incrementing _updateID is optional because most of Mesh objects do it anyway. + * @returns {PIXI.Buffer} + */ + get verticesBuffer() + { + return this.geometry.buffers[0].data; } /** @@ -220,12 +247,6 @@ // TODO could use a different way to grab verts? const vertices = this.geometry.buffers[0].data; - if (this.geometry.update && this.geometry._updateId !== renderer.tick) - { - this.geometry._updateId = renderer.tick; - this.geometry.update(); - } - // TODO benchmark check for attribute size.. if (this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < Mesh.BATCHABLE_SIZE * 2) { @@ -246,6 +267,7 @@ { const shader = this.shader; + shader.alpha = this.worldAlpha; if (shader.update) { shader.update(); @@ -280,56 +302,94 @@ { const geometry = this.geometry; - // set properties for batching.. - const vertices = geometry.buffers[0].data; - - if (geometry.vertexDirtyId !== this.vertexDirty || this._transformID !== this.transform._worldID) + if (this.shader.uvMatrix) { - this._transformID = this.transform._worldID; - - if (this.vertexData.length !== vertices.length) - { - this.vertexData = new Float32Array(vertices.length); - } - - const wt = this.transform.worldTransform; - const a = wt.a; - const b = wt.b; - const c = wt.c; - const d = wt.d; - const tx = wt.tx; - const ty = wt.ty; - - const vertexData = this.vertexData; - - for (let i = 0; i < vertexData.length / 2; i++) - { - const x = vertices[(i * 2)]; - const y = vertices[(i * 2) + 1]; - - vertexData[(i * 2)] = (a * x) + (c * y) + tx; - vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; - } - - if (this._roundPixels) - { - for (let i = 0; i < vertexData.length; i++) - { - vertexData[i] = Math.round(vertexData[i]); - } - } - - this.vertexDirty = geometry.vertexDirtyId; + this.shader.uvMatrix.update(); + this.calculateUvs(); } - // set batchable bits.. - this.uvs = geometry.buffers[1].data; + // set properties for batching.. + this.calculateVertices(); this.indices = geometry.indexBuffer.data; this._tintRGB = this.shader._tintRGB; this._texture = this.shader.texture; - renderer.batch.setObjectRenderer(renderer.plugins.batch); - renderer.plugins.batch.render(this); + const pluginName = this.material.pluginName; + + renderer.batch.setObjectRenderer(renderer.plugins[pluginName]); + renderer.plugins[pluginName].render(this); + } + + /** + * Updates vertexData field based on transform and vertices + */ + calculateVertices() + { + const geometry = this.geometry; + const vertices = geometry.buffers[0].data; + + if (geometry.vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) + { + return; + } + + this._transformID = this.transform._worldID; + + if (this.vertexData.length !== vertices.length) + { + this.vertexData = new Float32Array(vertices.length); + } + + const wt = this.transform.worldTransform; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + + const vertexData = this.vertexData; + + for (let i = 0; i < vertexData.length / 2; i++) + { + const x = vertices[(i * 2)]; + const y = vertices[(i * 2) + 1]; + + vertexData[(i * 2)] = (a * x) + (c * y) + tx; + vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; + } + + if (this._roundPixels) + { + for (let i = 0; i < vertexData.length; i++) + { + vertexData[i] = Math.round(vertexData[i]); + } + } + + this.vertexDirty = geometry.vertexDirtyId; + } + + /** + * Updates uv field based on from geometry uv's or batchUvs + */ + calculateUvs() + { + const geomUvs = this.geometry.buffers[1]; + + if (!this.shader.uvMatrix.isSimple) + { + if (!this.batchUvs) + { + this.batchUvs = new MeshBatchUvs(geomUvs, this.shader.uvMatrix); + } + this.batchUvs.update(); + this.uvs = this.batchUvs.data; + } + else + { + this.uvs = geomUvs.data; + } } /** @@ -340,14 +400,9 @@ */ _calculateBounds() { - // The position property could be set manually? - if (this.geometry.attributes.aVertexPosition) - { - const vertices = this.geometry.getAttribute('aVertexPosition').data; + this.calculateVertices(); - // TODO - we can cache local bounds and use them if they are dirty (like graphics) - this._bounds.addVertices(this.transform, vertices, 0, vertices.length); - } + this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); } /** diff --git a/packages/mesh/src/MeshBatchUvs.js b/packages/mesh/src/MeshBatchUvs.js new file mode 100644 index 0000000..4fce153 --- /dev/null +++ b/packages/mesh/src/MeshBatchUvs.js @@ -0,0 +1,69 @@ +/** + * Class controls cache for UV mapping from Texture normal space to BaseTexture normal space. + * + * @class + * @memberof PIXI + */ +export default class MeshBatchUvs +{ + /** + * @param {PIXI.Buffer} uvBuffer - Buffer with normalized uv's + * @param {PIXI.TextureMatrix} uvMatrix - Material UV matrix + */ + constructor(uvBuffer, uvMatrix) + { + /** + * Buffer with normalized UV's + * @member {PIXI.Buffer} + */ + this.uvBuffer = uvBuffer; + + /** + * Material UV matrix + * @member {PIXI.TextureMatrix} + */ + this.uvMatrix = uvMatrix; + + /** + * UV Buffer data + * @member {Float32Array} + * @readonly + */ + this.data = null; + + this._bufferUpdateId = -1; + + this._textureUpdateId = -1; + + this._updateID = 0; + } + + /** + * updates + * + * @param {boolean} forceUpdate - force the update + */ + update(forceUpdate) + { + if (!forceUpdate + && this._bufferUpdateId === this.uvBuffer._updateID + && this._textureUpdateId === this.uvMatrix._updateID) + { + return; + } + + this._bufferUpdateId = this.uvBuffer._updateID; + this._textureUpdateId = this.uvMatrix._updateID; + + const data = this.uvBuffer.data; + + if (!this.data || this.data.length !== data.length) + { + this.data = new Float32Array(data.length); + } + + this.uvMatrix.multiplyUvs(data, this.data); + + this._updateID++; + } +} diff --git a/packages/mesh/src/MeshMaterial.js b/packages/mesh/src/MeshMaterial.js index 028cf49..3440a58 100644 --- a/packages/mesh/src/MeshMaterial.js +++ b/packages/mesh/src/MeshMaterial.js @@ -17,11 +17,12 @@ * @param {object} [options] - Additional options * @param {number} [options.alpha=1] - Default alpha. * @param {number} [options.tint=0xFFFFFF] - Default tint. + * @param {string} [options.pluginName='batch'] - Renderer plugin for batching. + * @param {PIXI.Program} [options.program=0xFFFFFF] - Custom program. + * @param {object} [options.uniforms] - Custom uniforms. */ constructor(uSampler, options) { - const program = Program.from(vertex, fragment); - const uniforms = { uSampler, alpha: 1, @@ -29,7 +30,19 @@ uColor: new Float32Array([1, 1, 1, 1]), }; - super(program, uniforms); + // Set defaults + options = Object.assign({ + tint: 0xFFFFFF, + alpha: 1, + pluginName: 'batch', + }, options); + + if (options.uniforms) + { + Object.assign(uniforms, options.uniforms); + } + + super(options.program || Program.from(vertex, fragment), uniforms); /** * Only do update if tint or alpha changes. @@ -45,24 +58,25 @@ * @member {PIXI.TextureMatrix} * @readonly */ - // TODO get this back in! - this.uvMatrix = new TextureMatrix(this.uSampler); + this.uvMatrix = new TextureMatrix(uSampler); /** * `true` if shader can be batch with the renderer's batch system. * @member {boolean} * @default true */ - this.batchable = true; + this.batchable = options.program === undefined; - // Set defaults - const { tint, alpha } = Object.assign({ - tint: 0xFFFFFF, - alpha: 1, - }, options); + /** + * Renderer plugin for batching + * + * @member {string} + * @default 'batch' + */ + this.pluginName = options.pluginName; - this.tint = tint; - this.alpha = alpha; + this.tint = options.tint; + this.alpha = options.alpha; } /** @@ -75,11 +89,16 @@ } set texture(value) { - this.uniforms.uSampler = value; + if (this.uniforms.uSampler !== value) + { + this.uniforms.uSampler = value; + this.uvMatrix.texture = value; + } } /** * This gets automatically set by the object using this. + * * @default 1 * @member {number} */ @@ -126,5 +145,9 @@ premultiplyTintToRgba(this._tintRGB, this._alpha, this.uniforms.uColor, baseTexture.premultiplyAlpha); } + if (this.uvMatrix.update()) + { + this.uniforms.uTextureMatrix = this.uvMatrix.mapCoord; + } } } diff --git a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js index eec3dd3..887d93c 100644 --- a/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js +++ b/packages/canvas/canvas-mesh/src/CanvasMeshRenderer.js @@ -122,8 +122,7 @@ { const context = this.renderer.context; const vertices = mesh.geometry.buffers[0].data; - const uvs = mesh.geometry.buffers[1].data; - const texture = mesh._texture; + const { uvs, texture } = mesh; if (!texture.valid) { @@ -135,33 +134,12 @@ const textureWidth = base.width; const textureHeight = base.height; - let u0; - let u1; - let u2; - let v0; - let v1; - let v2; - - if (mesh.uploadUvTransform) - { - const ut = mesh._uvTransform.mapCoord; - - u0 = ((uvs[index0] * ut.a) + (uvs[index0 + 1] * ut.c) + ut.tx) * base.width; - u1 = ((uvs[index1] * ut.a) + (uvs[index1 + 1] * ut.c) + ut.tx) * base.width; - u2 = ((uvs[index2] * ut.a) + (uvs[index2 + 1] * ut.c) + ut.tx) * base.width; - v0 = ((uvs[index0] * ut.b) + (uvs[index0 + 1] * ut.d) + ut.ty) * base.height; - v1 = ((uvs[index1] * ut.b) + (uvs[index1 + 1] * ut.d) + ut.ty) * base.height; - v2 = ((uvs[index2] * ut.b) + (uvs[index2 + 1] * ut.d) + ut.ty) * base.height; - } - else - { - u0 = uvs[index0] * base.width; - u1 = uvs[index1] * base.width; - u2 = uvs[index2] * base.width; - v0 = uvs[index0 + 1] * base.height; - v1 = uvs[index1 + 1] * base.height; - v2 = uvs[index2 + 1] * base.height; - } + const u0 = uvs[index0] * base.width; + const u1 = uvs[index1] * base.width; + const u2 = uvs[index2] * base.width; + const v0 = uvs[index0 + 1] * base.height; + const v1 = uvs[index1 + 1] * base.height; + const v2 = uvs[index2 + 1] * base.height; let x0 = vertices[index0]; let x1 = vertices[index1]; diff --git a/packages/canvas/canvas-mesh/src/Mesh.js b/packages/canvas/canvas-mesh/src/Mesh.js index c43a74b..02799ed 100644 --- a/packages/canvas/canvas-mesh/src/Mesh.js +++ b/packages/canvas/canvas-mesh/src/Mesh.js @@ -1,4 +1,5 @@ import { Mesh } from '@pixi/mesh'; +import { settings } from './settings'; /** * Renders the object using the Canvas renderer @@ -10,5 +11,45 @@ */ Mesh.prototype._renderCanvas = function _renderCanvas(renderer) { - renderer.plugins[this.pluginName].render(this); + if (this.shader.uvMatrix) + { + this.shader.uvMatrix.update(); + this.calculateUvs(); + } + + this.material._renderCanvas(renderer, this); }; + +// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created +// this was merely created to completely decouple canvas from the base Mesh class and we are +// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. + +/** + * Internal variable for `canvasPadding`. + * + * @private + * @memberof PIXI.Mesh + * @member {number} + * @default null + */ +Mesh.prototype._canvasPadding = null; + +/** + * Triangles in canvas mode are automatically antialiased, use this value to force triangles + * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} + * + * @see PIXI.settings.MESH_CANVAS_PADDING + * @member {number} canvasPadding + * @memberof PIXI.SimpleMesh# + * @default 0 + */ +Object.defineProperty(Mesh.prototype, 'canvasPadding', { + get() + { + return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; + }, + set(value) + { + this._canvasPadding = value; + }, +}); diff --git a/packages/canvas/canvas-mesh/src/MeshMaterial.js b/packages/canvas/canvas-mesh/src/MeshMaterial.js new file mode 100644 index 0000000..6ed79f2 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/MeshMaterial.js @@ -0,0 +1,15 @@ +import { MeshMaterial } from '@pixi/mesh'; + +/** + * Renders the mesh using the Canvas renderer + * + * @private + * @method render + * @memberof PIXI.MeshMaterial# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + * @param {PIXI.Mesh} mesh - Mesh to render. + */ +MeshMaterial.prototype._renderCanvas = function _renderCanvas(renderer, mesh) +{ + renderer.plugins.mesh.render(mesh); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleMesh.js b/packages/canvas/canvas-mesh/src/SimpleMesh.js index 1af9ea6..e8c6456 100644 --- a/packages/canvas/canvas-mesh/src/SimpleMesh.js +++ b/packages/canvas/canvas-mesh/src/SimpleMesh.js @@ -1,36 +1,26 @@ import { SimpleMesh } from '@pixi/mesh-extras'; -import { settings } from './settings'; - -// IMPORTANT: Please do NOT use this as a precedent to use `settings` after the object is created -// this was merely created to completely decouple canvas from the base Mesh class and we are -// unable to add `canvasPadding` in the constructor anymore, as the case was for PixiJS v4. /** - * Internal variable for `canvasPadding`. + * Renders the object using the Canvas renderer * * @private - * @memberof PIXI.SimpleMesh - * @member {number} - * @default null + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ -SimpleMesh.prototype._canvasPadding = null; +SimpleMesh.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate) + { + this.geometry.getAttribute('aVertexPosition').update(); + } -/** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles - * to overlap a bit with each other. To set the global default, set {@link PIXI.settings.MESH_CANVAS_PADDING} - * - * @see PIXI.settings.MESH_CANVAS_PADDING - * @member {number} canvasPadding - * @memberof PIXI.SimpleMesh# - * @default 0 - */ -Object.defineProperty(SimpleMesh.prototype, 'canvasPadding', { - get() + if (this.shader.update) { - return this._canvasPadding !== null ? this._canvasPadding : settings.MESH_CANVAS_PADDING; - }, - set(value) - { - this._canvasPadding = value; - }, -}); + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/SimpleRope.js b/packages/canvas/canvas-mesh/src/SimpleRope.js new file mode 100644 index 0000000..7854486 --- /dev/null +++ b/packages/canvas/canvas-mesh/src/SimpleRope.js @@ -0,0 +1,28 @@ +import { SimpleRope } from '@pixi/mesh-extras'; + +/** + * Renders the object using the Canvas renderer + * + * @private + * @method _renderCanvas + * @memberof PIXI.Mesh# + * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. + */ +SimpleRope.prototype._renderCanvas = function _renderCanvas(renderer) +{ + if (this.autoUpdate + || this.geometry.width !== this.shader.texture.height) + { + this.geometry.width = this.shader.texture.height; + this.geometry.update(); + } + + if (this.shader.update) + { + this.shader.update(); + } + + this.calculateUvs(); + + this.material._renderCanvas(renderer, this); +}; diff --git a/packages/canvas/canvas-mesh/src/index.js b/packages/canvas/canvas-mesh/src/index.js index b563a68..6926e31 100644 --- a/packages/canvas/canvas-mesh/src/index.js +++ b/packages/canvas/canvas-mesh/src/index.js @@ -1,6 +1,8 @@ export { default as CanvasMeshRenderer } from './CanvasMeshRenderer'; import './settings'; -import './SimpleMesh'; +import './MeshMaterial'; import './NineSlicePlane'; import './Mesh'; +import './SimpleMesh'; +import './SimpleRope'; diff --git a/packages/core/src/textures/TextureMatrix.js b/packages/core/src/textures/TextureMatrix.js index 8198ed1..d3fd369 100644 --- a/packages/core/src/textures/TextureMatrix.js +++ b/packages/core/src/textures/TextureMatrix.js @@ -41,7 +41,7 @@ * @member {number} Tracks Texture frame changes * @private */ - this._lastTextureID = -1; + this._updateID = -1; /** * Changes frame clamping @@ -62,6 +62,14 @@ * @member {number} */ this.clampMargin = (typeof clampMargin === 'undefined') ? 0.5 : clampMargin; + + /** + * If texture size is the same as baseTexture + * @member {boolean} + * @default false + * @readonly + */ + this.isSimple = false; } /** @@ -121,12 +129,12 @@ } if (!forceUpdate - && this._lastTextureID === tex._updateID) + && this._updateID === tex._updateID) { return false; } - this._lastTextureID = tex._updateID; + this._updateID = tex._updateID; const uvs = tex._uvs; @@ -154,6 +162,10 @@ this.uClampOffset[0] = offset / texBase.realWidth; this.uClampOffset[1] = offset / texBase.realHeight; + this.isSimple = tex._frame.width === texBase.width + && tex._frame.height === texBase.height + && tex.rotate === 0; + return true; } } diff --git a/packages/display/src/Bounds.js b/packages/display/src/Bounds.js index fff4758..db88a3a 100644 --- a/packages/display/src/Bounds.js +++ b/packages/display/src/Bounds.js @@ -210,12 +210,43 @@ } /** - * Add an array of vertices + * Adds screen vertices from array * - * @param {PIXI.TransformBase} transform - TODO - * @param {Float32Array} vertices - TODO - * @param {number} beginOffset - TODO - * @param {number} endOffset - TODO + * @param {Float32Array} vertexData - calculated vertices + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded + */ + addVertexData(vertexData, beginOffset, endOffset) + { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + + for (let i = beginOffset; i < endOffset; i += 2) + { + const x = vertexData[i]; + const y = vertexData[i + 1]; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + + /** + * Add an array of mesh vertices + * + * @param {PIXI.TransformBase} transform - mesh transform + * @param {Float32Array} vertices - mesh coordinates in array + * @param {number} beginOffset - begin offset + * @param {number} endOffset - end offset, excluded */ addVertices(transform, vertices, beginOffset, endOffset) { diff --git a/packages/display/src/DisplayObject.js b/packages/display/src/DisplayObject.js index ebcd232..1d6d7d8 100644 --- a/packages/display/src/DisplayObject.js +++ b/packages/display/src/DisplayObject.js @@ -205,10 +205,10 @@ /** * Retrieves the bounds of the displayObject as a rectangle object. * - * @param {boolean} skipUpdate - Setting to `true` will stop the transforms of the scene graph from + * @param {boolean} [skipUpdate] - Setting to `true` will stop the transforms of the scene graph from * being updated. This means the calculation returned MAY be out of date BUT will give you a * nice performance boost. - * @param {PIXI.Rectangle} rect - Optional rectangle to store the result of the bounds calculation. + * @param {PIXI.Rectangle} [rect] - Optional rectangle to store the result of the bounds calculation. * @return {PIXI.Rectangle} The rectangular bounding area. */ getBounds(skipUpdate, rect) diff --git a/packages/mesh/src/Mesh.js b/packages/mesh/src/Mesh.js index 742870e..35667e2 100644 --- a/packages/mesh/src/Mesh.js +++ b/packages/mesh/src/Mesh.js @@ -3,6 +3,7 @@ import { BLEND_MODES, DRAW_MODES } from '@pixi/constants'; import { Container } from '@pixi/display'; import { settings } from '@pixi/settings'; +import MeshBatchUvs from './MeshBatchUvs'; const tempPoint = new Point(); const tempPolygon = new Polygon(); @@ -121,6 +122,32 @@ * @private */ this._roundPixels = settings.ROUND_PIXELS; + + /** + * Batched UV's are cached for atlas textures + * @member {PIXI.MeshBatchUvs} + * @private + */ + this.batchUvs = null; + } + + /** + * To change mesh uv's, change its uvBuffer data and increment its _updateID. + * @returns {PIXI.Buffer} + */ + get uvBuffer() + { + return this.geometry.buffers[1].data; + } + + /** + * To change mesh vertices, change its uvBuffer data and increment its _updateID. + * Incrementing _updateID is optional because most of Mesh objects do it anyway. + * @returns {PIXI.Buffer} + */ + get verticesBuffer() + { + return this.geometry.buffers[0].data; } /** @@ -220,12 +247,6 @@ // TODO could use a different way to grab verts? const vertices = this.geometry.buffers[0].data; - if (this.geometry.update && this.geometry._updateId !== renderer.tick) - { - this.geometry._updateId = renderer.tick; - this.geometry.update(); - } - // TODO benchmark check for attribute size.. if (this.shader.batchable && this.drawMode === DRAW_MODES.TRIANGLES && vertices.length < Mesh.BATCHABLE_SIZE * 2) { @@ -246,6 +267,7 @@ { const shader = this.shader; + shader.alpha = this.worldAlpha; if (shader.update) { shader.update(); @@ -280,56 +302,94 @@ { const geometry = this.geometry; - // set properties for batching.. - const vertices = geometry.buffers[0].data; - - if (geometry.vertexDirtyId !== this.vertexDirty || this._transformID !== this.transform._worldID) + if (this.shader.uvMatrix) { - this._transformID = this.transform._worldID; - - if (this.vertexData.length !== vertices.length) - { - this.vertexData = new Float32Array(vertices.length); - } - - const wt = this.transform.worldTransform; - const a = wt.a; - const b = wt.b; - const c = wt.c; - const d = wt.d; - const tx = wt.tx; - const ty = wt.ty; - - const vertexData = this.vertexData; - - for (let i = 0; i < vertexData.length / 2; i++) - { - const x = vertices[(i * 2)]; - const y = vertices[(i * 2) + 1]; - - vertexData[(i * 2)] = (a * x) + (c * y) + tx; - vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; - } - - if (this._roundPixels) - { - for (let i = 0; i < vertexData.length; i++) - { - vertexData[i] = Math.round(vertexData[i]); - } - } - - this.vertexDirty = geometry.vertexDirtyId; + this.shader.uvMatrix.update(); + this.calculateUvs(); } - // set batchable bits.. - this.uvs = geometry.buffers[1].data; + // set properties for batching.. + this.calculateVertices(); this.indices = geometry.indexBuffer.data; this._tintRGB = this.shader._tintRGB; this._texture = this.shader.texture; - renderer.batch.setObjectRenderer(renderer.plugins.batch); - renderer.plugins.batch.render(this); + const pluginName = this.material.pluginName; + + renderer.batch.setObjectRenderer(renderer.plugins[pluginName]); + renderer.plugins[pluginName].render(this); + } + + /** + * Updates vertexData field based on transform and vertices + */ + calculateVertices() + { + const geometry = this.geometry; + const vertices = geometry.buffers[0].data; + + if (geometry.vertexDirtyId === this.vertexDirty && this._transformID === this.transform._worldID) + { + return; + } + + this._transformID = this.transform._worldID; + + if (this.vertexData.length !== vertices.length) + { + this.vertexData = new Float32Array(vertices.length); + } + + const wt = this.transform.worldTransform; + const a = wt.a; + const b = wt.b; + const c = wt.c; + const d = wt.d; + const tx = wt.tx; + const ty = wt.ty; + + const vertexData = this.vertexData; + + for (let i = 0; i < vertexData.length / 2; i++) + { + const x = vertices[(i * 2)]; + const y = vertices[(i * 2) + 1]; + + vertexData[(i * 2)] = (a * x) + (c * y) + tx; + vertexData[(i * 2) + 1] = (b * x) + (d * y) + ty; + } + + if (this._roundPixels) + { + for (let i = 0; i < vertexData.length; i++) + { + vertexData[i] = Math.round(vertexData[i]); + } + } + + this.vertexDirty = geometry.vertexDirtyId; + } + + /** + * Updates uv field based on from geometry uv's or batchUvs + */ + calculateUvs() + { + const geomUvs = this.geometry.buffers[1]; + + if (!this.shader.uvMatrix.isSimple) + { + if (!this.batchUvs) + { + this.batchUvs = new MeshBatchUvs(geomUvs, this.shader.uvMatrix); + } + this.batchUvs.update(); + this.uvs = this.batchUvs.data; + } + else + { + this.uvs = geomUvs.data; + } } /** @@ -340,14 +400,9 @@ */ _calculateBounds() { - // The position property could be set manually? - if (this.geometry.attributes.aVertexPosition) - { - const vertices = this.geometry.getAttribute('aVertexPosition').data; + this.calculateVertices(); - // TODO - we can cache local bounds and use them if they are dirty (like graphics) - this._bounds.addVertices(this.transform, vertices, 0, vertices.length); - } + this._bounds.addVertexData(this.vertexData, 0, this.vertexData.length); } /** diff --git a/packages/mesh/src/MeshBatchUvs.js b/packages/mesh/src/MeshBatchUvs.js new file mode 100644 index 0000000..4fce153 --- /dev/null +++ b/packages/mesh/src/MeshBatchUvs.js @@ -0,0 +1,69 @@ +/** + * Class controls cache for UV mapping from Texture normal space to BaseTexture normal space. + * + * @class + * @memberof PIXI + */ +export default class MeshBatchUvs +{ + /** + * @param {PIXI.Buffer} uvBuffer - Buffer with normalized uv's + * @param {PIXI.TextureMatrix} uvMatrix - Material UV matrix + */ + constructor(uvBuffer, uvMatrix) + { + /** + * Buffer with normalized UV's + * @member {PIXI.Buffer} + */ + this.uvBuffer = uvBuffer; + + /** + * Material UV matrix + * @member {PIXI.TextureMatrix} + */ + this.uvMatrix = uvMatrix; + + /** + * UV Buffer data + * @member {Float32Array} + * @readonly + */ + this.data = null; + + this._bufferUpdateId = -1; + + this._textureUpdateId = -1; + + this._updateID = 0; + } + + /** + * updates + * + * @param {boolean} forceUpdate - force the update + */ + update(forceUpdate) + { + if (!forceUpdate + && this._bufferUpdateId === this.uvBuffer._updateID + && this._textureUpdateId === this.uvMatrix._updateID) + { + return; + } + + this._bufferUpdateId = this.uvBuffer._updateID; + this._textureUpdateId = this.uvMatrix._updateID; + + const data = this.uvBuffer.data; + + if (!this.data || this.data.length !== data.length) + { + this.data = new Float32Array(data.length); + } + + this.uvMatrix.multiplyUvs(data, this.data); + + this._updateID++; + } +} diff --git a/packages/mesh/src/MeshMaterial.js b/packages/mesh/src/MeshMaterial.js index 028cf49..3440a58 100644 --- a/packages/mesh/src/MeshMaterial.js +++ b/packages/mesh/src/MeshMaterial.js @@ -17,11 +17,12 @@ * @param {object} [options] - Additional options * @param {number} [options.alpha=1] - Default alpha. * @param {number} [options.tint=0xFFFFFF] - Default tint. + * @param {string} [options.pluginName='batch'] - Renderer plugin for batching. + * @param {PIXI.Program} [options.program=0xFFFFFF] - Custom program. + * @param {object} [options.uniforms] - Custom uniforms. */ constructor(uSampler, options) { - const program = Program.from(vertex, fragment); - const uniforms = { uSampler, alpha: 1, @@ -29,7 +30,19 @@ uColor: new Float32Array([1, 1, 1, 1]), }; - super(program, uniforms); + // Set defaults + options = Object.assign({ + tint: 0xFFFFFF, + alpha: 1, + pluginName: 'batch', + }, options); + + if (options.uniforms) + { + Object.assign(uniforms, options.uniforms); + } + + super(options.program || Program.from(vertex, fragment), uniforms); /** * Only do update if tint or alpha changes. @@ -45,24 +58,25 @@ * @member {PIXI.TextureMatrix} * @readonly */ - // TODO get this back in! - this.uvMatrix = new TextureMatrix(this.uSampler); + this.uvMatrix = new TextureMatrix(uSampler); /** * `true` if shader can be batch with the renderer's batch system. * @member {boolean} * @default true */ - this.batchable = true; + this.batchable = options.program === undefined; - // Set defaults - const { tint, alpha } = Object.assign({ - tint: 0xFFFFFF, - alpha: 1, - }, options); + /** + * Renderer plugin for batching + * + * @member {string} + * @default 'batch' + */ + this.pluginName = options.pluginName; - this.tint = tint; - this.alpha = alpha; + this.tint = options.tint; + this.alpha = options.alpha; } /** @@ -75,11 +89,16 @@ } set texture(value) { - this.uniforms.uSampler = value; + if (this.uniforms.uSampler !== value) + { + this.uniforms.uSampler = value; + this.uvMatrix.texture = value; + } } /** * This gets automatically set by the object using this. + * * @default 1 * @member {number} */ @@ -126,5 +145,9 @@ premultiplyTintToRgba(this._tintRGB, this._alpha, this.uniforms.uColor, baseTexture.premultiplyAlpha); } + if (this.uvMatrix.update()) + { + this.uniforms.uTextureMatrix = this.uvMatrix.mapCoord; + } } } diff --git a/packages/mesh/src/index.js b/packages/mesh/src/index.js index 9e6dcd8..c6a1197 100644 --- a/packages/mesh/src/index.js +++ b/packages/mesh/src/index.js @@ -1,4 +1,4 @@ export { default as Mesh } from './Mesh'; +export { default as MeshBatchUvs } from './MeshBatchUvs'; export { default as MeshMaterial } from './MeshMaterial'; export { default as MeshGeometry } from './MeshGeometry'; -