From cfa2c96637cda67ef66178e7c350628146b3e716 Mon Sep 17 00:00:00 2001 From: photonstorm Date: Sun, 16 Feb 2014 14:32:16 +0000 Subject: [PATCH] Updated to latest pixi and p2.js --- build/p2.js | 274 +++++++++++------- src/pixi/InteractionManager.js | 4 +- src/pixi/display/SpriteBatch.js | 51 ++-- src/pixi/extras/TilingSprite.js | 127 +++++--- .../renderers/webgl/utils/WebGLSpriteBatch.js | 8 +- src/pixi/textures/Texture.js | 2 + 6 files changed, 295 insertions(+), 171 deletions(-) diff --git a/build/p2.js b/build/p2.js index e558d094..50b2e2d7 100644 --- a/build/p2.js +++ b/build/p2.js @@ -1511,6 +1511,7 @@ AABB.prototype.extend = function(aabb){ /** * Returns true if the given AABB overlaps this AABB. + * @method overlaps * @param {AABB} aabb * @return {Boolean} */ @@ -1968,6 +1969,7 @@ function clearObject(obj){ /** * Throws away the old equations and gets ready to create new * @method reset + * @param {World} world */ Narrowphase.prototype.reset = function(world){ @@ -2105,6 +2107,7 @@ Narrowphase.prototype.createFrictionFromContact = function(c){ Narrowphase.prototype[Shape.LINE | Shape.CONVEX] = Narrowphase.prototype.convexLine = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2123,6 +2126,7 @@ Narrowphase.prototype.convexLine = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.LINE | Shape.RECTANGLE] = Narrowphase.prototype.lineRectangle = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2141,6 +2145,7 @@ Narrowphase.prototype.lineRectangle = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.CAPSULE | Shape.RECTANGLE] = Narrowphase.prototype.rectangleCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2159,6 +2164,7 @@ Narrowphase.prototype.rectangleCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.CAPSULE | Shape.CONVEX] = Narrowphase.prototype.convexCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2177,6 +2183,7 @@ Narrowphase.prototype.convexCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.CAPSULE | Shape.LINE] = Narrowphase.prototype.lineCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2195,6 +2202,7 @@ Narrowphase.prototype.lineCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.CAPSULE | Shape.CAPSULE] = Narrowphase.prototype.capsuleCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2213,6 +2221,7 @@ Narrowphase.prototype.capsuleCapsule = function(bi,si,xi,ai, bj,sj,xj,aj){ Narrowphase.prototype[Shape.LINE | Shape.LINE] = Narrowphase.prototype.lineLine = function(bi,si,xi,ai, bj,sj,xj,aj){ // TODO + return 0; }; /** @@ -2239,7 +2248,8 @@ Narrowphase.prototype.planeLine = function(planeBody, planeShape, planeOffset, p dist = tmp7, worldNormal = tmp8, worldTangent = tmp9, - verts = tmpArray; + verts = tmpArray + numContacts = 0; // Get start and end points vec2.set(worldVertex0, -lineShape.length/2, 0); @@ -2277,6 +2287,7 @@ Narrowphase.prototype.planeLine = function(planeBody, planeShape, planeOffset, p if(d < 0){ var c = this.createContactEquation(planeBody,lineBody,planeShape,lineShape); + numContacts++; vec2.copy(c.ni, worldNormal); vec2.normalize(c.ni,c.ni); @@ -2301,6 +2312,8 @@ Narrowphase.prototype.planeLine = function(planeBody, planeShape, planeOffset, p } } } + + return numContacts; }; Narrowphase.prototype[Shape.PARTICLE | Shape.CAPSULE] = @@ -2401,7 +2414,7 @@ Narrowphase.prototype.circleLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest, if(pos > pos0 && pos < pos1){ // We got contact! - if(justTest) return true; + if(justTest) return 1; var c = this.createContactEquation(circleBody,lineBody,si,sj); @@ -2422,7 +2435,7 @@ Narrowphase.prototype.circleLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest, this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; } } @@ -2438,7 +2451,7 @@ Narrowphase.prototype.circleLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest, if(vec2.squaredLength(dist) < (circleRadius+lineRadius)*(circleRadius+lineRadius)){ - if(justTest) return true; + if(justTest) return 1; var c = this.createContactEquation(circleBody,lineBody,si,sj); @@ -2462,11 +2475,11 @@ Narrowphase.prototype.circleLine = function(bi,si,xi,ai, bj,sj,xj,aj, justTest, this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; } } - return false; + return 0; }; /** @@ -2630,7 +2643,7 @@ Narrowphase.prototype.circleConvex = function( bi,si,xi,ai, bj,sj,xj,aj, justTe if(this.enableFriction) this.frictionEquations.push( this.createFrictionFromContact(c) ); - return true; + return 1; } /* @@ -2667,7 +2680,7 @@ Narrowphase.prototype.circleConvex = function( bi,si,xi,ai, bj,sj,xj,aj, justTe sub(dist, worldVertex, circleOffset); if(vec2.squaredLength(dist) < circleRadius*circleRadius){ - if(justTest) return true; + if(justTest) return 1; var c = this.createContactEquation(circleBody,convexBody,si,sj); @@ -2689,12 +2702,12 @@ Narrowphase.prototype.circleConvex = function( bi,si,xi,ai, bj,sj,xj,aj, justTe this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; } } } - return false; + return 0; }; // Check if a point is in a polygon @@ -2786,7 +2799,7 @@ Narrowphase.prototype.particleConvex = function( bi,si,xi,ai, bj,sj,xj,aj, just // Check if the particle is in the polygon at all if(!pointInConvex(particleOffset,convexShape,convexOffset,convexAngle)) - return false; + return 0; // Check edges first var lastCross = null; @@ -2874,11 +2887,11 @@ Narrowphase.prototype.particleConvex = function( bi,si,xi,ai, bj,sj,xj,aj, just if(this.enableFriction) this.frictionEquations.push( this.createFrictionFromContact(c) ); - return true; + return 1; } - return false; + return 0; }; /** @@ -2906,10 +2919,10 @@ Narrowphase.prototype.circleCircle = function( bi,si,xi,ai, bj,sj,xj,aj, justTe sub(dist,xi,xj); var r = si.radius + sj.radius; if(vec2.squaredLength(dist) > r*r){ - return false; + return 0; } - if(justTest) return true; + if(justTest) return 1; var c = this.createContactEquation(bodyA,bodyB,si,sj); sub(c.ni, offsetB, offsetA); @@ -2929,7 +2942,7 @@ Narrowphase.prototype.circleCircle = function( bi,si,xi,ai, bj,sj,xj,aj, justTe if(this.enableFriction){ this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; }; /** @@ -3003,7 +3016,8 @@ Narrowphase.prototype.planeConvex = function( bi,si,xi,ai, bj,sj,xj,aj ){ break; } } - return numReported > 0; + + return numReported; }; /** @@ -3047,8 +3061,8 @@ Narrowphase.prototype.particlePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTe var d = dot(dist, worldNormal); - if(d > 0) return false; - if(justTest) return true; + if(d > 0) return 0; + if(justTest) return 1; var c = this.createContactEquation(planeBody,particleBody,sj,si); @@ -3068,7 +3082,7 @@ Narrowphase.prototype.particlePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTe if(this.enableFriction){ this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; }; /** @@ -3094,8 +3108,8 @@ Narrowphase.prototype.circleParticle = function( bi,si,xi,ai, bj,sj,xj,aj, jus dist = tmp1; sub(dist, particleOffset, circleOffset); - if(vec2.squaredLength(dist) > circleShape.radius*circleShape.radius) return false; - if(justTest) return true; + if(vec2.squaredLength(dist) > circleShape.radius*circleShape.radius) return 0; + if(justTest) return 1; var c = this.createContactEquation(circleBody,particleBody,si,sj); vec2.copy(c.ni, dist); @@ -3115,7 +3129,7 @@ Narrowphase.prototype.circleParticle = function( bi,si,xi,ai, bj,sj,xj,aj, jus this.frictionEquations.push(this.createFrictionFromContact(c)); } - return true; + return 1; }; var capsulePlane_tmpCircle = new Circle(1), @@ -3142,8 +3156,10 @@ Narrowphase.prototype.planeCapsule = function( bi,si,xi,ai, bj,sj,xj,aj ){ circle.radius = sj.radius; // Do Narrowphase as two circles - this.circlePlane(bj,circle,end1,0, bi,si,xi,ai); - this.circlePlane(bj,circle,end2,0, bi,si,xi,ai); + var numContacts1 = this.circlePlane(bj,circle,end1,0, bi,si,xi,ai), + numContacts2 = this.circlePlane(bj,circle,end2,0, bi,si,xi,ai); + + return numContacts1 + numContacts2; }; /** @@ -3191,7 +3207,7 @@ Narrowphase.prototype.circlePlane = function( bi,si,xi,ai, bj,sj,xj,aj ){ // Normal direction distance var d = dot(worldNormal, planeToCircle); - if(d > circleShape.radius) return false; // No overlap. Abort. + if(d > circleShape.radius) return 0; // No overlap. Abort. // Create contact var contact = this.createContactEquation(planeBody,circleBody,sj,si); @@ -3216,7 +3232,7 @@ Narrowphase.prototype.circlePlane = function( bi,si,xi,ai, bj,sj,xj,aj ){ this.frictionEquations.push( this.createFrictionFromContact(contact) ); } - return true; + return 1; }; @@ -3243,10 +3259,11 @@ Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, precis penetrationVec = tmp7, dist = tmp8, worldNormal = tmp9, + numContacts = 0, precision = precision || 1e-10; var found = Narrowphase.findSeparatingAxis(si,xi,ai,sj,xj,aj,sepAxis); - if(!found) return false; + if(!found) return 0; // Make sure the separating axis is directed from shape i to shape j sub(dist,xj,xi); @@ -3258,7 +3275,7 @@ Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, precis var closestEdge1 = Narrowphase.getClosestEdge(si,ai,sepAxis,true), // Flipped axis closestEdge2 = Narrowphase.getClosestEdge(sj,aj,sepAxis); - if(closestEdge1==-1 || closestEdge2==-1) return false; + if(closestEdge1==-1 || closestEdge2==-1) return 0; // Loop over the shapes for(var k=0; k<2; k++){ @@ -3323,6 +3340,7 @@ Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, precis // Create contact var c = this.createContactEquation(bodyA,bodyB,shapeA,shapeB); + numContacts++; // Get center edge from body A var v0 = shapeA.vertices[(closestEdgeA) % shapeA.vertices.length], @@ -3343,7 +3361,6 @@ Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, precis var d = dot(c.ni,dist); // Penetration vec2.scale(penetrationVec, c.ni, d); // Vector penetration - sub(c.ri, worldPoint, offsetA); sub(c.ri, c.ri, penetrationVec); add(c.ri, c.ri, offsetA); @@ -3361,6 +3378,8 @@ Narrowphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj, precis } } } + + return numContacts; }; // .projectConvex is called by other functions, need local tmp vectors @@ -7592,9 +7611,14 @@ function Convex(vertices){ * @type {Number} */ this.boundingRadius = 0; - this.updateBoundingRadius(); + Shape.call(this,Shape.CONVEX); + + this.updateBoundingRadius(); + this.updateArea(); + if(this.area < 0) + throw new Error("Convex vertices must be given in conter-clockwise winding."); }; Convex.prototype = new Shape(); @@ -7668,7 +7692,7 @@ Convex.prototype.updateCenterOfMass = function(){ // Get mass for the triangle (density=1 in this case) // http://math.stackexchange.com/questions/80198/area-of-triangle-via-vectors - var m = decomp.Point.area(a,b,c) + var m = Convex.triangleArea(a,b,c) totalArea += m; // Add to center of mass @@ -7681,76 +7705,24 @@ Convex.prototype.updateCenterOfMass = function(){ /** * Compute the mass moment of inertia of the Convex. - * @method conputeMomentOfInertia + * @method computeMomentOfInertia * @param {Number} mass * @return {Number} - * @todo should use .triangles + * @see http://www.gamedev.net/topic/342822-moment-of-inertia-of-a-polygon-2d/ */ Convex.prototype.computeMomentOfInertia = function(mass){ - - // In short: Triangulate the Convex, compute centroid and inertia of - // each sub-triangle. Add up to total using parallel axis theorem. - - var I = 0; - - // Rewrite on polyk notation, array of numbers - var polykVerts = []; - for(var i=0; i h=2*a/b - - // Get mass for the triangle - var m = area_triangle * density; - - // Get inertia for this triangle: http://answers.yahoo.com/question/index?qid=20080721030038AA3oE1m - var I_triangle = m*(base * (Math.pow(height,3))) / 36; - - // Add to total inertia using parallel axis theorem - var r2 = vec2.squaredLength(centroid); - I += I_triangle + m*r2; - } - - return I; + return (mass / 6.0) * (denom / numer); }; /** @@ -7769,6 +7741,19 @@ Convex.prototype.updateBoundingRadius = function(){ this.boundingRadius = Math.sqrt(r2); }; +/** + * Get the area of the triangle spanned by the three points a, b, c. The area is positive if the points are given in counter-clockwise order, otherwise negative. + * @static + * @method triangleArea + * @param {Array} a + * @param {Array} b + * @param {Array} c + * @return {Number} + */ +Convex.triangleArea = function(a,b,c){ + return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1]))) * 0.5; +} + /** * Update the .area * @method updateArea @@ -7786,8 +7771,7 @@ Convex.prototype.updateArea = function(){ c = verts[t[2]]; // Get mass for the triangle (density=1 in this case) - // http://math.stackexchange.com/questions/80198/area-of-triangle-via-vectors - var m = decomp.Point.area(a,b,c) + var m = Convex.triangleArea(a,b,c); this.area += m; } }; @@ -9119,6 +9103,25 @@ function World(options){ * @type {Boolean} */ this.enableBodySleeping = false; + + this.beginContactEvent = { + type:"beginContact", + shapeA : null, + shapeB : null, + bodyA : null, + bodyB : null, + }; + + this.endContactEvent = { + type:"endContact", + shapeA : null, + shapeB : null, + }; + + // For keeping track of overlapping shapes + this.overlappingShapesLastState = { keys:[] }; + this.overlappingShapesCurrentState = { keys:[] }; + this.overlappingShapeLookup = { keys:[] }; }; World.prototype = new Object(EventEmitter.prototype); @@ -9340,11 +9343,43 @@ World.prototype.internalStep = function(dt){ } } - World.runNarrowphase(np,bi,si,xi,ai,bj,sj,xj,aj,mu,restitution); + this.runNarrowphase(np,bi,si,xi,ai,bj,sj,xj,aj,mu,restitution); } } } + // Emit shape end overlap events + var last = this.overlappingShapesLastState; + for(var i=0; i 0){ + var key = si.id < sj.id ? si.id+" "+ sj.id : sj.id+" "+ si.id; + if(!this.overlappingShapesLastState[key]){ + // Report new shape overlap + var e = this.beginContactEvent; + e.shapeA = si; + e.shapeB = sj; + e.bodyA = bi; + e.bodyB = bj; + this.emit(e); + var current = this.overlappingShapesCurrentState; + if(!current[key]){ + current[key] = true; + current.keys.push(key); + + // Also store shape & body data + current[key+"_shapeA"] = si; + current.keys.push(key+"_shapeA"); + current[key+"_shapeB"] = sj; + current.keys.push(key+"_shapeB"); + current[key+"_bodyA"] = bi; + current.keys.push(key+"_bodyA"); + current[key+"_bodyB"] = bj; + current.keys.push(key+"_bodyB"); + } + } } } + }; /** diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js index 7d0b0375..b80f1440 100644 --- a/src/pixi/InteractionManager.js +++ b/src/pixi/InteractionManager.js @@ -204,7 +204,7 @@ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) domElement.addEventListener('touchend', this.onTouchEnd, true); domElement.addEventListener('touchmove', this.onTouchMove, true); - document.body.addEventListener('mouseup', this.onMouseUp, true); + window.addEventListener('mouseup', this.onMouseUp, true); }; @@ -226,7 +226,7 @@ PIXI.InteractionManager.prototype.removeEvents = function() this.interactionDOMElement = null; - document.body.removeEventListener('mouseup', this.onMouseUp, true); + window.removeEventListener('mouseup', this.onMouseUp, true); }; /** diff --git a/src/pixi/display/SpriteBatch.js b/src/pixi/display/SpriteBatch.js index 0d319f7c..28562c9f 100644 --- a/src/pixi/display/SpriteBatch.js +++ b/src/pixi/display/SpriteBatch.js @@ -99,20 +99,12 @@ PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession) var context = renderSession.context; context.globalAlpha = this.worldAlpha; - var transform = this.worldTransform; + PIXI.DisplayObject.prototype.updateTransform.call(this); + var transform = this.worldTransform; // alow for trimming - if (renderSession.roundPixels) - { - context.setTransform(transform.a, transform.c, transform.b, transform.d, Math.floor(transform.tx), Math.floor(transform.ty)); - } - else - { - context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); - } - - context.save(); + var isRotated = true; for (var i = 0; i < this.children.length; i++) { @@ -124,8 +116,13 @@ PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession) if(child.rotation % (Math.PI * 2) === 0) { - - // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call + if(isRotated) + { + context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); + isRotated = false; + } + + // this is the fastest way to optimise! - if rotation is 0 then we can avoid any kind of setTransform call context.drawImage(texture.baseTexture.source, frame.x, frame.y, @@ -138,24 +135,23 @@ PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession) } else { + if(!isRotated)isRotated = true; + PIXI.DisplayObject.prototype.updateTransform.call(child); - transform = child.localTransform; + var childTransform = child.worldTransform; - if(this.rotation !== this.rotationCache) + // allow for trimming + + if (renderSession.roundPixels) { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); + context.setTransform(childTransform.a, childTransform.c, childTransform.b, childTransform.d, childTransform.tx || 0, childTransform.ty || 0); + } + else + { + context.setTransform(childTransform.a, childTransform.c, childTransform.b, childTransform.d, childTransform.tx, childTransform.ty); } - var a = child._cr * child.scale.x, - b = -child._sr * child.scale.y, - c = child._sr * child.scale.x, - d = child._cr * child.scale.y; - - context.setTransform(a, c, b, d, child.position.x, child.position.y); - context.drawImage(texture.baseTexture.source, frame.x, frame.y, @@ -165,10 +161,13 @@ PIXI.SpriteBatch.prototype._renderCanvas = function(renderSession) ((child.anchor.y) * (-frame.height) + 0.5) | 0, frame.width, frame.height); + } + + // context.restore(); } - context.restore(); +// context.restore(); }; diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index f20a0b36..91e10ec7 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -132,6 +132,36 @@ PIXI.TilingSprite.prototype.onTextureUpdate = function() this.updateFrame = true; }; +PIXI.TilingSprite.prototype.setTexture = function(texture) +{ + if(this.texture === texture)return; + + this.texture = texture; + + this.refreshTexture = true; + /* + if(this.tilingTexture) + { + this.generateTilingTexture(true); + } +*/ + + /* + // stop current texture; + if(this.texture.baseTexture !== texture.baseTexture) + { + this.textureChange = true; + this.texture = texture; + } + else + { + this.texture = texture; + } + + this.updateFrame = true;*/ + this.cachedTint = 0xFFFFFF; +}; + /** * Renders the object using the WebGL renderer * @@ -161,7 +191,7 @@ PIXI.TilingSprite.prototype._renderWebGL = function(renderSession) renderSession.filterManager.pushFilter(this._filterBlock); } - if(!this.tilingTexture)this.generateTilingTexture(true); + if(!this.tilingTexture || this.refreshTexture)this.generateTilingTexture(true); else renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -179,7 +209,17 @@ PIXI.TilingSprite.prototype._renderWebGL = function(renderSession) } else { - if(!this.tilingTexture)this.generateTilingTexture(true); + if(!this.tilingTexture || this.refreshTexture) + { + this.generateTilingTexture(true); + if(this.tilingTexture.needsUpdate) + { + //TODO - tweaking + PIXI.updateWebGLTexture(this.tilingTexture.baseTexture, renderSession.gl); + this.tilingTexture.needsUpdate = false; + // this.tilingTexture._uvs = null; + } + } else renderSession.spriteBatch.renderTilingSprite(this); // simple render children! @@ -218,10 +258,10 @@ PIXI.TilingSprite.prototype._renderCanvas = function(renderSession) context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); - if(!this.__tilePattern) + if(!this.__tilePattern || this.refreshTexture) { this.generateTilingTexture(false); - + if(this.tilingTexture) { this.__tilePattern = context.createPattern(this.tilingTexture.baseTexture.source, 'repeat'); @@ -360,59 +400,78 @@ PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo) var targetWidth, targetHeight; // check that the frame is the same size as the base texture. - var isFrame = frame.width !== baseTexture.width || frame.height !== baseTexture.height; - this.tilingTexture = texture; - var newTextureRequired = false; if(!forcePowerOfTwo) { if(isFrame) { - if (texture.trim) - { - targetWidth = texture.trim.width; - targetHeight = texture.trim.height; - } - else - { - targetWidth = frame.width; - targetHeight = frame.height; - } - + targetWidth = frame.width; + targetHeight = frame.height; + newTextureRequired = true; + } } else { - targetWidth = PIXI.getNextPowerOfTwo(texture.frame.width); - targetHeight = PIXI.getNextPowerOfTwo(texture.frame.height); - + targetWidth = PIXI.getNextPowerOfTwo(frame.width); + targetHeight = PIXI.getNextPowerOfTwo(frame.height); if(frame.width !== targetWidth && frame.height !== targetHeight)newTextureRequired = true; } if(newTextureRequired) { - var canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight); + var canvasBuffer; + + if(this.tilingTexture && this.tilingTexture.isTiling) + { + canvasBuffer = this.tilingTexture.canvasBuffer; + canvasBuffer.resize(targetWidth, targetHeight); + this.tilingTexture.baseTexture.width = targetWidth; + this.tilingTexture.baseTexture.height = targetHeight; + this.tilingTexture.needsUpdate = true; + } + else + { + canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight); + + this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); + this.tilingTexture.canvasBuffer = canvasBuffer; + this.tilingTexture.isTiling = true; + + } canvasBuffer.context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - targetWidth, - targetHeight); - - this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); + frame.x, + frame.y, + frame.width, + frame.height, + 0, + 0, + targetWidth, + targetHeight); this.tileScaleOffset.x = frame.width / targetWidth; this.tileScaleOffset.y = frame.height / targetHeight; - } - + } + else + { + //TODO - switching? + if(this.tilingTexture && this.tilingTexture.isTiling) + { + // destroy the tiling texture! + // TODO could store this somewhere? + this.tilingTexture.destroy(true); + } + + this.tileScaleOffset.x = 1; + this.tileScaleOffset.y = 1; + this.tilingTexture = texture; + } + this.refreshTexture = false; this.tilingTexture.baseTexture._powerOf2 = true; }; \ No newline at end of file diff --git a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js index 0a63b343..aa3326f5 100644 --- a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js +++ b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js @@ -277,11 +277,11 @@ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) var uvs = tilingSprite._uvs; - tilingSprite.tilePosition.x %= texture.baseTexture.width; - tilingSprite.tilePosition.y %= texture.baseTexture.height; + tilingSprite.tilePosition.x %= texture.baseTexture.width * tilingSprite.tileScaleOffset.x; + tilingSprite.tilePosition.y %= texture.baseTexture.height * tilingSprite.tileScaleOffset.y; - var offsetX = tilingSprite.tilePosition.x/texture.baseTexture.width; - var offsetY = tilingSprite.tilePosition.y/texture.baseTexture.height; + var offsetX = tilingSprite.tilePosition.x/(texture.baseTexture.width*tilingSprite.tileScaleOffset.x); + var offsetY = tilingSprite.tilePosition.y/(texture.baseTexture.height*tilingSprite.tileScaleOffset.y); var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x); var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y); diff --git a/src/pixi/textures/Texture.js b/src/pixi/textures/Texture.js index c826c07d..2025b7e0 100644 --- a/src/pixi/textures/Texture.js +++ b/src/pixi/textures/Texture.js @@ -56,6 +56,8 @@ PIXI.Texture = function(baseTexture, frame) this.scope = this; + this._uvs = null; + if(baseTexture.hasLoaded) { if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);