Skip to content

Commit 278177e

Browse files
Scene System Testing [AARD-1938] (#1217)
Co-authored-by: Alexey Dmitriev <157652245+AlexD717@users.noreply.github.com> Co-authored-by: Brandon Pacewic <92102436+BrandonPacewic@users.noreply.github.com>
2 parents 497de7c + 7d442a4 commit 278177e

File tree

8 files changed

+1587
-8
lines changed

8 files changed

+1587
-8
lines changed

fission/src/systems/scene/CameraControls.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,6 @@ export class CustomOrbitControls extends CameraControls {
203203
return { ...this._coords }
204204
}
205205

206-
public setTargetCoordinates(coords: Partial<SphericalCoords>) {
207-
if (coords.theta !== undefined) this._nextCoords.theta = coords.theta
208-
if (coords.phi !== undefined) this._nextCoords.phi = coords.phi
209-
if (coords.r !== undefined) this._nextCoords.r = coords.r
210-
}
211-
212206
public setImmediateCoordinates(coords: Partial<SphericalCoords>) {
213207
if (coords.theta !== undefined) {
214208
this._coords.theta = coords.theta

fission/src/systems/scene/SceneRenderer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const CLEAR_COLOR = 0x121212
2727
const GROUND_COLOR = 0xfffef0
2828

2929
const STANDARD_ASPECT = 16.0 / 9.0
30-
const STANDARD_CAMERA_FOV_X = 110.0
31-
const STANDARD_CAMERA_FOV_Y = STANDARD_CAMERA_FOV_X / STANDARD_ASPECT
30+
export const STANDARD_CAMERA_FOV_X = 110.0
31+
export const STANDARD_CAMERA_FOV_Y = STANDARD_CAMERA_FOV_X / STANDARD_ASPECT
3232

3333
const textureLoader = new THREE.TextureLoader()
3434

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import { expect, test, beforeEach, describe } from "vitest"
2+
import { CustomOrbitControls } from "@/systems/scene/CameraControls"
3+
import * as THREE from "three"
4+
import ScreenInteractionHandler, { InteractionType } from "@/systems/scene/ScreenInteractionHandler"
5+
6+
describe("CustomOrbitControls", () => {
7+
let camera: THREE.PerspectiveCamera
8+
let interactionHandler: ScreenInteractionHandler
9+
let controls: CustomOrbitControls
10+
11+
beforeEach(() => {
12+
camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
13+
camera.position.set(0, 0, 5)
14+
15+
const mockElement = document.createElement("div")
16+
interactionHandler = new ScreenInteractionHandler(mockElement)
17+
18+
controls = new CustomOrbitControls(camera, interactionHandler)
19+
})
20+
21+
describe("Camera Position and Update", () => {
22+
test("sets simple coordinates correctly", () => {
23+
controls.setImmediateCoordinates({ theta: Math.PI / 2, phi: 0, r: 2.0 })
24+
controls.update(1 / 60)
25+
26+
expect(camera.position.x).toBeCloseTo(2)
27+
expect(camera.position.y).toBeCloseTo(0)
28+
expect(camera.position.z).toBeCloseTo(0)
29+
})
30+
31+
test("sets complex coordinates correctly", () => {
32+
controls.setImmediateCoordinates({ theta: Math.PI / 3, phi: Math.PI / 6, r: 4.0 })
33+
controls.update(1 / 60)
34+
35+
expect(camera.position.distanceTo(new THREE.Vector3(0, 0, 0))).toBeCloseTo(4)
36+
37+
expect(camera.position.x).toBeCloseTo(3)
38+
expect(camera.position.y).toBeCloseTo(-2)
39+
expect(camera.position.z).toBeCloseTo(1.732)
40+
})
41+
42+
test("clamps extreme values", () => {
43+
// Test r (zoom) bounds - values should be clamped
44+
controls.setImmediateCoordinates({ r: 1000 })
45+
controls.update(1 / 60)
46+
const maxR = controls.getCurrentCoordinates().r
47+
48+
controls.setImmediateCoordinates({ r: 0.001 })
49+
controls.update(1 / 60)
50+
const minR = controls.getCurrentCoordinates().r
51+
52+
expect(maxR).toBeLessThan(1000)
53+
expect(minR).toBeGreaterThan(0.001)
54+
expect(minR).toBeLessThan(maxR)
55+
56+
// Test phi (vertical) bounds
57+
controls.setImmediateCoordinates({ phi: Math.PI })
58+
controls.update(1 / 60)
59+
const maxPhi = controls.getCurrentCoordinates().phi
60+
61+
controls.setImmediateCoordinates({ phi: -Math.PI })
62+
controls.update(1 / 60)
63+
const minPhi = controls.getCurrentCoordinates().phi
64+
65+
expect(maxPhi).toBeLessThan(Math.PI)
66+
expect(minPhi).toBeGreaterThan(-Math.PI)
67+
expect(minPhi).toBeLessThan(maxPhi)
68+
})
69+
})
70+
71+
describe("Mouse Interaction", () => {
72+
const simulateMouseInteraction = (options: {
73+
startPosition: [number, number]
74+
movement?: [number, number]
75+
scale?: number
76+
updateFrames: number
77+
endPosition: [number, number]
78+
interactionType?: InteractionType
79+
}) => {
80+
const { startPosition, movement, scale, updateFrames, endPosition, interactionType = 0 } = options
81+
82+
controls.interactionStart({
83+
interactionType,
84+
position: startPosition,
85+
})
86+
87+
if (movement || scale !== undefined) {
88+
controls.interactionMove({
89+
interactionType,
90+
movement,
91+
scale,
92+
})
93+
}
94+
95+
for (let i = 0; i < updateFrames; i++) {
96+
controls.update(1 / 60)
97+
}
98+
99+
controls.interactionEnd({
100+
interactionType,
101+
position: endPosition,
102+
})
103+
104+
for (let i = 0; i < 10; i++) {
105+
controls.update(1 / 60)
106+
}
107+
}
108+
109+
beforeEach(() => {
110+
controls.setImmediateCoordinates({ theta: 0, phi: 0, r: 5 })
111+
controls.update(1 / 60)
112+
})
113+
114+
test("simulate mouse drag", () => {
115+
const initialCoords = controls.getCurrentCoordinates()
116+
117+
simulateMouseInteraction({
118+
startPosition: [100, 100],
119+
movement: [0.28, -0.105],
120+
updateFrames: 60,
121+
endPosition: [180, 70],
122+
})
123+
124+
expect(controls.getCurrentCoordinates()).not.toEqual(initialCoords)
125+
126+
expect(camera.position.distanceTo(new THREE.Vector3(0, 0, 0))).toBeCloseTo(5)
127+
})
128+
129+
test("should zoom in and out correctly", () => {
130+
const initialDistance = camera.position.distanceTo(new THREE.Vector3(0, 0, 0))
131+
expect(initialDistance).toBeCloseTo(5, 0)
132+
133+
simulateMouseInteraction({
134+
scale: -1.0,
135+
updateFrames: 1,
136+
startPosition: [100, 100],
137+
endPosition: [100, 100],
138+
})
139+
140+
const zoomedInDistance = camera.position.distanceTo(new THREE.Vector3(0, 0, 0))
141+
142+
simulateMouseInteraction({
143+
scale: 2.0,
144+
updateFrames: 1,
145+
startPosition: [100, 100],
146+
endPosition: [100, 100],
147+
})
148+
149+
const finalDistance = camera.position.distanceTo(new THREE.Vector3(0, 0, 0))
150+
151+
expect(zoomedInDistance).toBeCloseTo(4, 0)
152+
expect(finalDistance).toBeCloseTo(5.4, 0)
153+
})
154+
155+
test("should not update when disabled", () => {
156+
const initialPosition = camera.position.clone()
157+
158+
controls.enabled = false
159+
160+
simulateMouseInteraction({
161+
startPosition: [100, 100],
162+
movement: [0.175, 0.35],
163+
updateFrames: 30,
164+
endPosition: [150, 200],
165+
})
166+
167+
expect(camera.position.distanceTo(initialPosition)).toBeCloseTo(0)
168+
})
169+
})
170+
})

0 commit comments

Comments
 (0)