// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Viewer.cpp
// Function: gaps::R3Viewer::FlyCamera(double, double, double, double, int, int, int, int, int, int)
void R3Viewer::
FlyCamera(RNScalar pitch_factor, RNScalar yaw_factor, RNScalar roll_factor, RNScalar step_factor, 
    RNBoolean relax_yaw, RNBoolean relax_roll, int x, int y, int dx, int dy)
{
    // Update pitch
    if (RNIsNotZero(pitch_factor)) {
	RotateCameraPitch(pitch_factor, x, y, dx, dy);
    }

    // Update yaw
    if (RNIsNotZero(yaw_factor)) {
	RotateCameraYaw(yaw_factor, x, y, dx, dy);
    }
    else if (relax_yaw && (RNIsNotZero(camera.Yaw()))) {
	if (RNIsZero(camera.Yaw(), 0.005)) RotateCameraYaw(-1.0 * camera.Yaw());
	else RotateCameraYaw(-0.05 * camera.Yaw());
    }
	
    // Update roll
    if (RNIsNotZero(roll_factor)) {
	RotateCameraRoll(roll_factor, x, y, dx, dy);
    }
    else if (relax_roll && (RNIsNotZero(camera.Roll()))) {
	if (camera.Roll() < 0.01) RotateCameraRoll(-1.0 * camera.Roll());
	else RotateCameraRoll(-0.05 * camera.Roll());
    }
	
    // Translate camera in direction of view 
    if (RNIsNotZero(step_factor)) {
	RNLength vx = (RNLength) ((2 * x) - viewport.Width()) / (RNLength) viewport.Width();
	if (vx > 1.0) vx = 1.0;
	else if (vx < -1.0) vx = -1.0;
	step_factor *= 1.0 - vx*vx;
	TranslateCamera(camera.Towards() * step_factor);
    }
}

// Assembly:
subq $0x98, %rsp
movl 0xa0(%rsp), %eax
movq %rdi, 0x90(%rsp)
movsd %xmm0, 0x88(%rsp)
movsd %xmm1, 0x80(%rsp)
movsd %xmm2, 0x78(%rsp)
movsd %xmm3, 0x70(%rsp)
movl %esi, 0x6c(%rsp)
movl %edx, 0x68(%rsp)
movl %ecx, 0x64(%rsp)
movl %r8d, 0x60(%rsp)
movl %r9d, 0x5c(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x18(%rsp)
movsd 0x88(%rsp), %xmm0
leaq 0x19ad71(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b56d
movq 0x18(%rsp), %rdi
movsd 0x88(%rsp), %xmm0
movl 0x64(%rsp), %esi
movl 0x60(%rsp), %edx
movl 0x5c(%rsp), %ecx
movl 0xa0(%rsp), %r8d
movq (%rdi), %rax
callq *0x20(%rax)
movsd 0x80(%rsp), %xmm0
leaq 0x19ad2b(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b5b8
movq 0x18(%rsp), %rdi
movsd 0x80(%rsp), %xmm0
movl 0x64(%rsp), %esi
movl 0x60(%rsp), %edx
movl 0x5c(%rsp), %ecx
movl 0xa0(%rsp), %r8d
movq (%rdi), %rax
callq *0x28(%rax)
jmp 0x5b65a
cmpl $0x0, 0x6c(%rsp)
je 0x5b658
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
leaq 0x19acd0(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b658
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movsd 0x1346a4(%rip), %xmm1   # 0x18fca0
callq 0x48790
cmpl $0x0, %eax
je 0x5b62f
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x132f8c(%rip), %xmm0   # 0x18e5b0
mulsd %xmm1, %xmm0
callq 0x5d350
jmp 0x5b656
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x13465b(%rip), %xmm0   # 0x18fca8
mulsd %xmm1, %xmm0
callq 0x5d350
jmp 0x5b658
jmp 0x5b65a
movsd 0x78(%rsp), %xmm0
leaq 0x19ac41(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b69f
movq 0x18(%rsp), %rdi
movsd 0x78(%rsp), %xmm0
movl 0x64(%rsp), %esi
movl 0x60(%rsp), %edx
movl 0x5c(%rsp), %ecx
movl 0xa0(%rsp), %r8d
movq (%rdi), %rax
callq *0x30(%rax)
jmp 0x5b740
cmpl $0x0, 0x68(%rsp)
je 0x5b73e
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
leaq 0x19abe9(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b73e
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movaps %xmm0, %xmm1
movsd 0x132952(%rip), %xmm0   # 0x18e038
ucomisd %xmm1, %xmm0
jbe 0x5b715
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x132ea6(%rip), %xmm0   # 0x18e5b0
mulsd %xmm1, %xmm0
callq 0x5d380
jmp 0x5b73c
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x134575(%rip), %xmm0   # 0x18fca8
mulsd %xmm1, %xmm0
callq 0x5d380
jmp 0x5b73e
jmp 0x5b740
movsd 0x70(%rsp), %xmm0
leaq 0x19ab5b(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b86b
movq 0x18(%rsp), %rdi
movl 0x64(%rsp), %eax
shll %eax
movl %eax, 0xc(%rsp)
addq $0x98, %rdi
callq 0x2be50
movq 0x18(%rsp), %rdi
movl %eax, %ecx
movl 0xc(%rsp), %eax
subl %ecx, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsp)
addq $0x98, %rdi
callq 0x2be50
movsd 0x10(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x50(%rsp), %xmm0
movsd 0x132851(%rip), %xmm1   # 0x18e010
ucomisd %xmm1, %xmm0
jbe 0x5b7d5
movsd 0x132843(%rip), %xmm0   # 0x18e010
movsd %xmm0, 0x50(%rsp)
jmp 0x5b7f5
movsd 0x132dd3(%rip), %xmm0   # 0x18e5b0
ucomisd 0x50(%rsp), %xmm0
jbe 0x5b7f3
movsd 0x132dc3(%rip), %xmm0   # 0x18e5b0
movsd %xmm0, 0x50(%rsp)
jmp 0x5b7f5
movq 0x18(%rsp), %rsi
movsd 0x50(%rsp), %xmm0
movsd 0x50(%rsp), %xmm1
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm1, %xmm0
movsd 0x1327e7(%rip), %xmm1   # 0x18e010
addsd %xmm1, %xmm0
mulsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
addq $0x8, %rsi
leaq 0x20(%rsp), %rdi
callq 0x2b770
movsd 0x70(%rsp), %xmm0
leaq 0x38(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0xce8a0
movq 0x18(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x2b740
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)