Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mat4 decomposition #305

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion spec/gl-matrix/mat4-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,48 @@ function buildMat4Tests() {
});
});

describe("removeTranslation", function() {
beforeEach(function() {
let q = quat.create();
q = quat.setAxisAngle(q, [0, 1, 0], 0.7);
let t = vec3.fromValues(1, 2, 3);
let s = vec3.fromValues(5, 6, 7);
mat4.fromRotationTranslationScale(matA, q, t, s);
mat4.removeTranslation(matB, matA);
result = vec3.fromValues(1, 2, 3);
mat4.getTranslation(result, matB);
})
it("should return the null translation", function() { expect(result).toBeEqualish([0, 0, 0]); });
});

describe("removeScaling", function() {
beforeEach(function() {
let q = quat.create();
q = quat.setAxisAngle(q, [0, 1, 0], 0.7);
let t = vec3.fromValues(1, 2, 3);
let s = vec3.fromValues(5, 6, 7);
mat4.fromRotationTranslationScale(matA, q, t, s);
mat4.removeScaling(matB, matA);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

result = mat4.removeScaling(out, matA); would be better, since that allows you to check more things.

  • You can check if it returns the result
  • If it sets out to the correct value
  • If matA is untouched

result = vec3.fromValues(5, 6, 7);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of this?

mat4.getScaling(result, matB);
})
it("should return the null scaling", function() { expect(result).toBeEqualish([1, 1, 1]); });
});

describe("removeRotation", function() {
beforeEach(function() {
let q = quat.create();
q = quat.setAxisAngle(q, [0, 1, 0], 0.7);
let t = vec3.fromValues(1, 2, 3);
let s = vec3.fromValues(5, 6, 7);
mat4.fromRotationTranslationScale(matA, q, t, s);
mat4.removeRotation(matB, matA);
result = quat.setAxisAngle(q, [0, 1, 0], 0.7);
quat.normalize(result, mat4.getRotation(result, matB) );
})
it("should return the null rotation", function() { expect(result).toBeEqualish([0, 0, 0, 1]); });
});

describe("frustum", function() {
beforeEach(function() { result = mat4.frustum(out, -1, 1, -1, 1, -1, 1); });
it("should place values into out", function() { expect(result).toBeEqualish([
Expand Down Expand Up @@ -1039,4 +1081,4 @@ function buildMat4Tests() {
});
}

describe("mat4", buildMat4Tests());
describe("mat4", buildMat4Tests());
132 changes: 132 additions & 0 deletions src/gl-matrix/mat4.js
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,138 @@ export function fromQuat(out, q) {
return out;
}

/**
* Removes the translation component from the transformation matrix.
* This is equivalent to (but much faster than):
*
* mat4.getScaling(s, mat);
* mat4.getRotation(q, mat);
* t = [0, 0, 0];
* mat4.fromRotationTranslationScale(dest, q, t, s);
*
* @param {mat4} out mat4 receiving operation result
* @param {mat4} mat Matrix to be decomposed (input)
* @returns {mat4} out
*/
export function removeTranslation(out, mat) {

out[0] = mat[0];
out[1] = mat[1];
out[2] = mat[2];
out[3] = 0;
out[4] = mat[4];
out[5] = mat[5];
out[6] = mat[6];
out[7] = 0;
out[8] = mat[8];
out[9] = mat[9];
out[10] = mat[10];
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;

return out;
}

/**
* Removes the scaling component from the transformation matrix.
* This is equivalent to (but much faster than):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have tests to support this claim? would be nice to have a look at them too

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right ... but the errors you have report are comments ... all unit tests work ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe they do, but regarding performance, how can I know that this option is faster than the alternative written on the comment?

*
* mat4.getTranslation(t, mat);
* mat4.getRotation(q, mat);
* mat4.fromRotationTranslation(dest, q, v);
*
* @param {mat4} out mat4 receiving operation result
* @param {mat4} mat Matrix to be decomposed (input)
* @returns {mat4} out
*/
export function removeScaling(out, mat) {

let m11 = mat[0];
let m12 = mat[1];
let m13 = mat[2];
let m21 = mat[4];
let m22 = mat[5];
let m23 = mat[6];
let m31 = mat[8];
let m32 = mat[9];
let m33 = mat[10];

let sx = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);
let sy = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);
let sz = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);

out[0] = mat[0] / sx;
out[1] = mat[1] / sx;
out[2] = mat[2] / sx;
out[3] = 0;
out[4] = mat[4] / sy;
out[5] = mat[5] / sy;
out[6] = mat[6] / sy;
out[7] = 0;
out[8] = mat[8] / sz;
out[9] = mat[9] / sz;
out[10] = mat[10] / sz;
out[11] = 0;
out[12] = mat[12];
out[13] = mat[13];
out[14] = mat[14];
out[15] = 1;

return out;
}

/**
* Removes the rotation component from the transformation matrix.
* This is equivalent to (but much faster than):
*
* mat4.getTranslation(t, mat);
* mat4.getScaling(s, mat);
* q = [0, 0, 0, 1];
* mat4.fromRotationTranslationScale(dest, q, t, s);
*
* @param {mat4} out mat4 receiving operation result
* @param {mat4} mat Matrix to be decomposed (input)
* @returns {mat4} out
*/
export function removeRotation(out, mat) {

let m11 = mat[0];
let m12 = mat[1];
let m13 = mat[2];
let m21 = mat[4];
let m22 = mat[5];
let m23 = mat[6];
let m31 = mat[8];
let m32 = mat[9];
let m33 = mat[10];

let sx = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);
let sy = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);
let sz = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);

out[0] = sx;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = sy;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = sz;
out[11] = 0;
out[12] = mat[12];
out[13] = mat[13];
out[14] = mat[14];
out[15] = 1;

return out;
}

/**
* Generates a frustum matrix with the given bounds
*
Expand Down