Skip to content

Commit 1eb066c

Browse files
authored
Merge branch 'develop' into int-touching-bounds
2 parents ffe3da7 + 58aa05c commit 1eb066c

File tree

15 files changed

+337
-210
lines changed

15 files changed

+337
-210
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"gh-pages": "^1.0.0",
3838
"jsdoc": "^3.5.5",
3939
"json": "^9.0.4",
40-
"scratch-vm": "0.2.0-prerelease.20190207224121",
40+
"scratch-vm": "0.2.0-prerelease.20190213162739",
4141
"tap": "^11.0.0",
4242
"travis-after-all": "^1.4.4",
4343
"uglifyjs-webpack-plugin": "^1.2.5",
@@ -53,7 +53,7 @@
5353
"minilog": "3.1.0",
5454
"raw-loader": "^0.5.1",
5555
"scratch-storage": "^1.0.0",
56-
"scratch-svg-renderer": "0.2.0-prerelease.20190523193400",
56+
"scratch-svg-renderer": "0.2.0-prerelease.20191104164753",
5757
"twgl.js": "4.4.0"
5858
}
5959
}

src/BitmapSkin.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ class BitmapSkin extends Skin {
2323

2424
/** @type {Array<int>} */
2525
this._textureSize = [0, 0];
26-
27-
/**
28-
* The "native" size, in texels, of this skin.
29-
* @type {Array<number>}
30-
*/
31-
this.size = [0, 0];
3226
}
3327

3428
/**
@@ -49,13 +43,20 @@ class BitmapSkin extends Skin {
4943
return true;
5044
}
5145

46+
/**
47+
* @return {Array<number>} the "native" size, in texels, of this skin.
48+
*/
49+
get size () {
50+
return [this._textureSize[0] / this._costumeResolution, this._textureSize[1] / this._costumeResolution];
51+
}
52+
5253
/**
5354
* @param {Array<number>} scale - The scaling factors to be used.
5455
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given scale.
5556
*/
5657
// eslint-disable-next-line no-unused-vars
5758
getTexture (scale) {
58-
return this._texture;
59+
return this._texture || super.getTexture();
5960
}
6061

6162
/**
@@ -77,6 +78,10 @@ class BitmapSkin extends Skin {
7778
* @fires Skin.event:WasAltered
7879
*/
7980
setBitmap (bitmapData, costumeResolution, rotationCenter) {
81+
if (!bitmapData.width || !bitmapData.height) {
82+
super.setEmptyImageData();
83+
return;
84+
}
8085
const gl = this._renderer.gl;
8186

8287
// Preferably bitmapData is ImageData. ImageData speeds up updating
@@ -109,7 +114,6 @@ class BitmapSkin extends Skin {
109114
// Do these last in case any of the above throws an exception
110115
this._costumeResolution = costumeResolution || 2;
111116
this._textureSize = BitmapSkin._getBitmapSize(bitmapData);
112-
this.size = [this._textureSize[0] / this._costumeResolution, this._textureSize[1] / this._costumeResolution];
113117

114118
if (typeof rotationCenter === 'undefined') rotationCenter = this.calculateRotationCenter();
115119
this.setRotationCenter.apply(this, rotationCenter);

src/Drawable.js

Lines changed: 111 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const twgl = require('twgl.js');
33
const Rectangle = require('./Rectangle');
44
const RenderConstants = require('./RenderConstants');
55
const ShaderManager = require('./ShaderManager');
6+
const Skin = require('./Skin');
67
const EffectTransform = require('./EffectTransform');
78

89
/**
@@ -103,6 +104,8 @@ class Drawable {
103104
/** @todo move convex hull functionality, maybe bounds functionality overall, to Skin classes */
104105
this._convexHullPoints = null;
105106
this._convexHullDirty = true;
107+
108+
this._skinWasAltered = this._skinWasAltered.bind(this);
106109
}
107110

108111
/**
@@ -141,7 +144,13 @@ class Drawable {
141144
*/
142145
set skin (newSkin) {
143146
if (this._skin !== newSkin) {
147+
if (this._skin) {
148+
this._skin.removeListener(Skin.Events.WasAltered, this._skinWasAltered);
149+
}
144150
this._skin = newSkin;
151+
if (this._skin) {
152+
this._skin.addListener(Skin.Events.WasAltered, this._skinWasAltered);
153+
}
145154
this._skinWasAltered();
146155
}
147156
}
@@ -178,55 +187,98 @@ class Drawable {
178187
}
179188

180189
/**
181-
* Update the position, direction, scale, or effect properties of this Drawable.
182-
* @param {object.<string,*>} properties The new property values to set.
190+
* Update the position if it is different. Marks the transform as dirty.
191+
* @param {Array.<number>} position A new position.
183192
*/
184-
updateProperties (properties) {
185-
let dirty = false;
186-
if ('position' in properties && (
187-
this._position[0] !== properties.position[0] ||
188-
this._position[1] !== properties.position[1])) {
189-
this._position[0] = Math.round(properties.position[0]);
190-
this._position[1] = Math.round(properties.position[1]);
191-
dirty = true;
192-
}
193-
if ('direction' in properties && this._direction !== properties.direction) {
194-
this._direction = properties.direction;
193+
updatePosition (position) {
194+
if (this._position[0] !== position[0] ||
195+
this._position[1] !== position[1]) {
196+
this._position[0] = Math.round(position[0]);
197+
this._position[1] = Math.round(position[1]);
198+
this.setTransformDirty();
199+
}
200+
}
201+
202+
/**
203+
* Update the direction if it is different. Marks the transform as dirty.
204+
* @param {number} direction A new direction.
205+
*/
206+
updateDirection (direction) {
207+
if (this._direction !== direction) {
208+
this._direction = direction;
195209
this._rotationTransformDirty = true;
196-
dirty = true;
210+
this.setTransformDirty();
197211
}
198-
if ('scale' in properties && (
199-
this._scale[0] !== properties.scale[0] ||
200-
this._scale[1] !== properties.scale[1])) {
201-
this._scale[0] = properties.scale[0];
202-
this._scale[1] = properties.scale[1];
212+
}
213+
214+
/**
215+
* Update the scale if it is different. Marks the transform as dirty.
216+
* @param {Array.<number>} scale A new scale.
217+
*/
218+
updateScale (scale) {
219+
if (this._scale[0] !== scale[0] ||
220+
this._scale[1] !== scale[1]) {
221+
this._scale[0] = scale[0];
222+
this._scale[1] = scale[1];
203223
this._rotationCenterDirty = true;
204224
this._skinScaleDirty = true;
205-
dirty = true;
225+
this.setTransformDirty();
206226
}
207-
if ('visible' in properties) {
208-
this._visible = properties.visible;
227+
}
228+
229+
/**
230+
* Update visibility if it is different. Marks the convex hull as dirty.
231+
* @param {boolean} visible A new visibility state.
232+
*/
233+
updateVisible (visible) {
234+
if (this._visible !== visible) {
235+
this._visible = visible;
209236
this.setConvexHullDirty();
210237
}
211-
if (dirty) {
212-
this.setTransformDirty();
238+
}
239+
240+
/**
241+
* Update an effect. Marks the convex hull as dirty if the effect changes shape.
242+
* @param {string} effectName The name of the effect.
243+
* @param {number} rawValue A new effect value.
244+
*/
245+
updateEffect (effectName, rawValue) {
246+
const effectInfo = ShaderManager.EFFECT_INFO[effectName];
247+
if (rawValue) {
248+
this._effectBits |= effectInfo.mask;
249+
} else {
250+
this._effectBits &= ~effectInfo.mask;
251+
}
252+
const converter = effectInfo.converter;
253+
this._uniforms[effectInfo.uniformName] = converter(rawValue);
254+
if (effectInfo.shapeChanges) {
255+
this.setConvexHullDirty();
256+
}
257+
}
258+
259+
/**
260+
* Update the position, direction, scale, or effect properties of this Drawable.
261+
* @deprecated Use specific update* methods instead.
262+
* @param {object.<string,*>} properties The new property values to set.
263+
*/
264+
updateProperties (properties) {
265+
if ('position' in properties) {
266+
this.updatePosition(properties.position);
267+
}
268+
if ('direction' in properties) {
269+
this.updateDirection(properties.direction);
270+
}
271+
if ('scale' in properties) {
272+
this.updateScale(properties.scale);
273+
}
274+
if ('visible' in properties) {
275+
this.updateVisible(properties.visible);
213276
}
214277
const numEffects = ShaderManager.EFFECTS.length;
215278
for (let index = 0; index < numEffects; ++index) {
216279
const effectName = ShaderManager.EFFECTS[index];
217280
if (effectName in properties) {
218-
const rawValue = properties[effectName];
219-
const effectInfo = ShaderManager.EFFECT_INFO[effectName];
220-
if (rawValue) {
221-
this._effectBits |= effectInfo.mask;
222-
} else {
223-
this._effectBits &= ~effectInfo.mask;
224-
}
225-
const converter = effectInfo.converter;
226-
this._uniforms[effectInfo.uniformName] = converter(rawValue);
227-
if (effectInfo.shapeChanges) {
228-
this.setConvexHullDirty();
229-
}
281+
this.updateEffect(effectName, properties[effectName]);
230282
}
231283
}
232284
}
@@ -412,29 +464,43 @@ class Drawable {
412464

413465
const localPosition = getLocalPosition(this, vec);
414466

415-
if (this.useNearest) {
467+
// We're not passing in a scale to useNearest, but that's okay because "touching" queries
468+
// happen at the "native" size anyway.
469+
if (this.useNearest()) {
416470
return this.skin.isTouchingNearest(localPosition);
417471
}
418472
return this.skin.isTouchingLinear(localPosition);
419473
}
420474

421475
/**
422476
* Should the drawable use NEAREST NEIGHBOR or LINEAR INTERPOLATION mode
477+
* @param {?Array<Number>} scale Optionally, the screen-space scale of the drawable.
478+
* @return {boolean} True if the drawable should use nearest-neighbor interpolation.
423479
*/
424-
get useNearest () {
480+
useNearest (scale = this.scale) {
425481
// Raster skins (bitmaps) should always prefer nearest neighbor
426482
if (this.skin.isRaster) {
427483
return true;
428484
}
429485

486+
// If the effect bits for mosaic, pixelate, whirl, or fisheye are set, use linear
487+
if ((this._effectBits & (
488+
ShaderManager.EFFECT_INFO.fisheye.mask |
489+
ShaderManager.EFFECT_INFO.whirl.mask |
490+
ShaderManager.EFFECT_INFO.pixelate.mask |
491+
ShaderManager.EFFECT_INFO.mosaic.mask
492+
)) !== 0) {
493+
return false;
494+
}
495+
430496
// We can't use nearest neighbor unless we are a multiple of 90 rotation
431497
if (this._direction % 90 !== 0) {
432498
return false;
433499
}
434500

435501
// If the scale of the skin is very close to 100 (0.99999 variance is okay I guess)
436-
if (Math.abs(this.scale[0]) > 99 && Math.abs(this.scale[0]) < 101 &&
437-
Math.abs(this.scale[1]) > 99 && Math.abs(this.scale[1]) < 101) {
502+
if (Math.abs(scale[0]) > 99 && Math.abs(scale[0]) < 101 &&
503+
Math.abs(scale[1]) > 99 && Math.abs(scale[1]) < 101) {
438504
return true;
439505
}
440506
return false;
@@ -514,7 +580,6 @@ class Drawable {
514580
* @return {!Rectangle} Bounds for the Drawable.
515581
*/
516582
getFastBounds (result) {
517-
this.updateMatrix();
518583
if (!this.needsConvexHullPoints()) {
519584
return this.getBounds(result);
520585
}
@@ -626,9 +691,11 @@ class Drawable {
626691
return dst;
627692
}
628693
const textColor =
629-
drawable.useNearest ?
630-
drawable.skin._silhouette.colorAtNearest(localPosition, dst) :
631-
drawable.skin._silhouette.colorAtLinear(localPosition, dst);
694+
// commenting out to only use nearest for now
695+
// drawable.useNearest() ?
696+
drawable.skin._silhouette.colorAtNearest(localPosition, dst);
697+
// : drawable.skin._silhouette.colorAtLinear(localPosition, dst);
698+
632699
return EffectTransform.transformColor(drawable, textColor, textColor);
633700
}
634701
}

0 commit comments

Comments
 (0)