-
Notifications
You must be signed in to change notification settings - Fork 0
/
camera.ts
62 lines (55 loc) · 2.77 KB
/
camera.ts
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
namespace threed {
export class Camera {
private _transform: Matrix4x4;
private _position: Vector3;
private _orientation: Matrix4x4;
private _clippingPlanes: Plane[];
private _transposedOrientation: Matrix4x4;
//% callInDebugger
public get transform() { return this._transform; }
//% callInDebugger
public get position() { return this._position; }
//% callInDebugger
public get orientation() { return this._orientation; }
//% callInDebugger
public get clippingPlanes() { return this._clippingPlanes; }
//% callInDebugger
public get transposedOrientation() { return this._transposedOrientation; }
constructor() {
this._orientation = Matrix4x4.Identity();
this._position = Vector3.Zero();
// Hacky. Todo: Use a real projection matrix
const s2 = Fx8(Math.SQRT2);
const ns2 = Fx8(-Math.SQRT2);
this._clippingPlanes = [
new Plane(new Vector3(Fx.zeroFx8, Fx.zeroFx8, Fx.oneFx8), Vector3.Zero()), // Near
new Plane(new Vector3(s2, Fx.zeroFx8, s2), Vector3.Zero()), // Left
new Plane(new Vector3(ns2, Fx.zeroFx8, s2), Vector3.Zero()), // Right
new Plane(new Vector3(Fx.zeroFx8, ns2, s2), Vector3.Zero()), // Top
new Plane(new Vector3(Fx.zeroFx8, s2, s2), Vector3.Zero()), // Bottom
];
this.update();
}
public update() {
const orientation = this.orientation;
const translation = Matrix4x4.TranslationMatrix(Vector3.Scale(negOneFx8, this.position));
this._transposedOrientation = Matrix4x4.Transposed(orientation);
this._transform = Matrix4x4.Multiply(this._transposedOrientation, translation);
}
public orbit(pt: Vector3, dist: Fx8, angle: Fx8, normal: Vector3) {
// Assuming here that [1, 0, 0] represents a zero-degree rotation on a unit circle in the XZ plane around Y axis.
const rotation = Matrix4x4.RotationMatrixFromAxisAngle(normal, angle);
const rotated = Matrix4x4.MultiplyVector4(rotation, Vector3.Scale(dist, Vector3.X()).toVector4()).toVector3();
this._position = Vector3.Add(rotated, pt);
}
public lookAt(pt: Vector3) {
const forward = Vector3.Normalized(Vector3.Subtract(pt, this.position));
const right = Vector3.Cross(Vector3.Y(), forward);
const up = Vector3.Cross(forward, right);
this._orientation = Matrix4x4.RotationMatrixFromAxisVectors(forward, right, up);
}
public rotate(angle: Fx8, axis: Vector3) {
this._orientation = Matrix4x4.RotationMatrixFromAxisAngle(axis, angle);
}
}
}