Advertisement
lignite0

ROBO24 - chunk2

Oct 25th, 2019
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const regex = new RegExp(`(?<mainType>\\w+)(?:<(?<subType>\\w+)>)?(?:\\[(?<count>\\w*)\\])?`);
  2.  
  3. const vectorAxes = [
  4.     ["x", "y"],
  5.     ["x", "y", "z"],
  6.     ["x", "y", "z", "w"],
  7. ];
  8.  
  9. const Descriptor = new class Descriptor {
  10.  
  11.     constructor() {
  12.         this.types = {};
  13.         this.staticTypes = {};
  14.         this.vectorClasses = {};
  15.         this.matrixClasses = {};
  16.         this.dataViewMap = {};
  17.         this.createStaticTypes();
  18.         this.createVectorTypes();
  19.         this.createMatrixTypes();
  20.     }
  21.  
  22.     createStaticTypes() {
  23.         for (let power of [0, 1, 2, 3]) {
  24.             this.createDataViewMapElement("s", "Int", power);
  25.             this.createStaticType("s", power);
  26.             this.createDataViewMapElement("u", "Uint", power);
  27.             this.createStaticType("u", power);
  28.         }
  29.         for (let power of [2, 3]) {
  30.             this.createDataViewMapElement("f", "Float", power);
  31.             this.createStaticType("f", power);
  32.         }
  33.     }
  34.  
  35.     createDataViewMapElement(char, mapped, power) {
  36.         const bitSize = (2 ** power) * 8;
  37.         this.dataViewMap[`${char}${bitSize}`] = `${mapped}${bitSize}`;
  38.     }
  39.  
  40.     createStaticType(char, power) {
  41.         const byteSize = 2 ** power;
  42.         const bitSize = byteSize * 8;
  43.         const typeName = `${char}${bitSize}`;
  44.         const dataViewType = this.dataViewMap[typeName];
  45.  
  46.         const constructor = (function () {
  47.             return function (offset) {
  48.                 this.offset = offset;
  49.             };
  50.         })();
  51.  
  52.         const {prototype} = constructor;
  53.  
  54.         Object.defineProperty(prototype, 'typeName', {value: typeName});
  55.         Object.defineProperty(prototype, 'byteSize', {value: byteSize});
  56.         Object.defineProperty(prototype, 'getterDataViewTypeName', {value: `set${dataViewType}`});
  57.         Object.defineProperty(prototype, 'setterDataViewTypeName', {value: `set${dataViewType}`});
  58.  
  59.         prototype.get = function (object) {
  60.             return object['dataView'][this['getterDataViewTypeName']](this.offset);
  61.         };
  62.         prototype.set = function (object, value) {
  63.             return object['dataView'][this['setterDataViewTypeName']](this.offset, value);
  64.         };
  65.  
  66.         this.staticTypes[typeName] = constructor;
  67.         this.types[typeName] = constructor;
  68.     }
  69.  
  70.     createVectorTypes() {
  71.         for (let axis of vectorAxes) {
  72.             for (let staticType of Object.values(this.staticTypes)) {
  73.                 this.createVectorType(axis, staticType)
  74.             }
  75.         }
  76.     }
  77.  
  78.     createVectorType(axis, staticType) {
  79.         const {typeName: staticTypeName, byteSize: staticByteSize} = staticType.prototype;
  80.         const vectorLength = axis.length;
  81.         const vectorTypeName = `vec${vectorLength}<${staticTypeName}>`;
  82.         const vectorByteSize = vectorLength * staticByteSize;
  83.  
  84.         const constructor = (function (length) {
  85.             return function (offset) {
  86.                 this.offset = offset;
  87.                 this.length = length;
  88.             };
  89.         })(vectorLength);
  90.  
  91.         const {prototype} = constructor;
  92.  
  93.         Object.defineProperty(prototype, 'typeName', {value: vectorTypeName});
  94.         Object.defineProperty(prototype, 'byteSize', {value: vectorByteSize});
  95.         Object.defineProperty(prototype, 'axisType', {value: staticType});
  96.  
  97.         for (let [axisOffset, field] of axis.entries()) {
  98.             const offset = staticByteSize * axisOffset;
  99.             const staticProperty = new staticType(offset);
  100.             prototype[field] = staticProperty;
  101.             prototype[axisOffset] = staticProperty;
  102.         }
  103.  
  104.         this.types[vectorTypeName] = constructor;
  105.     }
  106.  
  107.     createMatrixTypes() {
  108.         for (let matrixWidth = 2; matrixWidth <= 4; matrixWidth++) {
  109.             for (let staticTypes of Object.values(this.staticTypes)) {
  110.                 this.createMatrixType(matrixWidth, staticTypes);
  111.             }
  112.         }
  113.     }
  114.  
  115.     createMatrixType(matrixWidth, staticType) {
  116.         const {typeName: staticTypeName, byteSize: staticByteSize} = staticType.prototype;
  117.         const matrixTypeName = `mat${matrixWidth}<${staticTypeName}>`;
  118.         const matrixElements = (matrixWidth ** 2);
  119.         const matrixByteSize = matrixElements * staticByteSize;
  120.  
  121.         const constructor = (function (length) {
  122.             return function (offset) {
  123.                 this.offset = offset;
  124.                 this.length = length;
  125.             };
  126.         })(matrixElements);
  127.  
  128.         const {prototype} = constructor;
  129.  
  130.         Object.defineProperty(prototype, 'typeName', {value: matrixTypeName});
  131.         Object.defineProperty(prototype, 'byteSize', {value: matrixByteSize});
  132.         Object.defineProperty(prototype, 'axisType', {value: staticType});
  133.  
  134.         for (let i = 0; i < matrixElements; i++) {
  135.             const offset = staticByteSize * i;
  136.             const staticProperty = new staticType(offset);
  137.             prototype[i] = staticProperty;
  138.         }
  139.  
  140.         this.types[matrixTypeName] = constructor;
  141.     }
  142.  
  143.     register(constructor, config) {
  144.         const {prototype} = constructor;
  145.         const context = {
  146.             prototype,
  147.             offset: 0
  148.         };
  149.         for (let propertyDeclaration of config.properties) {
  150.             //const property = this.createProperty(context, propertyDeclaration);
  151.         }
  152.     }
  153.  
  154.     createProperty(context, propertyDeclaration) {
  155.         const {type} = propertyDeclaration;
  156.         const match = regex.exec(type);
  157.         const {mainType, subType, count} = match.groups;
  158.         const typeKey = `${mainType}` + (subType ? `<${subType}>` : '');
  159.         const typeDefinition = this.types[typeKey];
  160.  
  161.         if (count === "") {
  162.             return new DynamicArrayProperty({
  163.                 name: propertyDeclaration.name,
  164.             });
  165.         }
  166.  
  167.         const parsedCount = parseInt(count);
  168.  
  169.         if (!isNaN(parsedCount)) {
  170.             return new StaticArrayProperty({
  171.                 length: parsedCount,
  172.             })
  173.         }
  174.  
  175.         const {define, size} = property.type;
  176.         const descriptor = define(property, offset);
  177.  
  178.         if (size !== undefined && offset !== undefined) {
  179.             offset += size;
  180.         } else {
  181.             offset = undefined;
  182.         }
  183.  
  184.         Object.defineProperty(prototype, property.name, descriptor);
  185.     }
  186.  
  187.     parseProperty(propertyDeclaration) {
  188.         const {type} = propertyDeclaration;
  189.         const match = regex.exec(type);
  190.         const {mainType, subType, count} = match.groups;
  191.         const typeDefinition = this.types[typeKey];
  192.  
  193.         if (typeDefinition === undefined) {
  194.             throw new Error(`Type (${type}) not exists`);
  195.         }
  196.  
  197.         const {property: propertyName, ...others} = propertyDeclaration;
  198.  
  199.         return {
  200.             name: propertyName,
  201.             ...others,
  202.             type: {
  203.                 ...typeDefinition
  204.             },
  205.         };
  206.     }
  207. };
  208.  
  209. /**
  210.  * @property tragedia
  211.  */
  212. class Chunk {
  213.     constructor(options) {
  214.         this.dataView = options['dataView'];
  215.     }
  216. }
  217.  
  218. Descriptor.register(Chunk, {
  219.     name: "Chunk",
  220.     properties: [
  221.         {type: "u8", property: "type"},
  222.         {type: "u8[8]", property: "blockBitWidth"},
  223.         {type: "vec3<u16>[4]", property: "position"},
  224.         {type: "mat4<f32>", property: "modelViewMatrix"},
  225.         {type: "u16", property: "blockDataOffset"},
  226.         {type: "u16", property: "blockIndexDataOffset"},
  227.         {type: "u16", property: "terrainDataOffset"},
  228.         {type: "u16", property: "additionalDataOffset"},
  229.         {type: "u16", property: "overrideDataOffset"},
  230.         {type: "u16", property: "blockDataSize"},
  231.         {type: "u16", property: "blockIndexDataSize"},
  232.         {type: "u16", property: "terrainDataSize"},
  233.         {type: "u16", property: "additionalDataSize"},
  234.         {type: "u16", property: "overrideDataSize"},
  235.         {type: "blob"},
  236.         {type: "blob", property: "blockData"},
  237.         {type: "blob", property: "blockIndexData"},
  238.         {type: "blob", property: "terrainData"},
  239.         {type: "blob", property: "additionalData"},
  240.         {type: "blob", property: "overrideData"},
  241.     ],
  242. });
  243.  
  244. console.log(Descriptor);
  245.  
  246. const buffer = new ArrayBuffer(1000);
  247. const dataView = new DataView(buffer, 0);
  248. dataView.setInt8(0, 0xff);
  249.  
  250. const chunk = new Chunk({dataView});
  251.  
  252. chunk.get = function (propertyName) {
  253.     const property = this.description[propertyName];
  254.  
  255.     if (property === undefined) {
  256.         throw new Error(`Cannot get property (${propertyName})`);
  257.     }
  258.  
  259.     return property.getValue(this);
  260. };
  261.  
  262. chunk.position.index(3).x.read(chunk);
  263.  
  264.  
  265. chunk.getIndex("position", 2).set(48);
  266. console.log(buffer);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement