UNPKG

polygonjs-engine

Version:

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

142 lines (123 loc) 5.32 kB
import {Number3} from '../types/GlobalTypes'; import {Vector3} from 'three/src/math/Vector3'; import {Quaternion} from 'three/src/math/Quaternion'; import {Object3D} from 'three/src/core/Object3D'; import {Matrix4} from 'three/src/math/Matrix4'; import {Euler} from 'three/src/math/Euler'; import {BufferGeometry} from 'three/src/core/BufferGeometry'; import {MathUtils} from 'three/src/math/MathUtils'; import {BaseNodeType} from '../engine/nodes/_Base'; export enum TransformTargetType { OBJECTS = 'objects', GEOMETRIES = 'geometries', } export const TRANSFORM_TARGET_TYPES: Array<TransformTargetType> = [ TransformTargetType.GEOMETRIES, TransformTargetType.OBJECTS, ]; 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; } 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 set_params_from_matrix(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.toVector3(this.set_params_from_matrix_rotation); 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 set_params_from_object(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); translation_matrix(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 _matrix_q = new Quaternion(); private _matrix_euler = new Euler(); private _matrix_s = new Vector3(); matrix(t: Vector3, r: Vector3, s: Vector3, scale: number, rotation_order: RotationOrder) { this._matrix_euler.set( MathUtils.degToRad(r.x), MathUtils.degToRad(r.y), MathUtils.degToRad(r.z), rotation_order ); this._matrix_q.setFromEuler(this._matrix_euler); this._matrix_s.copy(s).multiplyScalar(scale); this._matrix.compose(t, this._matrix_q, this._matrix_s); return this._matrix; } private _rotate_geometry_m = new Matrix4(); private _rotate_geometry_q = new Quaternion(); private _rotate_geometry_vec_dest = new Vector3(); rotate_geometry(geometry: BufferGeometry, vec_origin: Vector3, vec_dest: Vector3) { this._rotate_geometry_vec_dest.copy(vec_dest); this._rotate_geometry_vec_dest.normalize(); this._rotate_geometry_q.setFromUnitVectors(vec_origin, this._rotate_geometry_vec_dest); // this._rotate_geometry_m.identity(); // not entirely sure this is necessary this._rotate_geometry_m.makeRotationFromQuaternion(this._rotate_geometry_q); geometry.applyMatrix4(this._rotate_geometry_m); } static decompose_matrix(object: Object3D) { object.matrix.decompose(object.position, object.quaternion, object.scale); } }