@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
252 lines (251 loc) • 9.34 kB
JavaScript
"use strict";
import { PolyEventName } from "./../../poly/utils/PolyEventName";
import { EventConnectionPoint, EventConnectionPointType } from "../utils/io/connections/Event";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { CoreGraphNode } from "../../../core/graph/CoreGraphNode";
import { TypedEventNode } from "./_Base";
import { isBooleanTrue } from "../../../core/Type";
var SceneNodeInput = /* @__PURE__ */ ((SceneNodeInput2) => {
SceneNodeInput2["SET_FRAME"] = "setFrame";
return SceneNodeInput2;
})(SceneNodeInput || {});
var SceneNodeOutput = /* @__PURE__ */ ((SceneNodeOutput2) => {
SceneNodeOutput2["TICK"] = "tick";
SceneNodeOutput2["TIME_REACHED"] = "timeReached";
return SceneNodeOutput2;
})(SceneNodeOutput || {});
const UPDATE_SCENE_EVENT_PARAM_OPTIONS = {
visibleIf: { active: 1 },
callback: (node) => {
SceneEventNode.PARAM_CALLBACK_updateSceneEventsController(node);
}
};
const UPDATE_TIME_DEPENDENCY_PARAM_OPTIONS = {
visibleIf: { active: 1 },
callback: (node) => {
SceneEventNode.PARAM_CALLBACK_updateTimeDependency(node);
}
};
var EventName = /* @__PURE__ */ ((EventName2) => {
EventName2["CREATED"] = "created";
EventName2["READY"] = "ready";
EventName2["PLAY"] = "play";
EventName2["PAUSE"] = "pause";
return EventName2;
})(EventName || {});
export const ACCEPTED_EVENT_TYPES = ["created" /* CREATED */, "ready" /* READY */, "play" /* PLAY */, "pause" /* PAUSE */];
class SceneEventParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @param toggle on to allow any event to be listened to */
this.active = ParamConfig.BOOLEAN(true, {
callback: (node, param) => {
SceneEventNode.PARAM_CALLBACK_updateActiveState(node);
},
separatorAfter: true
});
/** @param set which element triggers the event */
this.element = ParamConfig.INTEGER(0, {
hidden: true
});
/** @param toggle on to trigger an event when the scene has been created. This can be useful to initialize other nodes */
this.created = ParamConfig.BOOLEAN(1, UPDATE_SCENE_EVENT_PARAM_OPTIONS);
/** @param toggle on to trigger an event when every object in the scene has been loaded. This can be useful to initialize other nodes */
this.ready = ParamConfig.BOOLEAN(1, UPDATE_SCENE_EVENT_PARAM_OPTIONS);
/** @param toggle on to trigger an event when the scene starts playing */
this.play = ParamConfig.BOOLEAN(1, UPDATE_SCENE_EVENT_PARAM_OPTIONS);
/** @param toggle on to trigger an event when the scene pauses */
this.pause = ParamConfig.BOOLEAN(1, UPDATE_SCENE_EVENT_PARAM_OPTIONS);
/** @param toggle on to trigger an event on every tick */
this.tick = ParamConfig.BOOLEAN(1, {
separatorAfter: true,
...UPDATE_TIME_DEPENDENCY_PARAM_OPTIONS
});
/** @param toggle on to trigger an event on every tick */
this.treachedTime = ParamConfig.BOOLEAN(0, UPDATE_TIME_DEPENDENCY_PARAM_OPTIONS);
/** @param time to trigger an event */
this.reachedTime = ParamConfig.FLOAT(10, {
visibleIf: { treachedTime: 1 },
range: [0, 100],
separatorAfter: true,
...UPDATE_TIME_DEPENDENCY_PARAM_OPTIONS
});
/** @param frame to set */
this.setFrameValue = ParamConfig.INTEGER(1, {
range: [0, 100]
});
/** @param button to set a specific frame */
this.setFrame = ParamConfig.BUTTON(null, {
callback: (node) => {
SceneEventNode.PARAM_CALLBACK_setFrame(node);
}
});
}
}
const ParamsConfig = new SceneEventParamsConfig();
export class SceneEventNode extends TypedEventNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this._timeReached = false;
}
static type() {
return "scene";
}
dispose() {
var _a;
(_a = this._graphNode) == null ? void 0 : _a.dispose();
super.dispose();
}
initializeNode() {
this.io.inputs.setNamedInputConnectionPoints([
new EventConnectionPoint(
"setFrame" /* SET_FRAME */,
EventConnectionPointType.BASE,
this._onSetFrame.bind(this)
),
new EventConnectionPoint("play" /* PLAY */, EventConnectionPointType.BASE, this._play.bind(this)),
new EventConnectionPoint("pause" /* PAUSE */, EventConnectionPointType.BASE, this._pause.bind(this))
]);
const outConnectionPoints = ACCEPTED_EVENT_TYPES.map((event_type) => {
return new EventConnectionPoint(event_type, EventConnectionPointType.BASE);
});
outConnectionPoints.push(new EventConnectionPoint("tick" /* TICK */, EventConnectionPointType.BASE));
outConnectionPoints.push(new EventConnectionPoint("timeReached" /* TIME_REACHED */, EventConnectionPointType.BASE));
this.io.outputs.setNamedOutputConnectionPoints(outConnectionPoints);
this.params.onParamsCreated("updateTimeDependency", () => {
this._updateTimeDependency();
});
this._updateSceneEventsController();
const register = () => {
this._updateSceneEventsController();
};
const unregister = () => {
const eventsController = this.scene().eventsDispatcher.sceneEventsController;
eventsController.removeObserverFromAllEventTypes(this);
};
this.lifecycle.onAfterAdded(register);
this.lifecycle.onBeforeDeleted(unregister);
}
processEvent(eventContext) {
if (!this.pv.active) {
return;
}
if (!eventContext.event) {
return;
}
const eventType = eventContext.event.type;
switch (eventType) {
case PolyEventName.SCENE_CREATED: {
return this.dispatchEventToOutput("created" /* CREATED */, eventContext);
}
case PolyEventName.SCENE_READY: {
return this.dispatchEventToOutput("ready" /* READY */, eventContext);
}
case PolyEventName.SCENE_PLAY: {
return this.dispatchEventToOutput("play" /* PLAY */, eventContext);
}
case PolyEventName.SCENE_PAUSE: {
return this.dispatchEventToOutput("pause" /* PAUSE */, eventContext);
}
}
this.dispatchEventToOutput(eventContext.event.type, eventContext);
}
_onSetFrame(eventContext) {
this.scene().setFrame(this.pv.setFrameValue);
}
_play(eventContext) {
this.scene().play();
}
_pause(eventContext) {
this.scene().pause();
}
_onTickCheckTimeReached(time, reachedTime) {
if (time >= this.pv.reachedTime) {
if (!this._timeReached) {
this._timeReached = true;
this.dispatchEventToOutput("timeReached" /* TIME_REACHED */, {});
}
} else {
this._timeReached = false;
}
}
_onTickEvent() {
this.dispatchEventToOutput("tick" /* TICK */, {});
}
_updateTimeDependency() {
var _a, _b;
const timeGraphNode = this.scene().timeController.graphNode;
(_a = this._graphNode) == null ? void 0 : _a.removeGraphInput(timeGraphNode);
if (!isBooleanTrue(this.pv.active)) {
return;
}
if (isBooleanTrue(this.pv.treachedTime) || isBooleanTrue(this.pv.tick)) {
this._graphNode = this._graphNode || new CoreGraphNode(this.scene(), "sceneNodeTimeGraphNode");
this._graphNode.addGraphInput(timeGraphNode);
const options = {
tick: this.pv.tick,
treachedTime: this.pv.treachedTime,
reachedTime: this.pv.reachedTime
};
const callback = (_b = this._buildOnTickCallback(options)) == null ? void 0 : _b.bind(this);
if (callback) {
const callbackName = "timeUpdate";
this._graphNode.removePostDirtyHook(callbackName);
this._graphNode.addPostDirtyHook(callbackName, callback);
}
}
}
_buildOnTickCallback(options) {
if (isBooleanTrue(options.treachedTime) && isBooleanTrue(options.tick)) {
return () => {
const time = this.scene().time();
this._onTickEvent();
this._onTickCheckTimeReached(time, options.reachedTime);
};
} else {
if (isBooleanTrue(options.treachedTime)) {
return () => {
const time = this.scene().time();
this._onTickCheckTimeReached(time, options.reachedTime);
};
}
if (isBooleanTrue(options.tick)) {
return this._onTickEvent.bind(this);
}
}
}
static PARAM_CALLBACK_setFrame(node) {
node._onSetFrame({});
}
static PARAM_CALLBACK_updateTimeDependency(node) {
node._updateTimeDependency();
}
static PARAM_CALLBACK_updateSceneEventsController(node) {
node._updateSceneEventsController();
}
static PARAM_CALLBACK_updateActiveState(node) {
node._updateTimeDependency();
node._updateSceneEventsController();
}
_updateSceneEventsController() {
const eventsController = this.scene().eventsDispatcher.sceneEventsController;
eventsController.removeObserverFromAllEventTypes(this);
if (!this.pv.active) {
return;
}
this._updateTimeDependency();
if (isBooleanTrue(this.pv.created)) {
eventsController.addObserver(this, PolyEventName.SCENE_CREATED);
}
if (isBooleanTrue(this.pv.ready)) {
eventsController.addObserver(this, PolyEventName.SCENE_READY);
}
if (isBooleanTrue(this.pv.play)) {
eventsController.addObserver(this, PolyEventName.SCENE_PLAY);
}
if (isBooleanTrue(this.pv.pause)) {
eventsController.addObserver(this, PolyEventName.SCENE_PAUSE);
}
}
}