UNPKG

@polygonjs/polygonjs

Version:

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

79 lines (78 loc) 2.62 kB
"use strict"; import { Vector3 } from "three"; import { TypedSopNode } from "./_Base"; import { CameraController } from "../../../core/CameraController"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { InputCloneMode } from "../../poly/InputCloneMode"; import { CAMERA_TYPES, NodeContext } from "../../poly/NodeContext"; const UV_NAME = "uv"; const _position = new Vector3(); const _points = []; class UvProjectSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param camera node to use as projection */ this.camera = ParamConfig.NODE_PATH("", { nodeSelection: { context: NodeContext.OBJ, types: CAMERA_TYPES } }); } // 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 { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; this._cameraController = new CameraController(this._updateUVsFromCamera.bind(this)); } static type() { return "uvProject"; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE); } cook(core_groups) { this._processed_core_group = core_groups[0]; const cameraNode = this.pv.camera.nodeWithContext(NodeContext.OBJ, this.states.error); if (cameraNode != null && CAMERA_TYPES.includes(cameraNode.type())) { this._camera_object = cameraNode.object; this._cameraController.setTarget(this._camera_object); } else { this._camera_object = void 0; this._cameraController.removeTarget(); } this.setCoreGroup(this._processed_core_group); } _updateUVsFromCamera(look_at_target) { const parent = this.parent(); if (this._processed_core_group && parent) { this._processed_core_group.points(_points); const obj_world_matrix = parent.object.matrixWorld; for (const point of _points) { point.position(_position); const uvw = this._vectorInCameraSpace(_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); } } } } _vectorInCameraSpace(vector, obj_world_matrix) { if (this._camera_object) { vector.applyMatrix4(obj_world_matrix); return vector.project(this._camera_object).toArray(); } } }