/* Freetype GL - A C OpenGL Freetype engine * * Distributed under the OSI-approved BSD 2-Clause License. See accompanying * file `LICENSE` for more details. */ #include #include #include #include "mat4.h" mat4 * mat4_new( void ) { mat4 *self = (mat4 *) malloc( sizeof(mat4) ); return self; } void mat4_set_zero( mat4 *self ) { if (!self) return; memset( self, 0, sizeof( mat4 )); } void mat4_set_identity( mat4 *self ) { if (!self) return; memset( self, 0, sizeof( mat4 )); self->m00 = 1.0; self->m11 = 1.0; self->m22 = 1.0; self->m33 = 1.0; } void mat4_multiply( mat4 *self, mat4 *other ) { mat4 m; size_t i; if (!self || !other) return; for( i=0; i<4; ++i ) { m.data[i*4+0] = (self->data[i*4+0] * other->data[0*4+0]) + (self->data[i*4+1] * other->data[1*4+0]) + (self->data[i*4+2] * other->data[2*4+0]) + (self->data[i*4+3] * other->data[3*4+0]) ; m.data[i*4+1] = (self->data[i*4+0] * other->data[0*4+1]) + (self->data[i*4+1] * other->data[1*4+1]) + (self->data[i*4+2] * other->data[2*4+1]) + (self->data[i*4+3] * other->data[3*4+1]) ; m.data[i*4+2] = (self->data[i*4+0] * other->data[0*4+2]) + (self->data[i*4+1] * other->data[1*4+2]) + (self->data[i*4+2] * other->data[2*4+2]) + (self->data[i*4+3] * other->data[3*4+2]) ; m.data[i*4+3] = (self->data[i*4+0] * other->data[0*4+3]) + (self->data[i*4+1] * other->data[1*4+3]) + (self->data[i*4+2] * other->data[2*4+3]) + (self->data[i*4+3] * other->data[3*4+3]) ; } memcpy( self, &m, sizeof( mat4 ) ); } void mat4_set_orthographic( mat4 *self, float left, float right, float bottom, float top, float znear, float zfar ) { if (!self) return; if (left == right || bottom == top || znear == zfar) return; mat4_set_zero( self ); self->m00 = +2.0f/(right-left); self->m30 = -(right+left)/(right-left); self->m11 = +2.0f/(top-bottom); self->m31 = -(top+bottom)/(top-bottom); self->m22 = -2.0f/(zfar-znear); self->m32 = -(zfar+znear)/(zfar-znear); self->m33 = 1.0f; } void mat4_set_perspective( mat4 *self, float fovy, float aspect, float znear, float zfar) { float h, w; if (!self) return; if (znear == zfar) return; h = (float)tan(fovy / 360.0 * M_PI) * znear; w = h * aspect; mat4_set_frustum( self, -w, w, -h, h, znear, zfar ); } void mat4_set_frustum( mat4 *self, float left, float right, float bottom, float top, float znear, float zfar ) { if (!self) return; if (left == right || bottom == top || znear == zfar) return; mat4_set_zero( self ); self->m00 = (2.0f*znear)/(right-left); self->m20 = (right+left)/(right-left); self->m11 = (2.0f*znear)/(top-bottom); self->m21 = (top+bottom)/(top-bottom); self->m22 = -(zfar+znear)/(zfar-znear); self->m32 = -(2.0f*zfar*znear)/(zfar-znear); self->m23 = -1.0f; } void mat4_set_rotation( mat4 *self, float angle, float x, float y, float z) { float c, s, norm; if (!self) return; c = (float)cos( M_PI*angle/180.0 ); s = (float)sin( M_PI*angle/180.0 ); norm = (float)sqrt(x*x+y*y+z*z); x /= norm; y /= norm; z /= norm; mat4_set_identity( self ); self->m00 = x*x*(1-c)+c; self->m10 = y*x*(1-c)-z*s; self->m20 = z*x*(1-c)+y*s; self->m01 = x*y*(1-c)+z*s; self->m11 = y*y*(1-c)+c; self->m21 = z*y*(1-c)-x*s; self->m02 = x*z*(1-c)-y*s; self->m12 = y*z*(1-c)+x*s; self->m22 = z*z*(1-c)+c; } void mat4_set_translation( mat4 *self, float x, float y, float z) { if (!self) return; mat4_set_identity( self ); self-> m30 = x; self-> m31 = y; self-> m32 = z; } void mat4_set_scaling( mat4 *self, float x, float y, float z) { if (!self) return; mat4_set_identity( self ); self-> m00 = x; self-> m11 = y; self-> m22 = z; } void mat4_rotate( mat4 *self, float angle, float x, float y, float z) { mat4 m; if (!self) return; mat4_set_rotation( &m, angle, x, y, z); mat4_multiply( self, &m ); } void mat4_translate( mat4 *self, float x, float y, float z) { mat4 m; if (!self) return; mat4_set_translation( &m, x, y, z); mat4_multiply( self, &m ); } void mat4_scale( mat4 *self, float x, float y, float z) { mat4 m; if (!self) return; mat4_set_scaling( &m, x, y, z); mat4_multiply( self, &m ); }