@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
113 lines (112 loc) • 4.17 kB
JavaScript
;
import { BaseSopOperation } from "./_Base";
import { Vector3 } from "three";
import { InputCloneMode } from "../../../engine/poly/InputCloneMode";
import { stringToAttribNames } from "../../../core/String";
import { isBooleanTrue } from "../../../core/BooleanValue";
export var NormalizeMode = /* @__PURE__ */ ((NormalizeMode2) => {
NormalizeMode2["MIN_MAX_TO_01"] = "min/max to 0/1";
NormalizeMode2["VECTOR_TO_LENGTH_1"] = "vectors to length 1";
return NormalizeMode2;
})(NormalizeMode || {});
export const NORMALIZE_MODES = ["min/max to 0/1" /* MIN_MAX_TO_01 */, "vectors to length 1" /* VECTOR_TO_LENGTH_1 */];
const _attribNames = [];
export class AttribNormalizeSopOperation extends BaseSopOperation {
constructor() {
super(...arguments);
this.min3 = new Vector3();
this.max3 = new Vector3();
this._vec = new Vector3();
}
static type() {
return "attribNormalize";
}
cook(input_contents, params) {
const core_group = input_contents[0];
const objects = input_contents[0].threejsObjectsWithGeo();
stringToAttribNames(params.name, _attribNames);
for (const object of objects) {
const geometry = object.geometry;
for (const attribName of _attribNames) {
const srcAttrib = geometry.getAttribute(attribName);
if (srcAttrib) {
let destAttrib = srcAttrib;
if (isBooleanTrue(params.changeName) && params.newName != "") {
destAttrib = geometry.getAttribute(params.newName);
if (destAttrib) {
destAttrib.needsUpdate = true;
}
destAttrib = destAttrib || srcAttrib.clone();
}
this._normalize_attribute(srcAttrib, destAttrib, params);
}
}
}
return core_group;
}
_normalize_attribute(src_attrib, dest_attrib, params) {
const mode = NORMALIZE_MODES[params.mode];
switch (mode) {
case "min/max to 0/1" /* MIN_MAX_TO_01 */:
return this._normalize_from_min_max_to_01(src_attrib, dest_attrib);
case "vectors to length 1" /* VECTOR_TO_LENGTH_1 */:
return this._normalize_vectors(src_attrib, dest_attrib);
}
}
_normalize_from_min_max_to_01(src_attrib, dest_attrib) {
const attrib_size = src_attrib.itemSize;
const src_array = src_attrib.array;
const dest_array = dest_attrib.array;
switch (attrib_size) {
case 1: {
const minf = Math.min(...src_array);
const maxf = Math.max(...src_array);
for (let i = 0; i < dest_array.length; i++) {
dest_array[i] = (src_array[i] - minf) / (maxf - minf);
}
return;
}
case 3: {
const points_count = src_array.length / attrib_size;
const xs = new Array(points_count);
const ys = new Array(points_count);
const zs = new Array(points_count);
let j = 0;
for (let i = 0; i < points_count; i++) {
j = i * attrib_size;
xs[i] = src_array[j + 0];
ys[i] = src_array[j + 1];
zs[i] = src_array[j + 2];
}
this.min3.set(Math.min(...xs), Math.min(...ys), Math.min(...zs));
this.max3.set(Math.max(...xs), Math.max(...ys), Math.max(...zs));
for (let i = 0; i < points_count; i++) {
j = i * attrib_size;
dest_array[j + 0] = (xs[i] - this.min3.x) / (this.max3.x - this.min3.x);
dest_array[j + 1] = (ys[i] - this.min3.y) / (this.max3.y - this.min3.y);
dest_array[j + 2] = (zs[i] - this.min3.z) / (this.max3.z - this.min3.z);
}
return;
}
}
}
_normalize_vectors(src_attrib, dest_attrib) {
const src_array = src_attrib.array;
const dest_array = dest_attrib.array;
const elements_count = src_array.length;
if (src_attrib.itemSize == 3) {
for (let i = 0; i < elements_count; i += 3) {
this._vec.fromArray(src_array, i);
this._vec.normalize();
this._vec.toArray(dest_array, i);
}
}
}
}
AttribNormalizeSopOperation.DEFAULT_PARAMS = {
mode: 0,
name: "position",
changeName: false,
newName: ""
};
AttribNormalizeSopOperation.INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;