Skip to content

Commit

Permalink
step 1: getting the viewMatrix separated from the modelMatrix
Browse files Browse the repository at this point in the history
- pass the camera Matrix to the tool that need them
- adjust the modelViewMatrix and the groundplane matrix if we get a valid camera matrix
- copy some helperfunctions for matrix manipulation to not introduce dependencies on three.js
  • Loading branch information
ptc-rdeleeuw committed Jul 17, 2023
1 parent a4709f2 commit 551cf25
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 2 deletions.
116 changes: 115 additions & 1 deletion libraries/objectDefaultFiles/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,111 @@
document.body.appendChild(script);
}

/**
* heavily inspired by three.js, this returns a copy of the matrix without changing the original
* @param {number[]} matrix
* @returns {number[]}
*/
function invert(matrix) {
let ret = [];

// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
const te = matrix,

n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ],
n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ],
n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ],
n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ],

t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;

const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;

if ( det === 0 ) return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

const detInv = 1 / det;

ret.push(t11 * detInv);
ret.push(( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv);
ret.push(( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv);
ret.push(( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv);

ret.push(t12 * detInv);
ret.push(( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv);
ret.push(( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv);
ret.push(( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv);

ret.push(t13 * detInv);
ret.push(( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv);
ret.push(( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv);
ret.push(( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv);

ret.push(t14 * detInv);
ret.push(( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv);
ret.push(( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv);
ret.push(( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv);

return ret;
}

/**
* heavily inspired by three.js, this returns a copy of the matrix without changing the original
* @param {number[]} matA
* @param {number[]} matB
* @returns {number[]}
*/
function multiply(matA, matB) {
let ret = [];

const ae = matA;
const be = matB;

const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];

const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];

// reordered to fit the push

ret.push(a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41);
ret.push(a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41);
ret.push(a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41);
ret.push(a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41);

ret.push(a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42);
ret.push(a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42);

Check failure on line 287 in libraries/objectDefaultFiles/object.js

View workflow job for this annotation

GitHub Actions / build (18.x)

Mixed spaces and tabs
ret.push(a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42);
ret.push(a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42);

ret.push(a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43);
ret.push(a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43);
ret.push(a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43);
ret.push(a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43);

ret.push(a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44);
ret.push(a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44);
ret.push(a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44);
ret.push(a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44);

return ret;
}

function getScaleFromMatrix(matrix) {
let ret = [];
ret.push(Math.sqrt((matrix[0] * matrix[0]) + (matrix[1] * matrix[1]) + (matrix[2] * matrix[2])));
ret.push(Math.sqrt((matrix[4] * matrix[4]) + (matrix[5] * matrix[5]) + (matrix[6] * matrix[6])));
ret.push(Math.sqrt((matrix[8] * matrix[8]) + (matrix[9] * matrix[9]) + (matrix[10] * matrix[10])));
return ret;
}

/**
* Triggers all messageCallbacks functions.
* spatialObject.messageCallBacks.mainCall is the primary function always triggered by this, but additional
Expand All @@ -213,6 +318,15 @@
if (!MSG.data) { return; }
if (typeof MSG.data !== 'string') { return; }
var msgContent = JSON.parse(MSG.data);
// if a camera matrix was sent, we have the info to implement the corrections
if (msgContent.hasOwnProperty("floorOffset") && msgContent.hasOwnProperty("groundPlaneMatrix") && msgContent.hasOwnProperty("modelViewMatrix") && msgContent.hasOwnProperty("cameraMatrix")) {
// because the camera matrix is calculated within the modelViewMatrix, we need to correct it
msgContent.modelViewMatrix = multiply(msgContent.cameraMatrix, msgContent.modelViewMatrix);
// because the camera matrix is calculated within the groundPlaneMatrix, we need to correct it
msgContent.groundPlaneMatrix = multiply(msgContent.cameraMatrix, msgContent.groundPlaneMatrix);
// leave the floor offset as is, this variable is probably in groundPlane space
}

for (var key in spatialObject.messageCallBacks) {
spatialObject.messageCallBacks[key](msgContent);
}
Expand Down Expand Up @@ -2219,7 +2333,7 @@
callBackCounter.numMatrixCallbacks++;
spatialObject.messageCallBacks['matrixCall' + callBackCounter.numMatrixCallbacks] = function (msgContent) {
if (typeof msgContent.modelViewMatrix !== 'undefined') {
callback(msgContent.modelViewMatrix, spatialObject.matrices.projection);
callback(msgContent.modelViewMatrix, spatialObject.matrices.projection, msgContent.cameraMatrix);
}
}.bind(this);
};
Expand Down

0 comments on commit 551cf25

Please sign in to comment.