124 lines
3.7 KiB
JavaScript
124 lines
3.7 KiB
JavaScript
'use strict';
|
|
|
|
var EventEmitter = require('eventemitter3');
|
|
var Bounds = require('../../../../scene/container/bounds/Bounds.js');
|
|
var uid = require('../../../../utils/data/uid.js');
|
|
var Buffer = require('../buffer/Buffer.js');
|
|
var ensureIsBuffer = require('./utils/ensureIsBuffer.js');
|
|
var getGeometryBounds = require('./utils/getGeometryBounds.js');
|
|
|
|
"use strict";
|
|
function ensureIsAttribute(attribute) {
|
|
if (attribute instanceof Buffer.Buffer || Array.isArray(attribute) || attribute.BYTES_PER_ELEMENT) {
|
|
attribute = {
|
|
buffer: attribute
|
|
};
|
|
}
|
|
attribute.buffer = ensureIsBuffer.ensureIsBuffer(attribute.buffer, false);
|
|
return attribute;
|
|
}
|
|
class Geometry extends EventEmitter {
|
|
/**
|
|
* Create a new instance of a geometry
|
|
* @param options - The options for the geometry.
|
|
*/
|
|
constructor(options) {
|
|
const { attributes, indexBuffer, topology } = options;
|
|
super();
|
|
/** The unique id of the geometry. */
|
|
this.uid = uid.uid("geometry");
|
|
/**
|
|
* the layout key will be generated by WebGPU all geometries that have the same structure
|
|
* will have the same layout key. This is used to cache the pipeline layout
|
|
* @internal
|
|
* @ignore
|
|
*/
|
|
this._layoutKey = 0;
|
|
/** the instance count of the geometry to draw */
|
|
this.instanceCount = 1;
|
|
this._bounds = new Bounds.Bounds();
|
|
this._boundsDirty = true;
|
|
this.attributes = attributes;
|
|
this.buffers = [];
|
|
this.instanceCount = options.instanceCount || 1;
|
|
for (const i in attributes) {
|
|
const attribute = attributes[i] = ensureIsAttribute(attributes[i]);
|
|
const bufferIndex = this.buffers.indexOf(attribute.buffer);
|
|
if (bufferIndex === -1) {
|
|
this.buffers.push(attribute.buffer);
|
|
attribute.buffer.on("update", this.onBufferUpdate, this);
|
|
attribute.buffer.on("change", this.onBufferUpdate, this);
|
|
}
|
|
}
|
|
if (indexBuffer) {
|
|
this.indexBuffer = ensureIsBuffer.ensureIsBuffer(indexBuffer, true);
|
|
this.buffers.push(this.indexBuffer);
|
|
}
|
|
this.topology = topology || "triangle-list";
|
|
}
|
|
onBufferUpdate() {
|
|
this._boundsDirty = true;
|
|
this.emit("update", this);
|
|
}
|
|
/**
|
|
* Returns the requested attribute.
|
|
* @param id - The name of the attribute required
|
|
* @returns - The attribute requested.
|
|
*/
|
|
getAttribute(id) {
|
|
return this.attributes[id];
|
|
}
|
|
/**
|
|
* Returns the index buffer
|
|
* @returns - The index buffer.
|
|
*/
|
|
getIndex() {
|
|
return this.indexBuffer;
|
|
}
|
|
/**
|
|
* Returns the requested buffer.
|
|
* @param id - The name of the buffer required.
|
|
* @returns - The buffer requested.
|
|
*/
|
|
getBuffer(id) {
|
|
return this.getAttribute(id).buffer;
|
|
}
|
|
/**
|
|
* Used to figure out how many vertices there are in this geometry
|
|
* @returns the number of vertices in the geometry
|
|
*/
|
|
getSize() {
|
|
for (const i in this.attributes) {
|
|
const attribute = this.attributes[i];
|
|
const buffer = attribute.buffer;
|
|
return buffer.data.length / (attribute.stride / 4 || attribute.size);
|
|
}
|
|
return 0;
|
|
}
|
|
/** Returns the bounds of the geometry. */
|
|
get bounds() {
|
|
if (!this._boundsDirty)
|
|
return this._bounds;
|
|
this._boundsDirty = false;
|
|
return getGeometryBounds.getGeometryBounds(this, "aPosition", this._bounds);
|
|
}
|
|
/**
|
|
* destroys the geometry.
|
|
* @param destroyBuffers - destroy the buffers associated with this geometry
|
|
*/
|
|
destroy(destroyBuffers = false) {
|
|
this.emit("destroy", this);
|
|
this.removeAllListeners();
|
|
if (destroyBuffers) {
|
|
this.buffers.forEach((buffer) => buffer.destroy());
|
|
}
|
|
this.attributes = null;
|
|
this.buffers = null;
|
|
this.indexBuffer = null;
|
|
this._bounds = null;
|
|
}
|
|
}
|
|
|
|
exports.Geometry = Geometry;
|
|
//# sourceMappingURL=Geometry.js.map
|