// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Isect.cpp
// Function: gaps::R3Intersects(gaps::R3Ray const&, gaps::R3Cylinder const&, gaps::R3Point*, gaps::R3Vector*, double*)
RNClassID R3Intersects(const R3Ray& ray, const R3Cylinder& cylinder, 
    R3Point *hit_point1, R3Vector *hit_normal1, RNScalar *hit_t1)
{
    // Check if sphere contains ray start point
    RNBoolean start_inside = R3Contains(cylinder, ray.Start());
    if (start_inside) {
      if (hit_point1) *hit_point1 = ray.Start();
      if (hit_normal1) *hit_normal1 = -ray.Vector();
      if (hit_t1) *hit_t1 = 0;
      return R3_SPAN_CLASS_ID;
    }

    // See Graphics Gems IV, page 356
    // Compute parametric values of intersection with infinite cylinder
    RNScalar cyl_t1, cyl_t2;
    R3Vector R = ray.Vector();
    R3Vector A = cylinder.Axis().Vector();
    R3Vector D = R % A;
    RNScalar a = D.Length();
    if (RNIsZero(a)) {
	// Ray and axis are parallel
	RNScalar d = R3Distance(ray.Start(), cylinder.Axis().Line());
	if (RNIsLessOrEqual(d, cylinder.Radius())) {
	    // Ray lies entirely inside infinite cylinder
	    cyl_t1 = 0.0;
	    cyl_t2 = RN_INFINITY;
	}
	else {
	    // Ray lies entirely outside infinite cylinder
	    return RN_NULL_CLASS_ID;
	}
    }
    else {
	// Ray and axis are not parallel
	// Compute distance from axis to closest point on ray's line
	D /= a;
	R3Vector RC = ray.Start() - cylinder.Axis().Start();
	RNScalar d = RC.Dot(D);
	if (d < 0.0) d = -d;
	if (RNIsGreater(d, cylinder.Radius())) {
	    // Ray does not intersect infinite cylinder
	    return RN_NULL_CLASS_ID;
	}
	else {
	    // Find parametric value (cyl_t) of point on ray closest to axis
	    assert(RNIsNotZero(a));
	    RNScalar t = (RC % A).Dot(D) / -a;
	    
	    // Find parametric value delta (s) to intersection points
	    RNScalar s;
	    R3Vector O = D % A;
	    O.Normalize();
	    RNScalar b = cylinder.Radius() * cylinder.Radius() - d*d;
	    if (RNIsPositive(b)) {
		// Crossing span intersection
		RNScalar e = R.Dot(O);
		assert(RNIsNotZero(e));
		s = sqrt(b) / e;
		if (s < 0.0) s = -s;
	    }
	    else {
		// Grazing point intersection
		s = 0.0;
	    }
	    
	    // Find parametric value (cyl_t2) of second intersection
	    cyl_t2 = t + s;
	    if (RNIsNegative(cyl_t2)) {
		// Intersection point is behind ray
		return RN_NULL_CLASS_ID;
	    }
	    else {
		// Find parametric value (cyl_t1) of first intersection
		cyl_t1 = t - s;
		
		// Check if ray start is in infinite cylinder
		if (cyl_t1 < 0.0) cyl_t1 = 0.0;
	    }
	}
    }
	
    // Compute parametric values of intersection with caps
    RNScalar cap_t1 = 0, cap_t2 = 0;
    RNScalar dot = ray.Vector().Dot(cylinder.Axis().Vector());
    RNScalar d_top = R3SignedDistance(cylinder.Top().Plane(), ray.Start());
    RNScalar d_base = R3SignedDistance(cylinder.Base().Plane(), ray.Start());
    if (RNIsPositive(d_top)) {
	// Ray starts above top cap
	if (RNIsPositiveOrZero(dot)) {
	    // Ray points upward or orthogonally from above cylinder top
	    return RN_NULL_CLASS_ID;
	}
	else {
	    // Ray points downward from above cylinder top
	    if ((R3Intersects(ray, cylinder.Top().Plane(), NULL, &cap_t1)) &&
		(RNIsGreater(cap_t1, cyl_t2))) {
		// Ray misses cylinder
		return RN_NULL_CLASS_ID;
	    }
	    else if ((R3Intersects(ray, -(cylinder.Base().Plane()), NULL, &cap_t2)) &&
		     (RNIsLess(cap_t2, cyl_t1))) {
		// Ray misses cylinder
		return RN_NULL_CLASS_ID;
	    }
	    else if (RNIsGreater(cap_t1, cyl_t1)) {
		// Ray hits top cap 
		assert(cap_t1 >= 0.0);
		if (hit_t1) *hit_t1 = cap_t1;
		if (hit_point1) *hit_point1 = ray.Point(cap_t1);
		if (hit_normal1) *hit_normal1 = cylinder.Top().Normal();
		return R3_POINT_CLASS_ID;
	    }
	    else {
		// Ray hits side of cylinder
	    }
	}
    }
    else if (RNIsPositive(d_base)) {
	// Ray starts below base cap
	if (RNIsNegativeOrZero(dot)) {
	    // Ray points downward or orthogonally
	    return RN_NULL_CLASS_ID;
	}
	else {
	    // Ray points upward from below cylinder base
	    if ((R3Intersects(ray, cylinder.Base().Plane(), NULL, &cap_t1)) &&
		(RNIsGreater(cap_t1, cyl_t2))) {
		// Ray misses cylinder
		return RN_NULL_CLASS_ID;
	    }
	    else if ((R3Intersects(ray, -(cylinder.Top().Plane()), NULL, &cap_t2)) &&
		     (RNIsLess(cap_t2, cyl_t1))) {
		// Ray misses cylinder
		return RN_NULL_CLASS_ID;
	    }
	    else if (RNIsGreater(cap_t1, cyl_t1)) {
		// Ray hits base cap 
		assert(cap_t1 >= 0.0);
		if (hit_t1) *hit_t1 = cap_t1;
		if (hit_point1) *hit_point1 = ray.Point(cap_t1);
		if (hit_normal1) *hit_normal1 = cylinder.Base().Normal();
		return R3_POINT_CLASS_ID;
	    }
	    else {
		// Ray hits side of cylinder
	    }
	}
    }
    else {
	// Ray starts on or between caps
	if (RNIsPositive(dot)) {
	    if (R3Intersects(ray, -(cylinder.Top().Plane()), NULL, &cap_t1)) {
		if (RNIsLess(cap_t1, cyl_t1)) {
		    // Intersection with infinite cylinder is beyond cap
		    return RN_NULL_CLASS_ID;
		}
	    }
	}
	else if (RNIsNegative(dot)) {
	    if (R3Intersects(ray, -(cylinder.Base().Plane()), NULL, &cap_t1)) {
		if (RNIsLess(cap_t1, cyl_t1)) {
		    // Intersection with infinite cylinder is beyond cap
		    return RN_NULL_CLASS_ID;
		}
	    }
	}
    }

    // Ray hit side of cylinder
    assert(cyl_t1 >= 0.0);
    if (hit_t1) *hit_t1 = cyl_t1;
    if (hit_point1) *hit_point1 = ray.Point(cyl_t1);
    if (hit_normal1) {
	R3Point p, *H;
	if (hit_point1) H = hit_point1;
	else { p = ray.Point(cyl_t1); H = &p; }
        R3Vector HB = *H - cylinder.Axis().Start();
	*hit_normal1 = (HB - HB.Dot(A) * A) / cylinder.Radius();
    }
    return R3_POINT_CLASS_ID;
}

// Assembly:
subq $0x348, %rsp            # imm = 0x348
movq %rdi, 0x338(%rsp)
movq %rsi, 0x330(%rsp)
movq %rdx, 0x328(%rsp)
movq %rcx, 0x320(%rsp)
movq %r8, 0x318(%rsp)
movq 0x330(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq 0x90(%rsp), %rdi
movq %rax, %rsi
callq 0x86250
movl %eax, 0x314(%rsp)
cmpl $0x0, 0x314(%rsp)
je 0x7cac0
cmpq $0x0, 0x328(%rsp)
je 0x7ca59
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq %rax, %rsi
movq 0x328(%rsp), %rdi
callq 0x6f1e0
cmpq $0x0, 0x320(%rsp)
je 0x7ca96
movq 0x338(%rsp), %rdi
callq 0x3c0e0
movq %rax, %rsi
leaq 0x2f8(%rsp), %rdi
callq 0x70fa0
movq 0x320(%rsp), %rdi
leaq 0x2f8(%rsp), %rsi
callq 0x70970
cmpq $0x0, 0x318(%rsp)
je 0x7cab0
movq 0x318(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x4, 0x344(%rsp)
jmp 0x7d769
movq 0x338(%rsp), %rdi
callq 0x3c0e0
movq %rax, %rsi
leaq 0x2d0(%rsp), %rdi
callq 0x6fcf0
movq 0x330(%rsp), %rdi
callq 0x81e10
movq %rax, %rdi
callq 0x392b0
movq %rax, %rsi
leaq 0x2b8(%rsp), %rdi
callq 0x6fcf0
leaq 0x2a0(%rsp), %rdi
leaq 0x2d0(%rsp), %rsi
leaq 0x2b8(%rsp), %rdx
callq 0x70af0
leaq 0x2a0(%rsp), %rdi
callq 0x6fe90
movsd %xmm0, 0x298(%rsp)
movsd 0x298(%rsp), %xmm0
leaq 0xfb99b(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x7cc11
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq %rax, 0x80(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e10
movq %rax, %rdi
callq 0x81e20
movq 0x80(%rsp), %rdi
movq %rax, %rsi
callq 0x86c70
movsd %xmm0, 0x290(%rsp)
movsd 0x290(%rsp), %xmm0
movsd %xmm0, 0x88(%rsp)
movq 0x330(%rsp), %rdi
callq 0x39fd0
movaps %xmm0, %xmm1
movsd 0x88(%rsp), %xmm0
leaq 0xfb914(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x81b50
cmpl $0x0, %eax
je 0x7cbfc
xorps %xmm0, %xmm0
movsd %xmm0, 0x2f0(%rsp)
leaq 0xfb903(%rip), %rax     # 0x1784f0
movsd (%rax), %xmm0
movsd %xmm0, 0x2e8(%rsp)
jmp 0x7cc0c
movl $0x0, 0x344(%rsp)
jmp 0x7d769
jmp 0x7cf13
movsd 0x298(%rsp), %xmm0
leaq 0x2a0(%rsp), %rdi
callq 0x70ec0
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq %rax, 0x78(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e10
movq %rax, %rdi
callq 0x39250
movq 0x78(%rsp), %rsi
movq %rax, %rdx
leaq 0x278(%rsp), %rdi
callq 0x6eeb0
leaq 0x278(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x702c0
movsd %xmm0, 0x270(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x270(%rsp), %xmm0
jbe 0x7ccb8
movsd 0x270(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x270(%rsp)
movsd 0x270(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movq 0x330(%rsp), %rdi
callq 0x39fd0
movaps %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
leaq 0xfb7fc(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7cd02
movl $0x0, 0x344(%rsp)
jmp 0x7d769
leaq 0x250(%rsp), %rdi
leaq 0x278(%rsp), %rsi
leaq 0x2b8(%rsp), %rdx
callq 0x70af0
leaq 0x250(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x702c0
movsd 0x298(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x268(%rsp)
leaq 0x230(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
leaq 0x2b8(%rsp), %rdx
callq 0x70af0
leaq 0x230(%rsp), %rdi
callq 0x70410
movq 0x330(%rsp), %rdi
callq 0x39fd0
movsd %xmm0, 0x68(%rsp)
movq 0x330(%rsp), %rdi
callq 0x39fd0
movaps %xmm0, %xmm2
movsd 0x68(%rsp), %xmm0
movsd 0x270(%rsp), %xmm1
mulsd 0x270(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x228(%rsp)
movsd 0x228(%rsp), %xmm0
leaq 0xfb6e2(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x7ce83
leaq 0x2d0(%rsp), %rdi
leaq 0x230(%rsp), %rsi
callq 0x702c0
movsd %xmm0, 0x220(%rsp)
movsd 0x228(%rsp), %xmm0
callq 0xf390
divsd 0x220(%rsp), %xmm0
movsd %xmm0, 0x248(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x248(%rsp), %xmm0
jbe 0x7ce81
movsd 0x248(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x248(%rsp)
jmp 0x7ce8f
xorps %xmm0, %xmm0
movsd %xmm0, 0x248(%rsp)
movsd 0x268(%rsp), %xmm0
addsd 0x248(%rsp), %xmm0
movsd %xmm0, 0x2e8(%rsp)
movsd 0x2e8(%rsp), %xmm0
leaq 0xfb626(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x38fd0
cmpl $0x0, %eax
je 0x7ced8
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movsd 0x268(%rsp), %xmm0
subsd 0x248(%rsp), %xmm0
movsd %xmm0, 0x2f0(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x2f0(%rsp), %xmm0
jbe 0x7cf0d
xorps %xmm0, %xmm0
movsd %xmm0, 0x2f0(%rsp)
jmp 0x7cf0f
jmp 0x7cf11
jmp 0x7cf13
xorps %xmm0, %xmm0
movsd %xmm0, 0x218(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x210(%rsp)
movq 0x338(%rsp), %rdi
callq 0x3c0e0
movq %rax, 0x50(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e10
movq %rax, %rdi
callq 0x392b0
movq 0x50(%rsp), %rdi
movq %rax, %rsi
callq 0x702c0
movsd %xmm0, 0x208(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e30
movq %rax, %rdi
callq 0x81ca0
movq %rax, 0x58(%rsp)
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq 0x58(%rsp), %rdi
movq %rax, %rsi
callq 0x86f90
movsd %xmm0, 0x200(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e50
movq %rax, %rdi
callq 0x81ca0
movq %rax, 0x60(%rsp)
movq 0x338(%rsp), %rdi
callq 0x3c0c0
movq 0x60(%rsp), %rdi
movq %rax, %rsi
callq 0x86f90
movsd %xmm0, 0x1f8(%rsp)
movsd 0x200(%rsp), %xmm0
leaq 0xfb4ee(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x7d222
movsd 0x208(%rsp), %xmm0
leaq 0xfb4cc(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x3a5d0
cmpl $0x0, %eax
je 0x7d032
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movq 0x338(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e30
movq %rax, %rdi
callq 0x81ca0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x218(%rsp), %rcx
callq 0x7ae90
cmpl $0x0, %eax
je 0x7d0a9
movsd 0x218(%rsp), %xmm0
movsd 0x2e8(%rsp), %xmm1
leaq 0xfb455(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7d0a9
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movq 0x338(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e50
movq %rax, %rdi
callq 0x81ca0
movq %rax, %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x38f60
movq 0x38(%rsp), %rdi
leaq 0x1d8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x210(%rsp), %rcx
callq 0x7ae90
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, 0x47(%rsp)
je 0x7d132
movsd 0x210(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfb3c1(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x39630
cmpl $0x0, %eax
setne %al
movb %al, 0x47(%rsp)
movb 0x47(%rsp), %al
testb $0x1, %al
jne 0x7d13c
jmp 0x7d14c
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movsd 0x218(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfb37b(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7d215
cmpq $0x0, 0x318(%rsp)
je 0x7d197
movsd 0x218(%rsp), %xmm0
movq 0x318(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x328(%rsp)
je 0x7d1d5
movq 0x338(%rsp), %rsi
movsd 0x218(%rsp), %xmm0
leaq 0x1c0(%rsp), %rdi
callq 0x6e4e0
movq 0x328(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0x6f1e0
cmpq $0x0, 0x320(%rsp)
je 0x7d205
movq 0x330(%rsp), %rdi
callq 0x81e30
movq %rax, %rdi
callq 0x78a80
movq %rax, %rsi
movq 0x320(%rsp), %rdi
callq 0x70970
movl $0x1, 0x344(%rsp)
jmp 0x7d769
jmp 0x7d217
jmp 0x7d219
jmp 0x7d21b
jmp 0x7d21d
jmp 0x7d5cf
movsd 0x1f8(%rsp), %xmm0
leaq 0xfb2ae(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x7d462
movsd 0x208(%rsp), %xmm0
leaq 0xfb28c(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x382c0
cmpl $0x0, %eax
je 0x7d272
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movq 0x338(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e50
movq %rax, %rdi
callq 0x81ca0
movq 0x30(%rsp), %rdi
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x218(%rsp), %rcx
callq 0x7ae90
cmpl $0x0, %eax
je 0x7d2e9
movsd 0x218(%rsp), %xmm0
movsd 0x2e8(%rsp), %xmm1
leaq 0xfb215(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7d2e9
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movq 0x338(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e30
movq %rax, %rdi
callq 0x81ca0
movq %rax, %rsi
leaq 0x1a0(%rsp), %rdi
callq 0x38f60
movq 0x20(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x210(%rsp), %rcx
callq 0x7ae90
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, 0x2f(%rsp)
je 0x7d372
movsd 0x210(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfb181(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x39630
cmpl $0x0, %eax
setne %al
movb %al, 0x2f(%rsp)
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0x7d37c
jmp 0x7d38c
movl $0x0, 0x344(%rsp)
jmp 0x7d769
movsd 0x218(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfb13b(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x3c090
cmpl $0x0, %eax
je 0x7d455
cmpq $0x0, 0x318(%rsp)
je 0x7d3d7
movsd 0x218(%rsp), %xmm0
movq 0x318(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x328(%rsp)
je 0x7d415
movq 0x338(%rsp), %rsi
movsd 0x218(%rsp), %xmm0
leaq 0x188(%rsp), %rdi
callq 0x6e4e0
movq 0x328(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x6f1e0
cmpq $0x0, 0x320(%rsp)
je 0x7d445
movq 0x330(%rsp), %rdi
callq 0x81e50
movq %rax, %rdi
callq 0x78a80
movq %rax, %rsi
movq 0x320(%rsp), %rdi
callq 0x70970
movl $0x1, 0x344(%rsp)
jmp 0x7d769
jmp 0x7d457
jmp 0x7d459
jmp 0x7d45b
jmp 0x7d45d
jmp 0x7d5cd
movsd 0x208(%rsp), %xmm0
leaq 0xfb06e(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x7d517
movq 0x338(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e30
movq %rax, %rdi
callq 0x81ca0
movq %rax, %rsi
leaq 0x168(%rsp), %rdi
callq 0x38f60
movq 0x18(%rsp), %rdi
leaq 0x168(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x218(%rsp), %rcx
callq 0x7ae90
cmpl $0x0, %eax
je 0x7d512
movsd 0x218(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfafee(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x39630
cmpl $0x0, %eax
je 0x7d510
movl $0x0, 0x344(%rsp)
jmp 0x7d769
jmp 0x7d512
jmp 0x7d5cb
movsd 0x208(%rsp), %xmm0
leaq 0xfafb9(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x38fd0
cmpl $0x0, %eax
je 0x7d5c9
movq 0x338(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e50
movq %rax, %rdi
callq 0x81ca0
movq %rax, %rsi
leaq 0x148(%rsp), %rdi
callq 0x38f60
movq 0x10(%rsp), %rdi
leaq 0x148(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq 0x218(%rsp), %rcx
callq 0x7ae90
cmpl $0x0, %eax
je 0x7d5c7
movsd 0x218(%rsp), %xmm0
movsd 0x2f0(%rsp), %xmm1
leaq 0xfaf39(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x39630
cmpl $0x0, %eax
je 0x7d5c5
movl $0x0, 0x344(%rsp)
jmp 0x7d769
jmp 0x7d5c7
jmp 0x7d5c9
jmp 0x7d5cb
jmp 0x7d5cd
jmp 0x7d5cf
cmpq $0x0, 0x318(%rsp)
je 0x7d5ef
movsd 0x2f0(%rsp), %xmm0
movq 0x318(%rsp), %rax
movsd %xmm0, (%rax)
cmpq $0x0, 0x328(%rsp)
je 0x7d62d
movq 0x338(%rsp), %rsi
movsd 0x2f0(%rsp), %xmm0
leaq 0x130(%rsp), %rdi
callq 0x6e4e0
movq 0x328(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x6f1e0
cmpq $0x0, 0x320(%rsp)
je 0x7d75e
leaq 0x118(%rsp), %rdi
callq 0x6eb40
cmpq $0x0, 0x328(%rsp)
je 0x7d666
movq 0x328(%rsp), %rax
movq %rax, 0x110(%rsp)
jmp 0x7d6a9
movq 0x338(%rsp), %rsi
movsd 0x2f0(%rsp), %xmm0
leaq 0xf8(%rsp), %rdi
callq 0x6e4e0
leaq 0x118(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x6f1e0
leaq 0x118(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x330(%rsp), %rdi
callq 0x81e10
movq %rax, %rdi
callq 0x39250
movq 0x8(%rsp), %rsi
movq %rax, %rdx
leaq 0xe0(%rsp), %rdi
callq 0x6eeb0
leaq 0xe0(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x702c0
leaq 0x98(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x13800
leaq 0xb0(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x710a0
movq 0x330(%rsp), %rdi
callq 0x39fd0
leaq 0xc8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x711f0
movq 0x320(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x70970
movl $0x1, 0x344(%rsp)
movl 0x344(%rsp), %eax
addq $0x348, %rsp            # imm = 0x348
retq
nopl (%rax,%rax)