polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
103 lines (102 loc) • 3.2 kB
JavaScript
import {TypedSopNode} from "./_Base";
import {LOD as LOD2} from "three/src/objects/LOD";
import {InputCloneMode as InputCloneMode2} from "../../poly/InputCloneMode";
import {CameraNodeType, NodeContext as NodeContext2} from "../../poly/NodeContext";
import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig";
import {CoreTransform} from "../../../core/Transform";
class LODSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
this.distance0 = ParamConfig.FLOAT(1);
this.distance1 = ParamConfig.FLOAT(2);
this.autoUpdate = ParamConfig.BOOLEAN(1);
this.update = ParamConfig.BUTTON(null, {
callback: (node) => {
LodSopNode.PARAM_CALLBACK_update(node);
}
});
this.camera = ParamConfig.OPERATOR_PATH("/perspective_camera1", {
visibleIf: {autoUpdate: 0},
dependentOnFoundNode: false
});
}
}
const ParamsConfig2 = new LODSopParamsConfig();
export class LodSopNode extends TypedSopNode {
constructor() {
super(...arguments);
this.params_config = ParamsConfig2;
this._lod = this._create_LOD();
}
static type() {
return "lod";
}
static displayedInputNames() {
return ["high res", "mid res", "low res"];
}
initializeNode() {
this.io.inputs.setCount(1, 3);
this.io.inputs.initInputsClonedState(InputCloneMode2.FROM_NODE);
}
_create_LOD() {
const lod = new LOD2();
lod.matrixAutoUpdate = false;
return lod;
}
cook(input_contents) {
this._clear_lod();
this._add_level(input_contents[0], 0);
this._add_level(input_contents[1], this.pv.distance0);
this._add_level(input_contents[2], this.pv.distance1);
this._lod.autoUpdate = this.pv.autoUpdate;
this.setObject(this._lod);
}
_add_level(core_group, level) {
if (core_group) {
const objects = core_group.objects();
let object;
for (let i = 0; i < objects.length; i++) {
object = objects[i];
object.visible = true;
this._lod.addLevel(object, level);
if (level == 0) {
if (i == 0) {
this._lod.matrix.copy(object.matrix);
CoreTransform.decompose_matrix(this._lod);
}
}
object.matrix.identity();
CoreTransform.decompose_matrix(object);
}
}
}
_clear_lod() {
let child;
while (child = this._lod.children[0]) {
this._lod.remove(child);
child.matrix.multiply(this._lod.matrix);
CoreTransform.decompose_matrix(child);
}
while (this._lod.levels.pop()) {
}
}
static PARAM_CALLBACK_update(node) {
node._update_lod();
}
async _update_lod() {
if (this.p.autoUpdate) {
return;
}
const camera_param = this.p.camera;
if (camera_param.isDirty()) {
await camera_param.compute();
}
let camera_node = camera_param.found_node_with_context_and_type(NodeContext2.OBJ, CameraNodeType.PERSPECTIVE) || camera_param.found_node_with_context_and_type(NodeContext2.OBJ, CameraNodeType.ORTHOGRAPHIC);
if (camera_node) {
const object = camera_node.object;
this._lod.update(object);
} else {
this.states.error.set("no camera node found");
}
}
}