#version 120


mat3 isorot3     (mat4 iso) { return mat3(iso); }
vec3 isotrans3   (mat4 iso) { return iso[3].xyz; }

mat3 isorotinv3  (mat4 iso) { return transpose(isorot3(iso)); }
vec3 isotransinv3(mat4 iso) { return -isotrans3(iso); }

mat4 isorot4     (mat4 iso) { return mat4(isorot3     (iso)); }
mat4 isorotinv4  (mat4 iso) { return mat4(isorotinv3  (iso)); }
vec4 isotrans4   (mat4 iso) { return vec4(isotrans3   (iso), 0); }
vec4 isotransinv4(mat4 iso) { return vec4(isotransinv3(iso), 0); }

mat4 isoinv(mat4 iso)
{
    // mat4 inv = isorotinv4(iso);
    // inv[3] += inv * isotransinv4(iso);
    mat3 rotinv = isorotinv3(iso);
    mat4 inv = mat4(rotinv);
    inv[3].xyz = rotinv * isotransinv3(iso);
    return inv;
}


#ifdef GLSLRUN
void main()
{
    float phi = 1;
    mat4 iso = transpose(mat4(
        +cos(phi), -sin(phi), 0, 1,
        +sin(phi), +cos(phi), 0, 2,
        0,         0,         1, 3,
        0,         0,         0, 1
    ));
    vec4 vec = vec4(4, 5, 6, 1);

    cout
        << iso * vec << endl
        << isorot4(iso) *      vec  + isotrans4(iso) << endl
        << isorot3(iso) * vec3(vec) + isotrans3(iso) << endl;

    cout
        << inverse(iso) << endl
        << isoinv (iso) << endl;
}
#endif // GLSLRUN