From 3c69c5ca5af69703c324fde6bd06d5819776bb8d Mon Sep 17 00:00:00 2001 From: Jules BOURDAIS Date: Mon, 4 Mar 2024 19:04:26 +0100 Subject: [PATCH] perf(3dcontrollermodelselectormanipulator): pre-allocate needed array buffers for prop positioning --- .../index.js | 97 +++++++++++-------- Sources/Rendering/Core/Prop3D/index.d.ts | 4 +- Sources/Rendering/Core/Prop3D/index.js | 4 +- 3 files changed, 62 insertions(+), 43 deletions(-) diff --git a/Sources/Interaction/Manipulators/3DControllerModelSelectorManipulator/index.js b/Sources/Interaction/Manipulators/3DControllerModelSelectorManipulator/index.js index f5bfc79e08a..96330e0f03f 100644 --- a/Sources/Interaction/Manipulators/3DControllerModelSelectorManipulator/index.js +++ b/Sources/Interaction/Manipulators/3DControllerModelSelectorManipulator/index.js @@ -15,64 +15,81 @@ function vtk3DControllerModelSelectorManipulator(publicAPI, model) { // The current prop we are manipulating, if any. let pickedProp; + // pre-allocate array buffers const physicalToWorldMatrix = new Float64Array(16); + // arrays holding deltas from lastWorldPosition and lastOrientation + const translation = new Float64Array(3); + const rotation = new Float64Array(4); + const lastOrientationConjugate = new Float64Array(4); + const orientationAxis = new Float64Array(3); + + // arrays holding the transform + const computedTransform = new Float64Array(16); + const computedTransformRotation = new Float64Array(4); + + // arrays holding the current state of pickedProp. + const transposedPropMatrix = new Float64Array(16); + const propCurrentOrientation = new Float64Array(4); + const propCurrentOrientationConjugate = new Float64Array(4); + + // arrays holding the new properties that must be assigned to pickedProp. + const propNewTranslation = new Float64Array(3); + const propNewScaling = new Float64Array(3); + const propNewOrientation = new Float64Array(4); + function applyPositionAndOrientationToProp(prop, worldPosition, orientation) { - const translation = vec3.subtract( - [], - worldPosition, - model.lastWorldPosition - ); + vec3.subtract(translation, worldPosition, model.lastWorldPosition); - const lastOrientationConjugate = quat.conjugate([], model.lastOrientation); + quat.conjugate(lastOrientationConjugate, model.lastOrientation); - const newOrientation = quat.multiply( - [], - orientation, - lastOrientationConjugate - ); - quat.normalize(newOrientation, newOrientation); + quat.multiply(rotation, orientation, lastOrientationConjugate); + quat.normalize(rotation, rotation); - const newOrientationAxis = []; - const newOrientationAngle = quat.getAxisAngle( - newOrientationAxis, - newOrientation - ); + const rotationAngle = quat.getAxisAngle(orientationAxis, rotation); + + // reset to identity + mat4.identity(computedTransform); - // compute our transform - const transform = mat4.identity(new Float64Array(16)); - mat4.translate(transform, transform, worldPosition); - mat4.rotate(transform, transform, newOrientationAngle, newOrientationAxis); - mat4.translate(transform, transform, vec3.negate([], worldPosition)); - mat4.translate(transform, transform, translation); + // compute transform + mat4.translate(computedTransform, computedTransform, worldPosition); + mat4.rotate( + computedTransform, + computedTransform, + rotationAngle, + orientationAxis + ); + mat4.translate( + computedTransform, + computedTransform, + vec3.negate(new Float64Array(3), worldPosition) + ); + mat4.translate(computedTransform, computedTransform, translation); // lookup the prop internal matrix - const matrix = [...mat4.transpose([], prop.getMatrix())]; - // apply the new transform to the prop internal matrix - mat4.multiply(transform, transform, matrix); + mat4.transpose(transposedPropMatrix, prop.getMatrix()); + // apply the new computedTransform to the prop internal matrix + mat4.multiply(computedTransform, computedTransform, transposedPropMatrix); - // Multiply the transform with the current prop orientation to get the delta + // Multiply the computedTransform with the current prop orientation to get the delta // that must be applied to the prop - const transformRotation = mat4.getRotation([], transform); - const propCurrentOrientation = prop.getOrientationQuaternion(); - const propCurrentOrientationConjugate = quat.conjugate( - [], - propCurrentOrientation - ); - const propNewOrientation = quat.multiply( - [], + mat4.getRotation(computedTransformRotation, computedTransform); + prop.getOrientationQuaternion(propCurrentOrientation); + quat.conjugate(propCurrentOrientationConjugate, propCurrentOrientation); + quat.multiply( + propNewOrientation, propCurrentOrientationConjugate, - transformRotation + computedTransformRotation ); quat.normalize(propNewOrientation, propNewOrientation); - const transformTranslation = mat4.getTranslation([], transform); - const transformScaling = mat4.getScaling([], transform); + mat4.getTranslation(propNewTranslation, computedTransform); + mat4.getScaling(propNewScaling, computedTransform); // Update the prop internal matrix - prop.setPosition(...transformTranslation); - prop.setScale(...transformScaling); + prop.setPosition(...propNewTranslation); + prop.setScale(...propNewScaling); prop.rotateQuaternion(propNewOrientation); } diff --git a/Sources/Rendering/Core/Prop3D/index.d.ts b/Sources/Rendering/Core/Prop3D/index.d.ts index 740a4e156b2..e59f2da8eaf 100755 --- a/Sources/Rendering/Core/Prop3D/index.d.ts +++ b/Sources/Rendering/Core/Prop3D/index.d.ts @@ -90,8 +90,10 @@ export interface vtkProp3D extends vtkProp { /** * Get the orientation quaternion of the Prop3D. + * out is optional and will be created if not supplied. + * @param {quat | undefined} out */ - getOrientationQuaternion(): quat; + getOrientationQuaternion(out?: quat): quat; /** * Get a reference to the Prop3D’s 4x4 composite matrix. diff --git a/Sources/Rendering/Core/Prop3D/index.js b/Sources/Rendering/Core/Prop3D/index.js index 1c1512a4966..aaecd376e0a 100644 --- a/Sources/Rendering/Core/Prop3D/index.js +++ b/Sources/Rendering/Core/Prop3D/index.js @@ -30,8 +30,8 @@ function vtkProp3D(publicAPI, model) { return [vtkMath.degreesFromRadians(w), oaxis[0], oaxis[1], oaxis[2]]; }; - publicAPI.getOrientationQuaternion = () => - mat4.getRotation([], model.rotation); + publicAPI.getOrientationQuaternion = (out = []) => + mat4.getRotation(out, model.rotation); publicAPI.rotateX = (val) => { if (val === 0.0) {