@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
76 lines (75 loc) • 2.67 kB
JavaScript
;
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;