@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
146 lines (145 loc) • 4.85 kB
JavaScript
"use strict";
import { BaseSopOperation } from "./_Base";
import { Vector3 } from "three";
import { InputCloneMode } from "../../../engine/poly/InputCloneMode";
import { Matrix4 } from "three";
import { TypeAssert } from "../../poly/Assert";
import { Plane } from "three";
import { pointsFromObject } from "../../../core/geometry/entities/point/CorePointUtils";
export var ShearMode = /* @__PURE__ */ ((ShearMode2) => {
ShearMode2["MATRIX"] = "matrix";
ShearMode2["AXIS"] = "axis";
return ShearMode2;
})(ShearMode || {});
export const SHEAR_MODES = ["matrix" /* MATRIX */, "axis" /* AXIS */];
export var ShearCenterMode = /* @__PURE__ */ ((ShearCenterMode2) => {
ShearCenterMode2["BBOX_CENTER"] = "bbox center";
ShearCenterMode2["BBOX_CENTER_OFFSET"] = "bbox center offset";
ShearCenterMode2["CUSTOM"] = "custom";
return ShearCenterMode2;
})(ShearCenterMode || {});
export const SHEAR_CENTER_MODES = [
"bbox center" /* BBOX_CENTER */,
"bbox center offset" /* BBOX_CENTER_OFFSET */,
"custom" /* CUSTOM */
];
const _points = [];
export class ShearSopOperation extends BaseSopOperation {
constructor() {
super(...arguments);
this._m4 = new Matrix4();
this._axisNormalized = new Vector3();
this._center = new Vector3();
this._pointPos = new Vector3();
this._axisPlane = new Plane();
this._pointOnPlane = new Vector3();
this._delta = new Vector3();
this._deltaNormalized = new Vector3();
this._offset = new Vector3();
}
static type() {
return "shear";
}
cook(input_contents, params) {
const objects = input_contents[0].threejsObjects();
this._applyShear(objects, params);
return input_contents[0];
}
_applyShear(objects, params) {
const mode = SHEAR_MODES[params.mode];
switch (mode) {
case "matrix" /* MATRIX */: {
return this._applyMatrixShear(objects, params);
}
case "axis" /* AXIS */: {
return this._applyAxisShear(objects, params);
}
}
TypeAssert.unreachable(mode);
}
_applyMatrixShear(objects, params) {
this._m4.makeShear(params.xy, params.xz, params.yx, params.yz, params.zx, params.zy);
for (let object of objects) {
const mesh = object;
const geometry = mesh.geometry;
if (geometry) {
geometry.applyMatrix4(this._m4);
}
}
}
_applyAxisShear(objects, params) {
this._axisNormalized.copy(params.axis);
this._axisNormalized.normalize();
for (let object of objects) {
const mesh = object;
const geometry = mesh.geometry;
if (geometry) {
this._getAxisModeCenter(geometry, params);
this._axisPlane.setFromNormalAndCoplanarPoint(params.planeAxis, this._center);
pointsFromObject(object, _points);
for (const point of _points) {
point.position(this._pointPos);
this._axisPlane.projectPoint(this._pointPos, this._pointOnPlane);
this._delta.copy(this._pointOnPlane).sub(this._pointPos);
const distToPlane = this._delta.length();
this._deltaNormalized.copy(this._delta).normalize();
this._offset.copy(this._axisNormalized).multiplyScalar(params.axisAmount * distToPlane);
if (this._delta.dot(params.planeAxis) > 0) {
this._offset.multiplyScalar(-1);
}
this._pointPos.add(this._offset);
point.setPosition(this._pointPos);
}
}
}
}
_getAxisModeCenter(geometry, params) {
const mode = SHEAR_CENTER_MODES[params.centerMode];
switch (mode) {
case "bbox center" /* BBOX_CENTER */: {
return this._getAxisModeCenterBbox(geometry, params);
}
case "bbox center offset" /* BBOX_CENTER_OFFSET */: {
return this._getAxisModeCenterBboxOffset(geometry, params);
}
case "custom" /* CUSTOM */: {
return this._getAxisModeCenterCustom(params);
}
}
TypeAssert.unreachable(mode);
}
_getAxisModeCenterBbox(geometry, params) {
geometry.computeBoundingBox();
const box = geometry.boundingBox;
if (box) {
box.getCenter(this._center);
} else {
this._center.set(0, 0, 0);
}
}
_getAxisModeCenterBboxOffset(geometry, params) {
this._getAxisModeCenterBbox(geometry, params);
this._center.add(params.centerOffset);
}
_getAxisModeCenterCustom(params) {
return this._center.copy(params.center);
}
}
ShearSopOperation.DEFAULT_PARAMS = {
mode: SHEAR_MODES.indexOf("axis" /* AXIS */),
// matrix mode
xy: 0,
xz: 0,
yx: 0,
yz: 0,
zx: 0,
zy: 0,
// axis mode
centerMode: SHEAR_CENTER_MODES.indexOf("bbox center" /* BBOX_CENTER */),
centerOffset: new Vector3(0, 0, 0),
center: new Vector3(0, 0, 0),
planeAxis: new Vector3(0, 0, 1),
axis: new Vector3(0, 1, 0),
axisAmount: 0
};
ShearSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;