@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
63 lines (62 loc) • 2.09 kB
JavaScript
;
import { BaseSopOperation } from "./_Base";
import { InputCloneMode } from "../../poly/InputCloneMode";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { Potpack } from "../../../core/libs/Potpack";
export class UvLayoutSopOperation extends BaseSopOperation {
static type() {
return SopType.UV_LAYOUT;
}
cook(inputCoreGroups, params) {
const coreGroup = inputCoreGroups[0];
const objects = coreGroup.threejsObjectsWithGeo();
const meshes = [];
for (let object of objects) {
const mesh = object;
if (mesh.isMesh) {
meshes.push(mesh);
}
}
this._layoutUVs(meshes, params);
return coreGroup;
}
_layoutUVs(meshes, params) {
var _a;
const uv_boxes = [];
const objIndexByBox = /* @__PURE__ */ new WeakMap();
const padding = params.padding / params.res;
let index = 0;
for (let mesh of meshes) {
if (!mesh.geometry.hasAttribute(params.uv)) {
(_a = this.states) == null ? void 0 : _a.error.set(`attribute ${params.uv} not found`);
}
const box = { w: 1 + padding * 2, h: 1 + padding * 2 };
uv_boxes.push(box);
objIndexByBox.set(box, index);
index++;
}
const dimensions = Potpack(uv_boxes);
for (let uv_box of uv_boxes) {
const uvBoxResult = uv_box;
const index2 = objIndexByBox.get(uv_box);
if (index2 != null) {
const mesh = meshes[index2];
const uv2 = mesh.geometry.getAttribute(params.uv).clone();
const array = uv2.array;
for (let i = 0; i < uv2.array.length; i += uv2.itemSize) {
array[i] = (uv2.array[i] + uvBoxResult.x + padding) / dimensions.w;
array[i + 1] = (uv2.array[i + 1] + uvBoxResult.y + padding) / dimensions.h;
}
mesh.geometry.setAttribute(params.uv2, uv2);
mesh.geometry.getAttribute(params.uv2).needsUpdate = true;
}
}
}
}
UvLayoutSopOperation.DEFAULT_PARAMS = {
res: 1024,
padding: 3,
uv: "uv",
uv2: "uvLightMap"
};
UvLayoutSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;