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 }