UNPKG

@polygonjs/polygonjs

Version:

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

117 lines (116 loc) 3.67 kB
"use strict"; import { BaseController } from "./_BaseController"; import { ParamConfig } from "../../utils/params/ParamsConfig"; import { NodeContext } from "../../../poly/NodeContext"; import { Poly } from "../../../Poly"; export function TextureMapParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); this.useMap = ParamConfig.BOOLEAN(0); this.map = ParamConfig.NODE_PATH("", { visibleIf: { useMap: 1 } }); } }; } export function BooleanParamOptions(controller_class) { return { cook: false, callback: (node, param) => { controller_class.update(node); } }; } export function NodePathOptions(controller, use_map_name, options) { return { visibleIf: { [use_map_name]: 1 }, nodeSelection: { context: NodeContext.COP, types: options == null ? void 0 : options.types }, cook: false, callback: (node, param) => { controller.update(node); } }; } const CALLBACK_NAME = "TextureController"; export class BaseTextureMapController extends BaseController { constructor(node) { super(node); this.node = node; this.updateBound = this.update.bind(this); } add_hooks(use_map_param, path_param) { use_map_param.addPostDirtyHook(CALLBACK_NAME, this.updateBound); path_param.addPostDirtyHook(CALLBACK_NAME, this.updateBound); } static async update(node) { } async update() { } async _update(material, mat_attrib_name, use_map_param, path_param) { const mat = material; const attr_name = mat_attrib_name; await this._update_texture_on_material(mat, attr_name, use_map_param, path_param); } // // // FOR CASES WHERE THE TEXTURE IS ON THE MATERIAL // // async _update_texture_on_material(material, mat_attrib_name, use_map_param, path_param) { await this._update_required_attribute( material, material, mat_attrib_name, use_map_param, path_param, this._apply_texture_on_material.bind(this), this._remove_texture_from_material.bind(this) ); } _apply_texture_on_material(material, texture_owner, mat_attrib_name, newTexture) { const currentTexture = texture_owner[mat_attrib_name]; let textureChangeRequired = false; if (currentTexture) { if (currentTexture.uuid != newTexture.uuid) { textureChangeRequired = true; } } if (currentTexture == null || textureChangeRequired) { texture_owner[mat_attrib_name] = newTexture; material.needsUpdate = true; } Poly.onSceneUpdatedHooks.runHooks(); } _remove_texture_from_material(material, texture_owner, mat_attrib_name) { if (texture_owner[mat_attrib_name]) { texture_owner[mat_attrib_name] = null; material.needsUpdate = true; } Poly.onSceneUpdatedHooks.runHooks(); } // // // MAIN ALGO to decide if texture should be updated // // async _update_required_attribute(material, texture_owner, mat_attrib_name, use_map_param, path_param, update_callback, remove_callback) { if (use_map_param.isDirty()) { await use_map_param.compute(); } const use_map = use_map_param.value; if (use_map) { if (path_param.isDirty()) { await path_param.compute(); } const texture_node = path_param.value.nodeWithContext(NodeContext.COP); if (texture_node) { const container = await texture_node.compute(); const texture = container.texture(); if (texture) { await update_callback(material, texture_owner, mat_attrib_name, texture); return; } } } remove_callback(material, texture_owner, mat_attrib_name); } }