matrix.cc (3585B)
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] = 1.0; 49 m[5] = 1.0; 50 m[10] = 1.0; 51 m[12] = x; 52 m[13] = y; 53 m[14] = z; 54 m[15] = 1.0; 55 } 56 57 void __mat4_set_scale(float m[16], float x, float y, float z) { 58 memset(m, 0, sizeof(float[16])); 59 m[0] = x; 60 m[5] = y; 61 m[10] = z; 62 m[15] = 1.0; 63 } 64 65 void __mat4_set_rotate_x(float m[16], float rad) { 66 float s = sinf(rad); 67 float c = cosf(rad); 68 memset(m, 0, sizeof(float[16])); 69 m[0] = 1.0; 70 m[5] = c; 71 m[6] = s; 72 m[9] = -s; 73 m[10] = c; 74 m[15] = 1.0; 75 } 76 77 void __mat4_set_rotate_y(float m[16], float rad) { 78 float s = sinf(rad); 79 float c = cosf(rad); 80 memset(m, 0, sizeof(float[16])); 81 m[0] = c; 82 m[2] = -s; 83 m[5] = 1.0; 84 m[8] = s; 85 m[10] = c; 86 m[15] = 1.0; 87 } 88 89 void __mat4_set_rotate_z(float m[16], float rad) { 90 float s = sinf(rad); 91 float c = cosf(rad); 92 memset(m, 0, sizeof(float[16])); 93 m[0] = c; 94 m[1] = s; 95 m[4] = -s; 96 m[5] = c; 97 m[10] = 1.0; 98 m[15] = 1.0; 99 } 100 101 void __mat4_set_perspective(float m[16], float fov, float a, float zn, float zf) { 102 memset(m, 0, sizeof(float[16])); 103 float fn = 1.0f / (zf - zn); 104 float t = 1.0f / tanf(fov * 0.5f); 105 m[0] = (1.0f / a) * t; 106 m[5] = t; 107 m[10] = (-(zf - zn)) * fn; 108 m[11] = -1.0f; 109 m[14] = -2.0f * (zn * zf) * fn; 110 } 111 112 void __mat4_set_ortho(float m[16], float l, float r, float b, float t, float n, float f) { 113 memset(m, 0, sizeof(float[16])); 114 m[0] = 2.0 / (r - l); 115 m[5] = 2.0 / (t - b); 116 m[10] = 1.0 / (n - f); 117 m[12] = (l + r) / (l - r); 118 m[13] = (t + b) / (b - t); 119 m[14] = n / (n - f); 120 m[15] = 1.0; 121 } 122 123 /* per gluLookAt docs */ 124 mat4& mat4::lookAt(const vec3& eye, const vec3& center, const vec3& up) { 125 vec3 f = (center - eye).normalize(); 126 vec3 upn = up; 127 vec3 s = cross(f, upn); 128 vec3 u = cross(s, f); 129 m[0] = s[0]; 130 m[1] = u[0]; 131 m[2] = -f[0]; 132 m[3] = 0.0f; 133 m[4] = s[1]; 134 m[5] = u[1]; 135 m[6] = -f[1]; 136 m[7] = 0.0f; 137 m[8] = s[2]; 138 m[9] = u[2]; 139 m[10] = -f[2]; 140 m[11] = 0.0f; 141 m[12] = 0.0f; 142 m[13] = 0.0f; 143 m[14] = 0.0f; 144 m[15] = 1.0f; 145 return *this; 146 }