UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

138 lines (108 loc) 3.23 kB
import BinaryStream from '../../common/binarystream'; import TokenStream from './tokenstream'; import Layer from './layer'; /** * A material. */ export default class Material { priorityPlane: number = 0; flags: number = 0; /** * @since 900 */ shader: string = ''; layers: Layer[] = []; readMdx(stream: BinaryStream, version: number) { stream.readUint32(); // Don't care about the size. this.priorityPlane = stream.readInt32(); this.flags = stream.readUint32(); if (version > 800) { this.shader = stream.read(80); } stream.skip(4); // LAYS for (let i = 0, l = stream.readUint32(); i < l; i++) { let layer = new Layer(); layer.readMdx(stream, version); this.layers.push(layer); } } writeMdx(stream: BinaryStream, version: number) { stream.writeUint32(this.getByteLength(version)); stream.writeInt32(this.priorityPlane); stream.writeUint32(this.flags); if (version > 800) { stream.write(this.shader); stream.skip(80 - this.shader.length); } stream.write('LAYS'); stream.writeUint32(this.layers.length); for (let layer of this.layers) { layer.writeMdx(stream, version); } } readMdl(stream: TokenStream) { for (let token of stream.readBlock()) { if (token === 'ConstantColor') { this.flags |= 0x1; } else if (token === 'TwoSided') { this.flags |= 0x2; } else if (token === 'SortPrimsNearZ') { this.flags |= 0x8; } else if (token === 'SortPrimsFarZ') { this.flags |= 0x10; } else if (token === 'FullResolution') { this.flags |= 0x20; } else if (token === 'PriorityPlane') { this.priorityPlane = stream.readInt(); } else if (token === 'Shader') { this.shader = stream.read(); } else if (token === 'Layer') { let layer = new Layer(); layer.readMdl(stream); this.layers.push(layer); } else { throw new Error(`Unknown token in Material: "${token}"`); } } } writeMdl(stream: TokenStream, version: number) { stream.startBlock('Material'); if (this.flags & 0x1) { stream.writeFlag('ConstantColor'); } if (version > 800) { if (this.flags & 0x2) { stream.writeFlag('TwoSided'); } } if (this.flags & 0x8) { stream.writeFlag('SortPrimsNearZ'); } if (this.flags & 0x10) { stream.writeFlag('SortPrimsFarZ'); } if (this.flags & 0x20) { stream.writeFlag('FullResolution'); } if (this.priorityPlane !== 0) { stream.writeNumberAttrib('PriorityPlane', this.priorityPlane); } if (version > 800) { stream.writeStringAttrib('Shader', this.shader) } for (let layer of this.layers) { layer.writeMdl(stream, version); } stream.endBlock(); } getByteLength(version: number) { let size = 20; if (version > 800) { size += 80; } for (let layer of this.layers) { size += layer.getByteLength(version); } return size; } }