UNPKG

@polygonjs/polygonjs

Version:

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

174 lines (173 loc) 6.24 kB
"use strict"; import { TypedSopNode } from "./_Base"; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { SopType } from "../../poly/registers/nodes/types/Sop"; import { InputCloneMode } from "../../poly/InputCloneMode"; import { CoreWFCTileAttribute } from "../../../core/wfc/WFCAttributes"; import { filterObjectsFromCoreGroup } from "../../../core/geometry/Mask"; import { BufferGeometry, Vector3, Float32BufferAttribute } from "three"; import { CoreGeometryBuilderMerge } from "../../../core/geometry/modules/three/builders/Merge"; import { ObjectType } from "../../../core/geometry/Constant"; import { BaseSopOperation } from "../../operations/sop/_Base"; import { rotateGeometry } from "../../../core/Transform"; import { Attribute } from "../../../core/geometry/Attribute"; const DEFAULT_UP = new Vector3(0, 1, 0); const SOUTH_DIR = new Vector3(-1, 0, 0); const NORTH_DIR = new Vector3(1, 0, 0); const WEST_DIR = new Vector3(0, 0, -1); const EAST_DIR = new Vector3(0, 0, 1); const BOTTOM_DIR = new Vector3(0, -1, 0); const TOP_DIR = new Vector3(0, 1, 0); const _tmp = new Vector3(); class WFCTileSideNameSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param group to assign the material to */ this.group = ParamConfig.STRING("", { objectMask: true }); this.sameNameForSelectedSides = ParamConfig.BOOLEAN(1); /** @param south side */ this.south = ParamConfig.BOOLEAN(0); this.southName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, south: 1 } }); /** @param north side */ this.north = ParamConfig.BOOLEAN(0); this.northName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, north: 1 } }); /** @param west side */ this.west = ParamConfig.BOOLEAN(0); this.westName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, west: 1 } }); /** @param east side */ this.east = ParamConfig.BOOLEAN(0); this.eastName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, east: 1 } }); /** @param bottom side */ this.bottom = ParamConfig.BOOLEAN(0); this.bottomName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, bottom: 1 } }); /** @param top side */ this.top = ParamConfig.BOOLEAN(0); this.topName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 0, top: 1 } }); /** @param allowedRotationY */ this.sideName = ParamConfig.STRING("", { visibleIf: { sameNameForSelectedSides: 1 } }); /** @param highlight */ this.highlight = ParamConfig.BOOLEAN(false); } } const ParamsConfig = new WFCTileSideNameSopParamsConfig(); export class WFCTileSideNameSopNode extends TypedSopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return SopType.WFC_TILE_SIDE_NAME; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE); } async cook(inputCoreGroups) { const coreGroup = inputCoreGroups[0]; const objects = filterObjectsFromCoreGroup(coreGroup, this.pv); const { sameNameForSelectedSides, south, north, west, east, bottom, top } = this.pv; if (sameNameForSelectedSides == true) { const sideName = this.pv.sideName; for (const object of objects) { if (south) { CoreWFCTileAttribute.setSideName(object, "s", sideName); } if (north) { CoreWFCTileAttribute.setSideName(object, "n", sideName); } if (west) { CoreWFCTileAttribute.setSideName(object, "w", sideName); } if (east) { CoreWFCTileAttribute.setSideName(object, "e", sideName); } if (bottom) { CoreWFCTileAttribute.setSideName(object, "b", sideName); } if (top) { CoreWFCTileAttribute.setSideName(object, "t", sideName); } } } else { for (const object of objects) { if (south) { CoreWFCTileAttribute.setSideName(object, "s", this.pv.southName); } if (north) { CoreWFCTileAttribute.setSideName(object, "n", this.pv.northName); } if (west) { CoreWFCTileAttribute.setSideName(object, "w", this.pv.westName); } if (east) { CoreWFCTileAttribute.setSideName(object, "e", this.pv.eastName); } if (bottom) { CoreWFCTileAttribute.setSideName(object, "b", this.pv.bottomName); } if (top) { CoreWFCTileAttribute.setSideName(object, "t", this.pv.topName); } } } if (this.pv.highlight) { const geometries = []; if (south) { geometries.push(this._createHighlightPlane(SOUTH_DIR)); } if (north) { geometries.push(this._createHighlightPlane(NORTH_DIR)); } if (west) { geometries.push(this._createHighlightPlane(WEST_DIR)); } if (east) { geometries.push(this._createHighlightPlane(EAST_DIR)); } if (bottom) { geometries.push(this._createHighlightPlane(BOTTOM_DIR)); } if (top) { geometries.push(this._createHighlightPlane(TOP_DIR)); } const mergedGeometry = CoreGeometryBuilderMerge.merge(geometries); if (mergedGeometry) { const mergedObject = BaseSopOperation.createObject(mergedGeometry, ObjectType.LINE_SEGMENTS); objects.push(mergedObject); } } this.setObjects(objects); } _createHighlightPlane(dir) { const geometry = new BufferGeometry(); const positions = []; positions.push(-0.45, 0, -0.45); positions.push(0.45, 0, -0.45); positions.push(0.45, 0, 0.45); positions.push(-0.45, 0, 0.45); const indices = []; indices.push(0, 1, 1, 2, 2, 3, 3, 0); geometry.setAttribute(Attribute.POSITION, new Float32BufferAttribute(positions, 3)); geometry.setIndex(indices); rotateGeometry(geometry, DEFAULT_UP, dir); _tmp.copy(dir).multiplyScalar(0.55); geometry.translate(_tmp.x, _tmp.y, _tmp.z); return geometry; } }