// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3OrientedBox.cpp
// Function: gaps::R3OrientedBox::Reset(gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&, double, double, double)
void R3OrientedBox::
Reset(const R3Point& center, 
    const R3Vector& axis0, const R3Vector& axis1, 
    RNLength radius0, RNLength radius1, RNLength radius2)
{
    // Check axes
    assert(RNIsPositive(axis0.Length()));
    assert(RNIsPositive(axis1.Length()));

    // Normalize and orthogonalize axes
    R3Vector axis[3];
    axis[0] = axis0;
    axis[0].Normalize();
    axis[1] = axis1;
    axis[1].Normalize();
    axis[1] = axis[0] % axis[1];
    axis[1] = axis[1] % axis[0];
    axis[1].Normalize();
    axis[2] = axis[0] % axis[1];
    axis[2].Normalize();

    // Assign radii
    radius[0] = radius0;
    radius[1] = radius1;
    radius[2] = radius2;

#if 0
    // Sort axes
    // This works, but is not always desirable
    R3Vector swap_axis;
    RNScalar swap_radius;
    if (radius[1] > radius[0]) {
      swap_axis = axis[0]; swap_radius = radius[0];
      axis[0] = axis[1]; radius[0] = radius[1];
      axis[1] = swap_axis; radius[1] = swap_radius;
    }
    if (radius[2] > radius[0]) {
      swap_axis = axis[0]; swap_radius = radius[0];
      axis[0] = axis[2]; radius[0] = radius[2];
      axis[2] = swap_axis; radius[2] = swap_radius;
    }
    if (radius[2] > radius[1]) {
      swap_axis = axis[1]; swap_radius = radius[1];
      axis[1] = axis[2]; radius[1] = radius[2];
      axis[2] = swap_axis; radius[2] = swap_radius;
    }
    
    // Ensure right-handed coordinate system
    axis[2] = axis[0] % axis[1];
    axis[2].Normalize();
#endif

    // Set coordinate system
    cs.Reset(center, R3Triad(axis[0], axis[1], axis[2]));
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rdi, 0x140(%rsp)
movq %rsi, 0x138(%rsp)
movq %rdx, 0x130(%rsp)
movq %rcx, 0x128(%rsp)
movsd %xmm0, 0x120(%rsp)
movsd %xmm1, 0x118(%rsp)
movsd %xmm2, 0x110(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0xc0(%rsp), %rax
movq %rax, %rcx
addq $0x48, %rcx
movq %rcx, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x6fca0
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rcx
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, 0x28(%rsp)
jne 0xa0f58
movq 0x130(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
callq 0x70970
leaq 0xc0(%rsp), %rdi
callq 0x70410
movq 0x128(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
addq $0x18, %rdi
callq 0x70970
leaq 0xc0(%rsp), %rdi
addq $0x18, %rdi
callq 0x70410
leaq 0xc0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
addq $0x18, %rdx
leaq 0xa8(%rsp), %rdi
callq 0x70af0
leaq 0xc0(%rsp), %rdi
addq $0x18, %rdi
leaq 0xa8(%rsp), %rsi
callq 0x70970
leaq 0xc0(%rsp), %rsi
addq $0x18, %rsi
leaq 0xc0(%rsp), %rdx
leaq 0x90(%rsp), %rdi
callq 0x70af0
leaq 0xc0(%rsp), %rdi
addq $0x18, %rdi
leaq 0x90(%rsp), %rsi
callq 0x70970
leaq 0xc0(%rsp), %rdi
addq $0x18, %rdi
callq 0x70410
leaq 0xc0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
addq $0x18, %rdx
leaq 0x78(%rsp), %rdi
callq 0x70af0
leaq 0xc0(%rsp), %rdi
addq $0x30, %rdi
leaq 0x78(%rsp), %rsi
callq 0x70970
leaq 0xc0(%rsp), %rdi
addq $0x30, %rdi
callq 0x70410
movq 0x18(%rsp), %rax
movsd 0x120(%rsp), %xmm0
movsd %xmm0, 0x68(%rax)
movsd 0x118(%rsp), %xmm0
movsd %xmm0, 0x70(%rax)
movsd 0x110(%rsp), %xmm0
movsd %xmm0, 0x78(%rax)
addq $0x8, %rax
movq %rax, (%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0xc0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
addq $0x18, %rdx
leaq 0xc0(%rsp), %rcx
addq $0x30, %rcx
leaq 0x30(%rsp), %rdi
callq 0x4ec80
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x4e660
addq $0x148, %rsp            # imm = 0x148
retq
nop