document out how initFromModelMatrix works
This commit is contained in:
@@ -508,7 +508,7 @@ class Drawable {
|
||||
}
|
||||
const tm = this._uniforms.u_modelMatrix;
|
||||
result = result || new Rectangle();
|
||||
result.initFromMatrixRadius(tm, 0.5);
|
||||
result.initFromModelMatrix(tm);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,25 +54,99 @@ class Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
initFromMatrixRadius (m, r) {
|
||||
// const v0 = r;
|
||||
// const v1 = r;
|
||||
// const v2 = r;
|
||||
/**
|
||||
* Initialize a Rectangle to a 1 unit square transformed by a model matrix.
|
||||
* @param {Array.<number>} m A 4x4 matrix to transform the rectangle by.
|
||||
*/
|
||||
initFromModelMatrix (m) {
|
||||
// Treat this function like we are transforming a vector with each
|
||||
// component set to 0.5 by a matrix m.
|
||||
// const v0 = 0.5;
|
||||
// const v1 = 0.5;
|
||||
// const v2 = 0.5;
|
||||
|
||||
// Of the matrix to do this in 2D space, instead of the 3D provided by
|
||||
// the matrix, we need the 2x2 "top left" that represents the scale and
|
||||
// rotation ...
|
||||
const m00 = m[(0 * 4) + 0];
|
||||
const m01 = m[(0 * 4) + 1];
|
||||
const m10 = m[(1 * 4) + 0];
|
||||
const m11 = m[(1 * 4) + 1];
|
||||
// ... and the 1x2 "top right" that represents position.
|
||||
const m30 = m[(3 * 4) + 0];
|
||||
const m31 = m[(3 * 4) + 1];
|
||||
// var d = v0 * m03 + v1 * m13 + v2 * m23 + m33;
|
||||
// dst[0] = (
|
||||
const x = Math.abs(r * m00) + Math.abs(r * m10);
|
||||
// + v2 * m20 + m30) / d;
|
||||
// dst[1] = (
|
||||
const y = Math.abs(r * m01) + Math.abs(r * m11);
|
||||
// + v2 * m21 + m31) / d;
|
||||
// dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / d;
|
||||
|
||||
// This is how we would normally transform the vector by the matrix.
|
||||
// var determinant = v0 * m03 + v1 * m13 + v2 * m23 + m33;
|
||||
// dst[0] = (v0 * m00 + v1 * m10 + v2 * m20 + m30) / determinant;
|
||||
// dst[1] = (v0 * m01 + v1 * m11 + v2 * m21 + m31) / determinant;
|
||||
// dst[2] = (v0 * m02 + v1 * m12 + v2 * m22 + m32) / determinant;
|
||||
|
||||
// We can skip the v2 multiplications and the determinant.
|
||||
|
||||
// Alternatively done with 4 vectors, those vectors would be reflected
|
||||
// on the x and y axis. We can build those 4 vectors by transforming the
|
||||
// parts of one vector and reflecting them on the axises after
|
||||
// multiplication.
|
||||
|
||||
// const x0 = 0.5 * m00;
|
||||
// const x1 = 0.5 * m10;
|
||||
// const y0 = 0.5 * m01;
|
||||
// const y1 = 0.5 * m11;
|
||||
|
||||
// const p0x = x0 + x1;
|
||||
// const p0y = y0 + y1;
|
||||
// const p1x = -x0 + x1;
|
||||
// const p1y = -y0 + y1;
|
||||
// const p2x = -x0 + -x1;
|
||||
// const p2y = -y0 + -y1;
|
||||
// const p3x = x0 + -x1;
|
||||
// const p3y = y0 + -y1;
|
||||
|
||||
// Since we want to reduce those 4 points to a min and max for each
|
||||
// axis, we can use those multiplied components to build the min and max
|
||||
// values without comparing the points.
|
||||
|
||||
// We can start by getting the min and max for each of all the points.
|
||||
// const left = Math.min(x0 + x1, -x0 + x1, -x0 + -x1, x0 + -x1);
|
||||
// const right = Math.max(x0 + x1, -x0 + x1, -x0 + -x1, x0 + -x1);
|
||||
// const top = Math.max(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
|
||||
// const bottom = Math.min(y0 + y1, -y0 + y1, -y0 + -y1, y0 + -y1);
|
||||
|
||||
// Each of those can be replaced with min and max operations on the 0
|
||||
// and 1 matrix output components.
|
||||
// const left = Math.min(x0, -x0) + Math.min(x1, -x1);
|
||||
// const right = Math.max(x0, -x0) + Math.max(x1, -x1);
|
||||
// const top = Math.max(y0, -y0) + Math.max(y1, -y1);
|
||||
// const bottom = Math.min(y0, -y0) + Math.min(y1, -y1);
|
||||
|
||||
// And they can be replaced with absolute values.
|
||||
// const left = -Math.abs(x0) + -Math.abs(x1);
|
||||
// const right = Math.abs(x0) + Math.abs(x1);
|
||||
// const top = Math.abs(y0) + Math.abs(y1);
|
||||
// const bottom = -Math.abs(y0) + -Math.abs(y1);
|
||||
|
||||
// And those with positive and negative sums of the absolute values.
|
||||
// const left = -(Math.abs(x0) + Math.abs(x1));
|
||||
// const right = +(Math.abs(x0) + Math.abs(x1));
|
||||
// const top = +(Math.abs(y0) + Math.abs(y1));
|
||||
// const bottom = -(Math.abs(y0) + -Math.abs(y1));
|
||||
|
||||
// We can perform those sums once and reuse them for the bounds.
|
||||
// const x = Math.abs(x0) + Math.abs(x1);
|
||||
// const y = Math.abs(y0) + Math.abs(y1);
|
||||
// const left = -x;
|
||||
// const right = x;
|
||||
// const top = y;
|
||||
// const bottom = -y;
|
||||
|
||||
// Building those absolute sums for the 0.5 vector components by the
|
||||
// matrix components ...
|
||||
const x = Math.abs(0.5 * m00) + Math.abs(0.5 * m10);
|
||||
const y = Math.abs(0.5 * m01) + Math.abs(0.5 * m11);
|
||||
|
||||
// And adding them to the position components in the matrices
|
||||
// initializes our Rectangle.
|
||||
this.left = -x + m30;
|
||||
this.right = x + m30;
|
||||
this.top = y + m31;
|
||||
|
||||
Reference in New Issue
Block a user