UNPKG

@polygonjs/polygonjs

Version:

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

84 lines (83 loc) 2.82 kB
"use strict"; import { TypedCopNode } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { NodeContext } from "../../poly/NodeContext"; import { CoreMask } from "../../../core/geometry/Mask"; import { textureFromAttributes, textureFromAttributesTotalAttribSizes } from "../../../core/geometry/operation/TextureFromAttribute"; import { CoreAttribute } from "../../../core/geometry/Attribute"; import { corePointClassFactory } from "../../../core/geometry/CoreObjectFactory"; class GeometryAttributeCopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param sop node */ this.node = ParamConfig.NODE_PATH("", { nodeSelection: { context: NodeContext.SOP } }); /** @param group to read the material from */ this.group = ParamConfig.STRING("", { objectMask: true }); /** @param attribute name */ this.attribute = ParamConfig.STRING("P"); } } const ParamsConfig = new GeometryAttributeCopParamsConfig(); export class GeometryAttributeCopNode extends TypedCopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return "geometryAttribute"; } async cook() { const geometryNode = this.pv.node.nodeWithContext(NodeContext.SOP, this.states.error); if (!geometryNode) { this.states.error.set(`node not found at path '${this.pv.node.path()}'`); return; } const container = await geometryNode.compute(); const coreGroup = container.coreContent(); if (!coreGroup) { this.states.error.set(`geometry invalid`); return; } const selectedObjects = CoreMask.filterThreejsObjects(coreGroup, this.pv); if (selectedObjects.length == 0) { this.states.error.set(`no object matching group`); return; } let texture; for (const selectedObject of selectedObjects) { const geometry = selectedObject.geometry; if (geometry) { texture = texture || this._textureFromGeometry(selectedObject); } } if (!texture) { this.cookController.endCook(); return; } this.setTexture(texture); } _textureFromGeometry(object) { const corePointClass = corePointClassFactory(object); const geoAttribNames = corePointClass.attributeNames(object); const attribNames = CoreAttribute.attribNamesMatchingMask(this.pv.attribute, geoAttribNames); const geometry = object.geometry; if (!geometry) { return; } const totalSize = textureFromAttributesTotalAttribSizes(geometry, attribNames); if (totalSize > 4) { this.states.error.set(`total size of attributes is ${totalSize}, but maximum is 4`); return; } return textureFromAttributes(geometry, attribNames); } }