Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-core/src/painters/box-hit-simple.painter.ts is written in an unsupported language. File is not indexed.

0001 import {
0002   Object3D,
0003   Mesh,
0004   BoxGeometry,
0005   MeshBasicMaterial,
0006   Color,
0007 } from 'three';
0008 import { EventPiecePainter } from './event-piece-painter';
0009 import { BoxHitPiece } from '../model/box-hit.piece';
0010 import { EventPiece } from '../model/event-piece';
0011 
0012 /**
0013  * Alternative Painter class for rendering BoxHitPiece using individual Meshes.
0014  */
0015 export class BoxHitSimplePainter extends EventPiecePainter {
0016   /** Array of Mesh objects representing hits */
0017   private hitMeshes: Mesh[] = [];
0018 
0019   private boxPiece: BoxHitPiece;
0020 
0021   /**
0022    * Constructs a new BoxHitAlternativePainter.
0023    *
0024    * @param parentNode - The Object3D node where the hit meshes will be added.
0025    * @param piece - The BoxHitPiece containing the hit data.
0026    */
0027   constructor(parentNode: Object3D, piece: EventPiece) {
0028     super(parentNode, piece);
0029 
0030     // Runtime type check
0031     if (piece.type !== BoxHitPiece.type) {
0032       throw new Error('Invalid piece type for BoxHitAlternativePainter');
0033     }
0034 
0035     this.boxPiece = piece as BoxHitPiece;
0036 
0037     // Create a bright random color for this piece collection
0038     const hue = Math.random();
0039     const randomColor = new Color().setHSL(hue, 1, 0.5); // Bright color
0040 
0041     // Create a material with the random color
0042     const material = new MeshBasicMaterial({ color: randomColor });
0043 
0044     // Create a mesh for each hit using the same material
0045     this.createHitMeshes(material);
0046   }
0047 
0048   /**
0049    * Creates Mesh instances for each hit and adds them to the parent node.
0050    * Reads the piece columns directly: hit i lives at pos[3i..3i+2].
0051    *
0052    * @param material - The material to use for the hit meshes.
0053    */
0054   private createHitMeshes(material: MeshBasicMaterial): void {
0055     const piece = this.boxPiece;
0056     for (let i = 0; i < piece.count; i++) {
0057       // Create geometry for the box
0058       const geometry = new BoxGeometry(10, 10, 10);
0059 
0060       // Create the mesh
0061       const mesh = new Mesh(geometry, material);
0062 
0063       // Set position
0064       mesh.position.set(piece.pos[3 * i], piece.pos[3 * i + 1], piece.pos[3 * i + 2]);
0065 
0066       // Store the hit time (0 = always visible when no time column)
0067       mesh.userData['appearanceTime'] = piece.time !== null ? piece.time[i] : 0;
0068 
0069       // Initially make the mesh invisible
0070       mesh.visible = false;
0071 
0072       // Selection mapping: hit id ≡ index. The material is shared by all
0073       // hits, so the highlight scales the mesh instead of recoloring it.
0074       this.registerEntityObject(i, mesh);
0075       mesh.userData['highlightFunction'] = () => mesh.scale.setScalar(2.5);
0076       mesh.userData['unhighlightFunction'] = () => mesh.scale.setScalar(1);
0077 
0078       // Add the mesh to the parent node and to the array
0079       this.parentNode.add(mesh);
0080       this.hitMeshes.push(mesh);
0081     }
0082   }
0083 
0084   /**
0085    * Paint method to update the visibility of the hits based on time.
0086    *
0087    * @param time - The current time in nanoseconds or null for static rendering.
0088    */
0089   public paint(time: number | null): void {
0090     for (const mesh of this.hitMeshes) {
0091       if (time !== null) {
0092         // Show the mesh if its appearance time is less than or equal to the current time
0093         mesh.visible = mesh.userData['appearanceTime'] <= time;
0094       } else {
0095         // In static mode, make all meshes visible
0096         mesh.visible = true;
0097       }
0098     }
0099   }
0100 
0101   /**
0102    * Dispose of resources used by the painter.
0103    */
0104   override dispose(): void {
0105     for (const mesh of this.hitMeshes) {
0106       // Dispose of geometry and material
0107       mesh.geometry.dispose();
0108 
0109       // Dispose of the material only if it's not shared with other meshes
0110       if (mesh.material instanceof MeshBasicMaterial) {
0111         mesh.material.dispose();
0112       }
0113 
0114       // Remove the mesh from the parent node
0115       this.parentNode.remove(mesh);
0116     }
0117 
0118     // Clear the array
0119     this.hitMeshes = [];
0120 
0121     super.dispose();
0122   }
0123 }