@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
140 lines (115 loc) • 3.55 kB
JavaScript
import { assert } from "../../../core/assert.js";
import { BinaryDataType } from "../../../core/binary/type/BinaryDataType.js";
import { DataTypeByteSizes } from "../../../core/binary/type/DataTypeByteSizes.js";
import { computeStringHash } from "../../../core/primitives/strings/computeStringHash.js";
/**
* Describes data structure of a single data attribute, such as a scalar, or a vector
* This structure is designed to map well to GPU shader formats and is intended for larger datasets, such as meshes or particle clouds
*/
export class AttributeSpec {
/**
* Typically unique within a given set, used to identify the attribute
* @type {string}
*/
name = "";
/**
* How the attribute is stored in memory and interpreted
* @type {BinaryDataType}
*/
type = BinaryDataType.Float32;
/**
* How many elements the attribute uses. This is cardinality of a vector.
* 1 means the attribute is a scalar
* must be greater or equal to 1
* @type {number}
*/
itemSize = 1;
/**
* Normalized values will be automatically converted to float32 in the shader
* This gives good optimization opportunities for things like normal vectors
* Applies to integer types only
* @type {boolean}
*/
normalized = false;
static fromJSON(j) {
const r = new AttributeSpec();
r.fromJSON(j);
return r;
}
fromJSON({
name,
type,
itemSize,
normalized = false
}) {
assert.isString(name, 'name');
assert.enum(type, BinaryDataType, 'type');
assert.isNumber(itemSize, 'itemSize');
assert.isNonNegativeInteger(itemSize, 'itemSize');
assert.greaterThanOrEqual(itemSize, 1, 'itemSize must be >= 1');
assert.isBoolean(normalized, 'normalized');
this.name = name;
this.type = type;
this.itemSize = itemSize;
this.normalized = normalized;
}
toJSON() {
return {
name: this.name,
type: this.type,
itemSize: this.itemSize,
normalized: this.normalized
};
}
hash() {
return computeStringHash(this.name);
}
/**
*
* @param {AttributeSpec} other
* @returns {boolean}
*/
equals(other) {
return this.type === other.type
&& this.itemSize === other.itemSize
&& this.normalized === other.normalized
&& this.name === other.name
;
}
/**
*
* @param {AttributeSpec} other
*/
copy(other) {
this.type = other.type;
this.name = other.name;
this.itemSize = other.itemSize;
this.normalized = other.normalized;
}
clone() {
const r = new AttributeSpec();
r.copy(this);
return r;
}
/**
* How much space a single attribute value takes up
* @returns {number} in bytes
*/
getByteSize() {
return this.itemSize * DataTypeByteSizes[this.type];
}
/**
* Sorting comparator
* @param {AttributeSpec} a
* @param {AttributeSpec} b
* @return {number}
*/
static byName(a, b) {
return a.name.localeCompare(b.name);
}
}
/**
* @readonly
* @type {boolean}
*/
AttributeSpec.prototype.isAttributeSpec = true;