Skip to content

Commit 357d684

Browse files
authored
Merge branch 'develop' into penskin-silhouette-from-data
2 parents 5789910 + 13b9ed7 commit 357d684

File tree

13 files changed

+265
-174
lines changed

13 files changed

+265
-174
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.20190822202608",
5757
"twgl.js": "4.4.0"
5858
}
5959
}

src/BitmapSkin.js

Lines changed: 7 additions & 7 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,6 +43,13 @@ 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.
@@ -109,7 +110,6 @@ class BitmapSkin extends Skin {
109110
// Do these last in case any of the above throws an exception
110111
this._costumeResolution = costumeResolution || 2;
111112
this._textureSize = BitmapSkin._getBitmapSize(bitmapData);
112-
this.size = [this._textureSize[0] / this._costumeResolution, this._textureSize[1] / this._costumeResolution];
113113

114114
if (typeof rotationCenter === 'undefined') rotationCenter = this.calculateRotationCenter();
115115
this.setRotationCenter.apply(this, rotationCenter);

src/Drawable.js

Lines changed: 98 additions & 37 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
/**
@@ -100,6 +101,8 @@ class Drawable {
100101
/** @todo move convex hull functionality, maybe bounds functionality overall, to Skin classes */
101102
this._convexHullPoints = null;
102103
this._convexHullDirty = true;
104+
105+
this._skinWasAltered = this._skinWasAltered.bind(this);
103106
}
104107

105108
/**
@@ -138,7 +141,13 @@ class Drawable {
138141
*/
139142
set skin (newSkin) {
140143
if (this._skin !== newSkin) {
144+
if (this._skin) {
145+
this._skin.removeListener(Skin.Events.WasAltered, this._skinWasAltered);
146+
}
141147
this._skin = newSkin;
148+
if (this._skin) {
149+
this._skin.addListener(Skin.Events.WasAltered, this._skinWasAltered);
150+
}
142151
this._skinWasAltered();
143152
}
144153
}
@@ -175,55 +184,98 @@ class Drawable {
175184
}
176185

177186
/**
178-
* Update the position, direction, scale, or effect properties of this Drawable.
179-
* @param {object.<string,*>} properties The new property values to set.
187+
* Update the position if it is different. Marks the transform as dirty.
188+
* @param {Array.<number>} position A new position.
180189
*/
181-
updateProperties (properties) {
182-
let dirty = false;
183-
if ('position' in properties && (
184-
this._position[0] !== properties.position[0] ||
185-
this._position[1] !== properties.position[1])) {
186-
this._position[0] = Math.round(properties.position[0]);
187-
this._position[1] = Math.round(properties.position[1]);
188-
dirty = true;
189-
}
190-
if ('direction' in properties && this._direction !== properties.direction) {
191-
this._direction = properties.direction;
190+
updatePosition (position) {
191+
if (this._position[0] !== position[0] ||
192+
this._position[1] !== position[1]) {
193+
this._position[0] = Math.round(position[0]);
194+
this._position[1] = Math.round(position[1]);
195+
this.setTransformDirty();
196+
}
197+
}
198+
199+
/**
200+
* Update the direction if it is different. Marks the transform as dirty.
201+
* @param {number} direction A new direction.
202+
*/
203+
updateDirection (direction) {
204+
if (this._direction !== direction) {
205+
this._direction = direction;
192206
this._rotationTransformDirty = true;
193-
dirty = true;
207+
this.setTransformDirty();
194208
}
195-
if ('scale' in properties && (
196-
this._scale[0] !== properties.scale[0] ||
197-
this._scale[1] !== properties.scale[1])) {
198-
this._scale[0] = properties.scale[0];
199-
this._scale[1] = properties.scale[1];
209+
}
210+
211+
/**
212+
* Update the scale if it is different. Marks the transform as dirty.
213+
* @param {Array.<number>} scale A new scale.
214+
*/
215+
updateScale (scale) {
216+
if (this._scale[0] !== scale[0] ||
217+
this._scale[1] !== scale[1]) {
218+
this._scale[0] = scale[0];
219+
this._scale[1] = scale[1];
200220
this._rotationCenterDirty = true;
201221
this._skinScaleDirty = true;
202-
dirty = true;
222+
this.setTransformDirty();
203223
}
204-
if ('visible' in properties) {
205-
this._visible = properties.visible;
224+
}
225+
226+
/**
227+
* Update visibility if it is different. Marks the convex hull as dirty.
228+
* @param {boolean} visible A new visibility state.
229+
*/
230+
updateVisible (visible) {
231+
if (this._visible !== visible) {
232+
this._visible = visible;
206233
this.setConvexHullDirty();
207234
}
208-
if (dirty) {
209-
this.setTransformDirty();
235+
}
236+
237+
/**
238+
* Update an effect. Marks the convex hull as dirty if the effect changes shape.
239+
* @param {string} effectName The name of the effect.
240+
* @param {number} rawValue A new effect value.
241+
*/
242+
updateEffect (effectName, rawValue) {
243+
const effectInfo = ShaderManager.EFFECT_INFO[effectName];
244+
if (rawValue) {
245+
this._effectBits |= effectInfo.mask;
246+
} else {
247+
this._effectBits &= ~effectInfo.mask;
248+
}
249+
const converter = effectInfo.converter;
250+
this._uniforms[effectInfo.uniformName] = converter(rawValue);
251+
if (effectInfo.shapeChanges) {
252+
this.setConvexHullDirty();
253+
}
254+
}
255+
256+
/**
257+
* Update the position, direction, scale, or effect properties of this Drawable.
258+
* @deprecated Use specific update* methods instead.
259+
* @param {object.<string,*>} properties The new property values to set.
260+
*/
261+
updateProperties (properties) {
262+
if ('position' in properties) {
263+
this.updatePosition(properties.position);
264+
}
265+
if ('direction' in properties) {
266+
this.updateDirection(properties.direction);
267+
}
268+
if ('scale' in properties) {
269+
this.updateScale(properties.scale);
270+
}
271+
if ('visible' in properties) {
272+
this.updateVisible(properties.visible);
210273
}
211274
const numEffects = ShaderManager.EFFECTS.length;
212275
for (let index = 0; index < numEffects; ++index) {
213276
const effectName = ShaderManager.EFFECTS[index];
214277
if (effectName in properties) {
215-
const rawValue = properties[effectName];
216-
const effectInfo = ShaderManager.EFFECT_INFO[effectName];
217-
if (rawValue) {
218-
this._effectBits |= effectInfo.mask;
219-
} else {
220-
this._effectBits &= ~effectInfo.mask;
221-
}
222-
const converter = effectInfo.converter;
223-
this._uniforms[effectInfo.uniformName] = converter(rawValue);
224-
if (effectInfo.shapeChanges) {
225-
this.setConvexHullDirty();
226-
}
278+
this.updateEffect(effectName, properties[effectName]);
227279
}
228280
}
229281
}
@@ -424,6 +476,16 @@ class Drawable {
424476
return true;
425477
}
426478

479+
// If the effect bits for mosaic, pixelate, whirl, or fisheye are set, use linear
480+
if ((this._effectBits & (
481+
ShaderManager.EFFECT_INFO.fisheye.mask |
482+
ShaderManager.EFFECT_INFO.whirl.mask |
483+
ShaderManager.EFFECT_INFO.pixelate.mask |
484+
ShaderManager.EFFECT_INFO.mosaic.mask
485+
)) !== 0) {
486+
return false;
487+
}
488+
427489
// We can't use nearest neighbor unless we are a multiple of 90 rotation
428490
if (this._direction % 90 !== 0) {
429491
return false;
@@ -511,7 +573,6 @@ class Drawable {
511573
* @return {!Rectangle} Bounds for the Drawable.
512574
*/
513575
getFastBounds (result) {
514-
this.updateMatrix();
515576
if (!this.needsConvexHullPoints()) {
516577
return this.getBounds(result);
517578
}

src/PenSkin.js

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ class PenSkin extends Skin {
8888
/** @type {HTMLCanvasElement} */
8989
this._canvas = document.createElement('canvas');
9090

91-
/** @type {Array<number>} */
92-
this._canvasSize = twgl.v3.create();
93-
9491
/** @type {WebGLTexture} */
9592
this._texture = null;
9693

@@ -174,7 +171,7 @@ class PenSkin extends Skin {
174171
* @return {Array<number>} the "native" size, in texels, of this skin. [width, height]
175172
*/
176173
get size () {
177-
return this._canvasSize;
174+
return [this._canvas.width, this._canvas.height];
178175
}
179176

180177
/**
@@ -197,13 +194,13 @@ class PenSkin extends Skin {
197194
clear () {
198195
const gl = this._renderer.gl;
199196
twgl.bindFramebufferInfo(gl, this._framebuffer);
200-
197+
201198
/* Reset framebuffer to transparent black */
202199
gl.clearColor(0, 0, 0, 0);
203200
gl.clear(gl.COLOR_BUFFER_BIT);
204201

205202
const ctx = this._canvas.getContext('2d');
206-
ctx.clearRect(0, 0, this._canvasSize[0], this._canvasSize[1]);
203+
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
207204

208205
this._silhouetteDirty = true;
209206
}
@@ -341,8 +338,7 @@ class PenSkin extends Skin {
341338

342339
const uniforms = {
343340
u_skin: this._texture,
344-
u_projectionMatrix: projection,
345-
u_fudge: 0
341+
u_projectionMatrix: projection
346342
};
347343

348344
twgl.setUniforms(currentShader, uniforms);
@@ -460,7 +456,7 @@ class PenSkin extends Skin {
460456
* @param {number} x - centered at x
461457
* @param {number} y - centered at y
462458
*/
463-
_drawRectangle (currentShader, texture, bounds, x = -this._canvasSize[0] / 2, y = this._canvasSize[1] / 2) {
459+
_drawRectangle (currentShader, texture, bounds, x = -this._canvas.width / 2, y = this._canvas.height / 2) {
464460
const gl = this._renderer.gl;
465461

466462
const projection = twgl.m4.ortho(
@@ -483,8 +479,7 @@ class PenSkin extends Skin {
483479
0
484480
), __modelScalingMatrix),
485481
__modelMatrix
486-
),
487-
u_fudge: 0
482+
)
488483
};
489484

490485
twgl.setTextureParameters(gl, texture, {minMag: gl.NEAREST});
@@ -523,7 +518,7 @@ class PenSkin extends Skin {
523518
* @param {number} x - texture centered at x
524519
* @param {number} y - texture centered at y
525520
*/
526-
_drawToBuffer (texture = this._texture, x = -this._canvasSize[0] / 2, y = this._canvasSize[1] / 2) {
521+
_drawToBuffer (texture = this._texture, x = -this._canvas.width / 2, y = this._canvas.height / 2) {
527522
if (texture !== this._texture && this._canvasDirty) {
528523
this._drawToBuffer();
529524
}
@@ -537,7 +532,7 @@ class PenSkin extends Skin {
537532
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);
538533

539534
const ctx = this._canvas.getContext('2d');
540-
ctx.clearRect(0, 0, this._canvasSize[0], this._canvasSize[1]);
535+
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
541536

542537
this._canvasDirty = false;
543538
}
@@ -573,8 +568,8 @@ class PenSkin extends Skin {
573568
this._bounds = new Rectangle();
574569
this._bounds.initFromBounds(width / 2, width / -2, height / 2, height / -2);
575570

576-
this._canvas.width = this._canvasSize[0] = width;
577-
this._canvas.height = this._canvasSize[1] = height;
571+
this._canvas.width = width;
572+
this._canvas.height = height;
578573
this._rotationCenter[0] = width / 2;
579574
this._rotationCenter[1] = height / 2;
580575

@@ -663,7 +658,7 @@ class PenSkin extends Skin {
663658
// Sample the framebuffer's pixels into the silhouette instance
664659
gl.readPixels(
665660
0, 0,
666-
this._canvasSize[0], this._canvasSize[1],
661+
this._canvas.width, this._canvas.height,
667662
gl.RGBA, gl.UNSIGNED_BYTE, this._silhouettePixels
668663
);
669664

src/Rectangle.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ class Rectangle {
123123
this.right = Math.min(this.right, right);
124124
this.bottom = Math.max(this.bottom, bottom);
125125
this.top = Math.min(this.top, top);
126-
// Ensure rectangle coordinates in order.
127-
this.left = Math.min(this.left, this.right);
128-
this.right = Math.max(this.right, this.left);
129-
this.bottom = Math.min(this.bottom, this.top);
130-
this.top = Math.max(this.top, this.bottom);
126+
127+
this.left = Math.min(this.left, right);
128+
this.right = Math.max(this.right, left);
129+
this.bottom = Math.min(this.bottom, top);
130+
this.top = Math.max(this.top, bottom);
131131
}
132132

133133
/**

0 commit comments

Comments
 (0)