-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcamera.js
More file actions
129 lines (103 loc) · 2.82 KB
/
camera.js
File metadata and controls
129 lines (103 loc) · 2.82 KB
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
import { mat4 } from './gl-matrix/index.js'
export class Camera {
#jitterX
#jitterY
#aspect
#near
#far
#fov
#fovy
#projection
#viewProjection
#previousViewProjection
#projectionNoJitter
#viewProjectionNoJitter
#previousViewProjectionNoJitter
#view
#inverseView
constructor(fov = Math.PI / 2.0, aspect = 1.0, near = 0.1, far = Infinity) {
this.#fov = fov
this.aspect = aspect
this.#near = near
this.#far = far
this.#jitterX = 0
this.#jitterY = 0
this.#projection = mat4.create()
this.#viewProjection = mat4.create()
this.#projectionNoJitter = mat4.create()
this.#viewProjectionNoJitter = mat4.create()
this.#previousViewProjectionNoJitter = mat4.create()
this.#view = mat4.create()
this.#inverseView = mat4.create()
this.#previousViewProjection = mat4.create()
}
set aspect(aspect) {
this.#aspect = aspect
this.#fovy = 2.0 * Math.atan(Math.tan(this.#fov * 0.5) / Math.sqrt(1.0 + aspect * aspect))
}
set fov(fov) {
this.#fov = fov
this.#fovy = 2.0 * Math.atan(Math.tan(fov * 0.5) / Math.sqrt(1.0 + this.#aspect * this.#aspect))
}
get fov() {
return this.#fov
}
get fovy() {
return this.#fovy
}
get projection() {
return this.#projection
}
get viewProjection() {
return this.#viewProjection
}
get previousViewProjection() {
return this.#previousViewProjection
}
get previousViewProjectionNoJitter() {
return this.#previousViewProjectionNoJitter
}
get view() {
return this.#view
}
get inverseView() {
return this.#inverseView
}
get direction() {
const m = this.#inverseView
// Transform the local forward vector (0, 0, -1) by the rotation part of the inverse view matrix
return [
m[8] * -1 + m[0] * 0 + m[4] * 0,
m[9] * -1 + m[1] * 0 + m[5] * 0,
m[10] * -1 + m[2] * 0 + m[6] * 0
]
}
setJitter(x, y) {
this.#jitterX = x
this.#jitterY = y
this.updateProjection()
}
clearJitter() {
this.#jitterX = 0
this.#jitterY = 0
this.updateProjection()
}
lookAt(position, target, up) {
mat4.lookAt(this.#view, position, target, up)
mat4.invert(this.#inverseView, this.#view)
}
updateProjection() {
mat4.perspectiveNO(this.#projection, this.#fovy, this.#aspect, this.#near, this.#far)
mat4.copy(this.#projectionNoJitter, this.#projection)
if (this.#jitterX !== 0 || this.#jitterY !== 0) {
this.#projection[8] = this.#jitterX
this.#projection[9] = this.#jitterY
}
}
update() {
mat4.copy(this.#previousViewProjection, this.#viewProjection)
mat4.copy(this.#previousViewProjectionNoJitter, this.#viewProjectionNoJitter)
mat4.multiply(this.#viewProjection, this.#projection, this.#view)
mat4.multiply(this.#viewProjectionNoJitter, this.#projectionNoJitter, this.#view)
}
}