UNPKG

mdx-m3-viewer

Version:

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

96 lines (75 loc) 3.31 kB
import { vec3, quat } from 'gl-matrix'; import { VEC3_UNIT_Z } from '../../../common/gl-matrix-addon'; import { randomInRange } from '../../../common/math'; import Scene from '../../scene'; import EmittedObject from '../../emittedobject'; import ParticleEmitterObject from './particleemitterobject'; import MdxModelInstance from './modelinstance'; import ParticleEmitter from './particleemitter'; const rotationHeap = quat.create(); const velocityHeap = vec3.create(); const latitudeHeap = new Float32Array(1); // const longitudeHeap = new Float32Array(1); const lifeSpanHeap = new Float32Array(1); const gravityHeap = new Float32Array(1); const speedHeap = new Float32Array(1); /** * A spawned model particle. */ export default class Particle extends EmittedObject { internalInstance: MdxModelInstance; velocity: vec3 = vec3.create(); gravity: number = 0; constructor(emitter: ParticleEmitter) { super(emitter); let emitterObject = <ParticleEmitterObject>emitter.emitterObject; this.internalInstance = <MdxModelInstance>emitterObject.internalModel.addInstance(); } bind() { let emitter = <ParticleEmitter>this.emitter; let instance = <MdxModelInstance>emitter.instance; let sequence = instance.sequence; let frame = instance.frame; let counter = instance.counter; let scene = <Scene>instance.scene; let emitterObject = <ParticleEmitterObject>emitter.emitterObject; let node = instance.nodes[emitterObject.index]; let internalInstance = this.internalInstance; let scale = node.worldScale; let velocity = this.velocity; emitterObject.getLatitude(latitudeHeap, sequence, frame, counter); // emitterObject.getLongitude(longitudeHeap, sequence, frame, counter); emitterObject.getLifeSpan(lifeSpanHeap, sequence, frame, counter); emitterObject.getGravity(gravityHeap, sequence, frame, counter); emitterObject.getSpeed(speedHeap, sequence, frame, counter); this.health = lifeSpanHeap[0]; this.gravity = gravityHeap[0] * scale[2]; // Local rotation quat.identity(rotationHeap); quat.rotateZ(rotationHeap, rotationHeap, randomInRange(-Math.PI, Math.PI)); quat.rotateY(rotationHeap, rotationHeap, randomInRange(-latitudeHeap[0], latitudeHeap[0])); vec3.transformQuat(velocity, VEC3_UNIT_Z, rotationHeap); // World rotation vec3.transformQuat(velocity, velocity, node.worldRotation); // Apply speed vec3.scale(velocity, velocity, speedHeap[0]); // Apply the parent's scale vec3.mul(velocity, velocity, scale); scene.addInstance(internalInstance); internalInstance.setTransformation(node.worldLocation, quat.setAxisAngle(rotationHeap, VEC3_UNIT_Z, randomInRange(0, Math.PI * 2)), node.worldScale); internalInstance.setSequence(0); internalInstance.show(); } update(dt: number) { let internalInstance = this.internalInstance; internalInstance.paused = false; /// Why is this here? this.health -= dt; if (this.health > 0) { let velocity = this.velocity; velocity[2] -= this.gravity * dt; internalInstance.move(vec3.scale(velocityHeap, velocity, dt)); } else { internalInstance.hide(); } } }