Warning, /firebird/firebird-ng/src/app/utils/phoenix-three-facade.ts is written in an unsupported language. File is not indexed.
0001 // PhoenixThreeFacade.ts
0002
0003 import * as THREE from "three";
0004 import { EventDisplay, RendererManager } from "phoenix-event-display";
0005 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
0006
0007 /**
0008 * PhoenixThreeFacade serves as a facade to encapsulate and abstract
0009 * the functionalities provided by phoenix-event-display and phoenix-ui-components.
0010 * It provides a flat API for interacting with Three.js components.
0011 */
0012 export class PhoenixThreeFacade {
0013
0014 private eventDisplay: EventDisplay;
0015 private threeManager: any; // Replace 'any' with the actual type if available
0016 private rendererManager: RendererManager;
0017
0018 /**
0019 * Constructor initializes the facade with an instance of EventDisplay.
0020 * @param eventDisplay An instance of EventDisplay from phoenix-event-display.
0021 */
0022 constructor(eventDisplay: EventDisplay) {
0023 this.eventDisplay = eventDisplay;
0024 this.threeManager = this.eventDisplay.getThreeManager();
0025 this.rendererManager = this.threeManager.rendererManager as RendererManager;
0026 }
0027
0028 /**
0029 * Retrieves the Three.js Scene.
0030 * @returns The current THREE.Scene instance.
0031 */
0032 public getScene(): THREE.Scene {
0033 return this.threeManager.getSceneManager().getScene();
0034 }
0035
0036 /**
0037 * Retrieves all geometries in the scene.
0038 * @returns An array of THREE.Geometry or THREE.BufferGeometry instances.
0039 */
0040 public getSceneGeometries(): any {
0041 return this.threeManager.getSceneManager().getGeometries();
0042 }
0043
0044 /**
0045 * Retrieves the main Three.js Renderer.
0046 * @returns The main THREE.WebGLRenderer instance.
0047 */
0048 public getMainRenderer(): THREE.WebGLRenderer {
0049 return this.rendererManager.getMainRenderer();
0050 }
0051
0052 /**
0053 * Retrieves the main camera used in the scene.
0054 * @returns The main THREE.Camera instance.
0055 */
0056 public getMainCamera(): THREE.Camera {
0057 return this.threeManager.controlsManager.getMainCamera();
0058 }
0059
0060 /**
0061 * Retrieves the currently active camera.
0062 * @returns The active THREE.Camera instance.
0063 */
0064 public getActiveCamera(): THREE.Camera {
0065 return this.threeManager.controlsManager.getActiveCamera();
0066 }
0067
0068 /**
0069 * Retrieves the active OrbitControls instance.
0070 * @returns The active OrbitControls instance.
0071 */
0072 public getActiveOrbitControls(): OrbitControls {
0073 return this.threeManager.controlsManager.getActiveControls() as OrbitControls;
0074 }
0075
0076 /**
0077 * Retrieves the event data associated with the scene.
0078 * @returns The current event data.
0079 */
0080 public getSceneEventData(): any { // Replace 'any' with the actual event data type
0081 return this.threeManager.getSceneManager().getEventData();
0082 }
0083
0084 /**
0085 * Sets the size of the renderer and updates the camera projections.
0086 * @param width The new width in pixels.
0087 * @param height The new height in pixels.
0088 */
0089 public setSize(width: number, height: number): void {
0090
0091 // Update Perspective Camera
0092 if (!this.threeManager.isOrthographic && this.getMainCamera() instanceof THREE.PerspectiveCamera) {
0093 const perspectiveCamera = this.getMainCamera() as THREE.PerspectiveCamera;
0094 perspectiveCamera.aspect = width / height;
0095 perspectiveCamera.updateProjectionMatrix();
0096 }
0097
0098 // Update Orthographic Camera if applicable
0099 if (this.threeManager.isOrthographic && this.getMainCamera() instanceof THREE.OrthographicCamera) {
0100 const orthographicCamera = this.getMainCamera() as THREE.OrthographicCamera;
0101 const frustumSize = 2000;
0102 const aspect = width / height;
0103 orthographicCamera.left = (-frustumSize * aspect) / 2;
0104 orthographicCamera.right = (frustumSize * aspect) / 2;
0105 orthographicCamera.top = frustumSize / 2;
0106 orthographicCamera.bottom = -frustumSize / 2;
0107 orthographicCamera.updateProjectionMatrix();
0108 }
0109
0110 // Update OrbitControls
0111 this.getActiveOrbitControls().update();
0112 }
0113
0114 /**
0115 * Starts the animation loop for rendering the scene.
0116 */
0117 public animate(): void {
0118 const animateLoop = () => {
0119 requestAnimationFrame(animateLoop);
0120 this.getMainRenderer().render(this.getScene(), this.getMainCamera());
0121 };
0122 animateLoop();
0123 }
0124
0125 /**
0126 * Adds a mesh to the scene.
0127 * @param geometry The geometry of the mesh.
0128 * @param material The material of the mesh.
0129 * @returns The created THREE.Mesh instance.
0130 */
0131 public addMesh(geometry: THREE.BufferGeometry, material: THREE.Material): THREE.Mesh {
0132 const mesh = new THREE.Mesh(geometry, material);
0133 this.getScene().add(mesh);
0134 return mesh;
0135 }
0136
0137 /**
0138 * Removes a mesh from the scene.
0139 * @param mesh The THREE.Mesh instance to remove.
0140 */
0141 public removeMesh(mesh: THREE.Mesh): void {
0142 this.getScene().remove(mesh);
0143 }
0144
0145 /**
0146 * Clears all objects from the scene.
0147 */
0148 public clearScene(): void {
0149 while (this.getScene().children.length > 0) {
0150 this.getScene().remove(this.getScene().children[0]);
0151 }
0152 }
0153
0154 /**
0155 * Retrieves the Three.js Manager instance.
0156 * @returns The ThreeManager instance.
0157 */
0158 public getThreeManager(): any { // Replace 'any' with the actual ThreeManager type
0159 return this.threeManager;
0160 }
0161
0162 /**
0163 * Retrieves the RendererManager instance.
0164 * @returns The RendererManager instance.
0165 */
0166 public getRendererManager(): RendererManager {
0167 return this.rendererManager;
0168 }
0169
0170 /**
0171 * Switches between Perspective and Orthographic cameras.
0172 * @param useOrthographic If true, switches to Orthographic camera; otherwise, Perspective.
0173 */
0174 public switchCameraMode(useOrthographic: boolean): void {
0175 this.threeManager.isOrthographic = useOrthographic;
0176 this.threeManager.controlsManager.switchCameraMode(useOrthographic);
0177 this.setSize(this.getMainRenderer().domElement.clientWidth, this.getMainRenderer().domElement.clientHeight);
0178 }
0179
0180 /**
0181 * Toggles the visibility of the grid helper in the scene.
0182 * @param visible If true, shows the grid; otherwise, hides it.
0183 */
0184 public toggleGridHelper(visible: boolean): void {
0185 const gridHelper = this.getScene().getObjectByName("GridHelper") as THREE.GridHelper;
0186 if (gridHelper) {
0187 gridHelper.visible = visible;
0188 } else if (visible) {
0189 const newGridHelper = new THREE.GridHelper(1000, 100);
0190 newGridHelper.name = "GridHelper";
0191 this.getScene().add(newGridHelper);
0192 }
0193 }
0194
0195 /**
0196 * Adds a point light to the scene.
0197 * @param color The color of the light.
0198 * @param intensity The intensity of the light.
0199 * @param distance The maximum range of the light.
0200 * @returns The created THREE.PointLight instance.
0201 */
0202 public addPointLight(color: number, intensity: number, distance: number): THREE.PointLight {
0203 const pointLight = new THREE.PointLight(color, intensity, distance);
0204 this.getScene().add(pointLight);
0205 return pointLight;
0206 }
0207
0208 /**
0209 * Removes a light from the scene.
0210 * @param light The THREE.Light instance to remove.
0211 */
0212 public removeLight(light: THREE.Light): void {
0213 this.getScene().remove(light);
0214 }
0215
0216 /**
0217 * Updates the renderer's pixel ratio.
0218 * @param ratio The new pixel ratio.
0219 */
0220 public setPixelRatio(ratio: number): void {
0221 this.getMainRenderer().setPixelRatio(ratio);
0222 }
0223
0224 /**
0225 * Enables or disables antialiasing in the renderer.
0226 * Note: Changing antialiasing on the fly may require reinitializing the renderer.
0227 * @param enabled If true, enables antialiasing; otherwise, disables it.
0228 */
0229 public toggleAntialiasing(enabled: boolean): void {
0230 // Antialiasing cannot be toggled on the fly; requires reinitialization.
0231 // This method can be implemented to recreate the renderer if needed.
0232 console.warn("Antialiasing toggle not implemented. Requires renderer reinitialization.");
0233 }
0234
0235 /**
0236 * Updates the background color of the scene.
0237 * @param color The new background color as a hexadecimal number.
0238 */
0239 public setBackgroundColor(color: number): void {
0240 this.getScene().background = new THREE.Color(color);
0241 }
0242
0243 /**
0244 * Adds an axis helper to the scene.
0245 * @param size The length of the axes.
0246 * @returns The created THREE.AxesHelper instance.
0247 */
0248 public addAxesHelper(size: number = 5): THREE.AxesHelper {
0249 const axesHelper = new THREE.AxesHelper(size);
0250 this.getScene().add(axesHelper);
0251 return axesHelper;
0252 }
0253
0254 /**
0255 * Removes the axis helper from the scene.
0256 * @param axesHelper The THREE.AxesHelper instance to remove.
0257 */
0258 public removeAxesHelper(axesHelper: THREE.AxesHelper): void {
0259 this.getScene().remove(axesHelper);
0260 }
0261
0262 /**
0263 * Adds a fog effect to the scene.
0264 * @param color The color of the fog.
0265 * @param near The near distance where the fog starts.
0266 * @param far The far distance where the fog fully obscures objects.
0267 */
0268 public addFog(color: number, near: number, far: number): void {
0269 this.getScene().fog = new THREE.Fog(color, near, far);
0270 }
0271
0272 /**
0273 * Removes the fog effect from the scene.
0274 */
0275 public removeFog(): void {
0276 this.getScene().fog = null;
0277 }
0278
0279 /**
0280 * Switches the active camera.
0281 * @param camera The THREE.Camera instance to activate.
0282 */
0283 public switchActiveCamera(camera: THREE.Camera): void {
0284 this.threeManager.controlsManager.setActiveCamera(camera);
0285 this.setSize(this.getMainRenderer().domElement.clientWidth, this.getMainRenderer().domElement.clientHeight);
0286 }
0287
0288 /**
0289 * Retrieves the current pixel ratio of the renderer.
0290 * @returns The pixel ratio as a number.
0291 */
0292 public getPixelRatio(): number {
0293 return this.getMainRenderer().getPixelRatio();
0294 }
0295
0296 /**
0297 * Retrieves the current aspect ratio of the main camera.
0298 * @returns The aspect ratio as a number.
0299 */
0300 public getCameraAspectRatio(): number {
0301 const camera = this.getMainCamera();
0302 if (camera instanceof THREE.PerspectiveCamera) {
0303 return camera.aspect;
0304 }
0305 return 1; // Default aspect ratio for non-perspective cameras
0306 }
0307
0308 /**
0309 * Updates the camera's field of view.
0310 * @param fov The new field of view in degrees.
0311 */
0312 public updateCameraFOV(fov: number): void {
0313 const camera = this.getMainCamera();
0314 if (camera instanceof THREE.PerspectiveCamera) {
0315 camera.fov = fov;
0316 camera.updateProjectionMatrix();
0317 }
0318 }
0319
0320 /**
0321 * Enables or disables shadows in the renderer.
0322 * @param enabled If true, enables shadows; otherwise, disables them.
0323 */
0324 public toggleShadows(enabled: boolean): void {
0325 this.getMainRenderer().shadowMap.enabled = enabled;
0326 }
0327
0328 /**
0329 * Adds a grid helper to the scene.
0330 * @param size The size of the grid.
0331 * @param divisions The number of divisions in the grid.
0332 * @returns The created THREE.GridHelper instance.
0333 */
0334 public addGridHelper(size: number = 10, divisions: number = 10): THREE.GridHelper {
0335 const gridHelper = new THREE.GridHelper(size, divisions);
0336 gridHelper.name = "GridHelper";
0337 this.getScene().add(gridHelper);
0338 return gridHelper;
0339 }
0340
0341 /**
0342 * Removes the grid helper from the scene.
0343 */
0344 public removeGridHelper(): void {
0345 const gridHelper = this.getScene().getObjectByName("GridHelper") as THREE.GridHelper;
0346 if (gridHelper) {
0347 this.getScene().remove(gridHelper);
0348 }
0349 }
0350
0351 /**
0352 * Retrieves the current aspect ratio of the active camera.
0353 * @returns The aspect ratio as a number.
0354 */
0355 public getActiveCameraAspectRatio(): number {
0356 const camera = this.getActiveCamera();
0357 if (camera instanceof THREE.PerspectiveCamera) {
0358 return camera.aspect;
0359 }
0360 return 1; // Default aspect ratio for non-perspective cameras
0361 }
0362
0363 /**
0364 * Retrieves the current renderer size.
0365 * @returns An object containing width and height in pixels.
0366 */
0367 public getRendererSize(): { width: number; height: number } {
0368 return {
0369 width: this.getMainRenderer().domElement.clientWidth,
0370 height: this.getMainRenderer().domElement.clientHeight,
0371 };
0372 }
0373
0374 /**
0375 * Updates the renderer's size based on provided dimensions.
0376 * @param width The new width in pixels.
0377 * @param height The new height in pixels.
0378 */
0379 public updateRendererSize(width: number, height: number): void {
0380 this.setSize(width, height);
0381 }
0382
0383 /**
0384 * Enables or disables the visibility of OrbitControls.
0385 * @param enabled If true, enables OrbitControls; otherwise, disables them.
0386 */
0387 public toggleOrbitControls(enabled: boolean): void {
0388 this.getActiveOrbitControls().enabled = enabled;
0389 }
0390
0391 /**
0392 * Sets the target point for OrbitControls to look at.
0393 * @param x The x-coordinate of the target.
0394 * @param y The y-coordinate of the target.
0395 * @param z The z-coordinate of the target.
0396 */
0397 public setOrbitControlsTarget(x: number, y: number, z: number): void {
0398 this.getActiveOrbitControls().target.set(x, y, z);
0399 this.getActiveOrbitControls().update();
0400 }
0401
0402 /**
0403 * Retrieves the current target point of OrbitControls.
0404 * @returns An instance of THREE.Vector3 representing the target point.
0405 */
0406 public getOrbitControlsTarget(): THREE.Vector3 {
0407 return this.getActiveOrbitControls().target.clone();
0408 }
0409
0410 /**
0411 * Adds ambient light to the scene.
0412 * @param color The color of the ambient light.
0413 * @param intensity The intensity of the ambient light.
0414 * @returns The created THREE.AmbientLight instance.
0415 */
0416 public addAmbientLight(color: number, intensity: number): THREE.AmbientLight {
0417 const ambientLight = new THREE.AmbientLight(color, intensity);
0418 this.getScene().add(ambientLight);
0419 return ambientLight;
0420 }
0421
0422 /**
0423 * Removes ambient light from the scene.
0424 * @param ambientLight The THREE.AmbientLight instance to remove.
0425 */
0426 public removeAmbientLight(ambientLight: THREE.AmbientLight): void {
0427 this.getScene().remove(ambientLight);
0428 }
0429
0430 /**
0431 * Adds a directional light to the scene.
0432 * @param color The color of the directional light.
0433 * @param intensity The intensity of the directional light.
0434 * @param position The position of the directional light.
0435 * @returns The created THREE.DirectionalLight instance.
0436 */
0437 public addDirectionalLight(color: number, intensity: number, position: THREE.Vector3): THREE.DirectionalLight {
0438 const directionalLight = new THREE.DirectionalLight(color, intensity);
0439 directionalLight.position.copy(position);
0440 this.getScene().add(directionalLight);
0441 return directionalLight;
0442 }
0443
0444 /**
0445 * Removes a directional light from the scene.
0446 * @param directionalLight The THREE.DirectionalLight instance to remove.
0447 */
0448 public removeDirectionalLight(directionalLight: THREE.DirectionalLight): void {
0449 this.getScene().remove(directionalLight);
0450 }
0451
0452 /**
0453 * Adds a custom object to the scene.
0454 * @param object The THREE.Object3D instance to add.
0455 */
0456 public addObject(object: THREE.Object3D): void {
0457 this.getScene().add(object);
0458 }
0459
0460 /**
0461 * Removes a custom object from the scene.
0462 * @param object The THREE.Object3D instance to remove.
0463 */
0464 public removeObject(object: THREE.Object3D): void {
0465 this.getScene().remove(object);
0466 }
0467
0468 /**
0469 * Updates the position of the main camera.
0470 * @param x The x-coordinate.
0471 * @param y The y-coordinate.
0472 * @param z The z-coordinate.
0473 */
0474 public updateCameraPosition(x: number, y: number, z: number): void {
0475 const camera = this.getMainCamera();
0476 camera.position.set(x, y, z);
0477 camera.updateMatrix();
0478 this.getActiveOrbitControls().update();
0479 }
0480
0481 /**
0482 * Rotates the main camera around a specified axis.
0483 * @param axis The axis to rotate around (e.g., 'x', 'y', 'z').
0484 * @param angle The angle in radians.
0485 */
0486 public rotateCamera(axis: 'x' | 'y' | 'z', angle: number): void {
0487 const camera = this.getMainCamera();
0488 camera.rotateOnAxis(new THREE.Vector3(
0489 axis === 'x' ? 1 : 0,
0490 axis === 'y' ? 1 : 0,
0491 axis === 'z' ? 1 : 0
0492 ), angle);
0493 camera.updateMatrix();
0494 this.getActiveOrbitControls().update();
0495 }
0496
0497 /**
0498 * Switches the active camera to a new camera.
0499 * @param newCamera The THREE.Camera instance to switch to.
0500 */
0501 public switchActiveCameraTo(newCamera: THREE.Camera): void {
0502 this.threeManager.controlsManager.setActiveCamera(newCamera);
0503 this.setSize(this.getMainRenderer().domElement.clientWidth, this.getMainRenderer().domElement.clientHeight);
0504 }
0505
0506 /**
0507 * Retrieves the list of all objects in the scene.
0508 * @returns An array of THREE.Object3D instances.
0509 */
0510 public getAllObjects(): THREE.Object3D[] {
0511 return this.getScene().children;
0512 }
0513
0514 /**
0515 * Finds an object in the scene by its name.
0516 * @param name The name of the object to find.
0517 * @returns The found THREE.Object3D instance or undefined if not found.
0518 */
0519 public findObjectByName(name: string): THREE.Object3D | undefined {
0520 return this.getScene().getObjectByName(name);
0521 }
0522
0523 /**
0524 * Initializes the scene with default settings.
0525 */
0526 public initializeScene(): void {
0527 this.setBackgroundColor(0x000000); // Set default background to black
0528 this.addGridHelper();
0529 this.addAxesHelper();
0530 this.addAmbientLight(0xffffff, 0.5);
0531 this.addPointLight(0xffffff, 1, 100);
0532 this.addDirectionalLight(0xffffff, 1, new THREE.Vector3(10, 10, 10));
0533 }
0534
0535 /**
0536 * Cleans up the scene by removing all objects and resetting settings.
0537 */
0538 public cleanupScene(): void {
0539 this.clearScene();
0540 this.setBackgroundColor(0x000000);
0541 this.toggleShadows(false);
0542 this.removeFog();
0543 }
0544
0545 /**
0546 * Enables or disables the renderer's animation loop.
0547 * @param enabled If true, starts the animation loop; otherwise, stops it.
0548 */
0549 public toggleAnimationLoop(enabled: boolean): void {
0550 if (enabled) {
0551 this.animate();
0552 } else {
0553 // Implement stopping the animation loop if necessary
0554 console.warn("Animation loop toggle to stop not implemented.");
0555 }
0556 }
0557
0558 /**
0559 * Sets the renderer's clear color.
0560 * @param color The clear color as a hexadecimal number.
0561 * @param alpha The alpha value for the clear color.
0562 */
0563 public setClearColor(color: number, alpha: number = 1): void {
0564 this.getMainRenderer().setClearColor(color, alpha);
0565 }
0566
0567 /**
0568 * Enables or disables antialiasing by reinitializing the renderer.
0569 * Note: This will remove and re-add the canvas to the DOM.
0570 * @param enabled If true, enables antialiasing; otherwise, disables it.
0571 */
0572 public enableAntialiasing(enabled: boolean): void {
0573 // Reinitialize the renderer with the desired antialiasing setting
0574 const currentCanvas = this.getMainRenderer().domElement;
0575 const parent = currentCanvas.parentElement;
0576
0577 if (parent) {
0578 // Remove the old renderer's canvas
0579 parent.removeChild(currentCanvas);
0580
0581 // Create a new renderer with the updated antialiasing setting
0582 const newRenderer = new THREE.WebGLRenderer({
0583 antialias: enabled,
0584 canvas: currentCanvas,
0585 });
0586 newRenderer.setSize(currentCanvas.clientWidth, currentCanvas.clientHeight);
0587 newRenderer.setPixelRatio(window.devicePixelRatio);
0588
0589 // Update the renderer manager
0590 this.rendererManager.setMainRenderer(newRenderer);
0591
0592 // Re-add the canvas to the DOM
0593 parent.appendChild(currentCanvas);
0594
0595 // Update the camera aspect ratio
0596 this.setSize(currentCanvas.clientWidth, currentCanvas.clientHeight);
0597 } else {
0598 console.error("RendererManager: Unable to find the canvas parent element.");
0599 }
0600 }
0601 }