// File: /workspace/github_c_makefile_star2_O0/stetre[P]moonglmath/src/viewing.c
// Function: moonglmath_look_at
int look_at(mat_t dst, vec_t eye, vec_t at, vec_t up)
/* look_at(eye, at, up) 
 *
 * eye = camera position = (e1, e2, e3)
 * at  = target position
 * up  = camera 'up' direction
 *
 * NOTE: 'up' is the direction from the camera to a point above the target,
 *        on the vertical.
 *
 * d = (at - eye) : direction vector
 * n = (eye - at) = z : normal to the projection plane, oriented towards the camera
 * x = d % up = up % n : points to the right of the camera
 * y = z % x = n % x : points up fro the camera
 *  
 * M = |x1 x2 x3 0| |1 0 0 -e1|
 *     |y1 y2 y3 0|·|0 1 0 -e2|
 *     |z1 z2 z3 0| |0 0 1 -e3|
 *     |0  0  0  1| |0 0 0   1|
 *          |           |
 *       orient     translate
 */
    {

    size_t i;
    vec_t z, x, y;
    mat_t c, te;

    vec_sub(z, eye, at, 4); /* z = eye - at (normal vector = - direction vector) */
    vec_normalize(z, 4);

    vec_cross(x, up, z); /* x = up % z  (right vector) */
    vec_normalize(x, 4);

    vec_cross(y, z, x);  /* y = z % x  (up vector) */
    vec_normalize(y, 4);

    mat_clear(c);   
    /* c = x1 x2 x3  0
     *     y1 y2 y3  0
     *     z1 z2 z3  0
     *      0  0  0  1
     */
    for(i = 0; i< 4; i ++)
        {
        c[0][i] = x[i];
        c[1][i] = y[i];
        c[2][i] = z[i];
        }
    c[3][3] = 1;

    /* dst = c * translate(-eye) */
    translate(te, -eye[0], -eye[1], -eye[2]);
    mat_mul(dst, c, te, 4, 4, 4);

    return 0;
    }

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x180(%rsp)
movq %rsi, 0x178(%rsp)
movq %rdx, 0x170(%rsp)
movq %rcx, 0x168(%rsp)
leaq 0x140(%rsp), %rdi
movq 0x178(%rsp), %rsi
movq 0x170(%rsp), %rdx
movl $0x4, %ecx
callq 0x8830
leaq 0x140(%rsp), %rdi
movl $0x4, %esi
callq 0x8e70
leaq 0x120(%rsp), %rdi
movq 0x168(%rsp), %rsi
leaq 0x140(%rsp), %rdx
callq 0x8cd0
leaq 0x120(%rsp), %rdi
movl $0x4, %esi
callq 0x8e70
leaq 0x100(%rsp), %rdi
leaq 0x140(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0x8cd0
leaq 0x100(%rsp), %rdi
movl $0x4, %esi
callq 0x8e70
leaq 0x80(%rsp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x8530
movq $0x0, 0x160(%rsp)
cmpq $0x4, 0x160(%rsp)
jae 0x21463
movq 0x160(%rsp), %rax
movsd 0x120(%rsp,%rax,8), %xmm0
movq 0x160(%rsp), %rax
movsd %xmm0, 0x80(%rsp,%rax,8)
movq 0x160(%rsp), %rax
movsd 0x100(%rsp,%rax,8), %xmm0
movq 0x160(%rsp), %rax
movsd %xmm0, 0xa0(%rsp,%rax,8)
movq 0x160(%rsp), %rax
movsd 0x140(%rsp,%rax,8), %xmm0
movq 0x160(%rsp), %rax
movsd %xmm0, 0xc0(%rsp,%rax,8)
movq 0x160(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x160(%rsp)
jmp 0x213d9
movsd 0x1c55(%rip), %xmm0     # 0x230c0
movsd %xmm0, 0xf8(%rsp)
movq %rsp, %rdi
movq 0x178(%rsp), %rax
movsd (%rax), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movq 0x178(%rsp), %rax
movsd 0x8(%rax), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
movq 0x178(%rsp), %rax
movsd 0x10(%rax), %xmm2
movq %xmm2, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm2
callq 0x8570
movq 0x180(%rsp), %rdi
leaq 0x80(%rsp), %rsi
movq %rsp, %rdx
movl $0x4, %r9d
movq %r9, %rcx
movq %r9, %r8
callq 0x8790
xorl %eax, %eax
addq $0x188, %rsp            # imm = 0x188
retq
nopw %cs:(%rax,%rax)