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
text/typescript
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);
}
}