@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
145 lines (144 loc) • 5.05 kB
JavaScript
;
import { Poly } from "../Poly";
import { updateObjectChildrenCountRef } from "../../core/reactivity/ObjectHierarchyReactivity";
import { ON_OBJECT_BEFORE_DELETE } from "../../core/geometry/Event";
import { deregisterGeneratorsForObject } from "../nodes/js/code/assemblers/actor/ActorEvaluatorGenerator";
var HandlerName = /* @__PURE__ */ ((HandlerName2) => {
HandlerName2["ADD"] = "onObjectAddHookHandlerNodeIds";
HandlerName2["REMOVE"] = "onObjectRemoveHookHandlerNodeIds";
return HandlerName2;
})(HandlerName || {});
function assignHookHandler(object, node, handlerName) {
let ids = hookHandlers(object, handlerName);
if (!ids) {
ids = [];
object.userData[handlerName] = ids;
}
const id = node.graphNodeId();
if (!ids.includes(id)) {
ids.push(id);
}
}
const onAddRemoveCallbackByObject = /* @__PURE__ */ new WeakMap();
function assignOnAddRemoveHook(object, handlerName, hook) {
let mapForObject = onAddRemoveCallbackByObject.get(object);
if (!mapForObject) {
mapForObject = /* @__PURE__ */ new Map();
onAddRemoveCallbackByObject.set(object, mapForObject);
}
let callbacksForHandlerName = mapForObject.get(handlerName);
if (!callbacksForHandlerName) {
callbacksForHandlerName = /* @__PURE__ */ new Set();
mapForObject.set(handlerName, callbacksForHandlerName);
}
callbacksForHandlerName.add(hook);
}
function runOnAddRemoveHooks(object, handlerName) {
const mapForObject = onAddRemoveCallbackByObject.get(object);
if (!mapForObject) {
return;
}
const callbacksForHandlerName = mapForObject.get(handlerName);
if (!callbacksForHandlerName) {
return;
}
for (const callback of callbacksForHandlerName) {
callback(object);
}
}
function hookHandlers(object, handlerName) {
return object.userData[handlerName];
}
function runHooks(scene, parent, handlerName) {
const children = parent.children;
for (const child of children) {
child.traverse((grandChild) => {
runHookOnObject(grandChild, scene, handlerName);
});
}
}
function runHookOnObject(object, scene, handlerName) {
runOnAddRemoveHooks(object, handlerName);
if (object.parent) {
const ids = hookHandlers(object, handlerName);
if (!ids) {
return;
}
for (const id of ids) {
const node = scene.graph.nodeFromId(id);
if (node && !node.disposed()) {
switch (handlerName) {
case "onObjectAddHookHandlerNodeIds" /* ADD */: {
node.updateObjectOnAdd(object, object.parent);
break;
}
case "onObjectRemoveHookHandlerNodeIds" /* REMOVE */: {
node.updateObjectOnRemove(object, object.parent);
break;
}
}
}
}
}
}
export function replaceChild(parent, oldObject, newObject) {
const index = parent.children.indexOf(oldObject);
if (index < 0) {
console.warn("could not find object to replace");
return;
}
parent.children[index] = newObject;
newObject.parent = parent;
}
export function removeFromParent(scene, object) {
const parent = object.parent;
if (!parent) {
return;
}
object.dispatchEvent(ON_OBJECT_BEFORE_DELETE);
deregisterGeneratorsForObject(object);
Poly.onObjectsAddRemoveHooks.runOnRemoveHookOnObject(scene, object);
parent.remove(object);
updateObjectChildrenCountRef(parent);
}
export function addToParent(scene, parent, child) {
parent.add(child);
updateObjectChildrenCountRef(parent);
Poly.onObjectsAddRemoveHooks.runOnAddHookOnObject(scene, child);
}
export function copyBasicObjectProperties(srcObject, destObject) {
destObject.name = srcObject.name;
destObject.matrixAutoUpdate = srcObject.matrixAutoUpdate;
destObject.frustumCulled = srcObject.frustumCulled;
destObject.layers = srcObject.layers;
destObject.position.copy(srcObject.position);
destObject.quaternion.copy(srcObject.quaternion);
destObject.scale.copy(srcObject.scale);
destObject.matrix.copy(srcObject.matrix);
}
export class PolyOnObjectsAddRemoveHooksController {
assignOnAddHookHandler(object, node) {
assignHookHandler(object, node, "onObjectAddHookHandlerNodeIds" /* ADD */);
}
assignOnRemoveHookHandler(object, node) {
assignHookHandler(object, node, "onObjectRemoveHookHandlerNodeIds" /* REMOVE */);
}
assignOnAddHookCallback(object, callback) {
assignOnAddRemoveHook(object, "onObjectAddHookHandlerNodeIds" /* ADD */, callback);
}
assignOnRemoveHookCallback(object, callback) {
assignOnAddRemoveHook(object, "onObjectRemoveHookHandlerNodeIds" /* REMOVE */, callback);
}
runOnAddHooks(scene, parent) {
runHooks(scene, parent, "onObjectAddHookHandlerNodeIds" /* ADD */);
}
runOnRemoveHooks(scene, parent) {
runHooks(scene, parent, "onObjectRemoveHookHandlerNodeIds" /* REMOVE */);
}
runOnAddHookOnObject(scene, object) {
runHookOnObject(object, scene, "onObjectAddHookHandlerNodeIds" /* ADD */);
}
runOnRemoveHookOnObject(scene, object) {
runHookOnObject(object, scene, "onObjectRemoveHookHandlerNodeIds" /* REMOVE */);
}
}