diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js index f8f7b06..1684b53 100644 --- a/src/core/renderers/webgl/managers/ShaderManager.js +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -51,7 +51,7 @@ */ this.currentShader = null; - this.initPlugins(); +// this.initPlugins(); } ShaderManager.prototype = Object.create(WebGLManager.prototype); diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js index f8f7b06..1684b53 100644 --- a/src/core/renderers/webgl/managers/ShaderManager.js +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -51,7 +51,7 @@ */ this.currentShader = null; - this.initPlugins(); +// this.initPlugins(); } ShaderManager.prototype = Object.create(WebGLManager.prototype); diff --git a/src/extras/mesh/Mesh.js b/src/extras/mesh/Mesh.js new file mode 100644 index 0000000..4a84ee8 --- /dev/null +++ b/src/extras/mesh/Mesh.js @@ -0,0 +1,393 @@ +var core = require('../../core'); + +/** + * + * @class + * @extends Container + * @memberof PIXI.extras + * @param texture {Texture} The texture to use + * @param width {number} the width + * @param height {number} the height + * + */ +function Mesh(texture, vertices, uvs, indecies, drawMode) +{ + core.Container.call(this); + + /** + * The texture of the Mesh + * + * @member {Texture} + */ + this.texture = texture; + + /** + * The Uvs of the Mesh + * + * @member {Float32Array} + */ + this.uvs = uvs || new Float32Array([0, 1, + 1, 1, + 1, 0, + 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 = indecies || new Uint16Array([0, 1, 2, 3]); + + /** + * Whether the Mesh is dirty or not + * + * @member {boolean} + */ + this.dirty = true; + + /** + * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. + * + * @member {number} + * @default CONST.BLEND_MODES.NORMAL; + */ + this.blendMode = core.CONST.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 Mesh.DrawModes consts + * + * @member {number} + */ + this.drawMode = drawMode || Mesh.DrawModes.TRIANGLE_Mesh; +} + +// constructor +Mesh.prototype = Object.create(core.Container.prototype); +Mesh.prototype.constructor = Mesh; +module.exports = Mesh; + +/** + * Renders the object using the WebGL renderer + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + */ +Mesh.prototype._renderWebGL = function (renderer) +{ + renderer.setObjectRenderer(renderer.plugins.mesh); + renderer.plugins.mesh.render(this); +}; + +/** + * Creates the buffers and (in the darkness) binds them + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + * @private + */ + +/** + * Renders the object using the Canvas renderer + * + * @param renderer {CanvasRenderer} + */ +Mesh.prototype._renderCanvas = function (renderer) +{ + var context = renderer.context; + + var transform = this.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); + } + else + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); + } + + if (this.drawMode === Mesh.DrawModes.TRIANGLE_Mesh) + { + this._renderCanvasTriangleMesh(context); + } + else + { + this._renderCanvasTriangles(context); + } +}; + +/** + * Draws the object in TRIANGLE_Mesh mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangleMesh = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + + var length = vertices.length / 2; + // this.count++; + + for (var i = 0; i < length - 2; i++) + { + // draw some triangles! + var index = i * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); + } +}; + +/** + * Draws the object in triangle mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangles = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + var indices = this.indices; + + var length = indices.length; + // this.count++; + + for (var i = 0; i < length; i += 3) + { + // draw some triangles! + var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); + } +}; + +/** + * Draws one of the triangles that form this Mesh + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @param vertices {Float32Array} a reference to the the vertices of the Mesh + * @param uvs {Float32Array} a reference to the the vertices of the Mesh + * @param index0 {number} the index of the first vertex + * @param index1 {number} the index of the second vertex + * @param index2 {number} the index of the third vertex + * @private + */ +Mesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) +{ + var textureSource = this.texture.baseTexture.source; + var textureWidth = this.texture.width; + var textureHeight = this.texture.height; + + var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; + var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; + + var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; + var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; + + if (this.canvasPadding > 0) + { + var paddingX = this.canvasPadding / this.worldTransform.a; + var paddingY = this.canvasPadding / this.worldTransform.d; + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; + + var normX = x0 - centerX; + var normY = y0 - centerY; + + var dist = Math.sqrt(normX * normX + normY * normY); + x0 = centerX + (normX / dist) * (dist + paddingX); + y0 = centerY + (normY / dist) * (dist + paddingY); + + // + + normX = x1 - centerX; + normY = y1 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x1 = centerX + (normX / dist) * (dist + paddingX); + y1 = centerY + (normY / dist) * (dist + paddingY); + + normX = x2 - centerX; + normY = y2 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x2 = centerX + (normX / dist) * (dist + paddingX); + y2 = centerY + (normY / dist) * (dist + paddingY); + } + + context.save(); + context.beginPath(); + + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); + var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); + var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); + var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); + var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); + var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); + var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(textureSource, 0, 0); + context.restore(); +}; + + + +/** + * Renders a flat Mesh + * + * @param Mesh {Mesh} The Mesh to render + * @private + */ +Mesh.prototype.renderMeshFlat = function (Mesh) +{ + var context = this.context; + var vertices = Mesh.vertices; + + var length = vertices.length/2; + // this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; + var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; + +/* +Mesh.prototype.setTexture = function (texture) +{ + //TODO SET THE TEXTURES + //TODO VISIBILITY + //TODO SETTER + + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +}; + */ + +/** + * When the texture is updated, this event will fire to update the scale and frame + * + * @param event + * @private + */ + +Mesh.prototype.onTextureUpdate = function () +{ + this.updateFrame = true; +}; + +/** + * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. + * + * @param matrix {Matrix} the transformation matrix of the sprite + * @return {Rectangle} the framing rectangle + */ +Mesh.prototype.getBounds = function (matrix) +{ + var worldTransform = matrix || this.worldTransform; + + var a = worldTransform.a; + var b = worldTransform.b; + var c = worldTransform.c; + var d = worldTransform.d; + var tx = worldTransform.tx; + var ty = worldTransform.ty; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + var vertices = this.vertices; + for (var i = 0, n = vertices.length; i < n; i += 2) + { + var rawX = vertices[i], rawY = vertices[i + 1]; + var x = (a * rawX) + (c * rawY) + tx; + var y = (d * rawY) + (b * rawX) + ty; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + if (minX === -Infinity || maxY === Infinity) + { + return core.math.Rectangle.EMPTY; + } + + var bounds = this._bounds; + + bounds.x = minX; + bounds.width = maxX - minX; + + bounds.y = minY; + bounds.height = maxY - minY; + + // store a reference so that if this function gets called again in the render cycle we do not have to recalculate + this._currentBounds = bounds; + + return bounds; +}; + +/** + * Different drawing buffer modes supported + * + * @static + * @constant + * @property {object} DrawModes + * @property {number} DrawModes.TRIANGLE_Mesh + * @property {number} DrawModes.TRIANGLES + */ +Mesh.DrawModes = { + TRIANGLE_Mesh: 0, + TRIANGLES: 1 +}; diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js index f8f7b06..1684b53 100644 --- a/src/core/renderers/webgl/managers/ShaderManager.js +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -51,7 +51,7 @@ */ this.currentShader = null; - this.initPlugins(); +// this.initPlugins(); } ShaderManager.prototype = Object.create(WebGLManager.prototype); diff --git a/src/extras/mesh/Mesh.js b/src/extras/mesh/Mesh.js new file mode 100644 index 0000000..4a84ee8 --- /dev/null +++ b/src/extras/mesh/Mesh.js @@ -0,0 +1,393 @@ +var core = require('../../core'); + +/** + * + * @class + * @extends Container + * @memberof PIXI.extras + * @param texture {Texture} The texture to use + * @param width {number} the width + * @param height {number} the height + * + */ +function Mesh(texture, vertices, uvs, indecies, drawMode) +{ + core.Container.call(this); + + /** + * The texture of the Mesh + * + * @member {Texture} + */ + this.texture = texture; + + /** + * The Uvs of the Mesh + * + * @member {Float32Array} + */ + this.uvs = uvs || new Float32Array([0, 1, + 1, 1, + 1, 0, + 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 = indecies || new Uint16Array([0, 1, 2, 3]); + + /** + * Whether the Mesh is dirty or not + * + * @member {boolean} + */ + this.dirty = true; + + /** + * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. + * + * @member {number} + * @default CONST.BLEND_MODES.NORMAL; + */ + this.blendMode = core.CONST.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 Mesh.DrawModes consts + * + * @member {number} + */ + this.drawMode = drawMode || Mesh.DrawModes.TRIANGLE_Mesh; +} + +// constructor +Mesh.prototype = Object.create(core.Container.prototype); +Mesh.prototype.constructor = Mesh; +module.exports = Mesh; + +/** + * Renders the object using the WebGL renderer + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + */ +Mesh.prototype._renderWebGL = function (renderer) +{ + renderer.setObjectRenderer(renderer.plugins.mesh); + renderer.plugins.mesh.render(this); +}; + +/** + * Creates the buffers and (in the darkness) binds them + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + * @private + */ + +/** + * Renders the object using the Canvas renderer + * + * @param renderer {CanvasRenderer} + */ +Mesh.prototype._renderCanvas = function (renderer) +{ + var context = renderer.context; + + var transform = this.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); + } + else + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); + } + + if (this.drawMode === Mesh.DrawModes.TRIANGLE_Mesh) + { + this._renderCanvasTriangleMesh(context); + } + else + { + this._renderCanvasTriangles(context); + } +}; + +/** + * Draws the object in TRIANGLE_Mesh mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangleMesh = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + + var length = vertices.length / 2; + // this.count++; + + for (var i = 0; i < length - 2; i++) + { + // draw some triangles! + var index = i * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); + } +}; + +/** + * Draws the object in triangle mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangles = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + var indices = this.indices; + + var length = indices.length; + // this.count++; + + for (var i = 0; i < length; i += 3) + { + // draw some triangles! + var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); + } +}; + +/** + * Draws one of the triangles that form this Mesh + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @param vertices {Float32Array} a reference to the the vertices of the Mesh + * @param uvs {Float32Array} a reference to the the vertices of the Mesh + * @param index0 {number} the index of the first vertex + * @param index1 {number} the index of the second vertex + * @param index2 {number} the index of the third vertex + * @private + */ +Mesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) +{ + var textureSource = this.texture.baseTexture.source; + var textureWidth = this.texture.width; + var textureHeight = this.texture.height; + + var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; + var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; + + var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; + var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; + + if (this.canvasPadding > 0) + { + var paddingX = this.canvasPadding / this.worldTransform.a; + var paddingY = this.canvasPadding / this.worldTransform.d; + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; + + var normX = x0 - centerX; + var normY = y0 - centerY; + + var dist = Math.sqrt(normX * normX + normY * normY); + x0 = centerX + (normX / dist) * (dist + paddingX); + y0 = centerY + (normY / dist) * (dist + paddingY); + + // + + normX = x1 - centerX; + normY = y1 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x1 = centerX + (normX / dist) * (dist + paddingX); + y1 = centerY + (normY / dist) * (dist + paddingY); + + normX = x2 - centerX; + normY = y2 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x2 = centerX + (normX / dist) * (dist + paddingX); + y2 = centerY + (normY / dist) * (dist + paddingY); + } + + context.save(); + context.beginPath(); + + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); + var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); + var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); + var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); + var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); + var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); + var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(textureSource, 0, 0); + context.restore(); +}; + + + +/** + * Renders a flat Mesh + * + * @param Mesh {Mesh} The Mesh to render + * @private + */ +Mesh.prototype.renderMeshFlat = function (Mesh) +{ + var context = this.context; + var vertices = Mesh.vertices; + + var length = vertices.length/2; + // this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; + var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; + +/* +Mesh.prototype.setTexture = function (texture) +{ + //TODO SET THE TEXTURES + //TODO VISIBILITY + //TODO SETTER + + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +}; + */ + +/** + * When the texture is updated, this event will fire to update the scale and frame + * + * @param event + * @private + */ + +Mesh.prototype.onTextureUpdate = function () +{ + this.updateFrame = true; +}; + +/** + * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. + * + * @param matrix {Matrix} the transformation matrix of the sprite + * @return {Rectangle} the framing rectangle + */ +Mesh.prototype.getBounds = function (matrix) +{ + var worldTransform = matrix || this.worldTransform; + + var a = worldTransform.a; + var b = worldTransform.b; + var c = worldTransform.c; + var d = worldTransform.d; + var tx = worldTransform.tx; + var ty = worldTransform.ty; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + var vertices = this.vertices; + for (var i = 0, n = vertices.length; i < n; i += 2) + { + var rawX = vertices[i], rawY = vertices[i + 1]; + var x = (a * rawX) + (c * rawY) + tx; + var y = (d * rawY) + (b * rawX) + ty; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + if (minX === -Infinity || maxY === Infinity) + { + return core.math.Rectangle.EMPTY; + } + + var bounds = this._bounds; + + bounds.x = minX; + bounds.width = maxX - minX; + + bounds.y = minY; + bounds.height = maxY - minY; + + // store a reference so that if this function gets called again in the render cycle we do not have to recalculate + this._currentBounds = bounds; + + return bounds; +}; + +/** + * Different drawing buffer modes supported + * + * @static + * @constant + * @property {object} DrawModes + * @property {number} DrawModes.TRIANGLE_Mesh + * @property {number} DrawModes.TRIANGLES + */ +Mesh.DrawModes = { + TRIANGLE_Mesh: 0, + TRIANGLES: 1 +}; diff --git a/src/extras/mesh/Rope.js b/src/extras/mesh/Rope.js index 28e74f4..a6cfc44 100644 --- a/src/extras/mesh/Rope.js +++ b/src/extras/mesh/Rope.js @@ -1,4 +1,4 @@ -var Strip = require('./Strip'); +var Strip = require('./Mesh'); /** * diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js index f8f7b06..1684b53 100644 --- a/src/core/renderers/webgl/managers/ShaderManager.js +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -51,7 +51,7 @@ */ this.currentShader = null; - this.initPlugins(); +// this.initPlugins(); } ShaderManager.prototype = Object.create(WebGLManager.prototype); diff --git a/src/extras/mesh/Mesh.js b/src/extras/mesh/Mesh.js new file mode 100644 index 0000000..4a84ee8 --- /dev/null +++ b/src/extras/mesh/Mesh.js @@ -0,0 +1,393 @@ +var core = require('../../core'); + +/** + * + * @class + * @extends Container + * @memberof PIXI.extras + * @param texture {Texture} The texture to use + * @param width {number} the width + * @param height {number} the height + * + */ +function Mesh(texture, vertices, uvs, indecies, drawMode) +{ + core.Container.call(this); + + /** + * The texture of the Mesh + * + * @member {Texture} + */ + this.texture = texture; + + /** + * The Uvs of the Mesh + * + * @member {Float32Array} + */ + this.uvs = uvs || new Float32Array([0, 1, + 1, 1, + 1, 0, + 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 = indecies || new Uint16Array([0, 1, 2, 3]); + + /** + * Whether the Mesh is dirty or not + * + * @member {boolean} + */ + this.dirty = true; + + /** + * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. + * + * @member {number} + * @default CONST.BLEND_MODES.NORMAL; + */ + this.blendMode = core.CONST.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 Mesh.DrawModes consts + * + * @member {number} + */ + this.drawMode = drawMode || Mesh.DrawModes.TRIANGLE_Mesh; +} + +// constructor +Mesh.prototype = Object.create(core.Container.prototype); +Mesh.prototype.constructor = Mesh; +module.exports = Mesh; + +/** + * Renders the object using the WebGL renderer + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + */ +Mesh.prototype._renderWebGL = function (renderer) +{ + renderer.setObjectRenderer(renderer.plugins.mesh); + renderer.plugins.mesh.render(this); +}; + +/** + * Creates the buffers and (in the darkness) binds them + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + * @private + */ + +/** + * Renders the object using the Canvas renderer + * + * @param renderer {CanvasRenderer} + */ +Mesh.prototype._renderCanvas = function (renderer) +{ + var context = renderer.context; + + var transform = this.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); + } + else + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); + } + + if (this.drawMode === Mesh.DrawModes.TRIANGLE_Mesh) + { + this._renderCanvasTriangleMesh(context); + } + else + { + this._renderCanvasTriangles(context); + } +}; + +/** + * Draws the object in TRIANGLE_Mesh mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangleMesh = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + + var length = vertices.length / 2; + // this.count++; + + for (var i = 0; i < length - 2; i++) + { + // draw some triangles! + var index = i * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); + } +}; + +/** + * Draws the object in triangle mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangles = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + var indices = this.indices; + + var length = indices.length; + // this.count++; + + for (var i = 0; i < length; i += 3) + { + // draw some triangles! + var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); + } +}; + +/** + * Draws one of the triangles that form this Mesh + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @param vertices {Float32Array} a reference to the the vertices of the Mesh + * @param uvs {Float32Array} a reference to the the vertices of the Mesh + * @param index0 {number} the index of the first vertex + * @param index1 {number} the index of the second vertex + * @param index2 {number} the index of the third vertex + * @private + */ +Mesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) +{ + var textureSource = this.texture.baseTexture.source; + var textureWidth = this.texture.width; + var textureHeight = this.texture.height; + + var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; + var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; + + var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; + var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; + + if (this.canvasPadding > 0) + { + var paddingX = this.canvasPadding / this.worldTransform.a; + var paddingY = this.canvasPadding / this.worldTransform.d; + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; + + var normX = x0 - centerX; + var normY = y0 - centerY; + + var dist = Math.sqrt(normX * normX + normY * normY); + x0 = centerX + (normX / dist) * (dist + paddingX); + y0 = centerY + (normY / dist) * (dist + paddingY); + + // + + normX = x1 - centerX; + normY = y1 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x1 = centerX + (normX / dist) * (dist + paddingX); + y1 = centerY + (normY / dist) * (dist + paddingY); + + normX = x2 - centerX; + normY = y2 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x2 = centerX + (normX / dist) * (dist + paddingX); + y2 = centerY + (normY / dist) * (dist + paddingY); + } + + context.save(); + context.beginPath(); + + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); + var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); + var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); + var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); + var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); + var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); + var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(textureSource, 0, 0); + context.restore(); +}; + + + +/** + * Renders a flat Mesh + * + * @param Mesh {Mesh} The Mesh to render + * @private + */ +Mesh.prototype.renderMeshFlat = function (Mesh) +{ + var context = this.context; + var vertices = Mesh.vertices; + + var length = vertices.length/2; + // this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; + var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; + +/* +Mesh.prototype.setTexture = function (texture) +{ + //TODO SET THE TEXTURES + //TODO VISIBILITY + //TODO SETTER + + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +}; + */ + +/** + * When the texture is updated, this event will fire to update the scale and frame + * + * @param event + * @private + */ + +Mesh.prototype.onTextureUpdate = function () +{ + this.updateFrame = true; +}; + +/** + * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. + * + * @param matrix {Matrix} the transformation matrix of the sprite + * @return {Rectangle} the framing rectangle + */ +Mesh.prototype.getBounds = function (matrix) +{ + var worldTransform = matrix || this.worldTransform; + + var a = worldTransform.a; + var b = worldTransform.b; + var c = worldTransform.c; + var d = worldTransform.d; + var tx = worldTransform.tx; + var ty = worldTransform.ty; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + var vertices = this.vertices; + for (var i = 0, n = vertices.length; i < n; i += 2) + { + var rawX = vertices[i], rawY = vertices[i + 1]; + var x = (a * rawX) + (c * rawY) + tx; + var y = (d * rawY) + (b * rawX) + ty; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + if (minX === -Infinity || maxY === Infinity) + { + return core.math.Rectangle.EMPTY; + } + + var bounds = this._bounds; + + bounds.x = minX; + bounds.width = maxX - minX; + + bounds.y = minY; + bounds.height = maxY - minY; + + // store a reference so that if this function gets called again in the render cycle we do not have to recalculate + this._currentBounds = bounds; + + return bounds; +}; + +/** + * Different drawing buffer modes supported + * + * @static + * @constant + * @property {object} DrawModes + * @property {number} DrawModes.TRIANGLE_Mesh + * @property {number} DrawModes.TRIANGLES + */ +Mesh.DrawModes = { + TRIANGLE_Mesh: 0, + TRIANGLES: 1 +}; diff --git a/src/extras/mesh/Rope.js b/src/extras/mesh/Rope.js index 28e74f4..a6cfc44 100644 --- a/src/extras/mesh/Rope.js +++ b/src/extras/mesh/Rope.js @@ -1,4 +1,4 @@ -var Strip = require('./Strip'); +var Strip = require('./Mesh'); /** * diff --git a/src/extras/mesh/Strip.js b/src/extras/mesh/Strip.js deleted file mode 100644 index 1b06f2f..0000000 --- a/src/extras/mesh/Strip.js +++ /dev/null @@ -1,399 +0,0 @@ -var core = require('../../core'); - -/** - * - * @class - * @extends Container - * @memberof PIXI.extras - * @param texture {Texture} The texture to use - * @param width {number} the width - * @param height {number} the height - * - */ -function Strip(texture) -{ - core.Container.call(this); - - /** - * The texture of the strip - * - * @member {Texture} - */ - this.texture = texture; - - /** - * The Uvs of the strip - * - * @member {Float32Array} - */ - this.uvs = new Float32Array([0, 1, - 1, 1, - 1, 0, - 0, 1]); - - /** - * An array of vertices - * - * @member {Float32Array} - */ - this.vertices = new Float32Array([0, 0, - 100, 0, - 100, 100, - 0, 100]); - - /** - * The color components - * - * @member {Float32Array} - */ - this.colors = new Float32Array([1, 1, 1, 1]); - - /* - * @member {Uint16Array} An array containing the indices of the vertices - */ - this.indices = new Uint16Array([0, 1, 2, 3]); - - /** - * Whether the strip is dirty or not - * - * @member {boolean} - */ - this.dirty = true; - - /** - * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. - * - * @member {number} - * @default CONST.BLEND_MODES.NORMAL; - */ - this.blendMode = core.CONST.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 strip should be drawn, can be any of the Strip.DrawModes consts - * - * @member {number} - */ - this.drawMode = Strip.DrawModes.TRIANGLE_STRIP; -} - -// constructor -Strip.prototype = Object.create(core.Container.prototype); -Strip.prototype.constructor = Strip; -module.exports = Strip; - -/** - * Renders the object using the WebGL renderer - * - * @param renderer {WebGLRenderer} a reference to the WebGL renderer - */ -Strip.prototype._renderWebGL = function (renderer) -{ - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); -}; - -/** - * Creates the buffers and (in the darkness) binds them - * - * @param renderer {WebGLRenderer} a reference to the WebGL renderer - * @private - */ - -/** - * Renders the object using the Canvas renderer - * - * @param renderer {CanvasRenderer} - */ -Strip.prototype._renderCanvas = function (renderer) -{ - var context = renderer.context; - - var transform = this.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); - } - else - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); - } - - if (this.drawMode === Strip.DrawModes.TRIANGLE_STRIP) - { - this._renderCanvasTriangleStrip(context); - } - else - { - this._renderCanvasTriangles(context); - } -}; - -/** - * Draws the object in TRIANGLE_STRIP mode using canvas - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @private - */ -Strip.prototype._renderCanvasTriangleStrip = function (context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - - var length = vertices.length / 2; - // this.count++; - - for (var i = 0; i < length - 2; i++) - { - // draw some triangles! - var index = i * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); - } -}; - -/** - * Draws the object in triangle mode using canvas - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @private - */ -Strip.prototype._renderCanvasTriangles = function (context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - var indices = this.indices; - - var length = indices.length; - // this.count++; - - for (var i = 0; i < length; i += 3) - { - // draw some triangles! - var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); - } -}; - -/** - * Draws one of the triangles that form this strip - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @param vertices {Float32Array} a reference to the the vertices of the strip - * @param uvs {Float32Array} a reference to the the vertices of the strip - * @param index0 {number} the index of the first vertex - * @param index1 {number} the index of the second vertex - * @param index2 {number} the index of the third vertex - * @private - */ -Strip.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) -{ - var textureSource = this.texture.baseTexture.source; - var textureWidth = this.texture.width; - var textureHeight = this.texture.height; - - var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; - var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; - - var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; - var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; - - if (this.canvasPadding > 0) - { - var paddingX = this.canvasPadding / this.worldTransform.a; - var paddingY = this.canvasPadding / this.worldTransform.d; - var centerX = (x0 + x1 + x2) / 3; - var centerY = (y0 + y1 + y2) / 3; - - var normX = x0 - centerX; - var normY = y0 - centerY; - - var dist = Math.sqrt(normX * normX + normY * normY); - x0 = centerX + (normX / dist) * (dist + paddingX); - y0 = centerY + (normY / dist) * (dist + paddingY); - - // - - normX = x1 - centerX; - normY = y1 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x1 = centerX + (normX / dist) * (dist + paddingX); - y1 = centerY + (normY / dist) * (dist + paddingY); - - normX = x2 - centerX; - normY = y2 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x2 = centerX + (normX / dist) * (dist + paddingX); - y2 = centerY + (normY / dist) * (dist + paddingY); - } - - context.save(); - context.beginPath(); - - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - context.closePath(); - - context.clip(); - - // Compute matrix transform - var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); - var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); - var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); - var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); - var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); - var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); - var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); - - context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); - - context.drawImage(textureSource, 0, 0); - context.restore(); -}; - - - -/** - * Renders a flat strip - * - * @param strip {Strip} The Strip to render - * @private - */ -Strip.prototype.renderStripFlat = function (strip) -{ - var context = this.context; - var vertices = strip.vertices; - - var length = vertices.length/2; - // this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; - var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - } - - context.fillStyle = '#FF0000'; - context.fill(); - context.closePath(); -}; - -/* -Strip.prototype.setTexture = function (texture) -{ - //TODO SET THE TEXTURES - //TODO VISIBILITY - //TODO SETTER - - // stop current texture - this.texture = texture; - this.width = texture.frame.width; - this.height = texture.frame.height; - this.updateFrame = true; -}; - */ - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @param event - * @private - */ - -Strip.prototype.onTextureUpdate = function () -{ - this.updateFrame = true; -}; - -/** - * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. - * - * @param matrix {Matrix} the transformation matrix of the sprite - * @return {Rectangle} the framing rectangle - */ -Strip.prototype.getBounds = function (matrix) -{ - var worldTransform = matrix || this.worldTransform; - - var a = worldTransform.a; - var b = worldTransform.b; - var c = worldTransform.c; - var d = worldTransform.d; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) - { - var rawX = vertices[i], rawY = vertices[i + 1]; - var x = (a * rawX) + (c * rawY) + tx; - var y = (d * rawY) + (b * rawX) + ty; - - minX = x < minX ? x : minX; - minY = y < minY ? y : minY; - - maxX = x > maxX ? x : maxX; - maxY = y > maxY ? y : maxY; - } - - if (minX === -Infinity || maxY === Infinity) - { - return core.math.Rectangle.EMPTY; - } - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** - * Different drawing buffer modes supported - * - * @static - * @constant - * @property {object} DrawModes - * @property {number} DrawModes.TRIANGLE_STRIP - * @property {number} DrawModes.TRIANGLES - */ -Strip.DrawModes = { - TRIANGLE_STRIP: 0, - TRIANGLES: 1 -}; diff --git a/src/core/renderers/webgl/managers/ShaderManager.js b/src/core/renderers/webgl/managers/ShaderManager.js index f8f7b06..1684b53 100644 --- a/src/core/renderers/webgl/managers/ShaderManager.js +++ b/src/core/renderers/webgl/managers/ShaderManager.js @@ -51,7 +51,7 @@ */ this.currentShader = null; - this.initPlugins(); +// this.initPlugins(); } ShaderManager.prototype = Object.create(WebGLManager.prototype); diff --git a/src/extras/mesh/Mesh.js b/src/extras/mesh/Mesh.js new file mode 100644 index 0000000..4a84ee8 --- /dev/null +++ b/src/extras/mesh/Mesh.js @@ -0,0 +1,393 @@ +var core = require('../../core'); + +/** + * + * @class + * @extends Container + * @memberof PIXI.extras + * @param texture {Texture} The texture to use + * @param width {number} the width + * @param height {number} the height + * + */ +function Mesh(texture, vertices, uvs, indecies, drawMode) +{ + core.Container.call(this); + + /** + * The texture of the Mesh + * + * @member {Texture} + */ + this.texture = texture; + + /** + * The Uvs of the Mesh + * + * @member {Float32Array} + */ + this.uvs = uvs || new Float32Array([0, 1, + 1, 1, + 1, 0, + 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 = indecies || new Uint16Array([0, 1, 2, 3]); + + /** + * Whether the Mesh is dirty or not + * + * @member {boolean} + */ + this.dirty = true; + + /** + * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. + * + * @member {number} + * @default CONST.BLEND_MODES.NORMAL; + */ + this.blendMode = core.CONST.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 Mesh.DrawModes consts + * + * @member {number} + */ + this.drawMode = drawMode || Mesh.DrawModes.TRIANGLE_Mesh; +} + +// constructor +Mesh.prototype = Object.create(core.Container.prototype); +Mesh.prototype.constructor = Mesh; +module.exports = Mesh; + +/** + * Renders the object using the WebGL renderer + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + */ +Mesh.prototype._renderWebGL = function (renderer) +{ + renderer.setObjectRenderer(renderer.plugins.mesh); + renderer.plugins.mesh.render(this); +}; + +/** + * Creates the buffers and (in the darkness) binds them + * + * @param renderer {WebGLRenderer} a reference to the WebGL renderer + * @private + */ + +/** + * Renders the object using the Canvas renderer + * + * @param renderer {CanvasRenderer} + */ +Mesh.prototype._renderCanvas = function (renderer) +{ + var context = renderer.context; + + var transform = this.worldTransform; + + if (renderer.roundPixels) + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); + } + else + { + context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); + } + + if (this.drawMode === Mesh.DrawModes.TRIANGLE_Mesh) + { + this._renderCanvasTriangleMesh(context); + } + else + { + this._renderCanvasTriangles(context); + } +}; + +/** + * Draws the object in TRIANGLE_Mesh mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangleMesh = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + + var length = vertices.length / 2; + // this.count++; + + for (var i = 0; i < length - 2; i++) + { + // draw some triangles! + var index = i * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); + } +}; + +/** + * Draws the object in triangle mode using canvas + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @private + */ +Mesh.prototype._renderCanvasTriangles = function (context) +{ + // draw triangles!! + var vertices = this.vertices; + var uvs = this.uvs; + var indices = this.indices; + + var length = indices.length; + // this.count++; + + for (var i = 0; i < length; i += 3) + { + // draw some triangles! + var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; + this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); + } +}; + +/** + * Draws one of the triangles that form this Mesh + * + * @param context {CanvasRenderingContext2D} the current drawing context + * @param vertices {Float32Array} a reference to the the vertices of the Mesh + * @param uvs {Float32Array} a reference to the the vertices of the Mesh + * @param index0 {number} the index of the first vertex + * @param index1 {number} the index of the second vertex + * @param index2 {number} the index of the third vertex + * @private + */ +Mesh.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) +{ + var textureSource = this.texture.baseTexture.source; + var textureWidth = this.texture.width; + var textureHeight = this.texture.height; + + var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; + var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; + + var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; + var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; + + if (this.canvasPadding > 0) + { + var paddingX = this.canvasPadding / this.worldTransform.a; + var paddingY = this.canvasPadding / this.worldTransform.d; + var centerX = (x0 + x1 + x2) / 3; + var centerY = (y0 + y1 + y2) / 3; + + var normX = x0 - centerX; + var normY = y0 - centerY; + + var dist = Math.sqrt(normX * normX + normY * normY); + x0 = centerX + (normX / dist) * (dist + paddingX); + y0 = centerY + (normY / dist) * (dist + paddingY); + + // + + normX = x1 - centerX; + normY = y1 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x1 = centerX + (normX / dist) * (dist + paddingX); + y1 = centerY + (normY / dist) * (dist + paddingY); + + normX = x2 - centerX; + normY = y2 - centerY; + + dist = Math.sqrt(normX * normX + normY * normY); + x2 = centerX + (normX / dist) * (dist + paddingX); + y2 = centerY + (normY / dist) * (dist + paddingY); + } + + context.save(); + context.beginPath(); + + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); + var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); + var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); + var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); + var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); + var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); + var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(textureSource, 0, 0); + context.restore(); +}; + + + +/** + * Renders a flat Mesh + * + * @param Mesh {Mesh} The Mesh to render + * @private + */ +Mesh.prototype.renderMeshFlat = function (Mesh) +{ + var context = this.context; + var vertices = Mesh.vertices; + + var length = vertices.length/2; + // this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; + var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; + +/* +Mesh.prototype.setTexture = function (texture) +{ + //TODO SET THE TEXTURES + //TODO VISIBILITY + //TODO SETTER + + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +}; + */ + +/** + * When the texture is updated, this event will fire to update the scale and frame + * + * @param event + * @private + */ + +Mesh.prototype.onTextureUpdate = function () +{ + this.updateFrame = true; +}; + +/** + * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. + * + * @param matrix {Matrix} the transformation matrix of the sprite + * @return {Rectangle} the framing rectangle + */ +Mesh.prototype.getBounds = function (matrix) +{ + var worldTransform = matrix || this.worldTransform; + + var a = worldTransform.a; + var b = worldTransform.b; + var c = worldTransform.c; + var d = worldTransform.d; + var tx = worldTransform.tx; + var ty = worldTransform.ty; + + var maxX = -Infinity; + var maxY = -Infinity; + + var minX = Infinity; + var minY = Infinity; + + var vertices = this.vertices; + for (var i = 0, n = vertices.length; i < n; i += 2) + { + var rawX = vertices[i], rawY = vertices[i + 1]; + var x = (a * rawX) + (c * rawY) + tx; + var y = (d * rawY) + (b * rawX) + ty; + + minX = x < minX ? x : minX; + minY = y < minY ? y : minY; + + maxX = x > maxX ? x : maxX; + maxY = y > maxY ? y : maxY; + } + + if (minX === -Infinity || maxY === Infinity) + { + return core.math.Rectangle.EMPTY; + } + + var bounds = this._bounds; + + bounds.x = minX; + bounds.width = maxX - minX; + + bounds.y = minY; + bounds.height = maxY - minY; + + // store a reference so that if this function gets called again in the render cycle we do not have to recalculate + this._currentBounds = bounds; + + return bounds; +}; + +/** + * Different drawing buffer modes supported + * + * @static + * @constant + * @property {object} DrawModes + * @property {number} DrawModes.TRIANGLE_Mesh + * @property {number} DrawModes.TRIANGLES + */ +Mesh.DrawModes = { + TRIANGLE_Mesh: 0, + TRIANGLES: 1 +}; diff --git a/src/extras/mesh/Rope.js b/src/extras/mesh/Rope.js index 28e74f4..a6cfc44 100644 --- a/src/extras/mesh/Rope.js +++ b/src/extras/mesh/Rope.js @@ -1,4 +1,4 @@ -var Strip = require('./Strip'); +var Strip = require('./Mesh'); /** * diff --git a/src/extras/mesh/Strip.js b/src/extras/mesh/Strip.js deleted file mode 100644 index 1b06f2f..0000000 --- a/src/extras/mesh/Strip.js +++ /dev/null @@ -1,399 +0,0 @@ -var core = require('../../core'); - -/** - * - * @class - * @extends Container - * @memberof PIXI.extras - * @param texture {Texture} The texture to use - * @param width {number} the width - * @param height {number} the height - * - */ -function Strip(texture) -{ - core.Container.call(this); - - /** - * The texture of the strip - * - * @member {Texture} - */ - this.texture = texture; - - /** - * The Uvs of the strip - * - * @member {Float32Array} - */ - this.uvs = new Float32Array([0, 1, - 1, 1, - 1, 0, - 0, 1]); - - /** - * An array of vertices - * - * @member {Float32Array} - */ - this.vertices = new Float32Array([0, 0, - 100, 0, - 100, 100, - 0, 100]); - - /** - * The color components - * - * @member {Float32Array} - */ - this.colors = new Float32Array([1, 1, 1, 1]); - - /* - * @member {Uint16Array} An array containing the indices of the vertices - */ - this.indices = new Uint16Array([0, 1, 2, 3]); - - /** - * Whether the strip is dirty or not - * - * @member {boolean} - */ - this.dirty = true; - - /** - * The blend mode to be applied to the sprite. Set to blendModes.NORMAL to remove any blend mode. - * - * @member {number} - * @default CONST.BLEND_MODES.NORMAL; - */ - this.blendMode = core.CONST.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 strip should be drawn, can be any of the Strip.DrawModes consts - * - * @member {number} - */ - this.drawMode = Strip.DrawModes.TRIANGLE_STRIP; -} - -// constructor -Strip.prototype = Object.create(core.Container.prototype); -Strip.prototype.constructor = Strip; -module.exports = Strip; - -/** - * Renders the object using the WebGL renderer - * - * @param renderer {WebGLRenderer} a reference to the WebGL renderer - */ -Strip.prototype._renderWebGL = function (renderer) -{ - renderer.setObjectRenderer(renderer.plugins.mesh); - renderer.plugins.mesh.render(this); -}; - -/** - * Creates the buffers and (in the darkness) binds them - * - * @param renderer {WebGLRenderer} a reference to the WebGL renderer - * @private - */ - -/** - * Renders the object using the Canvas renderer - * - * @param renderer {CanvasRenderer} - */ -Strip.prototype._renderCanvas = function (renderer) -{ - var context = renderer.context; - - var transform = this.worldTransform; - - if (renderer.roundPixels) - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); - } - else - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); - } - - if (this.drawMode === Strip.DrawModes.TRIANGLE_STRIP) - { - this._renderCanvasTriangleStrip(context); - } - else - { - this._renderCanvasTriangles(context); - } -}; - -/** - * Draws the object in TRIANGLE_STRIP mode using canvas - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @private - */ -Strip.prototype._renderCanvasTriangleStrip = function (context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - - var length = vertices.length / 2; - // this.count++; - - for (var i = 0; i < length - 2; i++) - { - // draw some triangles! - var index = i * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); - } -}; - -/** - * Draws the object in triangle mode using canvas - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @private - */ -Strip.prototype._renderCanvasTriangles = function (context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - var indices = this.indices; - - var length = indices.length; - // this.count++; - - for (var i = 0; i < length; i += 3) - { - // draw some triangles! - var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); - } -}; - -/** - * Draws one of the triangles that form this strip - * - * @param context {CanvasRenderingContext2D} the current drawing context - * @param vertices {Float32Array} a reference to the the vertices of the strip - * @param uvs {Float32Array} a reference to the the vertices of the strip - * @param index0 {number} the index of the first vertex - * @param index1 {number} the index of the second vertex - * @param index2 {number} the index of the third vertex - * @private - */ -Strip.prototype._renderCanvasDrawTriangle = function (context, vertices, uvs, index0, index1, index2) -{ - var textureSource = this.texture.baseTexture.source; - var textureWidth = this.texture.width; - var textureHeight = this.texture.height; - - var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; - var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; - - var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; - var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; - - if (this.canvasPadding > 0) - { - var paddingX = this.canvasPadding / this.worldTransform.a; - var paddingY = this.canvasPadding / this.worldTransform.d; - var centerX = (x0 + x1 + x2) / 3; - var centerY = (y0 + y1 + y2) / 3; - - var normX = x0 - centerX; - var normY = y0 - centerY; - - var dist = Math.sqrt(normX * normX + normY * normY); - x0 = centerX + (normX / dist) * (dist + paddingX); - y0 = centerY + (normY / dist) * (dist + paddingY); - - // - - normX = x1 - centerX; - normY = y1 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x1 = centerX + (normX / dist) * (dist + paddingX); - y1 = centerY + (normY / dist) * (dist + paddingY); - - normX = x2 - centerX; - normY = y2 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x2 = centerX + (normX / dist) * (dist + paddingX); - y2 = centerY + (normY / dist) * (dist + paddingY); - } - - context.save(); - context.beginPath(); - - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - context.closePath(); - - context.clip(); - - // Compute matrix transform - var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); - var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); - var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); - var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); - var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); - var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); - var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); - - context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); - - context.drawImage(textureSource, 0, 0); - context.restore(); -}; - - - -/** - * Renders a flat strip - * - * @param strip {Strip} The Strip to render - * @private - */ -Strip.prototype.renderStripFlat = function (strip) -{ - var context = this.context; - var vertices = strip.vertices; - - var length = vertices.length/2; - // this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; - var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - } - - context.fillStyle = '#FF0000'; - context.fill(); - context.closePath(); -}; - -/* -Strip.prototype.setTexture = function (texture) -{ - //TODO SET THE TEXTURES - //TODO VISIBILITY - //TODO SETTER - - // stop current texture - this.texture = texture; - this.width = texture.frame.width; - this.height = texture.frame.height; - this.updateFrame = true; -}; - */ - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @param event - * @private - */ - -Strip.prototype.onTextureUpdate = function () -{ - this.updateFrame = true; -}; - -/** - * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. - * - * @param matrix {Matrix} the transformation matrix of the sprite - * @return {Rectangle} the framing rectangle - */ -Strip.prototype.getBounds = function (matrix) -{ - var worldTransform = matrix || this.worldTransform; - - var a = worldTransform.a; - var b = worldTransform.b; - var c = worldTransform.c; - var d = worldTransform.d; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) - { - var rawX = vertices[i], rawY = vertices[i + 1]; - var x = (a * rawX) + (c * rawY) + tx; - var y = (d * rawY) + (b * rawX) + ty; - - minX = x < minX ? x : minX; - minY = y < minY ? y : minY; - - maxX = x > maxX ? x : maxX; - maxY = y > maxY ? y : maxY; - } - - if (minX === -Infinity || maxY === Infinity) - { - return core.math.Rectangle.EMPTY; - } - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** - * Different drawing buffer modes supported - * - * @static - * @constant - * @property {object} DrawModes - * @property {number} DrawModes.TRIANGLE_STRIP - * @property {number} DrawModes.TRIANGLES - */ -Strip.DrawModes = { - TRIANGLE_STRIP: 0, - TRIANGLES: 1 -}; diff --git a/src/extras/mesh/webgl/MeshRenderer.js b/src/extras/mesh/webgl/MeshRenderer.js index 61fd28a..594a276 100644 --- a/src/extras/mesh/webgl/MeshRenderer.js +++ b/src/extras/mesh/webgl/MeshRenderer.js @@ -196,7 +196,7 @@ this.renderer.shaderManager.setShader(shader); // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicies); + //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicies); // this.s