commit 5be7aefa548e3400592795f04b109cb55f40016c parent 392f5e6196e2ae934d0e071517d7be5bb528eb7f Author: Michael Savage <mikejsavage@gmail.com> Date: Wed Oct 12 22:53:11 +0300 Add linear_algebra.h Diffstat:
linear_algebra.h | | | 208 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
diff --git a/linear_algebra.h b/linear_algebra.h @@ -0,0 +1,208 @@ +/* + * vector/matrix code + */ + +#ifndef _LINEAR_ALGEBRA_H_ +#define _LINEAR_ALGEBRA_H_ + +#include <math.h> + +#include "platform_inline.h" + +/* + * data definitions + */ + +struct v2 { + union { + struct { float x, y; }; + float elems[ 2 ]; + }; + + v2() { } + + explicit v2( float a ) { + x = a; + y = a; + } + + explicit v2( float a, float b ) { + x = a; + y = b; + } + + operator const GLfloat *() { + return elems; + } + + v2 xx() const { return v2( x, x ); } + v2 xy() const { return v2( x, y ); } + v2 yx() const { return v2( y, x ); } + v2 yy() const { return v2( y, y ); } +}; + +struct m2 { + // row major 2x2 matrix + float a, b, c, d; + + m2() { } + + explicit m2( float a_, float b_, float c_, float d_ ) { + a = a_; + b = b_; + c = c_; + d = d_; + } + + v2 row0() const { return v2( a, b ); } + v2 row1() const { return v2( c, d ); } + v2 col0() const { return v2( a, c ); } + v2 col1() const { return v2( b, d ); } +}; + +struct v3 { + float x, y, z; + + v3() { } + + explicit v3( float a ) { + x = a; + y = a; + z = a; + } + + explicit v3( float a, float b, float c ) { + x = a; + y = b; + z = c; + } + + explicit v3( v2 v, float c ) { + x = v.x; + y = v.y; + z = c; + } + + explicit v3( float a, v2 v ) { + x = a; + y = v.x; + z = v.y; + } +}; + +/* + * v2 + */ + +forceinline v2 operator+( v2 lhs, v2 rhs ) { + return v2( lhs.x + rhs.x, lhs.y + rhs.y ); +} + +forceinline v2 operator-( v2 lhs, v2 rhs ) { + return v2( lhs.x - rhs.x, lhs.y - rhs.y ); +} + +forceinline v2 operator*( v2 v, float scale ) { + return v2( v.x * scale, v.y * scale ); +} + +forceinline v2 operator*( float scale, v2 v ) { + return v * scale; + return v2( v.x * scale, v.y * scale ); +} + +forceinline v2 operator/( v2 v, float scale ) { + float inv_scale = 1.0f / scale; + return v * inv_scale; +} + +forceinline float dot( v2 lhs, v2 rhs ) { + return lhs.x * rhs.x + lhs.y * rhs.y; +} + +/* + * m2 + */ + +forceinline m2 rot2d( float theta ) { + float s = sinf( theta ); + float c = cosf( theta ); + + return m2( c, -s, s, c ); +} + +forceinline m2 m2_identity() { + return m2( 1, 0, 0, 1 ); +} + +forceinline m2 m2_scale( float scale ) { + return m2( scale, 0, 0, scale ); +} + +forceinline m2 m2_scale( float x, float y ) { + return m2( x, 0, 0, y ); +} + +forceinline m2 operator*( const m2 & lhs, const m2 & rhs ) { + return m2( + dot( lhs.row0(), rhs.col0() ), dot( lhs.row0(), rhs.col1() ), + dot( lhs.row1(), rhs.col0() ), dot( lhs.row1(), rhs.col1() ) + ); +} + +forceinline v2 operator*( const m2 & m, v2 v ) { + return v2( dot( m.row0(), v ), dot( m.row1(), v ) ); +} + +/* + * v3 + */ + +forceinline v3 operator+( v3 lhs, v3 rhs ) { + return v3( lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z ); +} + +forceinline void operator+=( v3 & lhs, v3 rhs ) { + lhs.x += rhs.x; + lhs.y += rhs.y; + lhs.z += rhs.z; +} + +forceinline v3 operator-( v3 lhs, v3 rhs ) { + return v3( lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z ); +} + +forceinline v3 operator*( v3 v, float scale ) { + return v3( v.x * scale, v.y * scale, v.z * scale ); +} + +forceinline v3 operator*( float scale, v3 v ) { + return v * scale; +} + +forceinline v3 operator/( v3 v, float scale ) { + float inv_scale = 1.0f / scale; + return v * inv_scale; +} + +forceinline float dot( v3 u, v3 v ) { + return u.x * v.x + u.y * v.y + u.z * v.z; +} + +forceinline v3 cross( v3 u, v3 v ) { + return v3( + u.y * v.z - v.y * u.z, + v.x * u.z - u.x * v.z, + u.x * v.y - v.x * u.y + ); +} + +forceinline float length( v3 v ) { + return sqrtf( v.x * v.x + v.y * v.y + v.z * v.z ); +} + +forceinline v3 normalize( v3 v ) { + return v / length( v ); +} + +#endif // _LINEAR_ALGEBRA_H_