@pmndrs/handle
Version:
framework agnostic expandable handle implementation for threejs
43 lines (42 loc) • 2.61 kB
JavaScript
import { Matrix4, Quaternion, Vector3 } from 'three';
import { computeHandleTransformState, addSpaceFromTransformOptions, projectOntoSpace } from './utils.js';
const matrixHelper1 = new Matrix4();
const matrixHelper2 = new Matrix4();
const vectorHelper1 = new Vector3();
const vectorHelper2 = new Vector3();
const quaternionHelper = new Quaternion();
const OneVector = new Vector3(1, 1, 1);
const spaceHelper = [];
export function computeOnePointerHandleTransformState(time, pointerData, storeData, targetParentWorldMatrix, options) {
//compute target parent world quaternion
if (targetParentWorldMatrix == null) {
quaternionHelper.identity();
}
else {
targetParentWorldMatrix.decompose(vectorHelper1, quaternionHelper, vectorHelper2);
}
//compute space
spaceHelper.length = 0;
addSpaceFromTransformOptions(spaceHelper, quaternionHelper, storeData.initialTargetRotation, options.translate ?? true, 'translate');
//pointerWorldMatrix * pointerToTargetParentOffset = TargetParentWorldMatrix =>
//initialPointerToTargetParentOffset = initialPointerWorldMatrix-1 * initialTargetParentWorldMatrix
//same as: matrixHelper2.compose(vectorHelper1, pointerData.initialPointerWorldQuaternion, OneVector).invert()
matrixHelper2
.makeRotationFromQuaternion(quaternionHelper.copy(pointerData.initialPointerWorldQuaternion).invert())
.multiply(matrixHelper1.makeTranslation(vectorHelper1.copy(pointerData.initialPointerWorldPoint).negate()));
if (storeData.initialTargetParentWorldMatrix != null) {
matrixHelper2.multiply(storeData.initialTargetParentWorldMatrix);
}
//matrixHelper2 = initialPointerToTargetParentOffset
projectOntoSpace(options.projectRays, spaceHelper, pointerData.initialPointerWorldPoint, pointerData.pointerWorldOrigin, vectorHelper1.copy(pointerData.pointerWorldPoint), pointerData.pointerWorldDirection);
quaternionHelper.copy(pointerData.pointerWorldQuaternion);
if ((options.rotate ?? true) === false) {
//TODO: this should actually directly apply all options.rotate (including projecting the rotation onto certain axes) but in local space
quaternionHelper.copy(pointerData.initialPointerWorldQuaternion);
}
matrixHelper1
.compose(vectorHelper1, quaternionHelper, OneVector)
.multiply(matrixHelper2)
.multiply(matrixHelper2.compose(storeData.initialTargetPosition, storeData.initialTargetQuaternion, storeData.initialTargetScale));
return computeHandleTransformState(time, 1, matrixHelper1, storeData, targetParentWorldMatrix, options);
}