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 }