// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Isect.cpp
// Function: gaps::R3Intersects(gaps::R3Line const&, gaps::R3Box const&, gaps::R3Point*)
RNClassID R3Intersects(const R3Line& line, const R3Box& box, 
    R3Point *hit_point)
{
    RNClassID id = RN_NULL_CLASS_ID;
    R3Point point1;
    RNScalar tval1;

    // Check if box contains point on line
    if (R3Contains(box, line.Point())) {
	if (hit_point) *hit_point = line.Point();
	return R3_SPAN_CLASS_ID;
    }
    else {
	// Find parametric distance to front plane in each dimension
	for (RNDimension dim = RN_X; dim <= RN_Z; dim++) {
	    if (RNIsPositive(line.Vector()[dim])) {
		RNScalar delta = box.Min()[dim] - line.Point()[dim];
		tval1 = delta / line.Vector()[dim];
	    }
	    else if (RNIsNegative(line.Vector()[dim])) {
		RNScalar delta = box.Max()[dim] - line.Point()[dim];
		tval1 = delta / line.Vector()[dim];
	    }
	    else {
		continue;
	    }
	    
	    // Compute intersection point on plane
	    RNDimension dim1 = (dim + 1) % 3;
	    RNDimension dim2 = (dim + 2) % 3;
	    point1[dim] = (line.Vector()[dim] > 0.0) ? box.Min()[dim] : box.Max()[dim];
	    assert(RNIsEqual(point1[dim], line.Point()[dim] + line.Vector()[dim] * tval1));
	    point1[dim1] = line.Point()[dim1] + line.Vector()[dim1] * tval1;
	    point1[dim2] = line.Point()[dim2] + line.Vector()[dim2] * tval1;
	    
	    // Check if intersection point on plane is inside box
	    if ((RNIsLessOrEqual(point1[dim1], box.Max()[dim1])) &&
		(RNIsGreaterOrEqual(point1[dim1], box.Min()[dim1])) &&
		(RNIsLessOrEqual(point1[dim2], box.Max()[dim2])) &&
		(RNIsGreaterOrEqual(point1[dim2], box.Min()[dim2]))) {
		// Found first intersection point 
		id = R3_SPAN_CLASS_ID;
		break;
	    }
	}

	// Fill in results
	if (id != RN_NULL_CLASS_ID) {
	    if (hit_point) *hit_point = point1;
	}
	
	// Return intersection 
	return id;
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movq %rsp, %r12
movq %r12, %rdi
callq 0x3c530
movq %r15, %rdi
movq %r14, %rsi
callq 0x47508
testl %eax, %eax
je 0x429b2
testq %rbx, %rbx
je 0x429a8
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3c89a
movl $0x4, %eax
jmp 0x42ac9
leaq 0xa31df(%rip), %rax     # 0xe5b98
movsd (%rax), %xmm0
movapd 0x5f65b(%rip), %xmm1    # 0xa2020
xorpd %xmm0, %xmm1
xorl %edi, %edi
leaq 0x20(%r15), %rax
leaq 0x8(%r15), %rcx
xorpd %xmm2, %xmm2
movl $0x2, %edx
movsd 0x18(%r14,%rdi,8), %xmm4
movl $0x8, %esi
ucomisd %xmm0, %xmm4
ja 0x42a04
movl $0x20, %esi
ucomisd %xmm4, %xmm1
ja 0x42a04
incq %rdi
movq %rdi, %rsi
jmp 0x42aba
addq %r15, %rsi
movsd (%rsi,%rdi,8), %xmm3
subsd (%r14,%rdi,8), %xmm3
divsd %xmm4, %xmm3
leaq 0x1(%rdi), %rsi
ucomisd %xmm2, %xmm4
movq %rax, %r9
cmovaq %rcx, %r9
cmpq $0x2, %rdi
movl %esi, %r10d
movl $0x0, %r8d
cmovneq %r10, %r8
leal -0x1(%rdi), %r10d
testq %rdi, %rdi
movsd (%r9,%rdi,8), %xmm4
movsd %xmm4, (%rsp,%rdi,8)
movsd 0x18(%r14,%r8,8), %xmm4
mulsd %xmm3, %xmm4
addsd (%r14,%r8,8), %xmm4
movslq %r10d, %rdi
movsd %xmm4, (%rsp,%r8,8)
cmoveq %rdx, %rdi
mulsd 0x18(%r14,%rdi,8), %xmm3
addsd (%r14,%rdi,8), %xmm3
movsd %xmm3, (%rsp,%rdi,8)
movsd (%rsp,%r8,8), %xmm4
movapd %xmm4, %xmm5
subsd 0x20(%r15,%r8,8), %xmm5
ucomisd %xmm5, %xmm0
jb 0x42aba
subsd 0x8(%r15,%r8,8), %xmm4
ucomisd %xmm1, %xmm4
jb 0x42aba
movapd %xmm3, %xmm4
subsd 0x20(%r15,%rdi,8), %xmm4
ucomisd %xmm4, %xmm0
jb 0x42aba
subsd 0x8(%r15,%rdi,8), %xmm3
ucomisd %xmm1, %xmm3
jae 0x42ad5
movq %rsi, %rdi
cmpq $0x3, %rsi
jne 0x429dc
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %r12, %r14
jmp 0x42998