UNPKG

mdx-m3-viewer

Version:

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

186 lines (154 loc) 4.78 kB
import Model from '../../../parsers/mdlx/model'; import GenericObject from '../../../parsers/mdlx/genericobject'; import { getObjectName, MdlxType } from './utils'; export interface SanityTestMessage { type: 'error' | 'severe' | 'warning' | 'unused'; message: string; } export interface SanityTestNode { type: 'node'; name: string; errors: number; severe: number; warnings: number; unused: number; nodes: (SanityTestNode | SanityTestMessage)[]; uses?: number; } export default class SanityTestData { model: Model; objects: GenericObject[] = []; current: SanityTestNode; stack: SanityTestNode[]; map: Map<MdlxType, SanityTestNode> = new Map(); foundStand: boolean = false; foundDeath: boolean = false; constructor(model: Model) { this.model = model; this.current = { type: 'node', name: '', errors: 0, severe: 0, warnings: 0, unused: 0, nodes: [] }; this.stack = [this.current]; this.addObjects(model.sequences); this.addObjects(model.globalSequences); this.addObjects(model.textures); this.addObjects(model.materials); this.addObjects(model.textureAnimations); this.addObjects(model.geosets); this.addObjects(model.geosetAnimations); this.addObjects(model.bones); this.addObjects(model.lights); this.addObjects(model.helpers); this.addObjects(model.attachments); this.addObjects(model.particleEmitters); this.addObjects(model.particleEmitters2); this.addObjects(model.particleEmittersPopcorn); this.addObjects(model.ribbonEmitters); this.addObjects(model.cameras); this.addObjects(model.eventObjects); this.addObjects(model.collisionShapes); this.addObjects(model.faceEffects); } /** * Adds nodes for all of the given objects. * Also handles the flat array of generic objects. */ addObjects(objects: MdlxType[]) { if (objects.length) { let areGeneric = objects[0] instanceof GenericObject; for (let i = 0, l = objects.length; i < l; i++) { let object = objects[i]; let name = getObjectName(object, i); let node = <SanityTestNode>{ type: 'node', name, errors: 0, severe: 0, warnings: 0, unused: 0, nodes: [] }; if (!areGeneric) { node.uses = 0; } this.map.set(object, node); } if (areGeneric) { this.objects.push(...<GenericObject[]>objects); } } } /** * Pushes to the stack the node the given object maps to. * If this node does not exist, a new one will be created, which is used by internal nodes like material layers. */ push(object: MdlxType, index: number) { let node = this.map.get(object); if (!node) { let name = getObjectName(object, index); node = <SanityTestNode>{ type: 'node', name, errors: 0, severe: 0, warnings: 0, unused: 0, nodes: [] }; } this.current.nodes.push(node); this.current = node; this.stack.unshift(node); } /** * Pops the current node from the stack. */ pop() { this.stack.shift(); this.current = this.stack[0]; } /** * Adds a reference to the node the given object maps to. */ addReference(object: MdlxType) { let node = <SanityTestNode>this.map.get(object); if (node.uses !== undefined) { node.uses += 1; } } /** * Add a reference to the current node. */ addImplicitReference() { let node = this.current; if (node.uses !== undefined) { node.uses += 1; } } addError(message: string) { this.current.nodes.push({ type: 'error', message }); for (let node of this.stack) { node.errors += 1; } } addSevere(message: string) { this.current.nodes.push({ type: 'severe', message }); for (let node of this.stack) { node.severe += 1; } } addWarning(message: string) { this.current.nodes.push({ type: 'warning', message }); for (let node of this.stack) { node.warnings += 1; } } addUnused(message: string) { this.current.nodes.push({ type: 'unused', message }); for (let node of this.stack) { node.unused += 1; } } assertError(condition: boolean, message: string) { if (!condition) { this.addError(message); } } assertSevere(condition: boolean, message: string) { if (!condition) { this.addSevere(message); } } assertWarning(condition: boolean, message: string) { if (!condition) { this.addWarning(message); } } assertUnused(condition: boolean, message: string) { if (!condition) { this.addUnused(message); } } }