Document projection matrix function (#722)

* Document projection matrix function

Document function for computing a projection matrix. Used for camera and graphics.

* Fix loop index bug

Fix straightforward loop index bug introduced in last commit

* Style guide updates

Changes to match style recommendations
* Update function variables to camelCase
* Use dOxygen tags
* Use block comment

---------

Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
This commit is contained in:
Jed Grabman 2025-06-21 14:15:45 -04:00 committed by GitHub
parent ac4dfe3211
commit 3288752b47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 21 deletions

View File

@ -218,32 +218,44 @@ void mtxf_translate(Mat4 dest, Vec3f b) {
dest[3][1] = b[1]; dest[3][1] = b[1];
dest[3][2] = b[2]; dest[3][2] = b[2];
} }
/*
* @brief Creates a projection matrix based on specified frustrum (i.e. where the camera can see)
* @param projMat A dummy variable that will be overwritten with the projection matrix
* @param arg1 Unknown dummy variable (will be overwritten)
* @param vertFov vertical field of view (in degrees)
* @param aspectRatio Width / Height of player screen
* @param near near clipping distance
* @param far far clipping distance
* @param homogeneousScale Scaling factor for homogeneous coordinates. Always 1.0 in game
* Note the use of `2` which generates diff asm than just using floats (2.0f).
*/
void get_projection_matrix(Mat4 projMat, u16* arg1, f32 vertFov, f32 aspectRatio, f32 near, f32 far,
f32 homogeneousScale) {
f32 half_cot;
s32 row_idx, col_idx;
mtxf_identity(projMat);
vertFov *= 0.017453292222222222; // convert from degrees to radians
half_cot = cosf(vertFov / 2) / sinf(vertFov / 2);
projMat[0][0] = half_cot / aspectRatio;
projMat[1][1] = half_cot;
// Literature usually prefers the clearer equivalent -(near + far) / (far - near)
projMat[2][2] = (near + far) / (near - far);
projMat[2][3] = -1.0f;
projMat[3][2] = (2 * near * far) / (near - far);
projMat[3][3] = 0.0f;
// Note the use of `2` which generates diff asm than just using floats (2.0f). for (row_idx = 0; row_idx < 4; row_idx++) {
void func_802B5564(Mat4 arg0, u16* arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6) { for (col_idx = 0; col_idx < 4; col_idx++) {
f32 temp; projMat[row_idx][col_idx] *= homogeneousScale;
s32 i, j;
mtxf_identity(arg0);
arg2 *= 0.017453292222222222;
temp = cosf(arg2 / 2) / sinf(arg2 / 2);
arg0[0][0] = temp / arg3;
arg0[1][1] = temp;
arg0[2][2] = (arg4 + arg5) / (arg4 - arg5);
arg0[2][3] = -1.0f;
arg0[3][2] = (2 * arg4 * arg5) / (arg4 - arg5);
arg0[3][3] = 0.0f;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
arg0[i][j] *= arg6;
} }
} }
// sets arg1 to 2**16 / (midpoint of near and far), then clamped to [1, 2**16 - 1]
if (arg1 != 0) { if (arg1 != 0) {
if ((arg4 + arg5) <= 2.0) { if ((near + far) <= 2.0) {
*arg1 = 0xFFFF; *arg1 = 0xFFFF;
} else { } else {
*arg1 = 131072.0 / (arg4 + arg5); *arg1 = 131072.0 / (near + far);
if (*arg1 <= 0) { if (*arg1 <= 0) {
*arg1 = 1; *arg1 = 1;
} }

View File

@ -32,7 +32,7 @@ void mtxf_identity(Mat4);
void add_translate_mat4_vec3f(Mat4, Mat4, Vec3f); void add_translate_mat4_vec3f(Mat4, Mat4, Vec3f);
void add_translate_mat4_vec3f_lite(Mat4, Mat4, Vec3f); void add_translate_mat4_vec3f_lite(Mat4, Mat4, Vec3f);
void mtxf_translate(Mat4, Vec3f); void mtxf_translate(Mat4, Vec3f);
void func_802B5564(Mat4, u16*, f32, f32, f32, f32, f32); void get_projection_matrix(Mat4, u16*, f32, f32, f32, f32, f32);
void func_802B5794(Mat4, Vec3f, Vec3f); void func_802B5794(Mat4, Vec3f, Vec3f);
void mtxf_rotate_x(Mat4, s16); void mtxf_rotate_x(Mat4, s16);
void mtxf_rotate_y(Mat4, s16); void mtxf_rotate_y(Mat4, s16);

View File

@ -478,7 +478,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U
sp5C[0] = 0.0f; sp5C[0] = 0.0f;
sp5C[1] = 0.0f; sp5C[1] = 0.0f;
sp5C[2] = 30000.0f; sp5C[2] = 30000.0f;
func_802B5564(matrix1, &sp128, camera->unk_B4, gScreenAspect, gCourseNearPersp, gCourseFarPersp, 1.0f); get_projection_matrix(matrix1, &sp128, camera->unk_B4, gScreenAspect, gCourseNearPersp, gCourseFarPersp, 1.0f);
func_802B5794(matrix2, camera->pos, camera->lookAt); func_802B5794(matrix2, camera->pos, camera->lookAt);
mtxf_multiplication(matrix3, matrix1, matrix2); mtxf_multiplication(matrix3, matrix1, matrix2);