UNPKG

source-mdl

Version:

This package can read source engines MDL files. To parse a model, it needs the VTX, VVD and MDL file.

133 lines (110 loc) 3.47 kB
const Import = require("./import/Import.js"); const toGLTF = require("./export/toGLTF.js"); const toOBJ = require("./export/toOBJ.js"); const toXMODEL = require("./export/toXMODEL.js"); const FLAGS = { 0: "STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX", 1: "STUDIOHDR_FLAGS_USES_ENV_CUBEMAP", 2: "STUDIOHDR_FLAGS_FORCE_OPAQUE", 3: "STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS", 4: "STUDIOHDR_FLAGS_STATIC_PROP", 5: "STUDIOHDR_FLAGS_USES_FB_TEXTURE", 6: "STUDIOHDR_FLAGS_HASSHADOWLOD", 7: "STUDIOHDR_FLAGS_USES_BUMPMAPPING", 8: "STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS", 9: "STUDIOHDR_FLAGS_OBSOLETE", 10: "STUDIOHDR_FLAGS_UNUSED", 11: "STUDIOHDR_FLAGS_NO_FORCED_FADE", 12: "STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE", 13: "STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT", 14: "STUDIOHDR_FLAGS_FLEXES_CONVERTED", 15: "STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE", 16: "STUDIOHDR_FLAGS_AMBIENT_BOOST", 17: "STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS", 18: "STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS" } class MDL { constructor() { this.name = ""; this.hasGeometry = false; this.eyeposition = [0, 0, 0]; this.illumposition = [0, 0, 0]; this.hullMin = [-1, -1, -1]; this.hullMax = [1, 1, 1]; this.viewBBMin = [0, 0, 0]; this.viewBBMax = [0, 0, 0]; this.flags = 0; this.mass = 0; this.surfaceProp = ""; this.keyvalues = []; this.bones = []; this.hitboxes = []; this.textures = []; this.textureDirs = [], // First layer: LOD, Second layer: Mesh this.meshes = []; // First Layer: LOD, Second layer: Vertice this.vertices = []; this.raw = {}; } getMetadata() { return { name: this.name, mass: this.mass, flags: this.getFlagStrings(), surfaceProp: this.surfaceProp, LODs: this.vertices.length, verticeNumber: this.vertices.length ? this.vertices[0].length : 0, textures: this.textures, textureDirs: this.textureDirs } } _flipFlags(flags) { /** * @todo Test this */ let flagsFlipped = 0; for (let i = 0; i < 4; i++) { for (let j = 0; j < 8; j++) { flagsFlipped |= (flags & (i * 8 + (8 - j))) << (i * 8 + j); } } return flagsFlipped; } getFlagStrings() { let flagsFlipped = this._flipFlags(this.flags); let out = []; for (let i = 0; i < 19; i++) { let bit = (this.flags << i) & 1; if (bit) { out.push(FLAGS[i]); } } for (let i = 19; i < 32; i++) { let bit = (flagsFlipped << i) & 1; if (bit) { out.push("UNKOWN FLAG: " + i); } } return out; } import(datas) { new Import(datas, this); } toGLTF() { if (!this.hasGeometry) throw new Error("No Geometry data is present. This most likely because no VVD and VTX file was supplied to the importer"); return toGLTF(this); } toObj() { if (!this.hasGeometry) throw new Error("No Geometry data is present. This most likely because no VVD and VTX file was supplied to the importer"); return toOBJ(this); } toXMODEL() { if (!this.hasGeometry) throw new Error("No Geometry data is present. This most likely because no VVD and VTX file was supplied to the importer"); return toXMODEL(this); } toData() { return this.raw; } } module.exports = MDL;