@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
131 lines (92 loc) • 3.2 kB
JavaScript
import { DynamicDrawUsage, LineBasicMaterial, LineSegments } from "three";
import { Float32BufferAttribute } from "three/src/core/BufferAttribute.js";
import { BufferGeometry } from "three/src/core/BufferGeometry.js";
import { assert } from "../../../core/assert.js";
import { array_copy } from "../../../core/collection/array/array_copy.js";
/**
*
* @param {number} capacity
* @return {BufferGeometry}
*/
function buildGeometry(capacity) {
assert.isNonNegativeInteger(capacity, 'capacity');
const geometry = new BufferGeometry();
geometry.dynamic = true;
// no index
const attribute_position = new Float32BufferAttribute(capacity * 3 * 2, 3, false);
const attribute_color = new Float32BufferAttribute(capacity * 4 * 2, 4, false);
attribute_position.setUsage(DynamicDrawUsage);
attribute_color.setUsage(DynamicDrawUsage);
geometry.setAttribute('position', attribute_position);
geometry.setAttribute('color', attribute_color);
return geometry;
}
export class Lines {
constructor() {
this.count = 0;
this.capacity = 64;
/**
*
* @type {BufferGeometry|null}
*/
this.geometry = buildGeometry(this.capacity);
this.mesh = new LineSegments(this.geometry, new LineBasicMaterial());
// disable automatic culling/updates
this.mesh.matrixAutoUpdate = false;
this.mesh.frustumCulled = false;
this.mesh.matrixWorldNeedsUpdate = false;
}
/**
*
* @param {number} x
*/
setCount(x) {
this.ensure_capacity(x);
this.count = x;
this.geometry.drawRange.count = x * 6;
}
/**
*
* @param {number} x
*/
ensure_capacity(x) {
if (this.capacity >= x) {
// enough capacity
return;
}
this.capacity = x;
this.build();
}
/**
*
* @param {vec3} from
* @param {vec3} to
* @param {vec4} color
*/
add_line(from, to, color) {
const index = this.count;
this.setCount(index + 1);
const position_attribute = this.geometry.getAttribute('position');
const color_attribute = this.geometry.getAttribute('color');
const position_array = position_attribute.array;
array_copy(from, 0, position_array, index * 6, 3);
array_copy(to, 0, position_array, index * 6 + 3, 3);
const color_array = color_attribute.array;
array_copy(color, 0, color_array, index * 8, 4);
array_copy(color, 0, color_array, index * 8 + 4, 4);
this.geometry.drawRange.count = this.count;
//
position_attribute.needsUpdate = true;
color_attribute.needsUpdate = true;
console.warn('feature not fully implemented');
}
build() {
const geometry = buildGeometry(this.capacity);
// TODO copy existing attribute values
this.geometry = geometry;
this.mesh.geometry = geometry;
}
dispose() {
this.geometry.dispose();
}
}