@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
140 lines (113 loc) • 4.19 kB
JavaScript
import { assert } from "../../../../../core/assert.js";
import { EndianType } from "../../../../../core/binary/EndianType.js";
import { BinaryDataType } from "../../../../../core/binary/type/BinaryDataType.js";
import { DataTypeByteSizes } from "../../../../../core/binary/type/DataTypeByteSizes.js";
import { dataTypeFromTypedArray } from "../../../../../core/binary/type/dataTypeFromTypedArray.js";
import { DataTypeIndices } from "../../../../../core/binary/type/DataTypeIndices.js";
import { Sampler2D } from "../Sampler2D.js";
/**
*
* @param {number} index
* @returns {BinaryDataType}
*/
function dataTypeByTypeIndex(index) {
for (let type in DataTypeIndices) {
const typeIndex = DataTypeIndices[type];
if (typeIndex === index) {
return type;
}
}
throw new Error(`No type found with index ${index}`);
}
/**
*
* @param {BinaryBuffer} buffer
* @param {BinaryDataType} type
* @param {number} length
*/
function readTypedArray(buffer, type, length) {
const oldEndianness = buffer.endianness;
buffer.endianness = EndianType.LittleEndian;
let result = null;
switch (type) {
case BinaryDataType.Uint8:
result = new Uint8Array(length);
buffer.readUint8Array(result, 0, length);
break;
case BinaryDataType.Uint16:
result = new Uint16Array(length);
buffer.readUint16Array(result, 0, length);
break;
case BinaryDataType.Uint32:
result = new Uint32Array(length);
buffer.readUint32Array(result, 0, length);
break;
case BinaryDataType.Int8:
result = new Int8Array(length);
buffer.readInt8Array(result, 0, length);
break;
case BinaryDataType.Int16:
result = new Int16Array(length);
buffer.readInt16Array(result, 0, length);
break;
case BinaryDataType.Int32:
result = new Int32Array(length);
buffer.readInt32Array(result, 0, length);
break;
case BinaryDataType.Float32:
result = new Float32Array(length);
buffer.readFloat32Array(result, 0, length);
break;
case BinaryDataType.Float64:
result = new Float64Array(length);
buffer.readFloat64Array(result, 0, length);
break;
default:
result = null;
}
//restore
buffer.endianness = oldEndianness;
if (result === null) {
throw new TypeError(`Unsupported data type ${type}`);
}
return result;
}
/**
*
* @param {BinaryBuffer} buffer
* @param {Sampler2D} texture
*/
export function serializeTexture(buffer, texture) {
const width = texture.width;
const height = texture.height;
const itemSize = texture.itemSize;
buffer.writeUint32(width);
buffer.writeUint32(height);
buffer.writeUint8(itemSize); //number of channels
const type = dataTypeFromTypedArray(texture.data);
buffer.writeUint8(DataTypeIndices[type]);
const array = texture.data;
const byteBuffer = array.buffer;
if (byteBuffer === undefined) {
throw new TypeError(`No buffer found on data array, only TypedArrays are supported. It appears that data array is not a TypedArray`);
}
const itemByteSize = DataTypeByteSizes[type];
assert.isNumber(itemByteSize, 'itemByteSize');
const byteSize = width * height * itemSize * itemByteSize;
buffer.writeBytes(new Uint8Array(byteBuffer), 0, byteSize);
}
/**
*
* @param {BinaryBuffer} buffer
* @returns {Sampler2D}
*/
export function deserializeTexture(buffer) {
const width = buffer.readUint32();
const height = buffer.readUint32();
const itemSize = buffer.readUint8();
const dataTypeId = buffer.readUint8();
const type = dataTypeByTypeIndex(dataTypeId);
const length = width * height * itemSize;
const array = readTypedArray(buffer, type, length);
return new Sampler2D(array, itemSize, width, height);
}