// File: soybin[P]idyll/src/renderer.cpp
// Function: renderer::updateRotationMatrix()
void renderer::updateRotationMatrix() {
	// determine camera's rotation so that it always looks
	// towards the center of the scene regardless of its
	// position

	// pitch
	double ry = 0.0;

	// yaw
	double rx = 0.0;
	
	double x = cameraPosition.x;
	double y = cameraPosition.y;
	double z = cameraPosition.z;

	// yaw
	// to calculate the yaw axis rotation we have to think
	// about the intersection of the sphere at y height
	// because the distance towards the center will decrease
	// as we get closer to the poles. i wasted a whole day 
	// because of this
	ry = std::asin(std::abs(z) / std::sqrt(x * x + z * z));
	if (x < 0.0) {
		if (z < 0.0) {
			ry = (PI / 2.0) + ry;
		} else if (z > 0.0) {
			ry = (PI / 2.0) - ry;
		} else {
			ry = 90.0;
		}
	} else if (x > 0.0) {
		if (z < 0.0) {
			ry = -((PI / 2.0) + ry);
		} else if (z > 0.0){
			ry = -((PI / 2.0) - ry);
		} else {
			ry = -(PI / 2.0);
		}
	} else {
		if (z < 0.0) {
			ry = -PI;
		} else if (z > 0.0) {
			ry = 0.0;
		}
	}

	// pitch
	rx = std::asin(y / std::sqrt(x * x + y * y + z * z));

	// trig
	double siny = std::sin(ry);
	double cosy = std::cos(ry);
	double sinx = std::sin(rx);
	double cosx = std::cos(rx);

	// rotation matrix. 
	// there's no explicit matrix implementation because there's
	// only one use case in the domain of this program. i've
	// implemented it by having a static array of vec3s with
	// precomputed values that are multiplied by each ray 
	// direction vector at runtime.
	// https://en.wikipedia.org/wiki/Rotation_matrix
	RMy = {
		math::vec3(cosy, 0.0, siny),
		math::vec3(0.0, 1.0, 0.0),
		math::vec3(-siny, 0.0, cosy)
	};

	RMx = {
		math::vec3(1.0, 0.0, 0.0),
		math::vec3(0.0, cosx, -sinx),
		math::vec3(0.0, sinx, cosx)
	};
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x110(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x10(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x18(%rbp)
movsd 0x30(%rax), %xmm0
movsd %xmm0, -0x20(%rbp)
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd 0x40(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
callq 0xcf30
movsd %xmm0, -0x108(%rbp)
movsd -0x20(%rbp), %xmm0
movsd -0x20(%rbp), %xmm2
movsd -0x30(%rbp), %xmm1
mulsd -0x30(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x42b0
movaps %xmm0, %xmm1
movsd -0x108(%rbp), %xmm0
divsd %xmm1, %xmm0
callq 0x4550
movsd %xmm0, -0x10(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0xd042
xorps %xmm0, %xmm0
ucomisd -0x30(%rbp), %xmm0
jbe 0xd00c
movsd 0x10860(%rip), %xmm0    # 0x1d860
addsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x10(%rbp)
jmp 0xd03d
movsd -0x30(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xd02e
movsd 0x1083e(%rip), %xmm0    # 0x1d860
subsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x10(%rbp)
jmp 0xd03b
movsd 0x10832(%rip), %xmm0    # 0x1d868
movsd %xmm0, -0x10(%rbp)
jmp 0xd03d
jmp 0xd104
movsd -0x20(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xd0cf
xorps %xmm0, %xmm0
ucomisd -0x30(%rbp), %xmm0
jbe 0xd085
movsd 0x107fe(%rip), %xmm0    # 0x1d860
addsd -0x10(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x10(%rbp)
jmp 0xd0cd
movsd -0x30(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xd0be
movsd 0x107c5(%rip), %xmm0    # 0x1d860
subsd -0x10(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x10(%rbp)
jmp 0xd0cb
movsd 0x10792(%rip), %xmm0    # 0x1d858
movsd %xmm0, -0x10(%rbp)
jmp 0xd0cd
jmp 0xd102
xorps %xmm0, %xmm0
ucomisd -0x30(%rbp), %xmm0
jbe 0xd0e8
movsd 0x1076f(%rip), %xmm0    # 0x1d850
movsd %xmm0, -0x10(%rbp)
jmp 0xd100
movsd -0x30(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xd0fe
xorps %xmm0, %xmm0
movsd %xmm0, -0x10(%rbp)
jmp 0xd100
jmp 0xd102
jmp 0xd104
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x118(%rbp)
movsd -0x20(%rbp), %xmm1
movsd -0x20(%rbp), %xmm2
movsd -0x28(%rbp), %xmm0
mulsd -0x28(%rbp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x30(%rbp), %xmm0
movsd -0x30(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x42b0
movaps %xmm0, %xmm1
movsd -0x118(%rbp), %xmm0
divsd %xmm1, %xmm0
callq 0x4550
movsd %xmm0, -0x18(%rbp)
movsd -0x10(%rbp), %xmm0
callq 0x40a0
movsd %xmm0, -0x38(%rbp)
movsd -0x10(%rbp), %xmm0
callq 0x4620
movsd %xmm0, -0x40(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x40a0
movsd %xmm0, -0x48(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x4620
movsd %xmm0, -0x50(%rbp)
movsd -0x40(%rbp), %xmm0
movsd -0x38(%rbp), %xmm2
leaq -0xa8(%rbp), %rdi
xorps %xmm1, %xmm1
callq 0xbe30
leaq -0xa8(%rbp), %rdi
addq $0x18, %rdi
xorps %xmm2, %xmm2
movsd 0x104a8(%rip), %xmm1    # 0x1d670
movaps %xmm2, %xmm0
callq 0xbe30
leaq -0xa8(%rbp), %rdi
addq $0x30, %rdi
movsd -0x38(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x40(%rbp), %xmm2
xorps %xmm1, %xmm1
callq 0xbe30
movq -0x110(%rbp), %rdi
leaq -0xa8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq $0x3, -0x58(%rbp)
addq $0xa8, %rdi
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0xf910
leaq -0x100(%rbp), %rdi
movsd 0x1042f(%rip), %xmm0    # 0x1d670
xorps %xmm2, %xmm2
movaps %xmm2, %xmm1
callq 0xbe30
leaq -0x100(%rbp), %rdi
addq $0x18, %rdi
movsd -0x50(%rbp), %xmm1
movsd -0x48(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm2
xorps %xmm0, %xmm0
callq 0xbe30
leaq -0x100(%rbp), %rdi
addq $0x30, %rdi
movsd -0x48(%rbp), %xmm1
movsd -0x50(%rbp), %xmm2
xorps %xmm0, %xmm0
callq 0xbe30
movq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq $0x3, -0xb0(%rbp)
addq $0x90, %rdi
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
callq 0xf910
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq