@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
200 lines (199 loc) • 6.85 kB
JavaScript
"use strict";
import { WebGLRenderer } from "three";
import { NodeParamsConfig } from "../utils/params/ParamsConfig";
import { NodeContext } from "../../poly/NodeContext";
import { InputCloneMode } from "../../poly/InputCloneMode";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { isFunction } from "../../../core/Type";
import { Poly } from "../../Poly";
import { ClothIdAttribute } from "../../../core/cloth/ClothAttribute";
import {
createOrFindClothController,
clothControllerNodeIdFromObject
} from "../../../core/cloth/ClothControllerRegister";
import { TypedSopNode } from "./_Base";
import { AssemblerName } from "../../poly/registers/assemblers/_BaseRegister";
import { ClothPersistedConfig } from "../gl/code/assemblers/cloth/ClothPersistedConfig";
import { GlobalsTextureHandler, GlobalsTextureHandlerPurpose } from "../gl/code/globals/Texture";
import { GlNodeFinder } from "../gl/code/utils/NodeFinder";
import { coreObjectClassFactory } from "../../../core/geometry/CoreObjectFactory";
class ClothSolverSopParamsConfig extends NodeParamsConfig {
}
const ParamsConfig = new ClothSolverSopParamsConfig();
export class ClothSolverSopNode extends TypedSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this._assemblerController = this._createAssemblerController();
this.persisted_config = new ClothPersistedConfig(this);
this._globalsHandler = new GlobalsTextureHandler(
GlobalsTextureHandler.PARTICLE_SIM_UV,
GlobalsTextureHandlerPurpose.PARTICLES_SHADER
);
this._shadersByName = /* @__PURE__ */ new Map();
this._childrenControllerContext = NodeContext.GL;
}
static type() {
return SopType.CLOTH_SOLVER;
}
assemblerController() {
return this._assemblerController;
}
usedAssembler() {
return AssemblerName.GL_CLOTH;
}
_createAssemblerController() {
return Poly.assemblersRegister.assembler(this, this.usedAssembler());
}
shadersByName() {
return this._shadersByName;
}
initializeNode() {
this.io.inputs.setCount(1);
this.io.inputs.initInputsClonedState(InputCloneMode.ALWAYS);
}
createNode(node_class, options) {
return super.createNode(node_class, options);
}
children() {
return super.children();
}
nodesByType(type) {
return super.nodesByType(type);
}
childrenAllowed() {
if (this.assemblerController()) {
return super.childrenAllowed();
}
return false;
}
sceneReadonly() {
return this.assemblerController() == null;
}
async cook(inputCoreGroups) {
this.compileIfRequired();
const coreGroup = inputCoreGroups[0];
const objects = coreGroup.allObjects();
const object = objects[0];
const existingActorIds = this.scene().actorsManager.objectActorNodeIds(object);
if (existingActorIds == null || existingActorIds.length == 0) {
this.states.error.set(`the input objects requires an actor node assigned to it`);
}
coreObjectClassFactory(object).addAttribute(object, ClothIdAttribute.OBJECT, this.graphNodeId());
Poly.onObjectsAddRemoveHooks.assignOnAddHookHandler(object, this);
this.setObject(object);
}
updateObjectOnAdd(object) {
const clothSolverNodeId = coreObjectClassFactory(object).attribValue(object, ClothIdAttribute.OBJECT);
if (clothSolverNodeId != null) {
if (clothSolverNodeId != this.graphNodeId()) {
return;
}
const clothObject = object;
const result = createOrFindClothController(this.scene(), this, clothObject);
if (!result) {
return;
}
const { controller } = result;
this.scene().renderersRegister.waitForRenderer().then((renderer) => {
if (!renderer) {
console.warn("no renderer");
return;
}
if (!(renderer instanceof WebGLRenderer)) {
console.warn("not a WebGLRenderer");
return;
}
controller.init(renderer);
});
}
}
compileIfRequired() {
var _a;
if ((_a = this.assemblerController()) == null ? void 0 : _a.compileRequired()) {
try {
this.run_assembler();
} catch (err) {
const message = err.message || "failed to compile";
this.states.error.set(message);
}
}
}
run_assembler() {
const assemblerController = this.assemblerController();
if (!assemblerController) {
return;
}
const export_nodes = this._findExportNodes();
if (export_nodes.length > 0) {
const root_nodes = export_nodes;
assemblerController.setAssemblerGlobalsHandler(this._globalsHandler);
assemblerController.assembler.set_root_nodes(root_nodes);
assemblerController.assembler.compile();
assemblerController.post_compile();
}
const shadersByName = assemblerController.assembler.shaders_by_name();
this._setShaderNames(shadersByName);
}
_setShaderNames(shadersByName) {
this._shadersByName = shadersByName;
}
init_with_persisted_config() {
const shaders_by_name = this.persisted_config.shaders_by_name();
const texture_allocations_controller = this.persisted_config.texture_allocations_controller();
if (shaders_by_name && texture_allocations_controller) {
this._setShaderNames(shaders_by_name);
}
}
initCoreClothControllerFromPersistedConfig(coreClothController) {
const shaders_by_name = this.persisted_config.shaders_by_name();
const texture_allocations_controller = this.persisted_config.texture_allocations_controller();
if (shaders_by_name && texture_allocations_controller) {
coreClothController.setPersistedTextureAllocationController(texture_allocations_controller);
}
}
_findExportNodes() {
const nodes = [];
const outputNodes = GlNodeFinder.findOutputNodes(this);
if (outputNodes.length == 0) {
this.states.error.set("one output node is required");
}
if (outputNodes.length > 1) {
this.states.error.set("only one output node is allowed");
return [];
}
const outputNode = outputNodes[0];
if (outputNode) {
nodes.push(outputNode);
}
return nodes;
}
// private _findActorNode() {
// // if (isBooleanTrue(this.pv.useThisNode)) {
// return this;
// // } else {
// // return this.pv.node.node() as ActorBuilderNode | undefined;
// // }
// }
}
export function getClothControllerNodeFromWorldObject(clothObject, scene) {
const nodeId = clothControllerNodeIdFromObject(clothObject);
if (nodeId == null) {
return;
}
const graphNode = scene.graph.nodeFromId(nodeId);
if (!graphNode) {
return;
}
const node = isFunction(graphNode.context) ? graphNode : null;
if (!node) {
return;
}
if (node.context() != NodeContext.SOP) {
return;
}
if (node.type() != SopType.CLOTH_SOLVER) {
return;
}
return node;
}