matrix.cc (3392B)
1 /* Copyright 2013 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <stdio.h> 17 #include <string.h> 18 #include <math.h> 19 20 #include "matrix.h" 21 22 /* m = a * b m and b must not point to the same matrix */ 23 void __mat4_mul_mat4(float m[16], const float a[16], const float b[16]) { 24 for (int i = 0; i < 16; i += 4) { 25 float ai0 = a[i+0], ai1 = a[i+1], ai2 = a[i+2], ai3 = a[i+3]; 26 m[i+0] = ai0*b[0] + ai1*b[4] + ai2*b[8] + ai3*b[12]; 27 m[i+1] = ai0*b[1] + ai1*b[5] + ai2*b[9] + ai3*b[13]; 28 m[i+2] = ai0*b[2] + ai1*b[6] + ai2*b[10] + ai3*b[14]; 29 m[i+3] = ai0*b[3] + ai1*b[7] + ai2*b[11] + ai3*b[15]; 30 } 31 } 32 33 void __mat4_mul_vec4(float o[4], const float m[16], const float v[4]) { 34 float v0=v[0], v1=v[1], v2=v[2], v3=v[3]; 35 o[0] = m[0]*v0 + m[4]*v1 + m[8]*v2 + m[12]*v3; 36 o[1] = m[1]*v0 + m[5]*v1 + m[9]*v2 + m[13]*v3; 37 o[2] = m[2]*v0 + m[6]*v1 + m[10]*v2 + m[14]*v3; 38 o[3] = m[3]*v0 + m[7]*v1 + m[11]*v2 + m[15]*v3; 39 } 40 41 void __mat4_set_identity(float m[16]) { 42 memset(m, 0, sizeof(float[16])); 43 m[0] = m[5] = m[10] = m[15] = 1.0f; 44 } 45 46 void __mat4_set_translate(float m[16], float x, float y, float z) { 47 memset(m, 0, sizeof(float[16])); 48 m[0] = m[5] = m[10] = 1.0; 49 m[12] = x; 50 m[13] = y; 51 m[14] = z; 52 m[15] = 1.0; 53 } 54 55 void __mat4_set_rotate_x(float m[16], float rad) { 56 float s = sinf(rad); 57 float c = cosf(rad); 58 memset(m, 0, sizeof(float[16])); 59 m[0] = 1.0; 60 m[5] = c; 61 m[6] = -s; 62 m[9] = s; 63 m[10] = c; 64 m[15] = 1.0; 65 } 66 67 void __mat4_set_rotate_y(float m[16], float rad) { 68 float s = sinf(rad); 69 float c = cosf(rad); 70 memset(m, 0, sizeof(float[16])); 71 m[0] = c; 72 m[2] = s; 73 m[5] = 1.0; 74 m[8] = -s; 75 m[10] = c; 76 m[15] = 1.0; 77 } 78 79 void __mat4_set_rotate_z(float m[16], float rad) { 80 float s = sinf(rad); 81 float c = cosf(rad); 82 memset(m, 0, sizeof(float[16])); 83 m[0] = c; 84 m[1] = -s; 85 m[4] = s; 86 m[5] = c; 87 m[10] = 1.0; 88 m[15] = 1.0; 89 } 90 91 void __mat4_set_frustum(float m[16], float left, float right, float bottom, float top, float znear, float zfar) { 92 float znear2 = 2.0 * znear; 93 float width = right - left; 94 float height = top - bottom; 95 float depth = zfar - znear; 96 memset(m, 0, sizeof(float[16])); 97 m[0] = znear2 / width; 98 m[5] = znear2 / height; 99 m[8] = (right + left) / width; 100 m[9] = (top + bottom) / height; 101 m[10] = (-zfar - znear) / depth; 102 m[11] = -1.0; 103 m[14] = (-znear2 * zfar) / depth; 104 } 105 106 void __mat4_set_perspective(float m[16], float fov, float aspect, float znear, float zfar) { 107 float ymax, xmax; 108 ymax = znear * tanf(fov / 2.0); 109 xmax = ymax * aspect; 110 __mat4_set_frustum(m, -xmax, xmax, -ymax, ymax, znear, zfar); 111 } 112 113 void __mat4_set_ortho(float m[16], float l, float r, float b, float t, float n, float f) { 114 memset(m, 0, sizeof(float[16])); 115 m[0] = 2.0 / (r - l); 116 m[5] = 2.0 / (t - b); 117 m[10] = -2.0 / (f - n); 118 m[12] = -((r + l) / (r - l)); 119 m[13] = -((t + b) / (t - b)); 120 m[14] = -((f + n) / (f - n)); 121 m[15] = 1.0; 122 } 123