UNPKG

@polygonjs/polygonjs

Version:

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

116 lines (107 loc) 4.12 kB
import {BaseSopOperation} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; import {MathUtils, Object3D, PerspectiveCamera, Vector3} from 'three'; import {InputCloneMode} from '../../../engine/poly/InputCloneMode'; import {DefaultOperationParams} from '../../../core/operations/_Base'; import {CameraNodeType} from '../../poly/NodeContext'; import {PERSPECTIVE_CAMERA_DEFAULT, registerPerspectiveCamera} from '../../../core/camera/CorePerspectiveCamera'; import {CameraAttribute, CORE_CAMERA_DEFAULT, PerspectiveCameraAttribute} from '../../../core/camera/CoreCamera'; import {isBooleanTrue} from '../../../core/Type'; import {CameraHelper} from '../../../core/helpers/CameraHelper'; import {ThreejsCoreObject} from '../../../core/geometry/modules/three/ThreejsCoreObject'; import type {BaseNodeType} from '../../nodes/_Base'; import {CoreSceneObjectsFactory, GeneratorName} from '../../../core/CoreSceneObjectsFactory'; interface CreatePerspectiveCameraParams { fov: number; near: number; far: number; } interface PerspectiveCameraSopParams extends CreatePerspectiveCameraParams, DefaultOperationParams { position: Vector3; rotation: Vector3; showHelper: boolean; matrixAutoUpdate: boolean; name: string; // PBR apertureBlades: number; fStop: number; focusDistance: number; apertureRotation: number; anamorphicRatio: number; } interface AttributeOptions { fov: number; } export class PerspectiveCameraSopOperation extends BaseSopOperation { static override readonly DEFAULT_PARAMS: PerspectiveCameraSopParams = { fov: PERSPECTIVE_CAMERA_DEFAULT.fov, near: CORE_CAMERA_DEFAULT.near, far: CORE_CAMERA_DEFAULT.far, position: new Vector3(0, 0, 0), rotation: new Vector3(0, 0, 0), showHelper: false, matrixAutoUpdate: true, name: CameraNodeType.PERSPECTIVE, // PBR apertureBlades: 6, fStop: 0.6, focusDistance: 10, apertureRotation: 0, anamorphicRatio: 1, }; static override readonly INPUT_CLONED_STATE = InputCloneMode.NEVER; static override type(): Readonly<CameraNodeType.PERSPECTIVE> { return CameraNodeType.PERSPECTIVE; } static override onRegister = registerPerspectiveCamera; override cook(inputCoreGroups: CoreGroup[], params: PerspectiveCameraSopParams) { const camera = PerspectiveCameraSopOperation.createCamera(params, this._node); camera.name = params.name || CameraNodeType.PERSPECTIVE; camera.position.copy(params.position); camera.rotation.set( MathUtils.degToRad(params.rotation.x), MathUtils.degToRad(params.rotation.y), MathUtils.degToRad(params.rotation.z) ); // this needs to be .updateWorldMatrix and not .updateMatrix // as otherwise the camera appears to behave find in most cases, // except when using the sop/cameraRenderScene camera.updateWorldMatrix(false, false); camera.updateProjectionMatrix(); camera.matrixAutoUpdate = params.matrixAutoUpdate; PerspectiveCameraSopOperation.setCameraAttributes(camera, params); const pbrUpdateFunc = CoreSceneObjectsFactory.generator(GeneratorName.PERSPECTIVE_CAMERA_UPDATE); pbrUpdateFunc({ camera, params: { apertureBlades: params.apertureBlades, fStop: params.fStop, focusDistance: params.focusDistance, apertureRotation: params.apertureRotation, anamorphicRatio: params.anamorphicRatio, }, }); const objects: Object3D[] = [camera]; if (isBooleanTrue(params.showHelper)) { const helper = new CameraHelper(camera); helper.update(); camera.add(helper); } return this.createCoreGroupFromObjects(objects); } static createCamera(params: CreatePerspectiveCameraParams, nodeGenerator?: BaseNodeType) { const camera = CoreSceneObjectsFactory.generator(GeneratorName.PERSPECTIVE_CAMERA)({ fov: params.fov, aspect: 1, near: params.near, far: params.far, }); if (nodeGenerator) { ThreejsCoreObject.addAttribute(camera, CameraAttribute.NODE_ID, nodeGenerator.graphNodeId()); } return camera; } static setCameraAttributes(camera: PerspectiveCamera, options: AttributeOptions) { ThreejsCoreObject.addAttribute(camera, PerspectiveCameraAttribute.FOV, options.fov); } }