UNPKG

@polygonjs/polygonjs

Version:

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

76 lines (75 loc) 2.67 kB
"use strict"; import { BaseSopOperation } from "./_Base"; import { InputCloneMode } from "../../../engine/poly/InputCloneMode"; import { Vector3, Plane } from "three"; import { CoreMask } from "../../../core/geometry/Mask"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { withChildrenRemoved } from "../../../core/geometry/util/HierarchyRemoved"; import { object3DHasGeometry } from "../../../core/geometry/GeometryUtils"; import { ThreejsCoreObject } from "../../../core/geometry/modules/three/ThreejsCoreObject"; import { meshInverse } from "../../../core/geometry/util/MeshInverse"; const _axis = new Vector3(); const _pos = new Vector3(); const _projectedPos = new Vector3(); const _delta = new Vector3(); const _plane = new Plane(); export class MirrorSopOperation extends BaseSopOperation { static type() { return SopType.MIRROR; } cook(inputCoreGroups, params) { const coreGroup = inputCoreGroups[0]; const newObjects = coreGroup.allObjects(); const objects = CoreMask.filterThreejsObjects(coreGroup, { group: params.group }).filter(object3DHasGeometry); _axis.copy(params.axis).normalize(); _plane.constant = -params.center.dot(_axis); _plane.normal.copy(_axis); for (const object of objects) { this._applyOrCreateMirrorObject(object, _plane, params, newObjects); } return this.createCoreGroupFromObjects(newObjects); } _applyOrCreateMirrorObject(object, plane, params, newObjects) { if (params.preserveInput) { const clonedObject = withChildrenRemoved(object, () => ThreejsCoreObject.clone(object)); this._mirrorObject(clonedObject, plane); if (clonedObject) { if (object.parent) { object.parent.add(clonedObject); } else { newObjects.push(clonedObject); } } } else { this._mirrorObject(object, plane); } } _mirrorObject(object, plane) { const geometry = object.geometry; if (!geometry) { return; } const position = geometry.getAttribute("position"); const pointsCount = position.count; const positions = position.array; for (let i = 0; i < pointsCount; i++) { _pos.fromArray(positions, i * 3); plane.projectPoint(_pos, _projectedPos); _delta.copy(_pos).sub(_projectedPos); _projectedPos.sub(_delta); _projectedPos.toArray(positions, i * 3); } if (object.isMesh) { meshInverse(object); } } } MirrorSopOperation.DEFAULT_PARAMS = { group: "*", axis: new Vector3(1, 0, 0), center: new Vector3(0, 0, 0), preserveInput: true }; MirrorSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;