// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Isect.cpp
// Function: gaps::R3Intersects(gaps::R3Ray const&, gaps::R3Ray const&, gaps::R3Point*, double*, double*)
RNClassID R3Intersects(const R3Ray& ray1, const R3Ray& ray2, 
    R3Point *hit_point, RNScalar *hit_t1, RNScalar *hit_t2)
{
    // Intersect ray1 with ray2's line
    R3Point point;
    RNScalar s1 = 0, s2 = 0;
    switch (R3Intersects(ray1, ray2.Line(), &point, &s1)) {
    case RN_NULL_CLASS_ID:
	// Rays do not intersect
	return RN_NULL_CLASS_ID;

    case R3_RAY_CLASS_ID:
	// Ray2's line contains ray1 -- check directions
	if (R3Contains(ray1.Vector(), ray2.Vector())) {
	    // Rays share same line in same direction
	    return R3_RAY_CLASS_ID;
	}
	else {
	    // Rays share same line, but in different directions
	    assert(R3Contains(ray1.Vector(), -(ray2.Vector())));

	    // Check intersection point
	    s2 = ray2.T(ray1.Start());
	    if (RNIsNegative(s2)) {
		// Rays share line, but intersection is behind endpoint of ray2
		return RN_NULL_CLASS_ID;
	    }
	    else if (RNIsZero(s2)) {
		// Rays share line and endpoint
		if (hit_t1) *hit_t1 = s1;
		if (hit_t2) *hit_t2 = s2;
		if (hit_point) *hit_point = point;
		return R3_POINT_CLASS_ID;
	    }
	    else {
		// Rays share line and intersect in span 
		return R3_SPAN_CLASS_ID;
	    }
	}

    case R3_POINT_CLASS_ID: 
	// Check if intersection point is on ray2
	s2 = ray2.T(point);
	if (RNIsNegative(s1)) {
	    // Line intersection is behind ray1
	    return RN_NULL_CLASS_ID;
	}
	else {
	    // Rays intersect at point
	    if (hit_t1) *hit_t1 = s1;
	    if (hit_t2) *hit_t2 = s2;
	    if (hit_point) *hit_point = point;
	    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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %r14
movq %rcx, %r15
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r13
leaq 0x10(%rsp), %rbp
movq %rbp, %rdi
callq 0x3ca24
leaq 0x8(%rsp), %rcx
movq $0x0, (%rcx)
movq %r12, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x42a0f
movl %eax, %ebp
movl %eax, %eax
leaq 0x65b6e(%rip), %rcx     # 0xa8f68
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0x3c662
movsd 0x8(%rsp), %xmm1
leaq 0xa277b(%rip), %rax     # 0xe5b98
movsd (%rax), %xmm2
xorpd 0x5ebf7(%rip), %xmm2    # 0xa2020
ucomisd %xmm1, %xmm2
ja 0x434eb
testq %r15, %r15
je 0x4343d
movsd %xmm1, (%r15)
testq %r14, %r14
je 0x43447
movsd %xmm0, (%r14)
movl $0x1, %ebp
testq %rbx, %rbx
je 0x434ed
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3cd94
jmp 0x434ed
leaq 0x65b5e(%rip), %rdi     # 0xa8fcc
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x72942
leaq 0x65b63(%rip), %rdi     # 0xa8fe1
xorl %eax, %eax
callq 0x72942
jmp 0x434ed
leaq 0x18(%r13), %rdi
leaq 0x18(%r12), %rsi
callq 0x46db8
movl $0x3, %ebp
testl %eax, %eax
jne 0x434ed
movq %r12, %rdi
movq %r13, %rsi
callq 0x3c662
leaq 0xa26e8(%rip), %rax     # 0xe5b98
movsd (%rax), %xmm1
movapd 0x5eb64(%rip), %xmm2    # 0xa2020
xorpd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
ja 0x434eb
ucomisd %xmm2, %xmm0
movl $0x4, %ebp
jb 0x434ed
ucomisd %xmm0, %xmm1
jb 0x434ed
testq %r15, %r15
je 0x4343d
movsd 0x8(%rsp), %xmm1
jmp 0x43438
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq