// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Viewer.cpp
// Function: gaps::R3Viewer::WalkCamera(double, double, double, double, int, int, int, int, int, int)
void R3Viewer::
WalkCamera(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 ALONG HORIZONTAL PLANE
    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;
	R3Vector v = camera.Towards();
	v.Project(R3Plane(camera.Origin(), R3default_camera_up_vector));
	TranslateCamera(v * step_factor);
    }
}

// Assembly:
subq $0xb8, %rsp
movl 0xc0(%rsp), %eax
movq %rdi, 0xb0(%rsp)
movsd %xmm0, 0xa8(%rsp)
movsd %xmm1, 0xa0(%rsp)
movsd %xmm2, 0x98(%rsp)
movsd %xmm3, 0x90(%rsp)
movl %esi, 0x8c(%rsp)
movl %edx, 0x88(%rsp)
movl %ecx, 0x84(%rsp)
movl %r8d, 0x80(%rsp)
movl %r9d, 0x7c(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0x18(%rsp)
movsd 0xa8(%rsp), %xmm0
leaq 0x19a9af(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b935
movq 0x18(%rsp), %rdi
movsd 0xa8(%rsp), %xmm0
movl 0x84(%rsp), %esi
movl 0x80(%rsp), %edx
movl 0x7c(%rsp), %ecx
movl 0xc0(%rsp), %r8d
movq (%rdi), %rax
callq *0x20(%rax)
movsd 0xa0(%rsp), %xmm0
leaq 0x19a963(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5b986
movq 0x18(%rsp), %rdi
movsd 0xa0(%rsp), %xmm0
movl 0x84(%rsp), %esi
movl 0x80(%rsp), %edx
movl 0x7c(%rsp), %ecx
movl 0xc0(%rsp), %r8d
movq (%rdi), %rax
callq *0x28(%rax)
jmp 0x5ba2b
cmpl $0x0, 0x8c(%rsp)
je 0x5ba29
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
leaq 0x19a8ff(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5ba29
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movsd 0x1342d3(%rip), %xmm1   # 0x18fca0
callq 0x48790
cmpl $0x0, %eax
je 0x5ba00
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x132bbb(%rip), %xmm0   # 0x18e5b0
mulsd %xmm1, %xmm0
callq 0x5d350
jmp 0x5ba27
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd40
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x13428a(%rip), %xmm0   # 0x18fca8
mulsd %xmm1, %xmm0
callq 0x5d350
jmp 0x5ba29
jmp 0x5ba2b
movsd 0x98(%rsp), %xmm0
leaq 0x19a86d(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5ba7c
movq 0x18(%rsp), %rdi
movsd 0x98(%rsp), %xmm0
movl 0x84(%rsp), %esi
movl 0x80(%rsp), %edx
movl 0x7c(%rsp), %ecx
movl 0xc0(%rsp), %r8d
movq (%rdi), %rax
callq *0x30(%rax)
jmp 0x5bb20
cmpl $0x0, 0x88(%rsp)
je 0x5bb1e
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
leaq 0x19a809(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5bb1e
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movaps %xmm0, %xmm1
movsd 0x132572(%rip), %xmm0   # 0x18e038
ucomisd %xmm1, %xmm0
jbe 0x5baf5
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x132ac6(%rip), %xmm0   # 0x18e5b0
mulsd %xmm1, %xmm0
callq 0x5d380
jmp 0x5bb1c
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x5dd90
movq 0x18(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x134195(%rip), %xmm0   # 0x18fca8
mulsd %xmm1, %xmm0
callq 0x5d380
jmp 0x5bb1e
jmp 0x5bb20
movsd 0x90(%rsp), %xmm0
leaq 0x19a778(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x5bc8b
movq 0x18(%rsp), %rdi
movl 0x84(%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, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
movsd 0x13246b(%rip), %xmm1   # 0x18e010
ucomisd %xmm1, %xmm0
jbe 0x5bbbb
movsd 0x13245d(%rip), %xmm0   # 0x18e010
movsd %xmm0, 0x70(%rsp)
jmp 0x5bbdb
movsd 0x1329ed(%rip), %xmm0   # 0x18e5b0
ucomisd 0x70(%rsp), %xmm0
jbe 0x5bbd9
movsd 0x1329dd(%rip), %xmm0   # 0x18e5b0
movsd %xmm0, 0x70(%rsp)
jmp 0x5bbdb
movq 0x18(%rsp), %rsi
movsd 0x70(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm1, %xmm0
movsd 0x132401(%rip), %xmm1   # 0x18e010
addsd %xmm1, %xmm0
mulsd 0x90(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
addq $0x8, %rsi
leaq 0x58(%rsp), %rdi
callq 0x2b770
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
callq 0x2b900
movq %rax, %rsi
leaq 0x38(%rsp), %rdi
leaq 0x1a0158(%rip), %rdx    # 0x1fbda8
callq 0xc9fb0
leaq 0x58(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0xcea60
movsd 0x90(%rsp), %xmm0
leaq 0x20(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xce8a0
movq 0x18(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x2b740
addq $0xb8, %rsp
retq
nopw %cs:(%rax,%rax)