UNPKG

polygonjs-engine

Version:

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

152 lines (151 loc) 5.68 kB
import {LineSegments as LineSegments2} from "three/src/objects/LineSegments"; import {Float32BufferAttribute} from "three/src/core/BufferAttribute"; import {BufferGeometry as BufferGeometry2} from "three/src/core/BufferGeometry"; import {CatmullRomCurve3 as CatmullRomCurve32} from "three/src/extras/curves/CatmullRomCurve3"; import {BufferGeometryUtils as BufferGeometryUtils2} from "../../../modules/three/examples/jsm/utils/BufferGeometryUtils"; import {TypedSopNode} from "./_Base"; import {ObjectType} from "../../../core/geometry/Constant"; import {CoreGeometryUtilCurve} from "../../../core/geometry/util/Curve"; import {CoreGeometry} from "../../../core/geometry/Geometry"; const POSITION_ATTRIBUTE_NAME = "position"; export var METHOD; (function(METHOD2) { METHOD2["POINTS_COUNT"] = "pointsCount"; METHOD2["SEGMENT_LENGTH"] = "segmentLength"; })(METHOD || (METHOD = {})); export const METHODS = [METHOD.POINTS_COUNT, METHOD.SEGMENT_LENGTH]; export var CURVE_TYPE; (function(CURVE_TYPE2) { CURVE_TYPE2["CENTRIPETAL"] = "centripetal"; CURVE_TYPE2["CHORDAL"] = "chordal"; CURVE_TYPE2["CATMULLROM"] = "catmullrom"; })(CURVE_TYPE || (CURVE_TYPE = {})); export const CURVE_TYPES = [CURVE_TYPE.CENTRIPETAL, CURVE_TYPE.CHORDAL, CURVE_TYPE.CATMULLROM]; import {NodeParamsConfig, ParamConfig} from "../utils/params/ParamsConfig"; import {TypeAssert} from "../../poly/Assert"; class ResampleSopParamsConfig extends NodeParamsConfig { constructor() { super(...arguments); this.method = ParamConfig.INTEGER(METHODS.indexOf(METHOD.POINTS_COUNT), { menu: { entries: METHODS.map((name, i) => { return { name, value: i }; }) } }); this.curveType = ParamConfig.INTEGER(CURVE_TYPES.indexOf(CURVE_TYPE.CATMULLROM), { range: [0, 2], rangeLocked: [true, true], menu: { entries: CURVE_TYPES.map((name, i) => { return { name, value: i }; }) } }); this.tension = ParamConfig.FLOAT(0.01, { range: [0, 1], rangeLocked: [true, true] }); this.pointsCount = ParamConfig.INTEGER(100, { visibleIf: {method: METHODS.indexOf(METHOD.POINTS_COUNT)}, range: [1, 1e3], rangeLocked: [true, false] }); this.segmentLength = ParamConfig.FLOAT(1, { visibleIf: {method: METHODS.indexOf(METHOD.SEGMENT_LENGTH)} }); } } const ParamsConfig2 = new ResampleSopParamsConfig(); export class ResampleSopNode extends TypedSopNode { constructor() { super(...arguments); this.params_config = ParamsConfig2; } static type() { return "resample"; } initializeNode() { this.io.inputs.setCount(1); } cook(input_contents) { const core_group = input_contents[0]; const resampled_objects = []; if (this.pv.pointsCount >= 2) { const core_objects = core_group.coreObjects(); for (let i = 0; i < core_objects.length; i++) { const core_object = core_objects[i]; const object = core_object.object(); if (object instanceof LineSegments2) { const resampled_object = this._resample(object); resampled_objects.push(resampled_object); } } } this.setObjects(resampled_objects); } _resample(line_segment) { const geometry = line_segment.geometry; const core_geometry = new CoreGeometry(geometry); const points = core_geometry.points(); const indices = geometry.getIndex()?.array; const accumulated_curve_point_indices = CoreGeometryUtilCurve.accumulated_curve_point_indices(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 merged_geometry = BufferGeometryUtils2.mergeBufferGeometries(geometries); const object = this.create_object(merged_geometry, ObjectType.LINE_SEGMENTS); return object; } _create_curve_from_points(points) { if (points.length <= 1) { return; } const old_curve_positions = points.map((point) => point.attribValue(POSITION_ATTRIBUTE_NAME)); const closed = false; const curveType = CURVE_TYPES[this.pv.curveType]; const tension = this.pv.tension; const curve = new CatmullRomCurve32(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 BufferGeometry2(); 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 METHOD.POINTS_COUNT: return curve.getSpacedPoints(Math.max(2, this.pv.pointsCount)); case METHOD.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); } }