@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
162 lines (161 loc) • 5.92 kB
JavaScript
;
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);
}
}