Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/services/scene-helpers.service.ts is written in an unsupported language. File is not indexed.

0001 import { Injectable } from '@angular/core';
0002 import * as THREE from 'three';
0003 import { ThreeService } from './three.service';
0004 
0005 /**
0006  * A simple service that keeps references to "helper" objects:
0007  * - Axis lines
0008  * - EtaPhi grids
0009  * - Cartesian grids
0010  * - 3D points picking
0011  * And exposes methods to toggle them on/off or move them.
0012  */
0013 @Injectable({ providedIn: 'root' })
0014 export class SceneHelpersService {
0015   private axisHelper: THREE.AxesHelper | null = null;
0016   private cartesianGridGroup: THREE.Group | null = null;
0017   private etaPhiGridGroup: THREE.Group | null = null;
0018   private labelsGroup: THREE.Group | null = null;
0019 
0020   // For "show distance" or "show 3D coords" logic:
0021   private onPointerMoveFn?: (event: MouseEvent) => void;
0022   private onPointerClickFn?: (event: MouseEvent) => void;
0023 
0024   constructor(private threeService: ThreeService) {}
0025 
0026   /**
0027    * Creates or toggles the axis lines. This uses a built-in AxesHelper or your custom approach.
0028    */
0029   setShowAxis(show: boolean) {
0030     // If we haven't created it yet, do so
0031     if (!this.axisHelper) {
0032       this.axisHelper = new THREE.AxesHelper(2000);
0033       this.axisHelper.name = "Axis";
0034       this.threeService.scene.add(this.axisHelper);
0035     }
0036     this.axisHelper.visible = show;
0037   }
0038 
0039   /**
0040    * Show/hide a cartesian grid. This can be a built-in GridHelper or a custom approach.
0041    * `scale` can define size, or you can store a config in an object.
0042    */
0043   setShowCartesianGrid(show: boolean, scale: number, config?: {
0044     showXY: boolean;
0045     showYZ: boolean;
0046     showZX: boolean;
0047     xDistance: number;
0048     yDistance: number;
0049     zDistance: number;
0050     sparsity: number;
0051   }) {
0052     if (!this.cartesianGridGroup) {
0053       // Make a group with three GridHelpers, or do your custom geometry
0054       this.cartesianGridGroup = new THREE.Group();
0055       this.cartesianGridGroup.name = 'CartesianGridGroup';
0056       // For example, add a built-in GridHelper on XZ plane:
0057       const grid = new THREE.GridHelper(scale, 20, 0xffffff, 0xffffff);
0058       grid.rotation.x = Math.PI / 2; // to show XZ?
0059       this.cartesianGridGroup.add(grid);
0060       this.cartesianGridGroup.name = "CartesianGrid"
0061       // add YZ plane, XY plane, etc., if needed...
0062       this.threeService.scene.add(this.cartesianGridGroup);
0063     }
0064     // If you want to store the config for each plane, do it here.
0065     this.cartesianGridGroup.visible = show;
0066   }
0067 
0068   /**
0069    * Show/hide an “eta-phi” grid if you want that feature.
0070    * You can create a custom geometry or skip it.
0071    */
0072   setShowEtaPhiGrid(show: boolean) {
0073     if (!this.etaPhiGridGroup) {
0074       this.etaPhiGridGroup = new THREE.Group();
0075       this.etaPhiGridGroup.name = 'EtaPhiGrid';
0076       // Build your geometry or lines for an eta-phi representation
0077       // e.g., custom circles or lines
0078       this.threeService.scene.add(this.etaPhiGridGroup);
0079     }
0080     this.etaPhiGridGroup.visible = show;
0081   }
0082 
0083   /**
0084    * Show/hide labels. If you do 2D overlays, you might skip a 3D group for labels.
0085    * Or you can do a sprite-based approach or text geometry approach.
0086    */
0087   showLabels(show: boolean) {
0088     if (!this.labelsGroup) {
0089       this.labelsGroup = new THREE.Group();
0090       this.labelsGroup.name = 'Labels';
0091       this.threeService.scene.add(this.labelsGroup);
0092       // Add text mesh or sprites as needed.
0093     }
0094     this.labelsGroup.visible = show;
0095   }
0096 
0097   /**
0098    * Show/hide 3D mouse coordinates by hooking pointer events, running a Raycaster, etc.
0099    */
0100   show3DMousePoints(show: boolean) {
0101     if (show) {
0102       // Attach event listeners
0103       this.onPointerClickFn = (evt) => this.handle3DPointClick(evt);
0104       window.addEventListener('click', this.onPointerClickFn);
0105     } else {
0106       // Remove event listeners
0107       if (this.onPointerClickFn) {
0108         window.removeEventListener('click', this.onPointerClickFn);
0109         this.onPointerClickFn = undefined;
0110       }
0111     }
0112   }
0113 
0114   private handle3DPointClick(evt: MouseEvent) {
0115     // example of raycasting
0116     const rect = this.threeService.renderer.domElement.getBoundingClientRect();
0117     const x = ((evt.clientX - rect.left) / rect.width) * 2 - 1;
0118     const y = -((evt.clientY - rect.top) / rect.height) * 2 + 1;
0119     const raycaster = new THREE.Raycaster();
0120     raycaster.setFromCamera(new THREE.Vector2(x, y), this.threeService.camera);
0121 
0122     const intersects = raycaster.intersectObjects(this.threeService.scene.children, true);
0123     if (intersects.length > 0) {
0124       const point = intersects[0].point;
0125       console.log('Clicked 3D coords:', point);
0126       // You could show an overlay or a small 3D marker, etc.
0127     }
0128   }
0129 
0130   /**
0131    * Toggle "show 3D distance" by hooking pointer events for measuring two points, etc.
0132    */
0133   show3DDistance(show: boolean) {
0134     // Similar approach: track the first click, second click, measure distance, show line, etc.
0135     console.warn('show3DDistance not implemented yet. You can replicate your old logic here.');
0136   }
0137 
0138   /**
0139    * SHIFT cartesian grid by pointer or by values. You can replicate the old logic.
0140    */
0141   shiftCartesianGridByPointer() {
0142     console.warn('shiftCartesianGridByPointer not implemented. You can replicate old logic here.');
0143   }
0144 
0145   translateCartesianGrid(shift: THREE.Vector3) {
0146     if (this.cartesianGridGroup) {
0147       this.cartesianGridGroup.position.add(shift);
0148     }
0149   }
0150 
0151   translateCartesianLabels(shift: THREE.Vector3) {
0152     // If you keep labels in a separate group or do 2D overlay, handle that here
0153   }
0154 
0155   // ...
0156   // Additional code for “preset camera views” if you want.
0157   setCameraView(targetPos: THREE.Vector3, cameraPos: THREE.Vector3) {
0158     // e.g. tween the camera, or set it instantly
0159     this.threeService.camera.position.copy(cameraPos);
0160     this.threeService.controls.target.copy(targetPos);
0161     this.threeService.controls.update();
0162   }
0163 }