Skip to content

Commit

Permalink
perf(3dcontrollermodelselectormanipulator): pre-allocate needed array…
Browse files Browse the repository at this point in the history
… buffers for prop positioning
  • Loading branch information
bourdaisj committed Mar 4, 2024
1 parent 2e6454b commit 3c69c5c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/Rendering/Core/Prop3D/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions Sources/Rendering/Core/Prop3D/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 3c69c5c

Please sign in to comment.