// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Isect.cpp
// Function: gaps::R2Intersects(gaps::R2Ray const&, gaps::R2Ray const&, gaps::R2Point*, double*, double*)
RNClassID R2Intersects(const R2Ray& ray1, const R2Ray& ray2, 
    R2Point *hit_point, RNScalar *hit_t1, RNScalar *hit_t2)
{
    // Get variables in more convenient form
    const R2Vector p1 = ray1.Start().Vector();
    const R2Vector p2 = ray2.Start().Vector();
    const R2Vector& v1 = ray1.Vector();
    const R2Vector& v2 = ray2.Vector();
    const R2Vector& n1 = ray1.Normal();
    const R2Vector& n2 = ray2.Normal();
    const RNScalar c1 = ray1.Line().C();
    const RNScalar c2 = ray2.Line().C();

    // Check if ray1 and ray2 are parallel
    RNScalar denom = n1.Dot(v2);
    if (RNIsZero(denom)) {
	// Check if ray1 and ray2 are coincident
	if (R2Contains(ray1.Line(), ray2.Start())) {
	    // Ray1 and ray2 share the same line
	    if (R2Contains(v1, v2)) {
	        // Rays are colinear and in same direction
	        return R2_RAY_CLASS_ID;
	    }
	    else {
	        // Rays are colinear and in opposite direction
	        if (R2Contains(ray1, ray2.Start())) return R2_SPAN_CLASS_ID;
		else return RN_NULL_CLASS_ID;
	    }
	}
	else {
	    // Rays are parallel and do not intersect
	    return RN_NULL_CLASS_ID;
	}
    }
    else {
	// Find parametric values of intersection point 
        RNScalar t1 = (c2 + n2.Dot(p1)) / denom;
        RNScalar t2 = (c1 + n1.Dot(p2)) / -denom;

	// Check if intersection point is on ray2
	if (RNIsPositiveOrZero(t1) && RNIsPositiveOrZero(t2)) {
	    if (hit_point) *hit_point = ray2.Point(t2);
	    if (hit_t1) *hit_t1 = t1;
	    if (hit_t2) *hit_t2 = t2;
	    return R2_POINT_CLASS_ID;
	}
	else {
	    // Ray1 and ray2 do not intersect
	    return RN_NULL_CLASS_ID;
	}
    }
}

// Assembly:
subq $0xc8, %rsp
movq %rdi, 0xb8(%rsp)
movq %rsi, 0xb0(%rsp)
movq %rdx, 0xa8(%rsp)
movq %rcx, 0xa0(%rsp)
movq %r8, 0x98(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa3560
movq %rax, %rsi
leaq 0x88(%rsp), %rdi
callq 0xa5b80
movq 0xb0(%rsp), %rdi
callq 0xa3560
movq %rax, %rsi
leaq 0x78(%rsp), %rdi
callq 0xa5b80
movq 0xb8(%rsp), %rdi
callq 0xa35c0
movq %rax, 0x70(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xa35c0
movq %rax, 0x68(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa5be0
movq %rax, 0x60(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xa5be0
movq %rax, 0x58(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xa35d0
movq %rax, %rdi
callq 0xa3550
movsd %xmm0, 0x50(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xa35d0
movq %rax, %rdi
callq 0xa3550
movsd %xmm0, 0x48(%rsp)
movq 0x60(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0xc3f40
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm0
leaq 0xd439a(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0xa4209
movq 0xb8(%rsp), %rdi
callq 0xa35d0
movq %rax, 0x18(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xa3560
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0xa1a10
cmpl $0x0, %eax
je 0xa41f9
movq 0x70(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0xa16f0
cmpl $0x0, %eax
je 0xa41ad
movl $0x3, 0xc4(%rsp)
jmp 0xa434e
movq 0xb8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xa3560
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xa1d20
cmpl $0x0, %eax
je 0xa41e9
movl $0x4, 0xc4(%rsp)
jmp 0xa434e
movl $0x0, 0xc4(%rsp)
jmp 0xa434e
movl $0x0, 0xc4(%rsp)
jmp 0xa434e
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rsp)
movq 0x58(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0xc3f40
movaps %xmm0, %xmm1
movsd (%rsp), %xmm0
addsd %xmm1, %xmm0
divsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x60(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0xc3f40
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd 0x40(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x38(%rsp), %xmm0
leaq 0xd4246(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x3a5d0
cmpl $0x0, %eax
je 0xa4343
movsd 0x30(%rsp), %xmm0
leaq 0xd4227(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x3a5d0
cmpl $0x0, %eax
je 0xa4343
cmpq $0x0, 0xa8(%rsp)
je 0xa42fc
movq 0xb0(%rsp), %rsi
movsd 0x30(%rsp), %xmm0
leaq 0x20(%rsp), %rdi
callq 0xc24c0
movq 0xa8(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0xc33e0
cmpq $0x0, 0xa0(%rsp)
je 0xa4319
movsd 0x38(%rsp), %xmm0
movq 0xa0(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x98(%rsp)
je 0xa4336
movsd 0x30(%rsp), %xmm0
movq 0x98(%rsp), %rax
movsd %xmm0, (%rax)
movl $0x1, 0xc4(%rsp)
jmp 0xa434e
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
addq $0xc8, %rsp
retq
nopl (%rax)