@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
107 lines (106 loc) • 3.87 kB
JavaScript
;
import { pushOnArrayAtEntry } from "./../../../core/MapUtils";
import { Vector2, Vector3, Box3 } from "three";
import { BaseSopOperation } from "./_Base";
import { InputCloneMode } from "../../../engine/poly/InputCloneMode";
import { isBooleanTrue } from "../../../core/Type";
import { coreObjectClassFactory } from "../../../core/geometry/CoreObjectFactory";
const currentPos = new Vector2(0, 0);
const maxPos = new Vector2(0, 0);
const box = new Box3();
const boxSize = new Vector3(0, 0);
const objectsByRow = /* @__PURE__ */ new Map();
export class ObjectsLayoutSopOperation extends BaseSopOperation {
static type() {
return "objectsLayout";
}
cook(inputCoreGroups, params) {
const objects = inputCoreGroups[0].threejsObjects();
currentPos.set(0, 0);
maxPos.set(0, 0);
objectsByRow.clear();
let rowIndex = 0;
const addRowWidth = isBooleanTrue(params.addRowWidthInner) || isBooleanTrue(params.addRowWidthOuter);
for (let object of objects) {
object.updateMatrix();
box.setFromObject(object);
box.getSize(boxSize);
const scaleFactor = params.rowHeight / boxSize.y;
object.scale.multiplyScalar(scaleFactor);
object.updateMatrix();
box.setFromObject(object);
box.getSize(boxSize);
boxSize.x += params.padding.x;
boxSize.y += params.padding.y;
currentPos.x += boxSize.x;
if (currentPos.x > params.maxLayoutWidth) {
currentPos.x = boxSize.x;
currentPos.y -= boxSize.y;
rowIndex++;
}
object.position.x = currentPos.x - boxSize.x * 0.5;
object.position.y = currentPos.y - boxSize.y * 0.5;
if (isBooleanTrue(params.addAttribs)) {
if (addRowWidth) {
pushOnArrayAtEntry(objectsByRow, rowIndex, object);
}
if (isBooleanTrue(params.addRowAttrib)) {
coreObjectClassFactory(object).addAttribute(object, "row", rowIndex);
}
}
maxPos.x = Math.max(maxPos.x, object.position.x + boxSize.x * 0.5);
maxPos.y = Math.min(maxPos.y, object.position.y - boxSize.y * 0.5);
}
for (let object of objects) {
object.position.x -= maxPos.x * 0.5;
object.position.y -= maxPos.y * 0.5;
object.updateMatrix();
}
if (isBooleanTrue(params.addAttribs)) {
if (addRowWidth) {
objectsByRow.forEach((objects2, _) => {
if (isBooleanTrue(params.addRowWidthInner)) {
const xs = objects2.map((o) => o.position.x);
const minX = Math.min(...xs);
const maxX = Math.max(...xs);
const width = maxX - minX;
for (let object of objects2) {
coreObjectClassFactory(object).addAttribute(object, "rowWidthInner", width);
}
}
if (isBooleanTrue(params.addRowWidthOuter)) {
const minX = Math.min(
...objects2.map((o) => {
box.setFromObject(o);
box.getSize(boxSize);
return o.position.x - boxSize.x * 0.5;
})
);
const maxX = Math.max(
...objects2.map((o) => {
box.setFromObject(o);
box.getSize(boxSize);
return o.position.x + boxSize.x * 0.5;
})
);
const width = maxX - minX;
for (let object of objects2) {
coreObjectClassFactory(object).addAttribute(object, "rowWidthOuter", width);
}
}
});
}
}
return this.createCoreGroupFromObjects(objects);
}
}
ObjectsLayoutSopOperation.DEFAULT_PARAMS = {
maxLayoutWidth: 10,
rowHeight: 1,
padding: new Vector2(0, 0),
addAttribs: false,
addRowAttrib: false,
addRowWidthInner: false,
addRowWidthOuter: false
};
ObjectsLayoutSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;