Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const regex = new RegExp(`(?<mainType>\\w+)(?:<(?<subType>\\w+)>)?(?:\\[(?<count>\\w*)\\])?`);
- const dataViewMapperBase = {
- "s": "Int",
- "u": "Uint"
- };
- const vectorAxes = [
- ["x", "y"],
- ["x", "y", "z"],
- ["x", "y", "z", "w"],
- ];
- const Descriptor = new class Descriptor {
- constructor() {
- this.types = {};
- this.staticTypes = {};
- this.vectorClasses = {};
- this.matrixClasses = {};
- this.dataViewMap = {};
- this.createDataViewMap();
- this.createStaticTypes();
- this.createVectorTypes();
- this.createMatrixTypes();
- this.createBlobTypes();
- }
- createDataViewMap() {
- for (let [signed, dataViewSigned] of Object.entries(dataViewMapperBase)) {
- for (let i = 0; i < 4; i++) {
- const bitSize = (2 ** i) * 8;
- this.dataViewMap[`${signed}${bitSize}`] = `${dataViewSigned}${bitSize}`;
- }
- }
- for (let i = 1; i <= 2; i++) {
- const bitSize = i * 32;
- this.dataViewMap[`f${bitSize}`] = `Float${bitSize}`;
- }
- }
- createStaticTypes() {
- for (let signed of ["s", "u"]) {
- for (let i = 0; i < 4; i++) {
- const byteSize = 2 ** i;
- const typeName = `${signed}${byteSize * 8}`;
- const staticType = {
- name: typeName,
- size: byteSize,
- define: this.createStaticDescriptorCreator(typeName),
- };
- this.staticTypes[typeName] = staticType;
- this.types[typeName] = staticType;
- }
- }
- for (let i = 1; i <= 2; i++) {
- const byteSize = i * 4;
- const bitSize = i * 32;
- const typeName = `f${bitSize}`;
- const staticType = {
- name: typeName,
- size: byteSize,
- define: this.createStaticDescriptorCreator(typeName),
- };
- this.staticTypes[typeName] = staticType;
- this.types[typeName] = staticType;
- }
- }
- createVectorTypes() {
- for (let axis of vectorAxes) {
- for (let {name: staticTypeName, size: staticTypeSize} of Object.values(this.staticTypes)) {
- const vectorTypeName = `vec${axis.length}<${staticTypeName}>`;
- const vectorTypeSize = axis.length * staticTypeSize;
- const vectorClassName = `Vector${axis.length}<${staticTypeName}>`;
- const vectorClass = (function (length) {
- return function (dataView) {
- this.length = length;
- this.dataView = dataView;
- };
- })(axis.length);
- vectorClass.prototype = Object.create(Array.prototype);
- vectorClass.prototype.constructor = vectorClass;
- vectorClass.size = vectorTypeSize;
- vectorClass.axisSize = staticTypeSize;
- vectorClass.axisType = staticTypeName;
- this.vectorClasses[vectorClassName] = vectorClass;
- for (let [axisOffset, field] of axis.entries()) {
- let subOffset = staticTypeSize * axisOffset;
- const staticDescriptorCreator = this.createStaticDescriptorCreator(staticTypeName);
- const descriptor = staticDescriptorCreator(null, subOffset);
- Object.defineProperty(vectorClass.prototype, axisOffset, descriptor);
- Object.defineProperty(vectorClass.prototype, field, descriptor);
- }
- const vectorDescriptorCreator = this.createSubObjectDescriptorCreator(vectorClass);
- this.types[vectorTypeName] = {
- name: vectorTypeName,
- size: vectorTypeSize,
- define: vectorDescriptorCreator
- }
- }
- }
- }
- createMatrixTypes() {
- for (let matrixWidth = 2; matrixWidth <= 4; matrixWidth++) {
- for (let {name: staticTypeName, size: staticTypeSize} of Object.values(this.staticTypes)) {
- const matrixTypeName = `mat${matrixWidth}<${staticTypeName}>`;
- const matrixElements = (matrixWidth ** 2);
- const matrixTypeSize = matrixElements * staticTypeSize;
- const matrixClassName = `Matrix${matrixWidth}<${staticTypeName}>`;
- const matrixClass = (function (length) {
- return function (dataView) {
- this.length = length;
- this.dataView = dataView;
- };
- })(matrixElements);
- matrixClass.prototype = Object.create(Array.prototype);
- matrixClass.prototype.constructor = matrixClass;
- matrixClass.size = matrixTypeSize;
- matrixClass.axisSize = staticTypeSize;
- matrixClass.axisType = staticTypeName;
- this.matrixClasses[matrixClassName] = matrixClass;
- for (let i = 0; i < matrixElements; i++) {
- let subOffset = staticTypeSize * i;
- const staticDescriptorCreator = this.createStaticDescriptorCreator(staticTypeName);
- const descriptor = staticDescriptorCreator(null, subOffset);
- Object.defineProperty(matrixClass.prototype, i, descriptor);
- }
- const matrixDescriptorCreator = this.createSubObjectDescriptorCreator(matrixClass);
- this.types[matrixTypeName] = {
- name: matrixTypeName,
- size: matrixTypeSize,
- define: matrixDescriptorCreator
- }
- }
- }
- }
- createBlobTypes() {
- this.types["blob"] = {
- name: "blob",
- size: undefined,
- define: this.createBlobDescriptorCreator(),
- };
- }
- createStaticDescriptorCreator(typeName) {
- const getterName = `get${this.dataViewMap[typeName]}`;
- const setterName = `set${this.dataViewMap[typeName]}`;
- return function createStaticDescriptor(property, offset) {
- offset = parseInt(offset);
- if (isNaN(offset)) {
- throw new Error("Static descriptor must have valid offset");
- }
- return {
- get: function () {
- return this['dataView'][getterName](offset);
- },
- set: function (value) {
- this['dataView'][setterName](offset, value);
- }
- }
- }
- }
- createSubObjectDescriptorCreator(constructor) {
- return function createSubObjectDescriptor(property, offset) {
- offset = parseInt(offset);
- if (isNaN(offset)) {
- throw new Error("Object descriptor must have valid offset");
- }
- return {
- get: function () {
- const {buffer, byteOffset} = this['dataView'];
- const dataView = new DataView(buffer, byteOffset + offset, constructor.size);
- const object = new constructor(dataView);
- Object.defineProperty(this, property.name, {value: object});
- return object;
- },
- set: function (value) {
- }
- };
- }
- }
- createBlobDescriptorCreator() {
- return function createBlobDescriptor(property) {
- return {
- get: function () {
- const size = this[`${property.name}Size`];
- const offset = this[`${property.name}Offset`];
- const {buffer, byteOffset} = this['dataView'];
- return new DataView(buffer, byteOffset + offset, size);
- },
- set: function (value) {
- }
- }
- }
- };
- extends(constructor, config) {
- const {prototype} = constructor;
- prototype.getDataView = function () {
- return this['dataView'];
- };
- let offset = 0;
- for (let propertyDeclaration of config.properties) {
- const property = this.parseProperty(propertyDeclaration);
- const {define, size} = property.type;
- const descriptor = define(property, offset);
- if (size !== undefined && offset !== undefined) {
- offset += size;
- } else {
- offset = undefined;
- }
- Object.defineProperty(prototype, property.name, descriptor);
- }
- }
- parseProperty(propertyDeclaration) {
- const {type} = propertyDeclaration;
- const match = regex.exec(type);
- const {mainType, subType, count} = match.groups;
- const typeKey = `${mainType}` + (subType ? `<${subType}>` : '');
- const typeDefinition = this.types[typeKey];
- if (typeDefinition === undefined) {
- throw new Error(`Type (${type}) not exists`);
- }
- const {property: propertyName, ...others} = propertyDeclaration;
- return {
- name: propertyName,
- ...others,
- type: {
- ...typeDefinition
- },
- };
- }
- };
- /**
- * @property tragedia
- */
- class Chunk {
- constructor(options) {
- this.dataView = options['dataView'];
- }
- }
- Descriptor.extends(Chunk, {
- properties: [
- {type: "u8", property: "type"},
- {type: "u8", property: "blockBitWidth"},
- {type: "vec3<u16>", property: "position"},
- {type: "mat4<f32>", property: "modelViewMatrix"},
- {type: "u16", property: "blockDataOffset"},
- {type: "u16", property: "blockIndexDataOffset"},
- {type: "u16", property: "terrainDataOffset"},
- {type: "u16", property: "additionalDataOffset"},
- {type: "u16", property: "overrideDataOffset"},
- {type: "u16", property: "blockDataSize"},
- {type: "u16", property: "blockIndexDataSize"},
- {type: "u16", property: "terrainDataSize"},
- {type: "u16", property: "additionalDataSize"},
- {type: "u16", property: "overrideDataSize"},
- {type: "blob"},
- {type: "blob", property: "blockData"},
- {type: "blob", property: "blockIndexData"},
- {type: "blob", property: "terrainData"},
- {type: "blob", property: "additionalData"},
- {type: "blob", property: "overrideData"},
- ],
- });
- const buffer = new ArrayBuffer(1000);
- const dataView = new DataView(buffer, 0);
- dataView.setInt8(0, 0xff);
- const chunk = new Chunk({dataView});
- chunk.blockBitWidth = 0x01;
- chunk.position.x = 5;
- chunk.position.y = 6;
- chunk.position.z = 0x4444;
- chunk.blockDataOffset = 0x04;
- chunk.blockDataSize = 0x08;
- chunk.modelViewMatrix[0] = 0.2;
- chunk.modelViewMatrix[4] = 0.10;
- const matrix = Array.from(chunk.modelViewMatrix);
- console.log(Descriptor);
- chunk.blockData.setInt8(0, 0xee);
- console.log(buffer);
- console.log(matrix);
- console.log([...chunk.modelViewMatrix]);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement