Skip to content

Commit 5886622

Browse files
committed
document out how initFromModelMatrix works
1 parent a840089 commit 5886622

File tree

2 files changed

+87
-13
lines changed

2 files changed

+87
-13
lines changed

src/Drawable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ class Drawable {
508508
}
509509
const tm = this._uniforms.u_modelMatrix;
510510
result = result || new Rectangle();
511-
result.initFromMatrixRadius(tm, 0.5);
511+
result.initFromModelMatrix(tm);
512512
return result;
513513
}
514514

src/Rectangle.js

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,99 @@ class Rectangle {
5454
}
5555
}
5656

57-
initFromMatrixRadius (m, r) {
58-
// const v0 = r;
59-
// const v1 = r;
60-
// const v2 = r;
57+
/**
58+
* Initialize a Rectangle to a 1 unit square transformed by a model matrix.
59+
* @param {Array.<number>} m A 4x4 matrix to transform the rectangle by.
60+
*/
61+
initFromModelMatrix (m) {
62+
// Treat this function like we are transforming a vector with each
63+
// component set to 0.5 by a matrix m.
64+
// const v0 = 0.5;
65+
// const v1 = 0.5;
66+
// const v2 = 0.5;
67+
68+
// Of the matrix to do this in 2D space, instead of the 3D provided by
69+
// the matrix, we need the 2x2 "top left" that represents the scale and
70+
// rotation ...
6171
const m00 = m[(0 * 4) + 0];
6272
const m01 = m[(0 * 4) + 1];
6373
const m10 = m[(1 * 4) + 0];
6474
const m11 = m[(1 * 4) + 1];
75+
// ... and the 1x2 "top right" that represents position.
6576
const m30 = m[(3 * 4) + 0];
6677
const m31 = m[(3 * 4) + 1];
67-
// var d = v0 * m03 + v1 * m13 + v2 * m23 + m33;
68-
// dst[0] = (
69-
const x = Math.abs(r * m00) + Math.abs(r * m10);
70-
// + v2 * m20 + m30) / d;
71-
// dst[1] = (
72-
const y = Math.abs(r * m01) + Math.abs(r * m11);
73-
// + v2 * m21 + m31) / d;
74-
// dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / d;
7578

79+
// This is how we would normally transform the vector by the matrix.
80+
// var determinant = v0 * m03 + v1 * m13 + v2 * m23 + m33;
81+
// dst[0] = (v0 * m00 + v1 * m10 + v2 * m20 + m30) / determinant;
82+
// dst[1] = (v0 * m01 + v1 * m11 + v2 * m21 + m31) / determinant;
83+
// dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / determinant;
84+
85+
// We can skip the v2 multiplications and the determinant.
86+
87+
// Alternatively done with 4 vectors, those vectors would be reflected
88+
// on the x and y axis. We can build those 4 vectors by transforming the
89+
// parts of one vector and reflecting them on the axises after
90+
// multiplication.
91+
92+
// const x0 = 0.5 * m00;
93+
// const x1 = 0.5 * m10;
94+
// const y0 = 0.5 * m01;
95+
// const y1 = 0.5 * m11;
96+
97+
// const p0x = x0 + -x1;
98+
// const p0y = y0 + y1;
99+
// const p1x = -x0 + -x1;
100+
// const p1y = -y0 + y1;
101+
// const p2x = -x0 + x1;
102+
// const p2y = -y0 + -y1;
103+
// const p3x = x0 + x1;
104+
// const p3y = y0 + -y1;
105+
106+
// Since we want to reduce those 4 points to a min and max for each
107+
// axis, we can use those multiplied components to build the min and max
108+
// values without comparing the points.
109+
110+
// We can start by getting the min and max for each of all the points.
111+
// const left = Math.min(x0 + -x1, -x0 + -x1, -x0 + x1, x0 + x1);
112+
// const right = Math.max(x0 + -x1, -x0 + -x1, -x0 + x1, x0 + x1);
113+
// const top = Math.max(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
114+
// const bottom = Math.min(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
115+
116+
// Each of those can be replaced with min and max operations on the 0
117+
// and 1 matrix output components.
118+
// const left = Math.min(x0, -x0) + Math.min(x1, -x1);
119+
// const right = Math.max(x0, -x0) + Math.max(x1, -x1);
120+
// const top = Math.max(y0, -y0) + Math.max(y1, -y1);
121+
// const bottom = Math.min(y0, -y0) + Math.min(y1, -y1);
122+
123+
// And they can be replaced with absolute values.
124+
// const left = -Math.abs(x0) + -Math.abs(x1);
125+
// const right = Math.abs(x0) + Math.abs(x1);
126+
// const top = Math.abs(y0) + Math.abs(y1);
127+
// const bottom = -Math.abs(y0) + -Math.abs(y1);
128+
129+
// And those with positive and negative sums of the absolute values.
130+
// const left = -(Math.abs(x0) + Math.abs(x1));
131+
// const right = +(Math.abs(x0) + Math.abs(x1));
132+
// const top = +(Math.abs(y0) + Math.abs(y1));
133+
// const bottom = -(Math.abs(y0) + -Math.abs(y1));
134+
135+
// We can perform those sums once and reuse them for the bounds.
136+
// const x = Math.abs(x0) + Math.abs(x1);
137+
// const y = Math.abs(y0) + Math.abs(y1);
138+
// const left = -x;
139+
// const right = x;
140+
// const top = y;
141+
// const bottom = -y;
142+
143+
// Building those absolute sums for the 0.5 vector components by the
144+
// matrix components ...
145+
const x = Math.abs(0.5 * m00) + Math.abs(0.5 * m10);
146+
const y = Math.abs(0.5 * m01) + Math.abs(0.5 * m11);
147+
148+
// And adding them to the position components in the matrices
149+
// initializes our Rectangle.
76150
this.left = -x + m30;
77151
this.right = x + m30;
78152
this.top = y + m31;

0 commit comments

Comments
 (0)