UNPKG

@polygonjs/polygonjs

Version:

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

147 lines (146 loc) 5.04 kB
"use strict"; import { BaseSopOperation } from "./_Base"; import { TypeAssert } from "../../../engine/poly/Assert"; import { CoreTransform, ROTATION_ORDERS, RotationOrder, TransformTargetType, TRANSFORM_TARGET_TYPES } from "../../../core/Transform"; import { InputCloneMode } from "../../../engine/poly/InputCloneMode"; import { coreObjectClassFactory } from "../../../core/geometry/CoreObjectFactory"; import { MathUtils, Vector3, Matrix4, Euler, Quaternion } from "three"; import { OBJECT_TRANSFORM_SPACES, OBJECT_TRANSFORM_MODES, ObjectTransformMode, ObjectTransformSpace, applyTransformWithSpaceToObject } from "../../../core/TransformSpace"; import { isObject3D } from "../../../core/geometry/ObjectContent"; import { CoreMask } from "../../../core/geometry/Mask"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { pointsFromObjectFromGroup } from "../../../core/geometry/entities/point/CorePointUtils"; const _r = new Vector3(); const _euler = new Euler(); const _q = new Quaternion(); const _s = new Vector3(); const _mat4 = new Matrix4(); const _pointPos = new Vector3(); const _points = []; export class TransformSopOperation extends BaseSopOperation { constructor() { super(...arguments); this._coreTransform = new CoreTransform(); } static type() { return SopType.TRANSFORM; } cook(inputCoreGroups, params) { const coreGroup = inputCoreGroups[0]; const selectedObjects = CoreMask.filterObjects(coreGroup, params); for (const inputObject of selectedObjects) { this._applyTransform(inputObject, coreGroup, params); } coreGroup.resetBoundingBox(); return coreGroup; } _applyTransform(object, coreGroup, params) { if (isObject3D(object)) { this._applyTransformWithTransformTargetType(object, coreGroup, params); } else { this._applyTransformWithoutTransformTargetType(object, params); } } _applyTransformWithoutTransformTargetType(object, params) { this._updateObject(object, params); } _applyTransformWithTransformTargetType(object, coreGroup, params) { const mode = TRANSFORM_TARGET_TYPES[params.applyOn]; switch (mode) { case TransformTargetType.GEOMETRY: { return this._updateGeometry(object, params); } case TransformTargetType.OBJECT: { return this._updateObject(object, params); } } TypeAssert.unreachable(mode); } _updateGeometry(object, params) { const matrix = this._matrix(params); const pointGroup = params.pointGroup; if (pointGroup.trim() === "") { const geometry = object.geometry; if (geometry) { geometry.translate(-params.pivot.x, -params.pivot.y, -params.pivot.z); geometry.applyMatrix4(matrix); geometry.translate(params.pivot.x, params.pivot.y, params.pivot.z); } } else { pointsFromObjectFromGroup(object, pointGroup, _points); for (const point of _points) { const position = point.position(_pointPos).sub(params.pivot); position.applyMatrix4(matrix); point.setPosition(position.add(params.pivot)); } } } _updateObject(object, params) { const objectMode = OBJECT_TRANSFORM_MODES[params.objectMode]; switch (objectMode) { case ObjectTransformMode.SET: { return this._setMatrix(object, params); } case ObjectTransformMode.MULT: { return this._multMatrix(object, params); } } TypeAssert.unreachable(objectMode); } _setMatrix(object, params) { const order = ROTATION_ORDERS[params.rotationOrder]; _r.copy(params.r).multiplyScalar(MathUtils.DEG2RAD); _euler.set(_r.x, _r.y, _r.z, order); _q.setFromEuler(_euler); _s.copy(params.s).multiplyScalar(params.scale); _mat4.compose(params.t, _q, _s); coreObjectClassFactory(object).applyMatrix( object, _mat4, TRANSFORM_TARGET_TYPES[params.applyOn], ObjectTransformSpace.LOCAL, ObjectTransformMode.SET ); } // private _objectPosition = new Vector3(); _multMatrix(object, params) { const matrix = this._matrix(params); const transformSpace = OBJECT_TRANSFORM_SPACES[params.objectTransformSpace]; applyTransformWithSpaceToObject(object, matrix, transformSpace, ObjectTransformMode.MULT); } _matrix(params) { return this._coreTransform.matrix( params.t, params.r, params.s, params.scale, ROTATION_ORDERS[params.rotationOrder] ); } } TransformSopOperation.DEFAULT_PARAMS = { applyOn: TRANSFORM_TARGET_TYPES.indexOf(TransformTargetType.GEOMETRY), group: "", objectMode: OBJECT_TRANSFORM_MODES.indexOf(ObjectTransformMode.SET), objectTransformSpace: OBJECT_TRANSFORM_SPACES.indexOf(ObjectTransformSpace.PARENT), pointGroup: "", rotationOrder: ROTATION_ORDERS.indexOf(RotationOrder.XYZ), t: new Vector3(0, 0, 0), r: new Vector3(0, 0, 0), s: new Vector3(1, 1, 1), scale: 1, pivot: new Vector3(0, 0, 0) }; TransformSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;