diff --git a/src/Drawable.js b/src/Drawable.js index d6d66581..208e0812 100644 --- a/src/Drawable.js +++ b/src/Drawable.js @@ -452,6 +452,8 @@ class Drawable { /** * Check if the world position touches the skin. + * The caller is responsible for ensuring this drawable's inverse matrix & its skin's silhouette are up-to-date. + * @see updateCPURenderAttributes * @param {twgl.v3} vec World coordinate vector. * @return {boolean} True if the world position touches the skin. */ @@ -632,6 +634,15 @@ class Drawable { } } + /** + * Update everything necessary to render this drawable on the CPU. + */ + updateCPURenderAttributes () { + this.updateMatrix(); + // CPU rendering always occurs at the "native" size, so no need to scale up this._scale + if (this.skin) this.skin.updateSilhouette(this._scale); + } + /** * Respond to an internal change in the current Skin. * @private @@ -676,6 +687,8 @@ class Drawable { /** * Sample a color from a drawable's texture. + * The caller is responsible for ensuring this drawable's inverse matrix & its skin's silhouette are up-to-date. + * @see updateCPURenderAttributes * @param {twgl.v3} vec The scratch space [x,y] vector * @param {Drawable} drawable The drawable to sample the texture from * @param {Uint8ClampedArray} dst The "color4b" representation of the texture at point. diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 5c9580bc..7103f5ef 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -985,12 +985,7 @@ class RenderWebGL extends EventEmitter { const bounds = this.clientSpaceToScratchBounds(centerX, centerY, touchWidth, touchHeight); const worldPos = twgl.v3.create(); - drawable.updateMatrix(); - if (drawable.skin) { - drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable)); - } else { - log.warn(`Could not find skin for drawable with id: ${drawableID}`); - } + drawable.updateCPURenderAttributes(); for (worldPos[1] = bounds.bottom; worldPos[1] <= bounds.top; worldPos[1]++) { for (worldPos[0] = bounds.left; worldPos[0] <= bounds.right; worldPos[0]++) { @@ -1021,12 +1016,7 @@ class RenderWebGL extends EventEmitter { const drawable = this._allDrawables[id]; // default pick list ignores visible and ghosted sprites. if (drawable.getVisible() && drawable.getUniforms().u_ghost !== 0) { - drawable.updateMatrix(); - if (drawable.skin) { - drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable)); - } else { - log.warn(`Could not find skin for drawable with id: ${id}`); - } + drawable.updateCPURenderAttributes(); return true; } return false; @@ -1258,8 +1248,8 @@ class RenderWebGL extends EventEmitter { /** @todo remove this once URL-based skin setting is removed. */ if (!drawable.skin || !drawable.skin.getTexture([100, 100])) return null; - drawable.updateMatrix(); - drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable)); + + drawable.updateCPURenderAttributes(); const bounds = drawable.getFastBounds(); // Limit queries to the stage size. @@ -1296,8 +1286,7 @@ class RenderWebGL extends EventEmitter { const drawable = this._allDrawables[id]; if (drawable.skin && drawable._visible) { // Update the CPU position data - drawable.updateMatrix(); - drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable)); + drawable.updateCPURenderAttributes(); const candidateBounds = drawable.getFastBounds(); if (bounds.intersects(candidateBounds)) { result.push({ @@ -1775,8 +1764,7 @@ class RenderWebGL extends EventEmitter { _getConvexHullPointsForDrawable (drawableID) { const drawable = this._allDrawables[drawableID]; - drawable.updateMatrix(); - drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable)); + drawable.updateCPURenderAttributes(); const [width, height] = drawable.skin.size; // No points in the hull if invisible or size is 0. diff --git a/src/SVGSkin.js b/src/SVGSkin.js index 9699b459..8da356f4 100644 --- a/src/SVGSkin.js +++ b/src/SVGSkin.js @@ -105,7 +105,7 @@ class SVGSkin extends Skin { return mip; } - updateSilhouette (scale = 1) { + updateSilhouette (scale = [100, 100]) { // Ensure a silhouette exists. this.getTexture(scale); } diff --git a/src/Skin.js b/src/Skin.js index 06cedd85..3a740a8f 100644 --- a/src/Skin.js +++ b/src/Skin.js @@ -222,6 +222,9 @@ class Skin extends EventEmitter { /** * Does this point touch an opaque or translucent point on this skin? * Nearest Neighbor version + * The caller is responsible for ensuring this skin's silhouette is up-to-date. + * @see updateSilhouette + * @see Drawable.updateCPURenderAttributes * @param {twgl.v3} vec A texture coordinate. * @return {boolean} Did it touch? */ @@ -232,6 +235,9 @@ class Skin extends EventEmitter { /** * Does this point touch an opaque or translucent point on this skin? * Linear Interpolation version + * The caller is responsible for ensuring this skin's silhouette is up-to-date. + * @see updateSilhouette + * @see Drawable.updateCPURenderAttributes * @param {twgl.v3} vec A texture coordinate. * @return {boolean} Did it touch? */ diff --git a/test/integration/cpu-render.html b/test/integration/cpu-render.html index 26a79c3f..7eec0a61 100644 --- a/test/integration/cpu-render.html +++ b/test/integration/cpu-render.html @@ -42,8 +42,7 @@ if (!(drawable._visible && drawable.skin)) { return; } - drawable.updateMatrix(); - drawable.skin.updateSilhouette(); + drawable.updateCPURenderAttributes(); return { id, drawable }; }).reverse().filter(Boolean); const color = new Uint8ClampedArray(3);