diff --git a/frontend/src/app/particles/services/intersection-plane.service.ts b/frontend/src/app/particles/services/intersection-plane.service.ts index 67cbbcc..af92f74 100644 --- a/frontend/src/app/particles/services/intersection-plane.service.ts +++ b/frontend/src/app/particles/services/intersection-plane.service.ts @@ -2,6 +2,18 @@ import {Injectable} from '@angular/core'; import * as THREE from 'three'; import {RendererService} from './renderer.service'; +/** + * Represents the possible orientations of the intersection plane + */ +enum PlaneOrientation { + VERTICAL_ABOVE, + VERTICAL_BELOW, + HORIZONTAL_FRONT, + HORIZONTAL_BEHIND, + HORIZONTAL_RIGHT, + HORIZONTAL_LEFT +} + /** * Service responsible for managing the intersection plane */ @@ -11,6 +23,7 @@ import {RendererService} from './renderer.service'; export class IntersectionPlaneService { private intersectionPlane!: THREE.Mesh; private planePosition: number = 8; // Position in 1/16th of a block + private currentOrientation: PlaneOrientation = PlaneOrientation.HORIZONTAL_FRONT; constructor(private rendererService: RendererService) { } @@ -37,45 +50,9 @@ export class IntersectionPlaneService { } /** - * Updates the plane position based on slider value + * Determines the plane orientation based on camera position */ - updatePlanePosition(value: number): void { - this.planePosition = value; - // Convert from 1/16th block to Three.js units - const position = (this.planePosition / 16) - 0.5; // Center at 0 - - // Check if the plane is rotated vertically (looking from above/below) - if (Math.abs(this.intersectionPlane.rotation.x) > 0.1) { - // For vertical orientation, adjust Y position - this.intersectionPlane.position.y = position * (this.intersectionPlane.rotation.x > 0 ? -1 : 1); - // Reset x and z positions - this.intersectionPlane.position.x = 0; - this.intersectionPlane.position.z = 0; - } else { - const rotation = this.intersectionPlane.rotation.y; - - if (Math.abs(rotation) < 0.1 || Math.abs(rotation - Math.PI) < 0.1) { - // Camera in front (0) or behind (PI) - const direction = Math.abs(rotation) < 0.1 ? 1 : -1; - this.intersectionPlane.position.z = position * direction; - // Reset x position to avoid cumulative changes - this.intersectionPlane.position.x = 0; - } else { - // Camera on right (PI/2) or left (-PI/2) - const direction = rotation > 0 ? 1 : -1; - this.intersectionPlane.position.x = position * direction; - // Reset z position to avoid cumulative changes - this.intersectionPlane.position.z = 0; - } - } - } - - /** - * Updates the plane orientation based on camera position - */ - updatePlaneOrientation(camera: THREE.Camera): void { - if (!this.intersectionPlane) return; - + private determinePlaneOrientation(camera: THREE.Camera): PlaneOrientation { // Check if camera is looking from above or below first const verticalAngle = Math.atan2( camera.position.y, @@ -86,19 +63,10 @@ export class IntersectionPlaneService { const verticalThreshold = Math.PI / 4; if (verticalAngle > verticalThreshold) { - // Camera is above - this.intersectionPlane.rotation.x = -Math.PI / 2; - this.intersectionPlane.rotation.y = 0; - this.updatePlaneMaterial(0xAA0000); + return PlaneOrientation.VERTICAL_ABOVE; } else if (verticalAngle < -verticalThreshold) { - // Camera is below - this.intersectionPlane.rotation.x = Math.PI / 2; - this.intersectionPlane.rotation.y = 0; - this.updatePlaneMaterial(0xAA0000); + return PlaneOrientation.VERTICAL_BELOW; } else { - // Reset rotation.x as we're now in the horizontal plane - this.intersectionPlane.rotation.x = 0; - // Calculate the angle between camera and player (in the XZ plane) const cameraAngle = Math.atan2( camera.position.x, @@ -108,26 +76,103 @@ export class IntersectionPlaneService { // Determine which quadrant the camera is in with a 45-degree offset const quadrant = Math.floor((cameraAngle + Math.PI + Math.PI / 4) / (Math.PI / 2)) % 4; - // Rotate the plane to face the camera - if (quadrant === 0) { - this.intersectionPlane.rotation.y = 0; // Camera in front - this.updatePlaneMaterial(0x00AA00); - } else if (quadrant === 1) { - this.intersectionPlane.rotation.y = Math.PI / 2; // Camera on right - this.updatePlaneMaterial(0x0000AA); - } else if (quadrant === 2) { - this.intersectionPlane.rotation.y = Math.PI; // Camera behind - this.updatePlaneMaterial(0x00AA00); - } else { - this.intersectionPlane.rotation.y = -Math.PI / 2; // Camera on left - this.updatePlaneMaterial(0x0000AA); + // Return the appropriate orientation based on quadrant + switch (quadrant) { + case 0: + return PlaneOrientation.HORIZONTAL_FRONT; + case 1: + return PlaneOrientation.HORIZONTAL_RIGHT; + case 2: + return PlaneOrientation.HORIZONTAL_BEHIND; + case 3: + return PlaneOrientation.HORIZONTAL_LEFT; + default: + return PlaneOrientation.HORIZONTAL_FRONT; } } + } + + /** + * Updates the plane orientation based on camera position + */ + updatePlaneOrientation(camera: THREE.Camera): void { + if (!this.intersectionPlane) return; + + this.currentOrientation = this.determinePlaneOrientation(camera); + + // Apply rotation and material based on orientation + switch (this.currentOrientation) { + case PlaneOrientation.VERTICAL_ABOVE: + this.intersectionPlane.rotation.x = -Math.PI / 2; + this.intersectionPlane.rotation.y = 0; + this.updatePlaneMaterial(0xAA0000); + break; + case PlaneOrientation.VERTICAL_BELOW: + this.intersectionPlane.rotation.x = Math.PI / 2; + this.intersectionPlane.rotation.y = 0; + this.updatePlaneMaterial(0xAA0000); + break; + case PlaneOrientation.HORIZONTAL_FRONT: + this.intersectionPlane.rotation.x = 0; + this.intersectionPlane.rotation.y = 0; + this.updatePlaneMaterial(0x00AA00); + break; + case PlaneOrientation.HORIZONTAL_BEHIND: + this.intersectionPlane.rotation.x = 0; + this.intersectionPlane.rotation.y = Math.PI; + this.updatePlaneMaterial(0x00AA00); + break; + case PlaneOrientation.HORIZONTAL_RIGHT: + this.intersectionPlane.rotation.x = 0; + this.intersectionPlane.rotation.y = Math.PI / 2; + this.updatePlaneMaterial(0x0000AA); + break; + case PlaneOrientation.HORIZONTAL_LEFT: + this.intersectionPlane.rotation.x = 0; + this.intersectionPlane.rotation.y = -Math.PI / 2; + this.updatePlaneMaterial(0x0000AA); + break; + } // Update position after rotation change this.updatePlanePosition(this.planePosition); } + /** + * Updates the plane position based on slider value + */ + updatePlanePosition(value: number): void { + this.planePosition = value; + // Convert from 1/16th block to Three.js units + const position = (this.planePosition / 16) - 0.5; // Center at 0 + + this.intersectionPlane.position.y = 0.8; + this.intersectionPlane.position.x = 0; + this.intersectionPlane.position.z = 0; + + // Position based on the current orientation + switch (this.currentOrientation) { + case PlaneOrientation.VERTICAL_ABOVE: + this.intersectionPlane.position.y = 0.8 - position; + break; + case PlaneOrientation.VERTICAL_BELOW: + this.intersectionPlane.position.y = 0.8 + position; + break; + case PlaneOrientation.HORIZONTAL_FRONT: + this.intersectionPlane.position.z = position; + break; + case PlaneOrientation.HORIZONTAL_BEHIND: + this.intersectionPlane.position.z = -position; + break; + case PlaneOrientation.HORIZONTAL_RIGHT: + this.intersectionPlane.position.x = position; + break; + case PlaneOrientation.HORIZONTAL_LEFT: + this.intersectionPlane.position.x = -position; + break; + } + } + /** * Updates the plane material color */