import * as core from '../core'; const tempPoint = new core.Point(); const tempPolygon = new core.Polygon(); /** * Base mesh class * @class * @extends PIXI.Container * @memberof PIXI.mesh */ export default class Mesh extends core.Container { /** * @param {PIXI.Texture} texture - The texture to use * @param {Float32Array} [vertices] - if you want to specify the vertices * @param {Float32Array} [uvs] - if you want to specify the uvs * @param {Uint16Array} [indices] - if you want to specify the indices * @param {number} [drawMode] - the drawMode, can be any of the Mesh.DRAW_MODES consts */ constructor(texture, vertices, uvs, indices, drawMode) { super(); /** * The texture of the Mesh * * @member {PIXI.Texture} * @private */ this._texture = null; /** * The Uvs of the Mesh * * @member {Float32Array} */ this.uvs = uvs || new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]); /** * An array of vertices * * @member {Float32Array} */ this.vertices = vertices || new Float32Array([0, 0, 100, 0, 100, 100, 0, 100]); /* * @member {Uint16Array} An array containing the indices of the vertices */ // TODO auto generate this based on draw mode! this.indices = indices || new Uint16Array([0, 1, 3, 2]); /** * Version of mesh uvs are dirty or not * * @member {number} */ this.dirty = 0; /** * Version of mesh indices * * @member {number} */ this.indexDirty = 0; /** * The blend mode to be applied to the sprite. Set to `PIXI.BLEND_MODES.NORMAL` to remove * any blend mode. * * @member {number} * @default PIXI.BLEND_MODES.NORMAL * @see PIXI.BLEND_MODES */ this.blendMode = core.BLEND_MODES.NORMAL; /** * Triangles in canvas mode are automatically antialiased, use this value to force triangles * to overlap a bit with each other. * * @member {number} */ this.canvasPadding = 0; /** * The way the Mesh should be drawn, can be any of the {@link PIXI.mesh.Mesh.DRAW_MODES} consts * * @member {number} * @see PIXI.mesh.Mesh.DRAW_MODES */ this.drawMode = drawMode || Mesh.DRAW_MODES.TRIANGLE_MESH; // run texture setter; this.texture = texture; /** * The default shader that is used if a mesh doesn't have a more specific one. * * @member {PIXI.Shader} */ this.shader = null; /** * The tint applied to the mesh. This is a [r,g,b] value. A value of [1,1,1] will remove any * tint effect. * * @member {number} * @memberof PIXI.mesh.Mesh# */ this.tintRgb = new Float32Array([1, 1, 1]); /** * A map of renderer IDs to webgl render data * * @private * @member {object<number, object>} */ this._glDatas = {}; } /** * Renders the object using the WebGL renderer * * @private * @param {PIXI.WebGLRenderer} renderer - a reference to the WebGL renderer */ _renderWebGL(renderer) { renderer.setObjectRenderer(renderer.plugins.mesh); renderer.plugins.mesh.render(this); } /** * Renders the object using the Canvas renderer * * @private * @param {PIXI.CanvasRenderer} renderer - The canvas renderer. */ _renderCanvas(renderer) { renderer.plugins.mesh.render(this); } /** * When the texture is updated, this event will fire to update the scale and frame * * @private */ _onTextureUpdate() { /* empty */ } /** * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. * */ _calculateBounds() { // TODO - we can cache local bounds and use them if they are dirty (like graphics) this._bounds.addVertices(this.transform, this.vertices, 0, this.vertices.length); } /** * Tests if a point is inside this mesh. Works only for TRIANGLE_MESH * * @param {PIXI.Point} point - the point to test * @return {boolean} the result of the test */ containsPoint(point) { if (!this.getBounds().contains(point.x, point.y)) { return false; } this.worldTransform.applyInverse(point, tempPoint); const vertices = this.vertices; const points = tempPolygon.points; const indices = this.indices; const len = this.indices.length; const step = this.drawMode === Mesh.DRAW_MODES.TRIANGLES ? 3 : 1; for (let i = 0; i + 2 < len; i += step) { const ind0 = indices[i] * 2; const ind1 = indices[i + 1] * 2; const ind2 = indices[i + 2] * 2; points[0] = vertices[ind0]; points[1] = vertices[ind0 + 1]; points[2] = vertices[ind1]; points[3] = vertices[ind1 + 1]; points[4] = vertices[ind2]; points[5] = vertices[ind2 + 1]; if (tempPolygon.contains(tempPoint.x, tempPoint.y)) { return true; } } return false; } /** * The texture that the mesh uses. * * @member {PIXI.Texture} * @memberof PIXI.mesh.Mesh# */ get texture() { return this._texture; } /** * Sets the texture the mesh uses. * * @param {Texture} value - The value to set. */ set texture(value) { if (this._texture === value) { return; } this._texture = value; if (value) { // wait for the texture to load if (value.baseTexture.hasLoaded) { this._onTextureUpdate(); } else { value.once('update', this._onTextureUpdate, this); } } } /** * The tint applied to the mesh. This is a hex value. A value of 0xFFFFFF will remove any tint effect. * * @member {number} * @memberof PIXI.mesh.Mesh# * @default 0xFFFFFF */ get tint() { return core.utils.rgb2hex(this.tintRgb); } /** * Sets the tint the mesh uses. * * @param {number} value - The value to set. */ set tint(value) { this.tintRgb = core.utils.hex2rgb(value, this.tintRgb); } } /** * Different drawing buffer modes supported * * @static * @constant * @type {object} * @property {number} TRIANGLE_MESH * @property {number} TRIANGLES */ Mesh.DRAW_MODES = { TRIANGLE_MESH: 0, TRIANGLES: 1, };