@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
331 lines (330 loc) • 10.8 kB
JavaScript
"use strict";
import { CoreTransform } from "../../../core/Transform";
import { ObjNodeRenderOrder } from "./_Base";
import { LayersController, LayerParamConfig } from "./utils/LayersController";
import { CameraRenderParamConfig } from "./utils/cameras/RenderController";
import { TransformedParamConfig, TransformController } from "./utils/TransformController";
import { ObjChildrenDisplayController } from "./utils/ObjChildrenDisplayController";
import { DisplayNodeController } from "../utils/DisplayNodeController";
import { NodeContext } from "../../poly/NodeContext";
import { FlagsControllerD } from "../utils/FlagsController";
import { TypedObjNode } from "./_Base";
import { HierarchyController } from "./utils/HierarchyController";
import { CameraHelper } from "../../../core/helpers/CameraHelper";
import { ParamConfig, NodeParamsConfig } from "../utils/params/ParamsConfig";
import { isBooleanTrue } from "../../../core/BooleanValue";
import { CameraPostProcessParamConfig } from "./utils/cameras/PostProcessParamOptions";
import { Poly } from "../../Poly";
import { CORE_CAMERA_DEFAULT } from "../../../core/camera/CoreCamera";
import { CameraControlsSopOperation } from "../../operations/sop/CameraControls";
import { CameraRendererSopOperation } from "../../operations/sop/CameraRenderer";
import { CameraCSSRendererSopOperation } from "../../operations/sop/CameraCSSRenderer";
import { CameraPostProcessSopOperation } from "../../operations/sop/CameraPostProcess";
import { CameraRenderSceneSopOperation } from "../../operations/sop/CameraRenderScene";
import { CameraFrameModeSopOperation } from "../../operations/sop/CameraFrameMode";
import { CoreCameraFrameParamConfig } from "../../../core/camera/CoreCameraFrameMode";
import { CorePath } from "../../../core/geometry/CorePath";
const EVENT_CHANGE = { type: "change" };
export function CameraMainCameraParamConfig(Base) {
return class Mixin extends Base {
constructor() {
super(...arguments);
this.setMainCamera = ParamConfig.BUTTON(null, {
callback: (node, param) => {
BaseCameraObjNodeClass.PARAM_CALLBACK_setMainCamera(node);
}
});
}
};
}
export function ThreejsCameraTransformParamConfig(Base) {
return class Mixin extends Base {
constructor() {
super(...arguments);
this.camera = ParamConfig.FOLDER();
/** @param controls node to allow the camera to be moved by user input */
this.controls = ParamConfig.NODE_PATH("", {
nodeSelection: {
context: NodeContext.EVENT
},
dependentOnFoundNode: true
});
/** @param near */
this.near = ParamConfig.FLOAT(CORE_CAMERA_DEFAULT.near, {
range: [0.1, 100],
cook: false,
computeOnDirty: true,
callback: (node, param) => {
BaseThreejsCameraObjNodeClass.PARAM_CALLBACK_update_near_far_from_param(
node,
param
);
}
});
/** @param far */
this.far = ParamConfig.FLOAT(CORE_CAMERA_DEFAULT.far, {
range: [0, 100],
cook: false,
computeOnDirty: true,
callback: (node, param) => {
BaseThreejsCameraObjNodeClass.PARAM_CALLBACK_update_near_far_from_param(
node,
param
);
}
});
// aspect = ParamConfig.FLOAT(1);
// lock_width = ParamConfig.BOOLEAN(1);
// look_at = ParamConfig.OPERATOR_PATH('');
/** @param display */
this.display = ParamConfig.BOOLEAN(1);
/** @param show helper */
this.showHelper = ParamConfig.BOOLEAN(0);
}
};
}
export class BaseCameraObjParamsConfig extends CameraMainCameraParamConfig(NodeParamsConfig) {
}
export class BaseThreejsCameraObjParamsConfig extends CameraPostProcessParamConfig(
CameraRenderParamConfig(
CoreCameraFrameParamConfig(
TransformedParamConfig(
LayerParamConfig(ThreejsCameraTransformParamConfig(CameraMainCameraParamConfig(NodeParamsConfig)))
)
)
)
) {
}
export class TypedCameraObjNode extends TypedObjNode {
constructor() {
super(...arguments);
// public readonly flags: FlagsControllerD = new FlagsControllerD(this);
this.renderOrder = ObjNodeRenderOrder.CAMERA;
this._aspect = -1;
}
get object() {
return this._object;
}
async cook() {
this.updateCamera();
this._object.dispatchEvent(EVENT_CHANGE);
this.cookController.endCook();
}
// prepareRaycaster(mouse: Vector2, raycaster: Raycaster) {}
camera() {
return this._object;
}
updateCamera() {
}
static PARAM_CALLBACK_setMainCamera(node) {
node.setAsMainCamera();
}
setAsMainCamera() {
const path = CorePath.objectPath(this.object);
this.scene().camerasController.setMainCameraPath(path);
}
setupForAspectRatio(aspect) {
}
// protected _updateForAspectRatio(): void {}
update_transform_params_from_object() {
CoreTransform.setParamsFromObject(this._object, this);
}
static PARAM_CALLBACK_update_from_param(node, param) {
node.object[param.name()] = node.pv[param.name()];
}
}
export class TypedThreejsCameraObjNode extends TypedCameraObjNode {
constructor() {
super(...arguments);
this.flags = new FlagsControllerD(this);
this.hierarchyController = new HierarchyController(this);
this.transformController = new TransformController(this);
// protected _renderController: RenderController | undefined;
// renderController(): RenderController {
// return (this._renderController = this._renderController || new RenderController(this));
// }
// protected _postProcessController: PostProcessController | undefined;
// postProcessController(): PostProcessController {
// return (this._postProcessController = this._postProcessController || new PostProcessController(this));
// }
// display_node and children_display controllers
this.childrenDisplayController = new ObjChildrenDisplayController(
this
);
this.displayNodeController = new DisplayNodeController(
this,
this.childrenDisplayController.displayNodeControllerCallbacks()
);
//
this._childrenControllerContext = NodeContext.SOP;
}
_layersController() {
return this.__layersController__ = this.__layersController__ || new LayersController(this);
}
initializeBaseNode() {
super.initializeBaseNode();
this.io.outputs.setHasOneOutput();
this.hierarchyController.initializeNode();
this.transformController.initializeNode();
this.childrenDisplayController.initializeNode();
this.initHelperHook();
}
createNode(node_class, options) {
return super.createNode(node_class, options);
}
children() {
return super.children();
}
nodesByType(type) {
return super.nodesByType(type);
}
// override prepareRaycaster(mouse: Vector2, raycaster: Raycaster) {
// raycaster.setFromCamera(mouse, this._object);
// }
async cook() {
this.transformController.update();
this._layersController().update();
this.updateNearFar();
this.updateCamera();
this._updateHelper();
const objects = [this._object];
const node = this;
const hierachyParams = {
group: ""
};
CameraControlsSopOperation.updateObject({
objects,
params: {
node: this.pv.controls,
...hierachyParams
},
node,
active: true,
errorIfNodeNotFound: false
});
CameraRendererSopOperation.updateObject({
objects,
params: {
node: this.pv.renderer,
...hierachyParams
},
node,
active: this.pv.setRenderer
});
CameraCSSRendererSopOperation.updateObject({
objects,
params: {
node: this.pv.CSSRenderer,
...hierachyParams
},
node,
active: this.pv.setCSSRenderer
});
CameraPostProcessSopOperation.updateObject({
objects,
params: {
node: this.pv.postProcessNode,
useOtherNode: false,
...hierachyParams
},
node,
active: this.pv.doPostProcess
});
CameraRenderSceneSopOperation.updateObject({
objects,
params: {
node: this.pv.scene,
...hierachyParams
},
node,
active: this.pv.setScene
});
CameraFrameModeSopOperation.updateObject({
objects,
params: {
frameMode: this.pv.frameMode,
expectedAspectRatio: this.pv.expectedAspectRatio,
...hierachyParams
}
});
this._object.dispatchEvent(EVENT_CHANGE);
this.scene().camerasController.updateFromChangeInObject(this.object);
this.cookController.endCook();
}
static PARAM_CALLBACK_update_near_far_from_param(node, param) {
node.updateNearFar();
}
updateNearFar() {
if (this._object.near != this.pv.near || this._object.far != this.pv.far) {
this._object.near = this.pv.near;
this._object.far = this.pv.far;
this._object.updateProjectionMatrix();
this._updateHelper();
}
}
// override setupForAspectRatio(aspect: number) {
// if (isNaN(aspect)) {
// return;
// }
// if (aspect && this._aspect != aspect) {
// this._aspect = aspect;
// this._updateForAspectRatio();
// }
// }
async createViewer(options) {
if (this.isDirty()) {
await this.compute();
}
const viewer = Poly.camerasRegister.createViewer({ camera: this.object, scene: this.scene() });
let element;
let updateAutoRenderOnIntersectionChange;
if (options && options instanceof HTMLElement) {
element = options;
} else {
element = options == null ? void 0 : options.element;
updateAutoRenderOnIntersectionChange = options == null ? void 0 : options.updateAutoRenderOnIntersectionChange;
}
if (viewer) {
if (element) {
viewer.mount(element, {
updateAutoRenderOnIntersectionChange
});
}
}
return viewer;
}
initHelperHook() {
this.flags.display.onUpdate(() => {
this._updateHelper();
});
}
helperVisible() {
return this.flags.display.active() && isBooleanTrue(this.pv.showHelper);
}
_createHelper() {
const helper = new CameraHelper(this.object);
helper.update();
return helper;
}
_updateHelper() {
if (this.helperVisible()) {
if (!this._helper) {
this._helper = this._createHelper();
}
if (this._helper) {
this.object.add(this._helper);
this._helper.update();
}
} else {
if (this._helper) {
this.object.remove(this._helper);
}
}
}
}
export class BaseCameraObjNodeClass extends TypedCameraObjNode {
}
export class BaseThreejsCameraObjNodeClass extends TypedThreejsCameraObjNode {
PARAM_CALLBACK_update_effects_composer(node) {
}
}