UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

200 lines (199 loc) 6.85 kB
"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; }