// File: /workspace/github_cpp_makefile_star2_O1/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Isect.cpp
// Function: gaps::R3Intersects(gaps::R3Span const&, gaps::R3Triangle const&, gaps::R3Point*, double*)
RNClassID R3Intersects(const R3Span& span, const R3Triangle& triangle, 
    R3Point *hit_point1, RNScalar *hit_t1)
{
    // Find intersection of span and plane
    R3Point p;
    RNScalar t;
    switch (R3Intersects(span, triangle.Plane(), &p, &t)) {
    case RN_NULL_CLASS_ID:
	// Span does not intersect triangle plane
	return RN_NULL_CLASS_ID;
	
    case R3_POINT_CLASS_ID:
	// Span intersects triangle plane in a single point
	// Check whether triangle contains intersection point
	if (!R3Contains(triangle, p)) return RN_NULL_CLASS_ID;
	if (hit_point1) *hit_point1 = p;
	if (hit_t1) *hit_t1 = t;
	return R3_POINT_CLASS_ID;

    case R3_SPAN_CLASS_ID: 
	// Span lies in triangle plane 
	{
	    // Clip span to all edges of triangle
	    R3Span s(span);
	    const R3Point *p1 = &(triangle.Vertex(2)->Position());
	    for (int i = 0; i < 3; i++) {
		// Get kth point
		const R3Point *p2 = &(triangle.Vertex(i)->Position());
		
		// Construct edge plane (containing edge and normal to triangle)
		R3Plane edge_plane(*p2, triangle.Normal(), *p2 - *p1);
		
		// Clip span to edge plane
		RNClassID s_type = s.Clip(edge_plane);
		if (s_type == RN_NULL_CLASS_ID) {
		    return RN_NULL_CLASS_ID;
		}
		else if (s_type == R3_POINT_CLASS_ID) {
		    if (hit_point1) *hit_point1 = s.Start();
		    if (hit_t1) *hit_t1 = span.T(s.Start());
		    return R3_POINT_CLASS_ID;
		}
		
		// Remember previous point
		p1 = p2;
	    }
	    
	    // Span intersects triangle in span
	    if (hit_point1) *hit_point1 = s.Start();
	    if (hit_t1) *hit_t1 = span.T(s.Start());
	    // if (hit_point2) *hit_point2 = s.End();
	    // if (hit_t2) *hit_t2 = span.T(s.End());
	    return R3_SPAN_CLASS_ID;
        }
	break;

    default:
	RNAbort("Invalid intersection result");
	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 $0xd8, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r12
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
callq 0x3ca24
movq %r13, (%rsp)
leaq 0x20(%r13), %rsi
leaq 0x30(%rsp), %rcx
movq %r12, %rdi
movq %rsi, 0x28(%rsp)
movq %rbx, %rdx
callq 0x45062
movl %eax, %ebp
testl %eax, %eax
je 0x4538f
cmpl $0x4, %ebp
je 0x4524a
cmpl $0x1, %ebp
jne 0x4536d
leaq 0x38(%rsp), %rsi
movq (%rsp), %rdi
callq 0x47c1f
testl %eax, %eax
je 0x4538d
testq %r15, %r15
je 0x4522c
leaq 0x38(%rsp), %rsi
movq %r15, %rdi
callq 0x3cd94
movl $0x1, %ebp
testq %r14, %r14
je 0x4538f
movsd 0x30(%rsp), %xmm0
movsd %xmm0, (%r14)
jmp 0x4538f
movq %r15, 0x10(%rsp)
movq %r14, 0x18(%rsp)
leaq 0x50(%rsp), %rdi
movq %r12, 0x8(%rsp)
movq %r12, %rsi
callq 0x3bdea
movq (%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x20(%rsp)
xorl %ebx, %ebx
xorl %r12d, %r12d
movq (%rsp), %rax
movq 0x8(%rax,%rbx,8), %r15
leaq 0xa0(%rsp), %r13
movq %r13, %rdi
movq %r15, %rsi
movq 0x20(%rsp), %rdx
callq 0x3cc88
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
movq 0x28(%rsp), %rdx
movq %r13, %rcx
callq 0x3b68c
leaq 0x50(%rsp), %rdi
movq %r14, %rsi
callq 0x3c3e8
testl %eax, %eax
je 0x45305
cmpl $0x1, %eax
jne 0x4530b
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x452de
leaq 0x50(%rsp), %rsi
callq 0x3cd94
movl $0x1, %ebp
movq 0x18(%rsp), %r15
testq %r15, %r15
je 0x45301
movq 0x8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x3c150
movsd %xmm0, (%r15)
xorl %ecx, %ecx
jmp 0x45312
xorl %ecx, %ecx
movl %eax, %ebp
jmp 0x45312
movb $0x1, %cl
movq %r15, 0x20(%rsp)
testb %cl, %cl
je 0x4532f
cmpq $0x2, %rbx
leaq 0x1(%rbx), %rax
setae %r12b
movq %rax, %rbx
cmpq $0x3, %rax
jne 0x45278
testb $0x1, %r12b
je 0x4538f
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x45349
leaq 0x50(%rsp), %rsi
callq 0x3cd94
movl $0x4, %ebp
movq 0x18(%rsp), %rbx
testq %rbx, %rbx
movq 0x8(%rsp), %rdi
je 0x4538f
leaq 0x50(%rsp), %rsi
callq 0x3c150
movsd %xmm0, (%rbx)
jmp 0x4538f
leaq 0x63c83(%rip), %rdi     # 0xa8ff7
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x72942
leaq 0x63c5d(%rip), %rdi     # 0xa8fe1
xorl %eax, %eax
callq 0x72942
jmp 0x4538f
xorl %ebp, %ebp
movl %ebp, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq