polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
130 lines (129 loc) • 5.16 kB
JavaScript
import {Float32BufferAttribute} from "three/src/core/BufferAttribute";
import {BufferGeometry as BufferGeometry2} from "three/src/core/BufferGeometry";
import {CoreAttributeData} from "../../geometry/AttributeData";
import {CoreAttribute} from "../../geometry/Attribute";
import {AttribType} from "../../geometry/Constant";
import {CoreGeometry} from "../../geometry/Geometry";
import {CoreType} from "../../Type";
const POSITION = "position";
const CsvLoader2 = class {
constructor(attribute_names) {
this.attribute_names = attribute_names;
this.attribute_names_from_first_line = false;
this.lines = [];
this.points_count = 0;
this.attribute_values_by_name = {};
this.attribute_data_by_name = {};
this._loading = false;
if (!this.attribute_names) {
this.attribute_names_from_first_line = true;
}
}
async load(url) {
if (this._loading) {
console.warn("is already loading");
return;
}
this._loading = true;
this.points_count = 0;
await this.load_data(url);
this.infer_types();
this.read_values();
const geometry = this.create_points();
return geometry;
}
async load_data(url) {
const response = await fetch(url);
const text = await response.text();
this.lines = text.split("\n");
if (!this.attribute_names) {
this.attribute_names = this.lines[0].split(CsvLoader2.SEPARATOR);
}
this.attribute_names = this.attribute_names.map((name) => CoreAttribute.remap_name(name));
for (let attribute_name of this.attribute_names) {
this.attribute_values_by_name[attribute_name] = [];
}
}
infer_types() {
const first_values_index = this.attribute_names_from_first_line ? 1 : 0;
const first_line = this.lines[first_values_index];
let line_attribute_values = first_line.split(CsvLoader2.SEPARATOR);
for (let i = 0; i < line_attribute_values.length; i++) {
const attribute_name = this.attribute_names[i];
const attribute_value = line_attribute_values[i];
const value = this._value_from_line_element(attribute_value);
this.attribute_data_by_name[attribute_name] = CoreAttributeData.from_value(value);
}
}
_value_from_line_element(attribute_value) {
if (CoreType.isString(attribute_value)) {
if (`${parseFloat(attribute_value)}` === attribute_value) {
return parseFloat(attribute_value);
} else if (attribute_value[0] === "[" && attribute_value[attribute_value.length - 1] === "]") {
const attribute_value_within_brackets = attribute_value.substring(1, attribute_value.length - 1);
const elements_s = attribute_value_within_brackets.split(CsvLoader2.VECTOR_SEPARATOR);
return elements_s.map((element_s) => parseFloat(element_s));
} else {
return attribute_value;
}
} else {
return attribute_value;
}
}
read_values() {
if (!this.attribute_names) {
return;
}
const first_values_index = this.attribute_names_from_first_line ? 1 : 0;
let line;
for (let line_index = first_values_index; line_index < this.lines.length; line_index++) {
line = this.lines[line_index];
const line_attribute_values = line.split(CsvLoader2.SEPARATOR);
if (line_attribute_values.length >= this.attribute_names.length) {
for (let i = 0; i < line_attribute_values.length; i++) {
const attribute_name = this.attribute_names[i];
if (attribute_name) {
const attribute_value = line_attribute_values[i];
const value = this._value_from_line_element(attribute_value);
this.attribute_values_by_name[attribute_name].push(value);
}
}
this.points_count += 1;
}
}
if (!this.attribute_values_by_name[POSITION]) {
const positions = new Array(this.points_count * 3);
positions.fill(0);
this.attribute_values_by_name[POSITION] = positions;
this.attribute_data_by_name[POSITION] = new CoreAttributeData(3, AttribType.NUMERIC);
this.attribute_names.push(POSITION);
}
}
create_points() {
if (!this.attribute_names) {
return;
}
const geometry = new BufferGeometry2();
const core_geometry = new CoreGeometry(geometry);
for (let attribute_name of this.attribute_names) {
const attribute_values = this.attribute_values_by_name[attribute_name].flat();
const size = this.attribute_data_by_name[attribute_name].size();
const type = this.attribute_data_by_name[attribute_name].type();
if (type == AttribType.STRING) {
const index_data = CoreAttribute.array_to_indexed_arrays(attribute_values);
core_geometry.setIndexedAttribute(attribute_name, index_data["values"], index_data["indices"]);
} else {
geometry.setAttribute(attribute_name, new Float32BufferAttribute(attribute_values, size));
}
}
const indices = new Array(this.points_count);
for (let i = 0; i < this.points_count; i++) {
indices.push(i);
}
geometry.setIndex(indices);
return geometry;
}
};
export let CsvLoader = CsvLoader2;
CsvLoader.SEPARATOR = ",";
CsvLoader.VECTOR_SEPARATOR = ",";