// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::SetWorldToGridTransformation(gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&, double)
void R3Grid::
SetWorldToGridTransformation(const R3Point& world_origin, const R3Vector& world_axis1, const R3Vector& world_axis2, RNLength world_radius)
{
  // Just checking
  if (grid_size == 0) return;

  // Compute grid origin
  R3Vector grid_diagonal(XResolution()-1, YResolution()-1, ZResolution()-1);
  R3Vector grid_origin = 0.5 * grid_diagonal;
  RNScalar grid_radius = grid_origin[0];
  if (grid_origin[1] < grid_radius) grid_radius = grid_origin[1];
  if (grid_origin[2] < grid_radius) grid_radius = grid_origin[2];

  // Compute scale
  if (RNIsZero(world_radius)) return;
  if (RNIsZero(grid_radius)) return;
  RNScalar scale = grid_radius / world_radius;

  // Compute rotation
  R3Triad world_triad(world_axis1, world_axis2);
  R3Affine rotation(world_triad.InverseMatrix());

  // Compute world-to-grid transformation
  R3Affine affine(R3identity_affine);
  affine.Translate(grid_origin);
  affine.Transform(rotation);
  affine.Scale(scale);
  affine.Translate(-(world_origin.Vector()));

  // Set transformations
  SetWorldToGridTransformation(affine);
}

// Assembly:
subq $0x3b8, %rsp            # imm = 0x3B8
movq %rdi, 0x3b0(%rsp)
movq %rsi, 0x3a8(%rsp)
movq %rdx, 0x3a0(%rsp)
movq %rcx, 0x398(%rsp)
movsd %xmm0, 0x390(%rsp)
movq 0x3b0(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpl $0x0, 0x24c(%rax)
jne 0x6293b
jmp 0x62bb2
movq 0x20(%rsp), %rdi
callq 0x138c0
movq 0x20(%rsp), %rdi
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x10(%rsp)
callq 0x138e0
movq 0x20(%rsp), %rdi
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x18(%rsp)
callq 0x13900
movsd 0x10(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
subl $0x1, %eax
cvtsi2sd %eax, %xmm2
leaq 0x378(%rsp), %rdi
callq 0x6fcb0
leaq 0x360(%rsp), %rdi
movsd 0xd066d(%rip), %xmm0    # 0x133010
leaq 0x378(%rsp), %rsi
callq 0x13800
leaq 0x360(%rsp), %rdi
xorl %esi, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x358(%rsp)
leaq 0x360(%rsp), %rdi
movl $0x1, %esi
callq 0x36c00
movsd (%rax), %xmm1
movsd 0x358(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x62a10
leaq 0x360(%rsp), %rdi
movl $0x1, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x358(%rsp)
leaq 0x360(%rsp), %rdi
movl $0x2, %esi
callq 0x36c00
movsd (%rax), %xmm1
movsd 0x358(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x62a54
leaq 0x360(%rsp), %rdi
movl $0x2, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x358(%rsp)
movsd 0x390(%rsp), %xmm0
leaq 0x115a7c(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x62a77
jmp 0x62bb2
movsd 0x358(%rsp), %xmm0
leaq 0x115a59(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x62a9a
jmp 0x62bb2
movsd 0x358(%rsp), %xmm0
movsd 0x390(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x350(%rsp)
movq 0x3a0(%rsp), %rsi
movq 0x398(%rsp), %rdx
leaq 0x308(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x4ed60
movq (%rsp), %rsi
leaq 0x178(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x4efe0
movq 0x8(%rsp), %rsi
leaq 0x1f8(%rsp), %rdi
xorl %edx, %edx
callq 0x4d390
leaq 0x115e45(%rip), %rsi    # 0x178950
leaq 0x68(%rsp), %rdi
callq 0x36c20
jmp 0x62b17
leaq 0x68(%rsp), %rdi
leaq 0x360(%rsp), %rsi
callq 0x36cd0
jmp 0x62b2b
leaq 0x68(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x4d700
jmp 0x62b3f
movsd 0x350(%rsp), %xmm0
leaq 0x68(%rsp), %rdi
callq 0x36d80
jmp 0x62b54
movq 0x3a8(%rsp), %rsi
leaq 0x28(%rsp), %rdi
callq 0x36d10
jmp 0x62b68
leaq 0x40(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x70fa0
jmp 0x62b79
leaq 0x68(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x36cd0
jmp 0x62b8a
movq 0x20(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x5e430
jmp 0x62b9b
leaq 0x68(%rsp), %rdi
callq 0x4d430
leaq 0x1f8(%rsp), %rdi
callq 0x4d430
addq $0x3b8, %rsp            # imm = 0x3B8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
jmp 0x62be2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x4d430
leaq 0x1f8(%rsp), %rdi
callq 0x4d430
movq 0x60(%rsp), %rdi
callq 0xf890
nopl (%rax)