UNPKG

polygonjs-engine

Version:

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

106 lines (94 loc) 3.31 kB
/** * Creates or update uv attribute. * * */ import {Camera} from 'three/src/cameras/Camera'; import {Object3D} from 'three/src/core/Object3D'; import {Matrix4} from 'three/src/math/Matrix4'; import {Vector3} from 'three/src/math/Vector3'; import {TypedSopNode} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; import {CameraController} from '../../../core/CameraController'; import {BaseCameraObjNodeType} from '../obj/_BaseCamera'; // const MODE = []; const UV_NAME = 'uv'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {NodeContext} from '../../poly/NodeContext'; import {BaseObjNodeType} from '../obj/_Base'; class UvProjectSopParamsConfig extends NodeParamsConfig { /** @param camera node to use as projection */ camera = ParamConfig.OPERATOR_PATH('/perspective_camera1', { nodeSelection: { context: NodeContext.OBJ, }, }); // force_aspect = ParamConfig.BOOLEAN(0) // aspect = ParamConfig.FLOAT(1, { // range: [0, 2], // visibleIf: {force_aspect: 1}, // }) } const ParamsConfig = new UvProjectSopParamsConfig(); export class UvProjectSopNode extends TypedSopNode<UvProjectSopParamsConfig> { params_config = ParamsConfig; static type() { return 'uvProject'; } private _camera_controller: CameraController = new CameraController(this._update_uvs_from_camera.bind(this)); // private _param_camera: string private _processed_core_group: CoreGroup | undefined; // private _camera_node: BaseCameraObjNodeType | undefined; private _camera_object: Camera | undefined; initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE); } cook(core_groups: CoreGroup[]) { this._processed_core_group = core_groups[0]; const camera_node = this.p.camera.found_node(); if (camera_node != null) { this._camera_object = (camera_node as BaseCameraObjNodeType).object; this._camera_controller.set_target(this._camera_object); // this._add_camera_event() } else { this._camera_object = undefined; //this._remove_camera_event() this._camera_controller.remove_target(); } this.setCoreGroup(this._processed_core_group); } _update_uvs_from_camera(look_at_target: Object3D) { // let old_aspect; // if (this.pv.force_aspect) { // old_aspect = this._camera_object.aspect; // this._camera_node.setup_for_aspect_ratio(this.pv.aspect); // } const parent = this.parent(); if (this._processed_core_group && parent) { const points = this._processed_core_group.points(); const obj_world_matrix = (parent as BaseObjNodeType).object.matrixWorld; points.forEach((point) => { const position = point.position(); const uvw = this._vector_in_camera_space(position, obj_world_matrix); if (uvw) { const uv = { x: 1 - (uvw[0] * 0.5 + 0.5), y: uvw[1] * 0.5 + 0.5, }; point.setAttribValue(UV_NAME, uv); } }); // if (this.pv.force_aspect) { // this._camera_node.setup_for_aspect_ratio(old_aspect); // } } } private _vector_in_camera_space(vector: Vector3, obj_world_matrix: Matrix4) { if (this._camera_object) { vector.applyMatrix4(obj_world_matrix); return vector.project(this._camera_object).toArray(); } } }