UNPKG

@polygonjs/polygonjs

Version:

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

162 lines (161 loc) 5.92 kB
"use strict"; import { Float32BufferAttribute } from "three"; import { BufferGeometry } from "three"; import { CatmullRomCurve3 } from "three"; import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils"; import { TypedSopNode } from "./_Base"; import { ObjectType } from "../../../core/geometry/Constant"; import { CoreGeometryUtilCurve } from "../../../core/geometry/util/Curve"; export var METHOD = /* @__PURE__ */ ((METHOD2) => { METHOD2["POINTS_COUNT"] = "pointsCount"; METHOD2["SEGMENT_LENGTH"] = "segmentLength"; return METHOD2; })(METHOD || {}); export const METHODS = ["pointsCount" /* POINTS_COUNT */, "segmentLength" /* SEGMENT_LENGTH */]; import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig"; import { TypeAssert } from "../../poly/Assert"; import { SplineCurveType, SPLINE_CURVE_TYPES } from "../../../core/geometry/Curve"; import { InputCloneMode } from "../../poly/InputCloneMode"; import { pointsFromObject } from "../../../core/geometry/entities/point/CorePointUtils"; import { Attribute } from "../../../core/geometry/Attribute"; const _points = []; class ResampleSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); /** @param resampling method */ this.method = ParamConfig.INTEGER(METHODS.indexOf("pointsCount" /* POINTS_COUNT */), { menu: { entries: METHODS.map((name, i) => { return { name, value: i }; }) } }); /** @param type of curve this will generate */ this.curveType = ParamConfig.INTEGER(SPLINE_CURVE_TYPES.indexOf(SplineCurveType.CATMULLROM), { range: [0, 2], rangeLocked: [true, true], menu: { entries: SPLINE_CURVE_TYPES.map((name, i) => { return { name, value: i }; }) } }); /** @param curve tension */ this.tension = ParamConfig.FLOAT(0.01, { range: [0, 1], rangeLocked: [true, true], visibleIf: { curveType: SPLINE_CURVE_TYPES.indexOf(SplineCurveType.CATMULLROM) } }); /** @param points count */ this.pointsCount = ParamConfig.INTEGER(100, { visibleIf: { method: METHODS.indexOf("pointsCount" /* POINTS_COUNT */) }, range: [1, 1e3], rangeLocked: [true, false] }); /** @param segments length */ this.segmentLength = ParamConfig.FLOAT(1, { visibleIf: { method: METHODS.indexOf("segmentLength" /* SEGMENT_LENGTH */) } }); } } const ParamsConfig = new ResampleSopParamsConfig(); export class ResampleSopNode extends TypedSopNode { constructor() { super(...arguments); this.paramsConfig = ParamsConfig; } static type() { return "resample"; } initializeNode() { this.io.inputs.setCount(1); this.io.inputs.initInputsClonedState(InputCloneMode.NEVER); } cook(inputCoreGroups) { const coreGroup = inputCoreGroups[0]; const resampledObjects = []; if (this.pv.pointsCount >= 2) { const coreObjects = coreGroup.threejsCoreObjects(); for (const coreObject of coreObjects) { const object = coreObject.object(); if (object.isLineSegments) { const resampledObject = this._resample(object); if (resampledObject) { resampledObjects.push(resampledObject); } } } } this.setObjects(resampledObjects); } setCurveType(curveType) { this.p.curveType.set(SPLINE_CURVE_TYPES.indexOf(curveType)); } _resample(lineSegment) { var _a; const geometry = lineSegment.geometry; pointsFromObject(lineSegment, _points); const indices = (_a = geometry.getIndex()) == null ? void 0 : _a.array; if (!indices) { return; } const accumulated_curve_point_indices = CoreGeometryUtilCurve.accumulatedCurvePointIndices(indices); const geometries = []; for (let i = 0; i < accumulated_curve_point_indices.length; i++) { const curve_point_indices = accumulated_curve_point_indices[i]; const current_points = curve_point_indices.map((index) => _points[index]); const geometry2 = this._create_curve_from_points(current_points); if (geometry2) { geometries.push(geometry2); } } const mergedGeometry = mergeGeometries(geometries); const object = this.createObject(mergedGeometry, ObjectType.LINE_SEGMENTS); return object; } _create_curve_from_points(points) { if (points.length <= 1) { return; } const old_curve_positions = points.map((point) => point.attribValue(Attribute.POSITION)); const closed = false; const curveType = SPLINE_CURVE_TYPES[this.pv.curveType]; const tension = this.pv.tension; const curve = new CatmullRomCurve3(old_curve_positions, closed, curveType, tension); const new_curve_points = this._get_points_from_curve(curve); let positions = []; const indices = []; for (let i = 0; i < new_curve_points.length; i++) { const point_position = new_curve_points[i]; const position = point_position.toArray(); positions.push(position); if (i > 0) { indices.push(i - 1); indices.push(i); } } const geometry = new BufferGeometry(); geometry.setAttribute("position", new Float32BufferAttribute(positions.flat(), 3)); geometry.setIndex(indices); return geometry; } _get_points_from_curve(curve) { const method = METHODS[this.pv.method]; switch (method) { case "pointsCount" /* POINTS_COUNT */: return curve.getSpacedPoints(Math.max(2, this.pv.pointsCount)); case "segmentLength" /* SEGMENT_LENGTH */: var length = curve.getLength(); var pointsCount = this.pv.segmentLength !== 0 ? 1 + length / this.pv.segmentLength : 2; pointsCount = Math.max(2, pointsCount); return curve.getSpacedPoints(pointsCount); } TypeAssert.unreachable(method); } }