Blame projects/asteroid/geometry.cpp

Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include <cstdlib>
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
#include "geometry.h"
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Real real_random()
Ivan Mahonin 223ac6
    { return rand()/(Real)RAND_MAX; }
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::operator*(const Matrix4 &m) const {
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        m00*m.m00 + m10*m.m01 + m20*m.m02 + m30*m.m02,
Ivan Mahonin 223ac6
        m01*m.m00 + m11*m.m01 + m21*m.m02 + m31*m.m02,
Ivan Mahonin 223ac6
        m02*m.m00 + m12*m.m01 + m22*m.m02 + m32*m.m02,
Ivan Mahonin 223ac6
        m03*m.m00 + m13*m.m01 + m23*m.m02 + m33*m.m02,
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        m00*m.m10 + m10*m.m11 + m20*m.m12 + m30*m.m12,
Ivan Mahonin 223ac6
        m01*m.m10 + m11*m.m11 + m21*m.m12 + m31*m.m12,
Ivan Mahonin 223ac6
        m02*m.m10 + m12*m.m11 + m22*m.m12 + m32*m.m12,
Ivan Mahonin 223ac6
        m03*m.m10 + m13*m.m11 + m23*m.m12 + m33*m.m12,
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        m00*m.m20 + m10*m.m21 + m20*m.m22 + m30*m.m22,
Ivan Mahonin 223ac6
        m01*m.m20 + m11*m.m21 + m21*m.m22 + m31*m.m22,
Ivan Mahonin 223ac6
        m02*m.m20 + m12*m.m21 + m22*m.m22 + m32*m.m22,
Ivan Mahonin 223ac6
        m03*m.m20 + m13*m.m21 + m23*m.m22 + m33*m.m22,
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
        m00*m.m30 + m10*m.m31 + m20*m.m32 + m30*m.m32,
Ivan Mahonin 223ac6
        m01*m.m30 + m11*m.m31 + m21*m.m32 + m31*m.m32,
Ivan Mahonin 223ac6
        m02*m.m30 + m12*m.m31 + m22*m.m32 + m32*m.m32,
Ivan Mahonin 223ac6
        m03*m.m30 + m13*m.m31 + m23*m.m32 + m33*m.m32 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Real Matrix4::det() const {
Ivan Mahonin 223ac6
    return m00 * (m11*(m22*m33 - m23*m32) + m12*(m23*m31 - m21*m33) + m13*(m21*m32 - m22*m31))
Ivan Mahonin 223ac6
         + m01 * (m01*(m23*m32 - m22*m33) + m02*(m21*m33 - m23*m31) + m03*(m22*m31 - m21*m32))
Ivan Mahonin 223ac6
         + m02 * (m01*(m12*m33 - m13*m32) + m02*(m13*m31 - m11*m33) + m03*(m11*m32 - m12*m31))
Ivan Mahonin 223ac6
         + m03 * (m01*(m13*m22 - m12*m23) + m02*(m11*m23 - m13*m21) + m03*(m12*m21 - m11*m22));
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::inv() const {
Ivan Mahonin 223ac6
    Matrix4 r;
Ivan Mahonin 223ac6
    r.m00 = m11*(m22*m33 - m23*m32) + m12*(m23*m31 - m21*m33) + m13*(m21*m32 - m22*m31);
Ivan Mahonin 223ac6
    r.m10 = m10*(m23*m32 - m22*m33) + m12*(m20*m33 - m23*m30) + m13*(m22*m30 - m20*m32);
Ivan Mahonin 223ac6
    r.m20 = m10*(m21*m33 - m23*m31) + m11*(m23*m30 - m20*m33) + m13*(m20*m31 - m21*m30);
Ivan Mahonin 223ac6
    r.m30 = m10*(m22*m31 - m21*m32) + m11*(m20*m32 - m22*m30) + m12*(m21*m30 - m20*m31);
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
    double det = m00*r.m00 + m01*r.m10 + m02*r.m20 + m03*r.m30;
Ivan Mahonin 223ac6
    if (fabs(det) <= precision) return zero();
Ivan Mahonin 223ac6
    det = 1/det;
Ivan Mahonin 223ac6
    r.m00 *= det;
Ivan Mahonin 223ac6
    r.m10 *= det;
Ivan Mahonin 223ac6
    r.m20 *= det;
Ivan Mahonin 223ac6
    r.m30 *= det;
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
    r.m01 = det*(m01*(m23*m32 - m22*m33) + m02*(m21*m33 - m23*m31) + m03*(m22*m31 - m21*m32));
Ivan Mahonin 223ac6
    r.m11 = det*(m00*(m22*m33 - m23*m32) + m02*(m23*m30 - m20*m33) + m03*(m20*m32 - m22*m30));
Ivan Mahonin 223ac6
    r.m21 = det*(m00*(m23*m31 - m21*m33) + m01*(m20*m33 - m23*m30) + m03*(m21*m30 - m20*m31));
Ivan Mahonin 223ac6
    r.m31 = det*(m00*(m21*m32 - m22*m31) + m01*(m22*m30 - m20*m32) + m02*(m20*m31 - m21*m30));
Ivan Mahonin 223ac6
    r.m02 = det*(m01*(m12*m33 - m13*m32) + m02*(m13*m31 - m11*m33) + m03*(m11*m32 - m12*m31));
Ivan Mahonin 223ac6
    r.m12 = det*(m00*(m13*m32 - m12*m33) + m02*(m10*m33 - m13*m30) + m03*(m12*m30 - m10*m32));
Ivan Mahonin 223ac6
    r.m22 = det*(m00*(m11*m33 - m13*m31) + m01*(m13*m30 - m10*m33) + m03*(m10*m31 - m11*m30));
Ivan Mahonin 223ac6
    r.m32 = det*(m00*(m12*m31 - m11*m32) + m01*(m10*m32 - m12*m30) + m02*(m11*m30 - m10*m31));
Ivan Mahonin 223ac6
    r.m03 = det*(m01*(m13*m22 - m12*m23) + m02*(m11*m23 - m13*m21) + m03*(m12*m21 - m11*m22));
Ivan Mahonin 223ac6
    r.m13 = det*(m00*(m12*m23 - m13*m22) + m02*(m13*m20 - m10*m23) + m03*(m10*m22 - m12*m20));
Ivan Mahonin 223ac6
    r.m23 = det*(m00*(m13*m21 - m11*m23) + m01*(m10*m23 - m13*m20) + m03*(m11*m20 - m10*m21));
Ivan Mahonin 223ac6
    r.m33 = det*(m00*(m11*m22 - m12*m21) + m01*(m12*m20 - m10*m22) + m02*(m10*m21 - m11*m20));
Ivan Mahonin 223ac6
    return r;
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::zero() {
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        0, 0, 0, 0,
Ivan Mahonin 223ac6
        0, 0, 0, 0,
Ivan Mahonin 223ac6
        0, 0, 0, 0,
Ivan Mahonin 223ac6
        0, 0, 0, 0 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::translation(const Vector3 &translate) {
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        1, 0, 0, 0,
Ivan Mahonin 223ac6
        0, 1, 0, 0,
Ivan Mahonin 223ac6
        0, 0, 1, 0,
Ivan Mahonin 223ac6
        translate.x, translate.y, translate.z, 1 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::scaling(const Vector3 &scale) {
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        scale.x, 0, 0, 0,
Ivan Mahonin 223ac6
        0, scale.y, 0, 0,
Ivan Mahonin 223ac6
        0, 0, scale.z, 0,
Ivan Mahonin 223ac6
        0, 0, 0, 1 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::rotation(const Vector3 &axis, Real angle) {
Ivan Mahonin 223ac6
    Real len = axis.len();
Ivan Mahonin 223ac6
    if (len < precision) return Matrix4();
Ivan Mahonin 223ac6
    Real s = sin(angle);
Ivan Mahonin 223ac6
    Real c = cos(angle);
Ivan Mahonin 223ac6
    Vector3 a = axis/len;
Ivan Mahonin 223ac6
    Vector3 ac = a*(1 - c);
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        a.x*ac.x + c    , a.y*ac.x + a.z*s, a.z*ac.x - a.y*s, 0,
Ivan Mahonin 223ac6
        a.x*ac.y - a.z*s, a.y*ac.y + c    , a.z*ac.y + a.x*s, 0,
Ivan Mahonin 223ac6
        a.x*ac.z + a.y*s, a.y*ac.z - a.x*s, a.z*ac.z + c    , 0,
Ivan Mahonin 223ac6
        0               , 0               , 0               , 1 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6
Ivan Mahonin 223ac6
Matrix4 Matrix4::perspective(Real fovy, Real aspect, Real z_near, Real z_far) {
Ivan Mahonin 223ac6
    if (fabs(fovy) <= precision) return zero();
Ivan Mahonin 223ac6
    if (fabs(fovy) >= 180.0-precision) return zero();
Ivan Mahonin 223ac6
    if (fabs(aspect) <= precision) return zero();
Ivan Mahonin 223ac6
    if (fabs(z_near - z_far) <= precision) return zero();
Ivan Mahonin 223ac6
    
Ivan Mahonin 223ac6
    Real f = 1/tan(0.5*fovy/180.0*M_PI);
Ivan Mahonin 223ac6
    Real d = 1/(z_near - z_far);
Ivan Mahonin 223ac6
    return Matrix4(
Ivan Mahonin 223ac6
        f/aspect, 0, 0                 ,  0,
Ivan Mahonin 223ac6
        0       , f, 0                 ,  0,
Ivan Mahonin 223ac6
        0       , 0, (z_near + z_far)*d, -1,
Ivan Mahonin 223ac6
        0       , 0, 2*z_near*z_far*d  ,  0 );
Ivan Mahonin 223ac6
}
Ivan Mahonin 223ac6