@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
176 lines (175 loc) • 6.79 kB
JavaScript
;
import { Vector3, BufferGeometry, Float32BufferAttribute } from "three";
import { QuadSopNode } from "./_BaseQuad";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { SopType } from "../../poly/registers/nodes/types/Sop";
import { InputCloneMode } from "../../poly/InputCloneMode";
import {
halfEdgeIndicesInCommonBetweenQuads,
pointInCommonBetweenQuadsSharingPoint,
quadGraphFromQuadObject
} from "../../../core/geometry/modules/quad/graph/QuadGraphUtils";
import { QuadPrimitive } from "../../../core/geometry/modules/quad/QuadPrimitive";
import { Attribute } from "../../../core/geometry/Attribute";
import { ObjectType } from "../../../core/geometry/Constant";
import { arrayDifference } from "../../../core/ArrayUtils";
const _neighbourIdsSharingEdge = [];
const _neighbourIdsSharingPoint = [];
const _neighbourIdsSharingPointOnly = [];
const _quadCenter0 = new Vector3();
const _quadCenter1 = new Vector3();
const _p0 = new Vector3();
const _p1 = new Vector3();
const _center = new Vector3();
const _halfEdgeIndices = {
index0: -1,
index1: -1
};
export var QuadConnectionMode = /* @__PURE__ */ ((QuadConnectionMode2) => {
QuadConnectionMode2["NEIGHBOUR_INDEX"] = "neighbourIndex";
QuadConnectionMode2["QUAD_ID"] = "quadId";
return QuadConnectionMode2;
})(QuadConnectionMode || {});
export const QUAD_CONNECTION_MODES = [
"neighbourIndex" /* NEIGHBOUR_INDEX */,
"quadId" /* QUAD_ID */
];
export var QuadConnectionType = /* @__PURE__ */ ((QuadConnectionType2) => {
QuadConnectionType2["STRAIGHT"] = "straight";
QuadConnectionType2["DIAGONAL"] = "diagonal";
return QuadConnectionType2;
})(QuadConnectionType || {});
export const QUAD_CONNECTION_TYPES = ["straight" /* STRAIGHT */, "diagonal" /* DIAGONAL */];
class QuadConnectionSopParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
this.mode = ParamConfig.INTEGER(QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */), {
menu: {
entries: QUAD_CONNECTION_MODES.map((name, value) => ({ name, value }))
}
});
this.type = ParamConfig.INTEGER(QUAD_CONNECTION_TYPES.indexOf("straight" /* STRAIGHT */), {
menu: {
entries: QUAD_CONNECTION_TYPES.map((name, value) => ({ name, value }))
},
visibleIf: {
mode: QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */)
}
});
this.quadId0 = ParamConfig.INTEGER(0, {
range: [0, 100],
rangeLocked: [true, false]
});
this.quadId1 = ParamConfig.INTEGER(0, {
range: [0, 100],
rangeLocked: [true, false],
visibleIf: {
mode: QUAD_CONNECTION_MODES.indexOf("quadId" /* QUAD_ID */)
}
});
this.neighbourIndex = ParamConfig.INTEGER(0, {
range: [0, 4],
rangeLocked: [true, false],
visibleIf: {
mode: QUAD_CONNECTION_MODES.indexOf("neighbourIndex" /* NEIGHBOUR_INDEX */)
}
});
}
}
const ParamsConfig = new QuadConnectionSopParamsConfig();
export class QuadConnectionSopNode extends QuadSopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
}
static type() {
return SopType.QUAD_CONNECTION;
}
initializeNode() {
this.io.inputs.setCount(1);
this.io.inputs.initInputsClonedState(InputCloneMode.NEVER);
}
setConnectionMode(mode) {
this.p.mode.set(QUAD_CONNECTION_MODES.indexOf(mode));
}
connectionMode() {
return QUAD_CONNECTION_MODES[this.pv.mode];
}
setConnectionType(type) {
this.p.type.set(QUAD_CONNECTION_TYPES.indexOf(type));
}
connectionType() {
return QUAD_CONNECTION_TYPES[this.pv.type];
}
async cook(inputCoreGroups) {
const coreGroup = inputCoreGroups[0];
const quadObjects = coreGroup.quadObjects();
const newGeometries = [];
if (quadObjects) {
for (const object of quadObjects) {
const newGeometry = this._process(object);
if (newGeometry) {
newGeometries.push(newGeometry);
}
}
}
this.setGeometries(newGeometries, ObjectType.LINE_SEGMENTS);
}
_process(quadObject) {
const graph = quadGraphFromQuadObject(quadObject);
const { quadId0 } = this.pv;
const mode = this.connectionMode();
if (graph.quadNode(quadId0) == null) {
return;
}
const getQuadId1ByNeighbourIndex = () => {
graph.neighbourIdsSharingEdge(quadId0, _neighbourIdsSharingEdge);
const type2 = this.connectionType();
if (type2 == "straight" /* STRAIGHT */) {
return _neighbourIdsSharingEdge[this.pv.neighbourIndex];
} else {
graph.neighbourIdsSharingPoint(quadId0, _neighbourIdsSharingPoint);
arrayDifference(_neighbourIdsSharingPoint, _neighbourIdsSharingEdge, _neighbourIdsSharingPointOnly);
return _neighbourIdsSharingPointOnly[this.pv.neighbourIndex];
}
};
const getConnectionTypeFromNeighbourId = (neighbourId) => {
graph.neighbourIdsSharingEdge(quadId0, _neighbourIdsSharingEdge);
graph.neighbourIdsSharingPoint(quadId0, _neighbourIdsSharingPoint);
arrayDifference(_neighbourIdsSharingPoint, _neighbourIdsSharingEdge, _neighbourIdsSharingPointOnly);
return _neighbourIdsSharingPointOnly.indexOf(neighbourId) >= 0 ? "diagonal" /* DIAGONAL */ : "straight" /* STRAIGHT */;
};
const quadId1 = mode == "neighbourIndex" /* NEIGHBOUR_INDEX */ ? getQuadId1ByNeighbourIndex() : this.pv.quadId1;
const type = mode == "neighbourIndex" /* NEIGHBOUR_INDEX */ ? this.connectionType() : getConnectionTypeFromNeighbourId(this.pv.quadId1);
if (graph.quadNode(quadId1) == null) {
return;
}
QuadPrimitive.position(quadObject, quadId0, _quadCenter0);
QuadPrimitive.position(quadObject, quadId1, _quadCenter1);
const srcPositions = quadObject.geometry.attributes[Attribute.POSITION].array;
const geometry = new BufferGeometry();
if (type == "straight" /* STRAIGHT */) {
halfEdgeIndicesInCommonBetweenQuads({
quadObject,
quadId0,
quadId1,
target: _halfEdgeIndices
});
_p0.fromArray(srcPositions, _halfEdgeIndices.index0 * 3);
_p1.fromArray(srcPositions, _halfEdgeIndices.index1 * 3);
_center.copy(_p0).add(_p1).multiplyScalar(0.5);
} else {
const sharedPointId = pointInCommonBetweenQuadsSharingPoint(graph, quadId0, quadId1);
if (sharedPointId != null) {
_center.fromArray(srcPositions, sharedPointId * 3);
}
}
const positions = new Float32Array(9);
_quadCenter0.toArray(positions, 0);
_center.toArray(positions, 3);
_quadCenter1.toArray(positions, 6);
geometry.setAttribute("position", new Float32BufferAttribute(positions, 3));
geometry.setIndex([0, 1, 1, 2]);
return geometry;
}
}