From 551cf259e34c7a6aaf9cbe2461788d5f41141f4a Mon Sep 17 00:00:00 2001 From: Rik de Leeuw Date: Mon, 17 Jul 2023 05:27:16 +0200 Subject: [PATCH] step 1: getting the viewMatrix separated from the modelMatrix - 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 --- addons/vuforia-spatial-core-addon | 2 +- libraries/objectDefaultFiles/object.js | 116 ++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/addons/vuforia-spatial-core-addon b/addons/vuforia-spatial-core-addon index 3c5770097..441310e3d 160000 --- a/addons/vuforia-spatial-core-addon +++ b/addons/vuforia-spatial-core-addon @@ -1 +1 @@ -Subproject commit 3c5770097d26c4320db1cb9eab26d2630599d684 +Subproject commit 441310e3d8e46de69af8079d676809ab6d68262d diff --git a/libraries/objectDefaultFiles/object.js b/libraries/objectDefaultFiles/object.js index 65052c251..19bc8b34e 100755 --- a/libraries/objectDefaultFiles/object.js +++ b/libraries/objectDefaultFiles/object.js @@ -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); + 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 @@ -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); } @@ -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); };