UNPKG

@blockv/threejs-to-v3d

Version:

Converts any format supported by ThreeJS to V3D.

137 lines (103 loc) 2.79 kB
// // V3DBuilder - Compiles blocks into a fully compatible .v3d file const BlobBuilder = require('./BlobBuilder'); module.exports = class V3DBuilder { constructor() { // Properties this.lastBlockID = 1; this.blocks = []; this.fileProperties = { version: 1, title: "Untitled Scene", "source.exporter": "Vatomic 3D Exporter" }; } /** Create a block */ newBlock() { // Create block var blk = new Block(); blk.builder = this; blk.id = this.lastBlockID++; // Store block this.blocks.push(blk); // Done return blk; } /** Compile file into a blob */ build() { // Create blob builder var builder = new BlobBuilder(); // Calculate header block size var fileMetaStr = JSON.stringify(this.fileProperties); var headerBlockSize = 4 + builder.stringLengthInBytes(fileMetaStr); // Write file header block builder.addByte(0x3D); builder.addByte(0x0B); builder.addByte(0x1E); builder.addByte(0xC7); builder.addString(fileMetaStr); // Calculate final size of the directory block var directoryBlockSize = 4 + 4 + 4; for (var block of this.blocks) { block.metadataStr = JSON.stringify(block.properties); block.metadataStrLen = builder.stringLengthInBytes(block.metadataStr); directoryBlockSize += 4 + 1 + 2 + block.metadataStrLen + 8 + 8; } // Write file directory block builder.addByte(0x44); builder.addByte(0x49); builder.addByte(0x52); builder.addByte(0x42); builder.addUInt32(directoryBlockSize); builder.addUInt32(this.blocks.length); for (var block of this.blocks) { // Calculate block payload offset var offset = headerBlockSize + directoryBlockSize; for (var blk of this.blocks) { offset += 4 + 4 + 1 + 8; if (blk === block) break; offset += blk.data.length; } // Add block info builder.addUInt32(block.id); builder.addUInt8(block.levelOfDetail); builder.addUInt16(block.metadataStrLen); builder.addString(block.metadataStr); builder.addUInt64(offset); builder.addUInt64(block.data.length); } // Write blocks for (var block of this.blocks) { // Write data block header builder.addByte(0x44); builder.addByte(0x41); builder.addByte(0x54); builder.addByte(0x41); builder.addUInt32(block.id); builder.addUInt8(block.levelOfDetail); builder.addUInt64(block.data.length); builder.addBlobBuilder(block.data); } // Done return builder.buildArrayBuffer(); } } class Block { constructor() { // Properties this.builder = null; this.id = 0; this.levelOfDetail = 0; this.data = new BlobBuilder(); this.properties = { type: "", parent: 0 }; } newChildBlock() { // Create new block var blk = this.builder.newBlock(); blk.properties.parent = this.id; return blk; } }