1 #include <cmath> // 用于数学运算
2
3 // 3D向量结构体(用于表示坐标、方向等)
4 struct vec3 {
5 float x, y, z;
6
7 vec3 operator-(const vec3& other) const {
8 return {x - other.x, y - other.y, z - other.z};
9 }
10
11 // 向量叉乘
12 vec3 cross(const vec3& other) const {
13 return {
14 y * other.z - z * other.y,
15 z * other.x - x * other.z,
16 x * other.y - y * other.x
17 };
18 }
19
20 // 向量点乘
21 float dot(const vec3& other) const {
22 return x * other.x + y * other.y + z * other.z;
23 }
24
25 // 向量归一化
26 vec3 normalize() const {
27 float len = std::sqrt(x*x + y*y + z*z);
28 return {x/len, y/len, z/len};
29 }
30 };
31
32 // 计算视图矩阵(View Matrix)
33 void createViewMatrix(vec3 position, vec3 target, vec3 up, float* matrix) {
34 // 1. 计算相机的三个正交轴
35 vec3 forward = (target - position).normalize(); // 相机朝向方向(Z轴负方向)
36 vec3 right = up.cross(forward).normalize(); // 右轴(X轴)
37 vec3 up_new = forward.cross(right); // 上轴(Y轴,已正交)
38
39 // 2. 计算平移分量(将相机位置转换到新坐标系)
40 float tx = -position.dot(right);
41 float ty = -position.dot(up_new);
42 float tz = position.dot(forward);
43
44 // 3. 按列主序填充视图矩阵
45 // 第一列:右轴分量
46 matrix[0] = right.x; matrix[1] = right.y; matrix[2] = right.z; matrix[3] = 0.0f;
47 // 第二列:上轴分量
48 matrix[4] = up_new.x; matrix[5] = up_new.y; matrix[6] = up_new.z; matrix[7] = 0.0f;
49 // 第三列:反向朝向轴分量
50 matrix[8] = -forward.x; matrix[9] = -forward.y; matrix[10] = -forward.z; matrix[11] = 0.0f;
51 // 第四列:平移分量
52 matrix[12] = tx; matrix[13] = ty; matrix[14] = tz; matrix[15] = 1.0f;
53 }
54
55 // 计算透视投影矩阵(Perspective Projection)
56 void createPerspectiveProjectionMatrix(float fovY, float aspect, float near, float far, float* matrix) {
57 const float PI = 3.14159265358979323846f;
58 float f = 1.0f / std::tan(fovY * 0.5f * PI / 180.0f); // 焦距
59
60 // 列主序填充矩阵
61 matrix[0] = f / aspect; matrix[1] = 0.0f; matrix[2] = 0.0f; matrix[3] = 0.0f;
62 matrix[4] = 0.0f; matrix[5] = f; matrix[6] = 0.0f; matrix[7] = 0.0f;
63 matrix[8] = 0.0f; matrix[9] = 0.0f; matrix[10] = (far + near) / (near - far); matrix[11] = -1.0f;
64 matrix[12] = 0.0f; matrix[13] = 0.0f; matrix[14] = (2 * far * near) / (near - far); matrix[15] = 0.0f;
65 }
66
67 // 计算正交投影矩阵(Orthographic Projection)
68 void createOrthoProjectionMatrix(float left, float right, float bottom, float top, float near, float far, float* matrix) {
69 // 计算缩放和平移因子
70 float r_l = right - left;
71 float t_b = top - bottom;
72 float f_n = far - near;
73
74 // 列主序填充矩阵
75 matrix[0] = 2.0f / r_l;
76 matrix[1] = 0.0f;
77 matrix[2] = 0.0f;
78 matrix[3] = 0.0f;
79 matrix[4] = 0.0f;
80 matrix[5] = 2.0f / t_b;
81 matrix[6] = 0.0f;
82 matrix[7] = 0.0f;
83 matrix[8] = 0.0f;
84 matrix[9] = 0.0f;
85 matrix[10] = -2.0f / f_n;
86 matrix[11] = 0.0f;
87 matrix[12] = -(right + left) / r_l;
88 matrix[13] = -(top + bottom) / t_b;
89 matrix[14] = -(far + near) / f_n;
90 matrix[15] = 1.0f;
91 }