File size: 3,300 Bytes
3bb263a
 
 
16b67eb
 
 
 
 
 
3bb263a
 
 
 
 
 
 
 
 
 
276ecc1
3bb263a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276ecc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3bb263a
16b67eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { describe, it, expect } from 'vitest';
import * as THREE from 'three';
import { Navigation } from '../src/engine/Navigation.js';
import {
  DEFAULT_FLIGHT_PROFILE,
  GALAXY_FLIGHT_PROFILE,
  applyGalaxyFlightProfile,
  restoreDefaultFlightProfile,
} from '../src/engine/galaxyFlightProfile.js';

function stubCamera() {
  return {
    position: new THREE.Vector3(),
    quaternion: new THREE.Quaternion(),
    lookAt() {},
  };
}

describe('Navigation default poses', () => {
  it('setAnalysisView uses ANALYSIS view fallback pose', () => {
    const camera = stubCamera();
    const nav = new Navigation(camera, { addEventListener() {} });
    nav.setAnalysisView();

    expect(nav.camera.position.x).toBeCloseTo(-75.2, 5);
    expect(nav.camera.position.y).toBeCloseTo(-0.8, 5);
    expect(nav.camera.position.z).toBeCloseTo(62.5, 5);
    expect(nav.euler.x).toBeCloseTo(0, 5);
    expect(nav.euler.y).toBeCloseTo(0, 5);
    expect(nav.euler.z).toBeCloseTo(0, 5);
  });

  it('setNavigationView keeps corridor pose', () => {
    const camera = stubCamera();
    const nav = new Navigation(camera, { addEventListener() {} });
    nav.setNavigationView();

    expect(nav.camera.position.x).toBeCloseTo(-178.3, 5);
    expect(nav.camera.position.y).toBeCloseTo(13.5, 5);
    expect(nav.camera.position.z).toBeCloseTo(52.2, 5);
  });

  it('setContextView applies COMPARE|NAVIGATION|POINTS captured pose', () => {
    const camera = stubCamera();
    const nav = new Navigation(camera, { addEventListener() {} });
    nav.setContextView({
      workspaceMode: 'COMPARE',
      viewMode: 'NAVIGATION',
      renderMode: 'POINTS',
    });

    expect(nav.camera.position.x).toBeCloseTo(-106.5, 5);
    expect(nav.camera.position.y).toBeCloseTo(20.4, 5);
    expect(nav.camera.position.z).toBeCloseTo(390.2, 5);
    const deg2rad = Math.PI / 180;
    expect(nav.euler.x).toBeCloseTo(-3.9 * deg2rad, 5);
    expect(nav.euler.y).toBeCloseTo(-8.4 * deg2rad, 5);
    expect(nav.euler.z).toBeCloseTo(0, 5);
  });

  it('setContextView does not leak COMPARE pose into ARITHMETIC|NAVIGATION', () => {
    const camera = stubCamera();
    const nav = new Navigation(camera, { addEventListener() {} });
    nav.setContextView({
      workspaceMode: 'ARITHMETIC',
      viewMode: 'NAVIGATION',
      renderMode: 'POINTS',
    });

    expect(nav.camera.position.x).toBeCloseTo(-178.3, 5);
    expect(nav.camera.position.y).toBeCloseTo(13.5, 5);
    expect(nav.camera.position.z).toBeCloseTo(52.2, 5);
  });
});

describe('Navigation flight profile', () => {
  it('starts on default profile and applyLookDelta uses lookSensitivity', () => {
    const camera = stubCamera();
    const nav = new Navigation(camera, { addEventListener() {} });
    expect(nav.moveSpeed).toBe(DEFAULT_FLIGHT_PROFILE.moveSpeed);
    expect(nav.lookSensitivity).toBe(DEFAULT_FLIGHT_PROFILE.lookSensitivity);

    applyGalaxyFlightProfile(nav);
    expect(nav.moveSpeed).toBe(GALAXY_FLIGHT_PROFILE.moveSpeed);

    nav.euler.set(0, 0, 0, 'YXZ');
    nav.camera.quaternion.setFromEuler(nav.euler);
    nav.applyLookDelta(100, 0);
    expect(nav.euler.y).toBeCloseTo(-100 * GALAXY_FLIGHT_PROFILE.lookSensitivity, 6);

    restoreDefaultFlightProfile(nav);
    expect(nav.moveSpeed).toBe(DEFAULT_FLIGHT_PROFILE.moveSpeed);
  });
});