polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
82 lines (81 loc) • 3.2 kB
JavaScript
import {CoreGeometry} from "../Geometry";
import {Float32BufferAttribute} from "three/src/core/BufferAttribute";
import {BufferGeometry as BufferGeometry2} from "three/src/core/BufferGeometry";
export class CoreGeometryUtilCurve {
static accumulated_curve_point_indices(indices) {
let curve_point_indices = [];
const accumulated_curve_point_indices = [];
let last_index_added = null;
let index;
for (let i = 0; i < indices.length; i++) {
if (i % 2 === 1) {
index = indices[i];
const previous_index = indices[i - 1];
if (last_index_added == null || previous_index === last_index_added) {
if (curve_point_indices.length === 0) {
curve_point_indices.push(previous_index);
}
curve_point_indices.push(index);
last_index_added = index;
} else {
accumulated_curve_point_indices.push(curve_point_indices);
curve_point_indices = [previous_index, index];
last_index_added = index;
}
}
}
accumulated_curve_point_indices.push(curve_point_indices);
return accumulated_curve_point_indices;
}
static create_line_segment_geometry(points, indices, attrib_names, attrib_sizes_by_name) {
const new_indices = [];
const new_attribute_values_by_name = {};
attrib_names.forEach((attrib_name) => {
new_attribute_values_by_name[attrib_name] = [];
});
indices.forEach((index, i) => {
const point = points[index];
attrib_names.forEach((attrib_name) => {
const attrib_value = point.attribValue(attrib_name);
const attrib_size = attrib_sizes_by_name[attrib_name];
let attrib_value_f;
if (attrib_size > 1) {
attrib_value_f = attrib_value.toArray();
} else {
attrib_value_f = [attrib_value];
}
attrib_value_f.forEach((v) => {
new_attribute_values_by_name[attrib_name].push(v);
});
});
if (i > 0) {
new_indices.push(i - 1);
new_indices.push(i);
}
});
const geometry = new BufferGeometry2();
attrib_names.forEach((attrib_name) => {
const attrib_size = attrib_sizes_by_name[attrib_name];
const values = new_attribute_values_by_name[attrib_name];
geometry.setAttribute(attrib_name, new Float32BufferAttribute(values, attrib_size));
});
geometry.setIndex(new_indices);
return geometry;
}
static line_segment_to_geometries(geometry) {
const geometries = [];
const core_geometry = new CoreGeometry(geometry);
const attrib_names = core_geometry.attribNames();
const points = core_geometry.points();
const indices = geometry.getIndex()?.array || [];
const accumulated_curve_point_indices = this.accumulated_curve_point_indices(indices);
if (accumulated_curve_point_indices.length > 0) {
const attribute_sizes_by_name = core_geometry.attribSizes();
accumulated_curve_point_indices.forEach((curve_point_indices, i) => {
geometry = this.create_line_segment_geometry(points, curve_point_indices, attrib_names, attribute_sizes_by_name);
geometries.push(geometry);
});
}
return geometries;
}
}