File size: 4,586 Bytes
276ecc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48fe637
276ecc1
 
 
 
 
 
 
 
 
 
 
 
 
48fe637
276ecc1
 
 
 
 
 
48fe637
276ecc1
 
 
 
 
 
48fe637
276ecc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b3487a
9af5f8b
 
 
 
 
 
 
 
 
 
 
 
 
 
4b3487a
 
 
 
 
 
 
 
 
 
 
 
 
74f4fb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276ecc1
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import { describe, it, expect, afterEach } from 'vitest';
import {
  VIEW_CAMERA_FALLBACKS,
  CAMERA_DEFAULT_OVERRIDES,
  resolveCameraPose,
} from '../src/engine/cameraViewDefaults.js';

describe('resolveCameraPose', () => {
  const savedKeys = [];

  afterEach(() => {
    for (const key of savedKeys.splice(0)) {
      delete CAMERA_DEFAULT_OVERRIDES[key];
    }
  });

  function setOverride(key, partial) {
    CAMERA_DEFAULT_OVERRIDES[key] = partial;
    savedKeys.push(key);
  }

  it('falls back to NAVIGATION corridor pose when no overrides exist', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'ARITHMETIC',
      viewMode: 'NAVIGATION',
      renderMode: 'POINTS',
    });
    expect(pose.position).toEqual(VIEW_CAMERA_FALLBACKS.NAVIGATION.position);
    expect(pose.rotationDeg).toEqual(VIEW_CAMERA_FALLBACKS.NAVIGATION.rotationDeg);
  });

  it('falls back to ANALYSIS framing when no overrides exist', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'ANALYSIS',
      renderMode: 'RIBBONS',
    });
    expect(pose.position).toEqual(VIEW_CAMERA_FALLBACKS.ANALYSIS.position);
    expect(pose.rotationDeg).toEqual(VIEW_CAMERA_FALLBACKS.ANALYSIS.rotationDeg);
  });

  it('applies workspace → view → render layers (more specific wins)', () => {
    setOverride('ARITHMETIC', {
      position: [1, 2, 3],
      rotationDeg: [10, 20, 30],
    });
    setOverride('ARITHMETIC|NAVIGATION', {
      rotationDeg: [1, 2, 3],
    });
    setOverride('ARITHMETIC|NAVIGATION|RIBBONS', {
      position: [9, 8, 7],
    });

    const pose = resolveCameraPose({
      workspaceMode: 'ARITHMETIC',
      viewMode: 'NAVIGATION',
      renderMode: 'RIBBONS',
    });
    expect(pose.position).toEqual([9, 8, 7]);
    expect(pose.rotationDeg).toEqual([1, 2, 3]);
  });

  it('does not leak overrides from a different context', () => {
    setOverride('COMPARE|ANALYSIS|RIBBONS', {
      position: [-1, -2, -3],
      rotationDeg: [9, 8, 7],
    });

    const pose = resolveCameraPose({
      workspaceMode: 'ARITHMETIC',
      viewMode: 'NAVIGATION',
      renderMode: 'POINTS',
    });
    expect(pose.position).toEqual(VIEW_CAMERA_FALLBACKS.NAVIGATION.position);
  });

  it('applies captured COMPARE|NAVIGATION|POINTS pose', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'NAVIGATION',
      renderMode: 'POINTS',
    });
    expect(pose.position[0]).toBeCloseTo(-106.5, 5);
    expect(pose.position[1]).toBeCloseTo(20.4, 5);
    expect(pose.position[2]).toBeCloseTo(390.2, 5);
    expect(pose.rotationDeg[0]).toBeCloseTo(-3.9, 5);
    expect(pose.rotationDeg[1]).toBeCloseTo(-8.4, 5);
    expect(pose.rotationDeg[2]).toBeCloseTo(0, 5);
  });

  it('applies captured COMPARE|ANALYSIS|POINTS pose', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'ANALYSIS',
      renderMode: 'POINTS',
    });
    expect(pose.position[0]).toBeCloseTo(-150.3, 5);
    expect(pose.position[1]).toBeCloseTo(0.7, 5);
    expect(pose.position[2]).toBeCloseTo(276.6, 5);
    expect(pose.rotationDeg[0]).toBeCloseTo(-0.5, 5);
    expect(pose.rotationDeg[1]).toBeCloseTo(0.9, 5);
    expect(pose.rotationDeg[2]).toBeCloseTo(0, 5);
  });

  it('applies captured COMPARE|NAVIGATION|RIBBONS pose', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'NAVIGATION',
      renderMode: 'RIBBONS',
    });
    expect(pose.position[0]).toBeCloseTo(-575.8, 5);
    expect(pose.position[1]).toBeCloseTo(43.8, 5);
    expect(pose.position[2]).toBeCloseTo(237.9, 5);
    expect(pose.rotationDeg[0]).toBeCloseTo(-22.4, 5);
    expect(pose.rotationDeg[1]).toBeCloseTo(-35.7, 5);
    expect(pose.rotationDeg[2]).toBeCloseTo(0, 5);
  });

  it('applies captured COMPARE|GALAXY|POINTS pose', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'GALAXY',
      renderMode: 'POINTS',
    });
    expect(pose.position).toEqual([25.5, 155.2, 328.9]);
    expect(pose.rotationDeg[0]).toBeCloseTo(-23.2, 5);
    expect(pose.rotationDeg[1]).toBeCloseTo(14.0, 5);
    expect(pose.rotationDeg[2]).toBeCloseTo(0, 5);
    expect(pose.position).toEqual([...VIEW_CAMERA_FALLBACKS.GALAXY.position]);
  });

  it('does not collapse GALAXY into NAVIGATION fallback', () => {
    const pose = resolveCameraPose({
      workspaceMode: 'COMPARE',
      viewMode: 'GALAXY',
      renderMode: 'POINTS',
    });
    expect(pose.position).not.toEqual([...VIEW_CAMERA_FALLBACKS.NAVIGATION.position]);
  });
});