Skip to content

Commit 9e80f1c

Browse files
committed
Better handle matrix + silhouette updates
1 parent d73aeb1 commit 9e80f1c

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
@@ -763,6 +763,8 @@ class RenderWebGL extends EventEmitter {
763763
const color = __touchingColor;
764764
const hasMask = Boolean(mask3b);
765765

766+
drawable.updateCPURenderAttributes();
767+
766768
// Masked drawable ignores ghost effect
767769
const effectMask = ~ShaderManager.EFFECT_INFO.ghost.mask;
768770

@@ -909,6 +911,8 @@ class RenderWebGL extends EventEmitter {
909911
const drawable = this._allDrawables[drawableID];
910912
const point = __isTouchingDrawablesPoint;
911913

914+
drawable.updateCPURenderAttributes();
915+
912916
// This is an EXTREMELY brute force collision detector, but it is
913917
// still faster than asking the GPU to give us the pixels.
914918
for (let x = bounds.left; x <= bounds.right; x++) {
@@ -985,12 +989,7 @@ class RenderWebGL extends EventEmitter {
985989
const bounds = this.clientSpaceToScratchBounds(centerX, centerY, touchWidth, touchHeight);
986990
const worldPos = twgl.v3.create();
987991

988-
drawable.updateMatrix();
989-
if (drawable.skin) {
990-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
991-
} else {
992-
log.warn(`Could not find skin for drawable with id: ${drawableID}`);
993-
}
992+
drawable.updateCPURenderAttributes();
994993

995994
for (worldPos[1] = bounds.bottom; worldPos[1] <= bounds.top; worldPos[1]++) {
996995
for (worldPos[0] = bounds.left; worldPos[0] <= bounds.right; worldPos[0]++) {
@@ -1021,12 +1020,7 @@ class RenderWebGL extends EventEmitter {
10211020
const drawable = this._allDrawables[id];
10221021
// default pick list ignores visible and ghosted sprites.
10231022
if (drawable.getVisible() && drawable.getUniforms().u_ghost !== 0) {
1024-
drawable.updateMatrix();
1025-
if (drawable.skin) {
1026-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1027-
} else {
1028-
log.warn(`Could not find skin for drawable with id: ${id}`);
1029-
}
1023+
drawable.updateCPURenderAttributes();
10301024
return true;
10311025
}
10321026
return false;
@@ -1258,8 +1252,6 @@ class RenderWebGL extends EventEmitter {
12581252
/** @todo remove this once URL-based skin setting is removed. */
12591253
if (!drawable.skin || !drawable.skin.getTexture([100, 100])) return null;
12601254

1261-
drawable.updateMatrix();
1262-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
12631255
const bounds = drawable.getFastBounds();
12641256

12651257
// Limit queries to the stage size.
@@ -1296,8 +1288,7 @@ class RenderWebGL extends EventEmitter {
12961288
const drawable = this._allDrawables[id];
12971289
if (drawable.skin && drawable._visible) {
12981290
// Update the CPU position data
1299-
drawable.updateMatrix();
1300-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1291+
drawable.updateCPURenderAttributes();
13011292
const candidateBounds = drawable.getFastBounds();
13021293
if (bounds.intersects(candidateBounds)) {
13031294
result.push({
@@ -1775,15 +1766,14 @@ class RenderWebGL extends EventEmitter {
17751766
_getConvexHullPointsForDrawable (drawableID) {
17761767
const drawable = this._allDrawables[drawableID];
17771768

1778-
drawable.updateMatrix();
1779-
drawable.skin.updateSilhouette(this._getDrawableScreenSpaceScale(drawable));
1780-
17811769
const [width, height] = drawable.skin.size;
17821770
// No points in the hull if invisible or size is 0.
17831771
if (!drawable.getVisible() || width === 0 || height === 0) {
17841772
return [];
17851773
}
17861774

1775+
drawable.updateCPURenderAttributes();
1776+
17871777
/**
17881778
* Return the determinant of two vectors, the vector from A to B and the vector from A to C.
17891779
*

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
@@ -42,8 +42,7 @@
4242
if (!(drawable._visible && drawable.skin)) {
4343
return;
4444
}
45-
drawable.updateMatrix();
46-
drawable.skin.updateSilhouette();
45+
drawable.updateCPURenderAttributes();
4746
return { id, drawable };
4847
}).reverse().filter(Boolean);
4948
const color = new Uint8ClampedArray(3);

0 commit comments

Comments
 (0)