UNPKG

@polygonjs/polygonjs

Version:

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

147 lines (127 loc) 5.66 kB
import {Number3} from '../types/GlobalTypes'; import {MathUtils, BufferGeometry, Euler, Matrix4, Object3D, Vector3, Quaternion} from 'three'; import {BaseNodeType} from '../engine/nodes/_Base'; export enum TransformTargetType { OBJECT = 'object', GEOMETRY = 'geometry', } export const TRANSFORM_TARGET_TYPES: TransformTargetType[] = [TransformTargetType.GEOMETRY, TransformTargetType.OBJECT]; export enum RotationOrder { XYZ = 'XYZ', XZY = 'XZY', YXZ = 'YXZ', YZX = 'YZX', ZYX = 'ZYX', ZXY = 'ZXY', } export const ROTATION_ORDERS: RotationOrder[] = [ RotationOrder.XYZ, RotationOrder.XZY, RotationOrder.YXZ, RotationOrder.YZX, RotationOrder.ZXY, RotationOrder.ZYX, ]; export const DEFAULT_ROTATION_ORDER = RotationOrder.XYZ; export interface SetParamsFromMatrixOptions { scale?: boolean; } const eulerArray: Number3 = [0, 0, 0]; const _m = new Matrix4(); const _q = new Quaternion(); const _rotateDirOrigin = new Vector3(); const _rotateDirDest = new Vector3(); export function rotationMatrix(dirOrigin: Vector3, dirDest: Vector3, target: Matrix4) { _rotateDirDest.copy(dirDest).normalize(); _rotateDirOrigin.copy(dirOrigin).normalize(); _q.setFromUnitVectors(_rotateDirOrigin, _rotateDirDest); target.makeRotationFromQuaternion(_q); } export function rotateGeometry(geometry: BufferGeometry, dirOrigin: Vector3, dirDest: Vector3) { _rotateDirDest.copy(dirDest).normalize(); _rotateDirOrigin.copy(dirOrigin).normalize(); _q.setFromUnitVectors(_rotateDirOrigin, _rotateDirDest); _m.makeRotationFromQuaternion(_q); geometry.applyMatrix4(_m); } export class CoreTransform { private static set_params_from_matrix_position = new Vector3(); private static set_params_from_matrix_quaternion = new Quaternion(); private static set_params_from_matrix_scale = new Vector3(); private static set_params_from_matrix_euler = new Euler(); private static set_params_from_matrix_rotation = new Vector3(); private static set_params_from_matrix_t: Number3 = [0, 0, 0]; private static set_params_from_matrix_r: Number3 = [0, 0, 0]; private static set_params_from_matrix_s: Number3 = [0, 0, 0]; static setParamsFromMatrix(matrix: Matrix4, node: BaseNodeType, options: SetParamsFromMatrixOptions = {}) { let update_scale = options['scale']; if (update_scale == null) { update_scale = true; } matrix.decompose( this.set_params_from_matrix_position, this.set_params_from_matrix_quaternion, this.set_params_from_matrix_scale ); this.set_params_from_matrix_euler.setFromQuaternion(this.set_params_from_matrix_quaternion); this.set_params_from_matrix_euler.toArray(eulerArray); this.set_params_from_matrix_rotation.fromArray(eulerArray); this.set_params_from_matrix_rotation.divideScalar(Math.PI / 180); this.set_params_from_matrix_position.toArray(this.set_params_from_matrix_t); this.set_params_from_matrix_rotation.toArray(this.set_params_from_matrix_r); this.set_params_from_matrix_scale.toArray(this.set_params_from_matrix_s); node.scene().batchUpdates(() => { node.params.set_vector3('t', this.set_params_from_matrix_t); node.params.set_vector3('r', this.set_params_from_matrix_r); node.params.set_vector3('s', this.set_params_from_matrix_s); if (update_scale) { node.params.set_float('scale', 1); } }); } static set_params_from_object_position_array: Number3 = [0, 0, 0]; static set_params_from_object_rotation_deg = new Vector3(); static set_params_from_object_rotation_array: Number3 = [0, 0, 0]; static setParamsFromObject(object: Object3D, node: BaseNodeType) { object.position.toArray(this.set_params_from_object_position_array); object.rotation.toArray(this.set_params_from_object_rotation_array); this.set_params_from_object_rotation_deg.fromArray(this.set_params_from_object_rotation_array); this.set_params_from_object_rotation_deg.multiplyScalar(180 / Math.PI); this.set_params_from_object_rotation_deg.toArray(this.set_params_from_object_rotation_array); node.scene().batchUpdates(() => { node.params.set_vector3('t', this.set_params_from_object_position_array); node.params.set_vector3('r', this.set_params_from_object_rotation_array); }); } private _translation_matrix: Matrix4 = new Matrix4(); private _translation_matrix_q = new Quaternion(); private _translation_matrix_s = new Vector3(1, 1, 1); translationMatrix(t: Vector3): Matrix4 { this._translation_matrix.compose(t, this._translation_matrix_q, this._translation_matrix_s); return this._translation_matrix; } private _matrix = new Matrix4().identity(); private _matrixQ = new Quaternion(); private _matrixEuler = new Euler(); private _matrixS = new Vector3(); matrix(t: Vector3, r: Vector3, s: Vector3, scale: number, rotationOrder: RotationOrder) { this._matrixEuler.set(MathUtils.degToRad(r.x), MathUtils.degToRad(r.y), MathUtils.degToRad(r.z), rotationOrder); this._matrixQ.setFromEuler(this._matrixEuler); this._matrixS.copy(s).multiplyScalar(scale); this._matrix.compose(t, this._matrixQ, this._matrixS); return this._matrix; } static rotateObject(object: Object3D, dirOrigin: Vector3, dirDest: Vector3) { _rotateDirDest.copy(dirDest).normalize(); _rotateDirOrigin.copy(dirOrigin).normalize(); _q.setFromUnitVectors(_rotateDirOrigin, _rotateDirDest); // this._rotate_geometry_m.identity(); // not entirely sure this is necessary _m.makeRotationFromQuaternion(_q); object.matrix.multiply(_m); // object.updateMatrix(); object.matrix.decompose(object.position, object.quaternion, object.scale); } static decomposeMatrix(object: Object3D) { object.matrix.decompose(object.position, object.quaternion, object.scale); } }