Skip to content

Commit 2b129d8

Browse files
committed
Better handle matrix + silhouette updates
1 parent 4b2e171 commit 2b129d8

File tree

5 files changed

+30
-22
lines changed

5 files changed

+30
-22
lines changed

src/Drawable.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ class Drawable {
452452

453453
/**
454454
* Check if the world position touches the skin.
455+
* The caller is responsible for ensuring this drawable's inverse matrix & its skin's silhouette are up-to-date.
456+
* @see updateCPURenderAttributes
455457
* @param {twgl.v3} vec World coordinate vector.
456458
* @return {boolean} True if the world position touches the skin.
457459
*/
@@ -632,6 +634,15 @@ class Drawable {
632634
}
633635
}
634636

637+
/**
638+
* Update everything necessary to render this drawable on the CPU.
639+
*/
640+
updateCPURenderAttributes () {
641+
this.updateMatrix();
642+
// CPU rendering always occurs at the "native" size, so no need to scale up this._scale
643+
if (this.skin) this.skin.updateSilhouette(this._scale);
644+
}
645+
635646
/**
636647
* Respond to an internal change in the current Skin.
637648
* @private
@@ -676,6 +687,8 @@ class Drawable {
676687

677688
/**
678689
* Sample a color from a drawable's texture.
690+
* The caller is responsible for ensuring this drawable's inverse matrix & its skin's silhouette are up-to-date.
691+
* @see updateCPURenderAttributes
679692
* @param {twgl.v3} vec The scratch space [x,y] vector
680693
* @param {Drawable} drawable The drawable to sample the texture from
681694
* @param {Uint8ClampedArray} dst The "color4b" representation of the texture at point.

src/RenderWebGL.js

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@ class RenderWebGL extends EventEmitter {
752752
const color = __touchingColor;
753753
const hasMask = Boolean(mask3b);
754754

755+
drawable.updateCPURenderAttributes();
756+
755757
// Scratch Space - +y is top
756758
for (let y = bounds.bottom; y <= bounds.top; y++) {
757759
if (bounds.width * (y - bounds.bottom) * (candidates.length + 1) >= maxPixelsForCPU) {
@@ -895,6 +897,8 @@ class RenderWebGL extends EventEmitter {
895897
const drawable = this._allDrawables[drawableID];
896898
const point = __isTouchingDrawablesPoint;
897899

900+
drawable.updateCPURenderAttributes();
901+
898902
// This is an EXTREMELY brute force collision detector, but it is
899903
// still faster than asking the GPU to give us the pixels.
900904
for (let x = bounds.left; x <= bounds.right; x++) {
@@ -971,12 +975,7 @@ class RenderWebGL extends EventEmitter {
971975
const bounds = this.clientSpaceToScratchBounds(centerX, centerY, touchWidth, touchHeight);
972976
const worldPos = twgl.v3.create();
973977

974-
drawable.updateMatrix();
975-
if (drawable.skin) {
976-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
977-
} else {
978-
log.warn(`Could not find skin for drawable with id: ${drawableID}`);
979-
}
978+
drawable.updateCPURenderAttributes();
980979

981980
for (worldPos[1] = bounds.bottom; worldPos[1] <= bounds.top; worldPos[1]++) {
982981
for (worldPos[0] = bounds.left; worldPos[0] <= bounds.right; worldPos[0]++) {
@@ -1007,12 +1006,7 @@ class RenderWebGL extends EventEmitter {
10071006
const drawable = this._allDrawables[id];
10081007
// default pick list ignores visible and ghosted sprites.
10091008
if (drawable.getVisible() && drawable.getUniforms().u_ghost !== 0) {
1010-
drawable.updateMatrix();
1011-
if (drawable.skin) {
1012-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1013-
} else {
1014-
log.warn(`Could not find skin for drawable with id: ${id}`);
1015-
}
1009+
drawable.updateCPURenderAttributes();
10161010
return true;
10171011
}
10181012
return false;
@@ -1244,8 +1238,6 @@ class RenderWebGL extends EventEmitter {
12441238
/** @todo remove this once URL-based skin setting is removed. */
12451239
if (!drawable.skin || !drawable.skin.getTexture([100, 100])) return null;
12461240

1247-
drawable.updateMatrix();
1248-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
12491241
const bounds = drawable.getFastBounds();
12501242

12511243
// Limit queries to the stage size.
@@ -1282,8 +1274,7 @@ class RenderWebGL extends EventEmitter {
12821274
const drawable = this._allDrawables[id];
12831275
if (drawable.skin && drawable._visible) {
12841276
// Update the CPU position data
1285-
drawable.updateMatrix();
1286-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1277+
drawable.updateCPURenderAttributes();
12871278
const candidateBounds = drawable.getFastBounds();
12881279
if (bounds.intersects(candidateBounds)) {
12891280
result.push({
@@ -1763,15 +1754,14 @@ class RenderWebGL extends EventEmitter {
17631754
_getConvexHullPointsForDrawable (drawableID) {
17641755
const drawable = this._allDrawables[drawableID];
17651756

1766-
drawable.updateMatrix();
1767-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1768-
17691757
const [width, height] = drawable.skin.size;
17701758
// No points in the hull if invisible or size is 0.
17711759
if (!drawable.getVisible() || width === 0 || height === 0) {
17721760
return [];
17731761
}
17741762

1763+
drawable.updateCPURenderAttributes();
1764+
17751765
/**
17761766
* Return the determinant of two vectors, the vector from A to B and
17771767
* the vector from A to C.

src/SVGSkin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class SVGSkin extends Skin {
105105
return mip;
106106
}
107107

108-
updateSilhouette (scale = 1) {
108+
updateSilhouette (scale = [100, 100]) {
109109
// Ensure a silhouette exists.
110110
this.getTexture(scale);
111111
}

src/Skin.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ class Skin extends EventEmitter {
222222
/**
223223
* Does this point touch an opaque or translucent point on this skin?
224224
* Nearest Neighbor version
225+
* The caller is responsible for ensuring this skin's silhouette is up-to-date.
226+
* @see updateSilhouette
227+
* @see Drawable.updateCPURenderAttributes
225228
* @param {twgl.v3} vec A texture coordinate.
226229
* @return {boolean} Did it touch?
227230
*/
@@ -232,6 +235,9 @@ class Skin extends EventEmitter {
232235
/**
233236
* Does this point touch an opaque or translucent point on this skin?
234237
* Linear Interpolation version
238+
* The caller is responsible for ensuring this skin's silhouette is up-to-date.
239+
* @see updateSilhouette
240+
* @see Drawable.updateCPURenderAttributes
235241
* @param {twgl.v3} vec A texture coordinate.
236242
* @return {boolean} Did it touch?
237243
*/

test/integration/cpu-render.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@
6161
if (!(drawable._visible && drawable.skin)) {
6262
return;
6363
}
64-
drawable.updateMatrix();
65-
drawable.skin.updateSilhouette();
64+
drawable.updateCPURenderAttributes();
6665
return { id, drawable };
6766
}).reverse().filter(Boolean);
6867
const color = new Uint8ClampedArray(3);

0 commit comments

Comments
 (0)