Warning, /firebird/packages/epic/src/epic-collision-intro.ts is written in an unsupported language. File is not indexed.
0001 /**
0002 * The ePIC collision intro: the electron (blue, from +z) and the ion (red,
0003 * twice the size, from -z) fade in and fly to the interaction point, where
0004 * the event's time animation takes over. Registered by `withEpic()` through
0005 * a dynamic import (three.js).
0006 */
0007
0008 import { Mesh, MeshBasicMaterial, Object3D, SphereGeometry } from 'three';
0009 import type { CollisionIntro } from '@dexvis/firebird-ng';
0010
0011 /** Distance from the interaction point at which the beams start [mm]. */
0012 const START_DISTANCE = 5000;
0013 /** Electron sphere radius [mm]; the ion sphere is twice as large. */
0014 const ELECTRON_RADIUS = 30;
0015 /** Fade-in time of both spheres [ms]. */
0016 const FADE_IN_MS = 300;
0017
0018 export class EpicCollisionIntro implements CollisionIntro {
0019 readonly durationMs = 1000;
0020
0021 private electron: Mesh<SphereGeometry, MeshBasicMaterial> | null = null;
0022 private ion: Mesh<SphereGeometry, MeshBasicMaterial> | null = null;
0023
0024 begin(parent: Object3D): void {
0025 this.electron = this.beamParticle(ELECTRON_RADIUS, 0x0000FF);
0026 this.ion = this.beamParticle(2 * ELECTRON_RADIUS, 0xFF0000);
0027 parent.add(this.electron, this.ion);
0028 this.update(0);
0029 }
0030
0031 update(elapsedMs: number): void {
0032 if (!this.electron || !this.ion) return;
0033 // Linear in time: the spheres meet at the interaction point at durationMs
0034 const opacity = Math.min(1, elapsedMs / FADE_IN_MS);
0035 const distance = START_DISTANCE * (1 - Math.min(1, elapsedMs / this.durationMs));
0036 this.electron.material.opacity = opacity;
0037 this.ion.material.opacity = opacity;
0038 this.electron.position.setZ(distance);
0039 this.ion.position.setZ(-distance);
0040 }
0041
0042 end(): void {
0043 for (const particle of [this.electron, this.ion]) {
0044 if (!particle) continue;
0045 particle.removeFromParent();
0046 particle.geometry.dispose();
0047 particle.material.dispose();
0048 }
0049 this.electron = null;
0050 this.ion = null;
0051 }
0052
0053 private beamParticle(radius: number, color: number): Mesh<SphereGeometry, MeshBasicMaterial> {
0054 return new Mesh(
0055 new SphereGeometry(radius, 32, 32),
0056 new MeshBasicMaterial({ color, transparent: true, opacity: 0 }),
0057 );
0058 }
0059 }