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

Fix transformations not applied #14

Open
wants to merge 8 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
10 changes: 7 additions & 3 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.min.js.map

Large diffs are not rendered by default.

48 changes: 17 additions & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
},
"dependencies": {
"lodash": "^4.17.5",
"matrixmath": "^2.2.2"
"matrixmath": "^2.2.2",
"three": "^0.103.0"
Copy link
Member

Choose a reason for hiding this comment

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

Sorry for the late answer !
We don't want to depend on a specific engine like Three, especially as we usually work with Babylonjs. I saw that three was used only in trs-matrix.js to break down matrices. Is it possible to implement functions like multiply, or quaternions in the lib?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see three options:

  • writing a small implementation of affine transformation matrices, but that could be wasted time given that many tested implementations already exist.
  • using a lightweight library that provides affine transformations but does not interfere with babylon, three and others.
  • providing an option to the user to pass his preferred implementation of affine matrices, given a specification of what API is expected; this would most likely require the user to build an adapter class for the library he is using, since they are all different.

Personally I would prefer the second option, but I haven't been able to find a library like that.

Copy link
Member

Choose a reason for hiding this comment

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

I know https://github.com/toji/gl-matrix develop by Tojiro (but I nevers used it), well know and tested library, feel free to take a look !

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I saw you were using it and it seemed ok, but the API looked a bit weird to me.
I'll try converting to using that when I have some time.

}
}
5 changes: 3 additions & 2 deletions src/gltf1-bounding-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { flattenDeep, includes } from 'lodash';
import { loadPositions } from './gltf-reader';

import precise from './precise';
import trsMatrix from './trs-matrix';

const gltf1BoundingBox = {

Expand Down Expand Up @@ -70,8 +71,8 @@ const gltf1BoundingBox = {
includes(nodes[nodeName].children, childNodeName)
);

// Specify identity matrix if not present
const nodeMatrix = nodes[childNodeName].matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
// Get matrix or compose TRS fields if present, TRS is by default Identity
const nodeMatrix = nodes[childNodeName].matrix || trsMatrix.getTRSMatrix(nodes[childNodeName]);;

return parentNodeName ?

Expand Down
5 changes: 3 additions & 2 deletions src/gltf2-bounding-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { flattenDeep, includes } from 'lodash';
import { loadPositions } from './gltf-reader';

import precise from './precise';
import trsMatrix from './trs-matrix';

const gltf2BoundingBox = {

Expand Down Expand Up @@ -61,8 +62,8 @@ const gltf2BoundingBox = {
includes(node.children, childNode.index)
);

// Specify identity matrix if not present
const childNodeMatrix = childNode.matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
// Get matrix or compose TRS fields if present, TRS is by default Identity
const childNodeMatrix = childNode.matrix || trsMatrix.getTRSMatrix(childNode);

return (parentNode !== undefined) ?

Expand Down
67 changes: 67 additions & 0 deletions src/trs-matrix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Matrix4, Quaternion } from 'three';

const trsMatrix = {

/**
* Get the composed TRS (trasnlation, rotation, scale) affine transformation matrix for a given node.
*
* @param {Object} node a node in a GLTF
* @param {Array<number>} [node.translation] array of 3 values for a translation
* @param {Array<number>} [node.rotation] an array of four values for a rotation (quaternion)
* @param {Array<number>} [node.scale] an array of three values for a scale
*/
getTRSMatrix({ translation, rotation, scale }) {
const t = translation ? trsMatrix._affineT(translation) : trsMatrix._I();
const r = rotation ? trsMatrix._affineR(rotation) : trsMatrix._I();
const s = scale ? trsMatrix._affineS(scale) : trsMatrix._I();

// Post-multiply: T * R * S
const TRS = t.multiply(r).multiply(s);

// toArray returns a column-major, and we need exactly that one
return TRS.toArray();
},

/**
* Three functions that use `_affine`, to simplify calls above.
*/
_affineT(t) {
return trsMatrix._affine({ t });
},
_affineR(r) {
return trsMatrix._affine({ r });
},
_affineS(s) {
return trsMatrix._affine({ s });
},

/**
* Identity 4x4 matrix.
*/
_I() {
return new Matrix4().identity();
},

/**
* Convert one of the t, r, or s arrays into a 4x4 affine transformation matrix.
* The passed parameter object p should contain only one of the fields t, r, or s.
*
* @param {Object} p
* @param {Array<number>} [p.t] an array of three values for a transaltion
* @param {Array<number>} [p.r] an array of four values for a rotation (quaternion)
* @param {Array<number>} [p.s] an array of three values for a scale
*/
_affine({ t, r, s }) {
if (t) {
return new Matrix4().makeTranslation(t[0], t[1], t[2]);
}
if (r) {
return new Matrix4().makeRotationFromQuaternion(new Quaternion(r[0], r[1], r[2], r[3]));
}
if (s) {
return new Matrix4().makeScale(s[0], s[1], s[2]);
}
},
};

export default trsMatrix;
Binary file added test/example-models/flat_cylinder.glb
Binary file not shown.
Binary file added test/example-models/translated_cubes.glb
Binary file not shown.
Binary file added test/example-models/weird_cube.glb
Binary file not shown.
Loading