Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/engine/math/src/transform.cpp

132 lines
4 KiB
C++
Raw Normal View History

2020-08-11 12:07:21 -04:00
#include "transform.hpp"
#include <cmath>
2020-08-27 20:28:16 -04:00
#include <limits>
2020-08-11 12:07:21 -04:00
#include "math.hpp"
/*
These produce left-handed matrices.
Metal/DX12 are both NDC +y down.
*/
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::perspective(const float field_of_view, const float aspect, const float z_near, const float z_far) {
const float tan_half_fov = tanf(field_of_view / 2.0f);
Matrix4x4 result(0.0f);
result[0][0] = 1.0f / (aspect * tan_half_fov);
result[1][1] = 1.0f / tan_half_fov;
result[2][2] = z_far / (z_far - z_near);
result[2][3] = 1.0f;
result[3][2] = -(z_far * z_near) / (z_far - z_near);
return result;
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::infinite_perspective(const float field_of_view, const float aspect, const float z_near) {
const float range = tanf(field_of_view / 2.0f) * z_near;
2020-08-11 12:07:21 -04:00
const float left = -range * aspect;
const float right = range * aspect;
const float bottom = -range;
const float top = range;
Matrix4x4 result(0.0f);
result[0][0] = (2.0f * z_near) / (right - left);
result[1][1] = (2.0f * z_near) / (top - bottom);
result[2][2] = 1.0f - std::numeric_limits<float>::epsilon(); // prevent NaN
result[2][3] = 1.0f;
result[3][2] = -(2.0 - std::numeric_limits<float>::epsilon()) * z_near;
2020-08-11 12:07:21 -04:00
return result;
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::orthographic(float left, float right, float bottom, float top, float zNear, float zFar) {
2020-08-11 12:07:21 -04:00
Matrix4x4 result(1.0f);
result[0][0] = 2.0f / (right - left);
result[1][1] = 2.0f / (top - bottom);
result[2][2] = 1.0f / (zFar - zNear);
2020-08-11 12:07:21 -04:00
result[3][0] = -(right + left) / (right - left);
result[3][1] = -(top + bottom) / (top - bottom);
result[3][2] = - zNear / (zFar - zNear);
return result;
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::look_at(const float3 eye, const float3 center, const float3 up) {
const float3 f = normalize(center - eye);
const float3 s = normalize(cross(up, f));
const float3 u = cross(f, s);
2020-08-11 12:07:21 -04:00
Matrix4x4 result(1.0f);
result[0][0] = s.x;
result[1][0] = s.y;
result[2][0] = s.z;
result[0][1] = u.x;
result[1][1] = u.y;
result[2][1] = u.z;
result[0][2] = f.x;
result[1][2] = f.y;
result[2][2] = f.z;
2020-08-11 12:07:21 -04:00
result[3][0] = -dot(s, eye);
result[3][1] = -dot(u, eye);
result[3][2] = -dot(f, eye);
2020-08-11 12:07:21 -04:00
return result;
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::translate(const Matrix4x4 matrix, const float3 translation) {
2020-08-11 12:07:21 -04:00
Matrix4x4 result(1.0f);
2021-05-12 09:56:44 -04:00
result[3] = float4(translation, 1.0);
2020-08-11 12:07:21 -04:00
return matrix * result;
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::rotate(const Matrix4x4 matrix, const float angle, const float3 v) {
2020-08-11 12:07:21 -04:00
const float a = angle;
const float c = cosf(a);
const float s = sinf(a);
2021-05-12 09:56:44 -04:00
const float3 axis = normalize(v);
const float3 temp = float3((1.0f - c) * axis);
2020-08-11 12:07:21 -04:00
Matrix4x4 Rotate(1.0f);
Rotate[0][0] = c + temp[0] * axis[0];
Rotate[0][1] = temp[0] * axis[1] + s * axis[2];
Rotate[0][2] = temp[0] * axis[2] - s * axis[1];
Rotate[1][0] = temp[1] * axis[0] - s * axis[2];
Rotate[1][1] = c + temp[1] * axis[1];
Rotate[1][2] = temp[1] * axis[2] + s * axis[0];
Rotate[2][0] = temp[2] * axis[0] + s * axis[1];
Rotate[2][1] = temp[2] * axis[1] - s * axis[0];
Rotate[2][2] = c + temp[2] * axis[2];
Matrix4x4 result(1.0f);
result[0] = matrix[0] * Rotate[0][0] + matrix[1] * Rotate[0][1] + matrix[2] * Rotate[0][2];
result[1] = matrix[0] * Rotate[1][0] + matrix[1] * Rotate[1][1] + matrix[2] * Rotate[1][2];
result[2] = matrix[0] * Rotate[2][0] + matrix[1] * Rotate[2][1] + matrix[2] * Rotate[2][2];
result[3] = matrix[3];
2020-08-11 12:07:21 -04:00
return result;
2020-08-11 12:07:21 -04:00
}
2021-05-12 09:56:44 -04:00
Matrix4x4 prism::scale(const Matrix4x4 matrix, const float3 scale) {
2020-08-11 12:07:21 -04:00
Matrix4x4 result(1.0f);
result[0][0] = scale.x;
result[1][1] = scale.y;
result[2][2] = scale.z;
return matrix * result;
}
2021-05-12 09:56:44 -04:00
Quaternion prism::quat_look_at(const float3 eye, const float3 center, const float3 up) {
const float3 direction = normalize(center - eye);
2020-08-11 12:07:21 -04:00
Matrix3x3 result(1.0f);
result[2] = direction;
2020-08-19 22:46:07 -04:00
result[0] = normalize(cross(up, result[2]));
2020-08-11 12:07:21 -04:00
result[1] = cross(result[2], result[0]);
return quat_from_matrix(result);
}