UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

91 lines 3.48 kB
import { DoubleSide, FrontSide } from "three"; import { FrameEvent } from "../../engine/engine_setup.js"; import { $shadowDomOwner } from "./Symbols.js"; export function tryGetUIComponent(obj) { const owner = obj[$shadowDomOwner]; if (owner) { return owner; } if (obj.parent) { return tryGetUIComponent(obj.parent); } return null; } export function isUIObject(obj) { return obj["isUI"] === true || typeof obj[$shadowDomOwner] === "object"; } export function updateRenderSettings(shadowComponent, settings) { if (!shadowComponent) return; // const owner = shadowComponent[$shadowDomOwner]; // if (!owner) // console.log(shadowComponent) const mat = shadowComponent["material"]; if (mat?.isMaterial === true) { const parent = shadowComponent.parent; if (parent && parent["isText"] === true) { // console.log(shadowComponent, shadowComponent.name); } // mat.depthTest = !settings.renderOnTop ?? true; // mat.depthWrite = settings.depthWrite ?? false; mat.side = (settings.doubleSided ?? true) ? DoubleSide : FrontSide; mat.shadowSide = settings.doubleSided ? DoubleSide : FrontSide; shadowComponent.castShadow = settings.castShadows ? settings.castShadows : false; shadowComponent.receiveShadow = settings.receiveShadows ? settings.receiveShadows : false; } for (const ch of shadowComponent.children) { updateRenderSettings(ch, settings); } } // TODO: change to use utils Watch since a revocable proxy makes a object completely useless once it is revoked /** internal method to proxy a field to detect changes */ /**@deprecated use watcher instead */ export function onChange(caller, field, callback) { if (caller[field] === undefined) { console.warn("Field", field, "is undefined on", caller); } // create proxy that notifies on value change const res = Proxy.revocable(caller[field], { // get(target, prop, receiver) { // return Reflect.get(target, prop, receiver); // }, set(target, prop, value, receiver) { const currentValue = target[prop]; const res = Reflect.set(target, prop, value, receiver); callback(value, currentValue); return res; } }); // setup revokeable const revoke = res.revoke; const original = caller[field]; res.revoke = () => { caller[field] = original; revoke(); }; caller[field] = res.proxy; return res; } const $scheduledActionKey = Symbol("Scheduled action"); // use to schedule a callback at a specific moment in the frame /** internal method to schedule a function at a specific moment in the update loop */ export function scheduleAction(caller, action, timing = FrameEvent.OnBeforeRender) { let cache = caller[$scheduledActionKey]; if (!cache) cache = caller[$scheduledActionKey] = {}; const key = action.name; if (!cache[timing]) cache[timing] = {}; const actions = cache[timing]; const existing = actions[key]; if (existing) return; function* gen() { // yield; action?.call(caller); actions[key] = null; } const coroutine = caller.startCoroutine(gen(), timing); actions[key] = coroutine; } //# sourceMappingURL=Utils.js.map