UNPKG

mdx-m3-viewer

Version:

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

149 lines (120 loc) 5.07 kB
import MdlxParticleEmitter2 from '../../../parsers/mdlx/particleemitter2'; import Texture from '../../texture'; import MdxModel from './model'; import GenericObject from './genericobject'; import { emitterFilterMode } from './filtermode'; import replaceableIds from './replaceableids'; import { EMITTER_PARTICLE2 } from './geometryemitterfuncs'; /** * An MDX particle emitter type 2. */ export default class ParticleEmitter2Object extends GenericObject { geometryEmitterType: number = EMITTER_PARTICLE2; width: number; length: number; speed: number; latitude: number; gravity: number; emissionRate: number; squirt: number; lifeSpan: number; variation: number; tailLength: number; timeMiddle: number; columns: number; rows: number; teamColored: number = 0; internalTexture: Texture | null = null; replaceableId: number; head: boolean; tail: boolean; cellWidth: number; cellHeight: number; colors: Float32Array[] = []; scaling: Float32Array; intervals: Float32Array[]; blendSrc: number; blendDst: number; priorityPlane: number; /** * Even if the internal texture isn't loaded, it's fine to run emitters based on this emitter object. * * The particles will simply be black. */ ok: boolean = true; constructor(model: MdxModel, emitter: MdlxParticleEmitter2, index: number) { super(model, emitter, index); this.width = emitter.width; this.length = emitter.length; this.speed = emitter.speed; this.latitude = emitter.latitude; this.gravity = emitter.gravity; this.emissionRate = emitter.emissionRate; this.squirt = emitter.squirt; this.lifeSpan = emitter.lifeSpan; this.variation = emitter.variation; this.tailLength = emitter.tailLength; this.timeMiddle = emitter.timeMiddle; let replaceableId = emitter.replaceableId; this.columns = emitter.columns; this.rows = emitter.rows; if (replaceableId === 0) { this.internalTexture = model.textures[emitter.textureId]; } else if (replaceableId === 1 || replaceableId === 2) { this.teamColored = 1; } else { let texturesExt = model.reforged ? '.dds' : '.blp'; this.internalTexture = <Texture>model.viewer.load(`ReplaceableTextures\\${replaceableIds[replaceableId]}${texturesExt}`, model.pathSolver, model.solverParams); } this.replaceableId = emitter.replaceableId; let headOrTail = emitter.headOrTail; this.head = (headOrTail === 0 || headOrTail === 2); this.tail = (headOrTail === 1 || headOrTail === 2); this.cellWidth = 1 / emitter.columns; this.cellHeight = 1 / emitter.rows; let colors = emitter.segmentColors; let alpha = emitter.segmentAlphas; for (let i = 0; i < 3; i++) { let color = colors[i]; this.colors[i] = new Float32Array([color[0], color[1], color[2], alpha[i] / 255]); } this.scaling = emitter.segmentScaling; let headIntervals = emitter.headIntervals; let tailIntervals = emitter.tailIntervals; // Change to Float32Array instead of Uint32Array to be able to pass the intervals directly using uniform3fv(). this.intervals = [ new Float32Array(headIntervals[0]), new Float32Array(headIntervals[1]), new Float32Array(tailIntervals[0]), new Float32Array(tailIntervals[1]), ]; let blendModes = emitterFilterMode(emitter.filterMode, this.model.viewer.gl); this.blendSrc = blendModes[0]; this.blendDst = blendModes[1]; this.priorityPlane = emitter.priorityPlane; } getWidth(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2N', sequence, frame, counter, this.width); } getLength(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2W', sequence, frame, counter, this.length); } getSpeed(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2S', sequence, frame, counter, this.speed); } getLatitude(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2L', sequence, frame, counter, this.latitude); } getGravity(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2G', sequence, frame, counter, this.gravity); } getEmissionRate(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2E', sequence, frame, counter, this.emissionRate); } getVisibility(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2V', sequence, frame, counter, 1); } getVariation(out: Float32Array, sequence: number, frame: number, counter: number) { return this.getScalarValue(out, 'KP2R', sequence, frame, counter, this.variation); } }