File size: 3,186 Bytes
352fb85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { Quaternion } from "../math/Quaternion";
import { Matrix3 } from "../math/Matrix3";
import { Matrix4 } from "../math/Matrix4";
import { Vector3 } from "../math/Vector3";

class CameraData {
    private _fx: number = 1132;
    private _fy: number = 1132;
    private _near: number = 0.1;
    private _far: number = 100;

    private _width: number = 512;
    private _height: number = 512;

    private _projectionMatrix: Matrix4 = new Matrix4();
    private _viewMatrix: Matrix4 = new Matrix4();
    private _viewProj: Matrix4 = new Matrix4();

    update: (position: Vector3, rotation: Quaternion) => void;
    setSize: (width: number, height: number) => void;

    private _updateProjectionMatrix: () => void;

    constructor() {
        this._updateProjectionMatrix = () => {
            // prettier-ignore
            this._projectionMatrix = new Matrix4(
                2 * this.fx / this.width, 0, 0, 0,
                0, -2 * this.fy / this.height, 0, 0,
                0, 0, this.far / (this.far - this.near), 1,
                0, 0, -(this.far * this.near) / (this.far - this.near), 0
            );

            this._viewProj = this.projectionMatrix.multiply(this.viewMatrix);
        };

        this.update = (position: Vector3, rotation: Quaternion) => {
            const R = Matrix3.RotationFromQuaternion(rotation).buffer;
            const t = position.flat();

            // prettier-ignore
            this._viewMatrix = new Matrix4(
                R[0], R[1], R[2], 0,
                R[3], R[4], R[5], 0,
                R[6], R[7], R[8], 0,
                -t[0] * R[0] - t[1] * R[3] - t[2] * R[6],
                -t[0] * R[1] - t[1] * R[4] - t[2] * R[7],
                -t[0] * R[2] - t[1] * R[5] - t[2] * R[8],
                1,
            );

            this._viewProj = this.projectionMatrix.multiply(this.viewMatrix);
        };

        this.setSize = (width: number, height: number) => {
            this._width = width;
            this._height = height;
            this._updateProjectionMatrix();
        };
    }

    get fx() {
        return this._fx;
    }

    set fx(fx: number) {
        if (this._fx !== fx) {
            this._fx = fx;
            this._updateProjectionMatrix();
        }
    }

    get fy() {
        return this._fy;
    }

    set fy(fy: number) {
        if (this._fy !== fy) {
            this._fy = fy;
            this._updateProjectionMatrix();
        }
    }

    get near() {
        return this._near;
    }

    set near(near: number) {
        if (this._near !== near) {
            this._near = near;
            this._updateProjectionMatrix();
        }
    }

    get far() {
        return this._far;
    }

    set far(far: number) {
        if (this._far !== far) {
            this._far = far;
            this._updateProjectionMatrix();
        }
    }

    get width() {
        return this._width;
    }

    get height() {
        return this._height;
    }

    get projectionMatrix() {
        return this._projectionMatrix;
    }

    get viewMatrix() {
        return this._viewMatrix;
    }

    get viewProj() {
        return this._viewProj;
    }
}

export { CameraData };