I’m having trouble getting my Mat4 multiplications to work correctly.
Basically what I’m doing is building a fence using hardware instancing.
So each board has its own rotation quad, positon vec3 and scale vec3.
What I do next is the same steps which you have in your example for hardware instancing, I’m creating a matrix, and using setTRS to properly position each instance.
// boards is just an array of all matrix data for my boards.
var instances = boards.length;
var matrices = new Float32Array(instances * 16);
var matrixIndex = 0;
var matrix = new pc.Mat4();
boards.forEach((board) => {
matrix.setTRS(board.TRS.pos, board.TRS.rot, board.TRS.scale);
for (let m = 0; m < 16; m++) matrices[matrixIndex++] = matrix.data[m];
}
// And then I create a vertexBuffer and loop over meshinstances -
// just as in your example. This part works fine.
An illustration of the result is basically:
My problem arises when I want to be able to rotate this fence.
Sometimes, for example. the fence might need to have this rotation:
My problem is that when I use matrix multiplication to achieve this, it is either rotated along some “origin” which is far away causing the entire fence to be “translated” far away but in a correctly rotationed manner.
Or every individual board is rotated on its local axis which isnt right either.
I’ve appended the forEach with the matrix multiplication and I hope you might be able to see where I’m going wrong. As I’m not sure exactly in what order the mul2() operation works.
Basically my goal is to revert the translation in the matrix, rotate the boards 90 degree along the Y axis, and then revert the translation via an inverse matrix.
var instances = boards.length;
var matrices = new Float32Array(instances * 16);
var matrixIndex = 0;
var matrix = new pc.Mat4();
boards.forEach((board) => {
matrix.setTRS(board.TRS.pos, board.TRS.rot, board.TRS.scale);
var rotationMatrix = new pc.Mat4().setFromEulerAngles(0,90,0);
var negativePositionVector = board.TRS.pos.clone().scale(-1);
var translationMat = new pc.Mat4().setTRS(
negativePositionVector,
new pc.Quat(),
new pc.vec3(1,1,1)
);
var inverseTranslationMat = translationMat.clone().invert();
var rotatedMatrix = new pc.Mat4().mul2(inverseTranslationMat, rotationMatrix);
rotatedMatrix.mul2(rotatedMatrix, transMatrix);
matrix.mul2(rotatedMatrix, matrix);
for (let m = 0; m < 16; m++) matrices[matrixIndex++] = matrix.data[m];
}
I’m assuming the mathematical order should now be the original inverseTranslationMat -> RotationMat -> translationMat -> orignalMatrix
Am I wrong ?
TL;DR
If I want to make a translation -> rotation -> revertTranslation.
In which order do I have to use pc.Mat4().mul2() in order to get it right ?