UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

65 lines (64 loc) 2.4 kB
"use strict"; import { Euler, Quaternion, Vector3, Object3D } from "three"; import { degToRad, radToDeg } from "three/src/math/MathUtils"; export const CHANGE_EVENT = { type: "change" }; export const EPS = 1e-6; export const PI_DEG = radToDeg(Math.PI); export const PI_DEG2 = 2 * radToDeg(Math.PI); const AXIS_Z = new Vector3(0, 0, 1); const euler = new Euler(); const q0 = new Quaternion(); const q1 = new Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); const q2 = new Quaternion(); const ROTATION_ORDER_YXZ = "YXZ"; function _setQuaternionFromAlphaBetaGamma(alpha, beta, gamma, orient, target) { euler.set(beta, alpha, -gamma, ROTATION_ORDER_YXZ); target.setFromEuler(euler); target.multiply(q1); target.multiply(q0.setFromAxisAngle(AXIS_Z, -orient)); } const alphaOffset = 0; export function setQuaternionFromEvent(event, screenOrientation, target) { const alpha = event.alpha ? degToRad(event.alpha) + alphaOffset : 0; const beta = event.beta ? degToRad(event.beta) : 0; const gamma = event.gamma ? degToRad(event.gamma) : 0; const orient = screenOrientation ? degToRad(screenOrientation) : 0; _setQuaternionFromAlphaBetaGamma(alpha, beta, gamma, orient, target); } export function quaternionYAngle(relativeQuaternion) { euler.setFromQuaternion(relativeQuaternion); return -radToDeg(euler.y); } export function yAngleFromEvent(event, screenOrientation) { setQuaternionFromEvent(event, screenOrientation, q2); return quaternionYAngle(q2); } function _createObjects() { const ryOffset = new Object3D(); const ry = new Object3D(); const rx = new Object3D(); const rz = new Object3D(); ryOffset.add(ry); ry.add(rx); rx.add(rz); return { ryOffset, ry, rx, rz }; } let _rotationHierarchy; function _getRotationHierarchy() { return _rotationHierarchy || (_rotationHierarchy = _createObjects()); } export function blendQuaternionToAbsoluteYAngle(relativeQuaternion, yAngleOffset, target) { euler.setFromQuaternion(relativeQuaternion); const rotationHierarchy = _getRotationHierarchy(); rotationHierarchy.ryOffset.rotation.set(0, -degToRad(yAngleOffset), 0); rotationHierarchy.ry.rotation.set(0, euler.y, 0); rotationHierarchy.rx.rotation.set(euler.x, 0, 0); rotationHierarchy.rz.rotation.set(0, 0, euler.z); rotationHierarchy.rz.updateWorldMatrix(true, true); target.setFromRotationMatrix(rotationHierarchy.rz.matrixWorld); }