@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
79 lines (78 loc) • 2.62 kB
JavaScript
"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();
}
}
}