Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/components/cube-viewport-control/cube-viewport-control.component.ts is written in an unsupported language. File is not indexed.

0001 // cube-viewport-control.component.ts
0002 import { Component, ElementRef, OnInit, OnDestroy, NgZone } from '@angular/core';
0003 import { GizmoOptions, ViewportGizmo } from 'three-viewport-gizmo';
0004 import { ThreeService } from '../../services/three.service';
0005 import {
0006   OrthographicCamera,
0007   PerspectiveCamera,
0008   Scene,
0009   WebGLRenderer
0010 } from 'three';
0011 
0012 @Component({
0013   selector: 'app-cube-viewport-control',
0014   standalone: true,
0015   templateUrl: './cube-viewport-control.component.html',
0016 })
0017 export class CubeViewportControlComponent implements OnInit, OnDestroy {
0018   // References to externally provided objects
0019   public camera!: PerspectiveCamera | OrthographicCamera;
0020   public scene!: Scene;
0021   public renderer!: WebGLRenderer;
0022 
0023   // The ViewportGizmo instance
0024   public gizmo!: ViewportGizmo;
0025 
0026   private lastCamera!: PerspectiveCamera | OrthographicCamera;
0027   private animationFrameId: number | null = null;
0028 
0029   constructor(
0030     private elRef: ElementRef,
0031     private threeService: ThreeService,
0032     private ngZone: NgZone
0033   ) {}
0034 
0035   ngOnInit(): void {
0036     // We do NOT call initThreeJS() here.
0037     // The external scene/camera/renderer will be provided from outside.
0038   }
0039 
0040   ngOnDestroy(): void {
0041     // Clean up animation frame on component destruction
0042     if (this.animationFrameId !== null) {
0043       cancelAnimationFrame(this.animationFrameId);
0044     }
0045 
0046     // Clean up any event listeners
0047     this.threeService.controls.removeEventListener('change', this.handleControlsChange);
0048 
0049     // Dispose of the gizmo if it exists
0050     if (this.gizmo) {
0051       this.gizmo.dispose();
0052     }
0053   }
0054 
0055   /**
0056    * Called from the parent component (e.g. MainDisplayComponent) to link
0057    * the same scene/camera/renderer that are used for the main 3D view.
0058    */
0059   public initWithExternalScene(
0060     scene: Scene,
0061     camera: PerspectiveCamera | OrthographicCamera,
0062     renderer: WebGLRenderer
0063   ): void {
0064     this.scene = scene;
0065     this.camera = camera;
0066     this.renderer = renderer;
0067     this.lastCamera = camera;
0068 
0069     const container = this.elRef.nativeElement.querySelector('.three-container');
0070     const gizmoConfig: GizmoOptions = {
0071       container: container,
0072       size: 90,
0073       type: 'cube',
0074       offset: { top: 85 },
0075       background: { color: 0x444444, hover: { color: 0x444444 } },
0076       corners: {
0077         color: 0x333333,
0078         hover: { color: 0x4bac84 },
0079       },
0080       front: { label: "Right" },   // Original left face
0081       left: { label: "Front" },    // Original back face
0082       back: { label: "Left" },     // Original right face
0083       right: { label: "Back" }     // Original front face
0084     };
0085 
0086     // Create gizmo with custom config (autoPlace = false)
0087     this.gizmo = new ViewportGizmo(this.camera, this.renderer, gizmoConfig);
0088 
0089     // Bind the method to maintain 'this' context
0090     this.handleControlsChange = this.handleControlsChange.bind(this);
0091 
0092     // Listen for any changes to OrbitControls
0093     this.threeService.controls.addEventListener('change', this.handleControlsChange);
0094 
0095     // Start continuous update loop for the gizmo
0096     this.startGizmoUpdateLoop();
0097   }
0098 
0099   private handleControlsChange = (): void => {
0100     this.updateGizmo();
0101   }
0102 
0103   // Update the gizmo when controls change
0104   private updateGizmo(): void {
0105     if (!this.gizmo) return;
0106 
0107     // Check if camera reference has changed
0108     const current = this.threeService.camera;
0109     if (current && current !== this.lastCamera) {
0110       this.lastCamera = current;
0111       this.camera = current;
0112       this.gizmo.camera = current;
0113     }
0114 
0115     // Always update the gizmo to match camera orientation
0116     this.gizmo.cameraUpdate();
0117   }
0118 
0119   // Start a continuous update loop to keep the gizmo in sync with camera
0120   private startGizmoUpdateLoop(): void {
0121     this.ngZone.runOutsideAngular(() => {
0122       const animate = () => {
0123         this.updateGizmo();
0124         this.animationFrameId = requestAnimationFrame(animate);
0125       };
0126       this.animationFrameId = requestAnimationFrame(animate);
0127     });
0128   }
0129 }