@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
88 lines (87 loc) • 3.54 kB
JavaScript
;
import { BaseSopOperation } from "./_Base";
import { InputCloneMode } from "../../../engine/poly/InputCloneMode";
import { TypeAssert } from "../../poly/Assert";
import { CoreInstancer } from "../../../core/geometry/Instancer";
const _instancePts = [];
export var InstanceUpdateMode = /* @__PURE__ */ ((InstanceUpdateMode2) => {
InstanceUpdateMode2["GEO"] = "geo";
InstanceUpdateMode2["POINTS"] = "points";
return InstanceUpdateMode2;
})(InstanceUpdateMode || {});
export const INSTANCE_UPDATE_MODES = ["geo" /* GEO */, "points" /* POINTS */];
export class InstanceUpdateSopOperation extends BaseSopOperation {
static type() {
return "instanceUpdate";
}
cook(inputCoreGroups, params) {
this._cookFromUpdateMode(inputCoreGroups, params);
return inputCoreGroups[0];
}
_cookFromUpdateMode(inputCoreGroups, params) {
const mode = INSTANCE_UPDATE_MODES[params.mode];
switch (mode) {
case "geo" /* GEO */: {
return this._updateGeo(inputCoreGroups, params);
}
case "points" /* POINTS */: {
return this._updatePoints(inputCoreGroups, params);
}
}
TypeAssert.unreachable(mode);
}
_updateGeo(inputCoreGroups, params) {
const instanceCoreGroup = inputCoreGroups[0];
const updatingCoreGroup = inputCoreGroups[1];
const instanceObject = instanceCoreGroup.threejsObjects()[0];
const instanceGeometry = instanceObject.geometry;
const updatingMesh = updatingCoreGroup.threejsObjectsWithGeo()[0];
const updatingGeometry = updatingMesh.geometry;
const attribNames = instanceCoreGroup.pointAttribNamesMatchingMask(params.geoAttributes);
for (const attribName of attribNames) {
const updatingAttrib = updatingGeometry.getAttribute(attribName);
instanceGeometry.setAttribute(attribName, updatingAttrib);
const instanceAttrib = instanceGeometry.getAttribute(attribName);
instanceAttrib.needsUpdate = true;
}
if (updatingGeometry.index) {
instanceGeometry.setIndex(updatingGeometry.index);
const index = instanceGeometry.getIndex();
if (index) {
index.needsUpdate = true;
}
} else {
instanceGeometry.setIndex(null);
}
instanceGeometry.groups = updatingGeometry.groups;
}
_updatePoints(inputCoreGroups, params) {
const instanceCoreGroup = inputCoreGroups[0];
const updatingCoreGroup = inputCoreGroups[1];
const instanceObject = instanceCoreGroup.threejsObjects()[0];
const instanceBufferGeo = instanceObject.geometry;
const attribNames = instanceCoreGroup.pointAttribNamesMatchingMask(params.pointAttributes).map((attribName) => CoreInstancer.remapName(attribName));
let updateTransforms = false;
for (const attribName of attribNames) {
if (CoreInstancer.transformAttributeNames.includes(attribName)) {
updateTransforms = true;
}
}
updatingCoreGroup.points(_instancePts);
if (updateTransforms) {
CoreInstancer.updateTransformInstanceAttributes(_instancePts, updatingCoreGroup, instanceBufferGeo);
for (const attribName of CoreInstancer.transformAttributeNames) {
const attrib = instanceBufferGeo.getAttribute(attribName);
if (attrib) {
attrib.needsUpdate = true;
}
}
}
}
}
InstanceUpdateSopOperation.DEFAULT_PARAMS = {
mode: INSTANCE_UPDATE_MODES.indexOf("geo" /* GEO */),
geoAttributes: "P N",
pointAttributes: "P"
};
InstanceUpdateSopOperation.INPUT_CLONED_STATE = [InputCloneMode.FROM_NODE, InputCloneMode.NEVER];