import glm # We assume all the spaces up to and including view space to feature a Y-axis pointing upwards. # Screen space in Vulkan, however, has the +Y-axis pointing downwards, +X to the left, and +Z into the screen. # We are staying in right-handed (RH) coordinate systems throughout ALL the spaces. # Therefore, we are representing the coordinates from here on -- actually exactly BETWEEN View Space and # Clip Space -- in a coordinate system which is rotated 180 around X, having Y point down, still RH. let rotateAroundXFrom_RH_Yup_to_RH_Ydown*: Mat4[float32] = mat4f( vec4f(1.float32, 0, 0, 0) , -vec4f(0.float32, 1, 0, 0) , -vec4f(0.float32, 0, 1, 0) , vec4f(0.float32, 0, 0, 1) ) let rotateAroundXFrom_RH_Yup_to_RH_Ydown_Inverse* = inverse rotateAroundXFrom_RH_Yup_to_RH_Ydown proc ortho*(left, right, bottom, top, near, far: float32): Mat4f = var m = mat4[float32](1.0) let rl = right - left tb = top - bottom fn = far - near m[0][0] = 2.float32 / rl m[1][1] = 2.float32 / tb m[2][2] = 1.float32 / fn m[3][0] = -(right + left) / rl m[3][1] = -(top + bottom) / tb m[3][2] = -(near) / fn result = m * rotateAroundXFrom_RH_Yup_to_RH_Ydown_Inverse proc lookAtRH*( eye , center , up: Vec3[float32] ): Mat4[float32] = let f = normalize(center - eye) s = normalize(cross(f, up)) u = cross(s, f) 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 result[3][0] = -dot(s, eye) result[3][1] = -dot(u, eye) result[3][2] = dot(f, eye) proc perspectiveLH*[T]( fovy, aspect, zNear, zFar:T): Mat4[T] = let tanHalfFovy = tan(fovy / T(2)) result = mat4[T](0.0) result[0,0] = T(1) / (aspect * tanHalfFovy) result[1,1] = T(1) / (tanHalfFovy) result[2,2] = (zFar + zNear) / (zFar - zNear) result[2,3] = T(1) result[3,2] = - (T(2) * zFar * zNear) / (zFar - zNear) proc perspectiveRH*[T]( fovy, aspect, zNear, zFar:T): Mat4f = let tanHalfFovy = tan(fovy / T(2)) result = mat4[T](0.0) result[0,0] = T(1) / (aspect * tanHalfFovy) result[1,1] = T(1) / (tanHalfFovy) result[2,3] = T(-1) result[2,2] = -(zFar + zNear) / (zFar - zNear) result[3,2] = -(T(2) * zFar * zNear) / (zFar - zNear)