// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Isect.cpp
// Function: gaps::R3Intersects(gaps::R3Ray const&, gaps::R3Span const&, gaps::R3Point*, double*, double*)
RNClassID R3Intersects(const R3Ray& ray, const R3Span& span, 
    R3Point *hit_point, RNScalar *hit_tray, RNScalar *hit_tspan)
{
    // Intersect ray with span's ray
    RNScalar s1 = 0, s2 = 0;
    switch (R3Intersects(ray, span.Ray(), hit_point, &s1, &s2)) {
    case RN_NULL_CLASS_ID:
	// Span and ray do not intersect
	return RN_NULL_CLASS_ID;

    case R3_SPAN_CLASS_ID:
	// Ray and span point at each other on same line
	return R3_SPAN_CLASS_ID;

    case R3_RAY_CLASS_ID:
	// Ray and span point in same direction on same line
	if (RNIsGreater(s2, span.Length())) {
	    // Intersection is beyond span endpoint 
	    return RN_NULL_CLASS_ID;
	}
	else if (RNIsEqual(s2, span.Length())) {
	    // Span endpoint is ray start point
	    if (hit_tray) *hit_tray = s1;
	    if (hit_tspan) *hit_tspan = s2;
	    return R3_POINT_CLASS_ID;
	}
	else {
	    // Span and ray have non-null intersection in same line
	    return R3_SPAN_CLASS_ID;
	}
	break;

    case R3_POINT_CLASS_ID: 
	// Check if intersection point is on span
	if (RNIsGreater(s2, span.Length())) {
	    // Intersection is beyond span endpoint 
	    return RN_NULL_CLASS_ID;
	}
	else {
	    // Span and ray intersect at point
	    if (hit_tray) *hit_tray = s1;
	    if (hit_tspan) *hit_tspan = s2;
	    return R3_POINT_CLASS_ID;
	}
	break;

    default:
	RNAbort("Illegal intersection");
	break;
    }

    // Should never get here
    RNAbort("Should never get here");
    return RN_NULL_CLASS_ID;
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movq %rsi, 0x50(%rsp)
movq %rdx, 0x48(%rsp)
movq %rcx, 0x40(%rsp)
movq %r8, 0x38(%rsp)
movq $0x0, 0x30(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x50(%rsp), %rdi
callq 0x81b20
movq 0x18(%rsp), %rdi
movq %rax, %rsi
movq 0x48(%rsp), %rdx
leaq 0x30(%rsp), %rcx
leaq 0x28(%rsp), %r8
callq 0x7aa10
movl %eax, %ecx
movq %rcx, 0x20(%rsp)
subl $0x4, %eax
ja 0x7ae5f
movq 0x20(%rsp), %rax
leaq 0xbac55(%rip), %rcx     # 0x135960
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, 0x64(%rsp)
jmp 0x7ae83
movl $0x4, 0x64(%rsp)
jmp 0x7ae83
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x50(%rsp), %rdi
callq 0x37a50
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
leaq 0xfd78c(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7ad6f
movl $0x0, 0x64(%rsp)
jmp 0x7ae83
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x50(%rsp), %rdi
callq 0x37a50
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
leaq 0xfd74b(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x37170
cmpl $0x0, %eax
je 0x7adde
cmpq $0x0, 0x40(%rsp)
je 0x7adba
movsd 0x30(%rsp), %xmm0
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x38(%rsp)
je 0x7add1
movsd 0x28(%rsp), %xmm0
movq 0x38(%rsp), %rax
movsd %xmm0, (%rax)
movl $0x1, 0x64(%rsp)
jmp 0x7ae83
movl $0x4, 0x64(%rsp)
jmp 0x7ae83
movsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rsp)
movq 0x50(%rsp), %rdi
callq 0x37a50
movaps %xmm0, %xmm1
movsd (%rsp), %xmm0
leaq 0xfd6d1(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7ae27
movl $0x0, 0x64(%rsp)
jmp 0x7ae83
cmpq $0x0, 0x40(%rsp)
je 0x7ae3e
movsd 0x30(%rsp), %xmm0
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x38(%rsp)
je 0x7ae55
movsd 0x28(%rsp), %xmm0
movq 0x38(%rsp), %rax
movsd %xmm0, (%rax)
movl $0x1, 0x64(%rsp)
jmp 0x7ae83
leaq 0xbab0e(%rip), %rdi     # 0x135974
movb $0x0, %al
callq 0xd4e20
leaq 0xbab15(%rip), %rdi     # 0x135989
movb $0x0, %al
callq 0xd4e20
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nopl (%rax)