Skip to content

Commit c1d4462

Browse files
committed
Tighten pen bounds
1 parent 9e12f09 commit c1d4462

File tree

2 files changed

+23
-39
lines changed

2 files changed

+23
-39
lines changed

src/PenSkin.js

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ class PenSkin extends Skin {
217217

218218
this._drawLineOnBuffer(
219219
penAttributes,
220-
this._rotationCenter[0] + x0 + offset, this._rotationCenter[1] - y0 + offset,
221-
this._rotationCenter[0] + x1 + offset, this._rotationCenter[1] - y1 + offset
220+
x0 + offset, -y0 + offset,
221+
x1 + offset, -y1 + offset
222222
);
223223

224224
this._silhouetteDirty = true;
@@ -230,17 +230,6 @@ class PenSkin extends Skin {
230230
_createLineGeometry () {
231231
const quads = {
232232
a_position: {
233-
numComponents: 2,
234-
data: [
235-
-1, -1,
236-
1, -1,
237-
-1, 1,
238-
-1, 1,
239-
1, -1,
240-
1, 1
241-
]
242-
},
243-
a_texCoord: {
244233
numComponents: 2,
245234
data: [
246235
1, 0,
@@ -293,6 +282,8 @@ class PenSkin extends Skin {
293282

294283
/**
295284
* Draw a line on the framebuffer.
285+
* Note that the point coordinates are in the following coordinate space:
286+
* +y is down, (0, 0) is the center, and the coords range from (-width / 2, -height / 2) to (height / 2, width / 2).
296287
* @param {PenAttributes} penAttributes - how the line should be drawn.
297288
* @param {number} x0 - the X coordinate of the beginning of the line.
298289
* @param {number} y0 - the Y coordinate of the beginning of the line.
@@ -306,31 +297,26 @@ class PenSkin extends Skin {
306297

307298
this._renderer.enterDrawRegion(this._lineOnBufferDrawRegionId);
308299

309-
const radius = penAttributes.diameter / 2;
300+
const radius = (penAttributes.diameter || DefaultPenAttributes.diameter) / 2;
301+
// Expand line bounds by sqrt(2) / 2 each side-- this ensures that all antialiased pixels
302+
// fall within the quad, even at a 45-degree diagonal
303+
const expandedRadius = radius + 1.4142135623730951;
310304

311-
// Clip drawn polygon to line's AABB.
312-
const transformMatrix = __modelMatrix;
305+
const lineLength = Math.hypot(x1 - x0, y1 - y0);
306+
const lineAngle = Math.atan2(y1 - y0, x1 - x0);
313307

314-
const left = Math.floor(Math.min(x0, x1) - radius) - 1;
315-
const right = Math.ceil(Math.max(x0, x1) + radius) + 1;
316-
const top = Math.floor(Math.min(y0, y1) - radius) - 1;
317-
const bottom = Math.floor(Math.max(y0, y1) + radius) + 1;
308+
const halfWidth = this._bounds.width * 0.5;
309+
const halfHeight = this._bounds.height * 0.5;
318310

319-
const width = this._bounds.width;
320-
const height = this._bounds.height;
321-
322-
const translationVector = __modelTranslationVector;
323-
translationVector[0] = (left / (width * 0.5)) - 1;
324-
translationVector[1] = (top / (height * 0.5)) - 1;
325-
326-
const scalingVector = __modelScalingVector;
327-
scalingVector[0] = (right - left) / width;
328-
scalingVector[1] = (bottom - top) / height;
311+
const transformMatrix = __modelMatrix;
312+
twgl.m4.identity(transformMatrix);
313+
// Apply view transform to matrix
314+
twgl.m4.scale(transformMatrix, [1 / halfWidth, 1 / halfHeight, 1], transformMatrix);
329315

330-
transformMatrix[0] = scalingVector[0];
331-
transformMatrix[5] = scalingVector[1];
332-
transformMatrix[12] = translationVector[0] + scalingVector[0];
333-
transformMatrix[13] = translationVector[1] + scalingVector[1];
316+
twgl.m4.translate(transformMatrix, [x0, y0, 0], transformMatrix);
317+
twgl.m4.rotateZ(transformMatrix, lineAngle, transformMatrix);
318+
twgl.m4.translate(transformMatrix, [-expandedRadius, -expandedRadius, 0], transformMatrix);
319+
twgl.m4.scale(transformMatrix, [lineLength + (expandedRadius * 2), (expandedRadius * 2), 1], transformMatrix);
334320

335321
// Premultiply pen color by pen transparency
336322
const penColor = penAttributes.color4f || DefaultPenAttributes.color4f;
@@ -343,8 +329,7 @@ class PenSkin extends Skin {
343329
u_modelMatrix: transformMatrix,
344330
u_lineColor: __premultipliedColor,
345331
u_lineThickness: penAttributes.diameter,
346-
u_p1: [x0, y0],
347-
u_p2: [x1, y1],
332+
u_penPoints: [x0 + halfWidth, y0 + halfHeight, x1 + halfWidth, y1 + halfHeight],
348333
u_stageSize: this.size
349334
};
350335

src/shaders/sprite.frag

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ uniform float u_ghost;
3636
#ifdef DRAW_MODE_line
3737
uniform vec4 u_lineColor;
3838
uniform float u_lineThickness;
39-
uniform vec2 u_p1;
40-
uniform vec2 u_p2;
39+
uniform vec4 u_penPoints;
4140
#endif // DRAW_MODE_line
4241

4342
uniform sampler2D u_skin;
@@ -215,7 +214,7 @@ void main()
215214
// Maaaaagic antialiased-line-with-round-caps shader.
216215
// Adapted from Inigo Quilez' 2D distance function cheat sheet
217216
// https://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
218-
vec2 pa = v_texCoord - u_p1, ba = u_p2 - u_p1;
217+
vec2 pa = v_texCoord - u_penPoints.xy, ba = u_penPoints.zw - u_penPoints.xy;
219218
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
220219

221220
float cappedLine = clamp((u_lineThickness + 1.0) * 0.5 - length(pa - ba*h), 0.0, 1.0);

0 commit comments

Comments
 (0)