// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelBlock.cpp
// Function: gaps::R3SurfelBlock::Transform(gaps::R3Affine const&)
void R3SurfelBlock::
Transform(const R3Affine& transformation) 
{
  // Check if transformation is identity
  if (transformation.IsIdentity()) return;

  // Get scale factor
  RNScalar scale = transformation.ScaleFactor();
  if (RNIsEqual(scale, 1.0)) scale = 1.0;
  if (scale == 0) return;

  // Update resolution
  if (resolution > 0) resolution /= scale * scale;

  // Transform position_origin
  R3Point old_position_origin = position_origin;
  position_origin.Transform(transformation);

  // Read block
  if (database) database->ReadBlock(this);

  // Transform surfels 
  bbox = R3null_box;
  for (int i = 0; i < NSurfels(); i++) {
    R3Surfel *surfel = &surfels[i];
    R3Point position(surfel->X() + old_position_origin[0], surfel->Y() + old_position_origin[1], surfel->Z() + old_position_origin[2]);
    R3Vector normal(surfel->NX(), surfel->NY(), surfel->NZ());
    R3Vector tangent(surfel->TX(), surfel->TY(), surfel->TZ());
    position.Transform(transformation);
    normal.Transform(transformation);
    tangent.Transform(transformation);
    surfel->SetPosition(position.X() - position_origin.X(), position.Y() - position_origin.Y(), position.Z() - position_origin.Z());
    surfel->SetNormal(normal.X(), normal.Y(), normal.Z());
    surfel->SetTangent(tangent.X(), tangent.Y(), tangent.Z());
    surfel->SetRadius(0, scale * surfel->Radius(0));
    surfel->SetRadius(1, scale * surfel->Radius(1));
    bbox.Union(position);
  }

  // Remember that block is dirty
  SetDirty();

  // Release block
  if (database) database->ReleaseBlock(this);

  // Update database
  // ???
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rdi, 0x140(%rsp)
movq %rsi, 0x138(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0x138(%rsp), %rdi
movq (%rdi), %rax
callq *0x10(%rax)
cmpl $0x0, %eax
je 0x4bd7f
jmp 0x4c36e
movq 0x138(%rsp), %rdi
movq (%rdi), %rax
callq *0xc0(%rax)
movsd %xmm0, 0x130(%rsp)
movsd 0x130(%rsp), %xmm0
leaq 0x1b079f(%rip), %rax    # 0x1fc548
movsd (%rax), %xmm2
movsd 0x1583b3(%rip), %xmm1   # 0x1a4168
callq 0x4fe80
cmpl $0x0, %eax
je 0x4bdd0
movsd 0x1583a1(%rip), %xmm0   # 0x1a4168
movsd %xmm0, 0x130(%rsp)
movsd 0x130(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4bde9
jp 0x4bde9
jmp 0x4c36e
movq 0xb8(%rsp), %rax
movsd 0x80(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4be30
movq 0xb8(%rsp), %rax
movsd 0x130(%rsp), %xmm1
mulsd 0x130(%rsp), %xmm1
movsd 0x80(%rax), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rax)
movq 0xb8(%rsp), %rsi
addq $0x10, %rsi
leaq 0x118(%rsp), %rdi
callq 0xf8390
movq 0xb8(%rsp), %rdi
addq $0x10, %rdi
movq 0x138(%rsp), %rsi
callq 0xf8fc0
movq 0xb8(%rsp), %rax
cmpq $0x0, 0x98(%rax)
je 0x4be88
movq 0xb8(%rsp), %rsi
movq 0x98(%rsi), %rdi
callq 0x31140
movq 0xb8(%rsp), %rdi
addq $0x28, %rdi
leaq 0x1b146d(%rip), %rsi    # 0x1fd308
callq 0x1bd40
movl $0x0, 0x114(%rsp)
movq 0xb8(%rsp), %rdi
movl 0x114(%rsp), %eax
movl %eax, 0xb4(%rsp)
callq 0x1c0e0
movl %eax, %ecx
movl 0xb4(%rsp), %eax
cmpl %ecx, %eax
jge 0x4c336
movq 0xb8(%rsp), %rax
movq (%rax), %rax
movslq 0x114(%rsp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rdi
callq 0x44190
cvtss2sd %xmm0, %xmm0
movsd %xmm0, (%rsp)
leaq 0x118(%rsp), %rdi
xorl %esi, %esi
callq 0x1bde0
movsd (%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x108(%rsp), %rdi
callq 0x441a0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x118(%rsp), %rdi
movl $0x1, %esi
callq 0x1bde0
movsd 0x8(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x108(%rsp), %rdi
callq 0x441b0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x118(%rsp), %rdi
movl $0x2, %esi
callq 0x1bde0
movsd 0x10(%rsp), %xmm2
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
addsd (%rax), %xmm2
leaq 0xf0(%rsp), %rdi
callq 0xf8350
movq 0x108(%rsp), %rdi
callq 0x31fb0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x108(%rsp), %rdi
callq 0x31fd0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x108(%rsp), %rdi
callq 0x31ff0
movsd 0x28(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x30(%rsp), %xmm0
cvtss2sd %xmm2, %xmm2
leaq 0xd8(%rsp), %rdi
callq 0xf94b0
movq 0x108(%rsp), %rdi
callq 0x32010
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x108(%rsp), %rdi
callq 0x32030
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x108(%rsp), %rdi
callq 0x32050
movsd 0x38(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x40(%rsp), %xmm0
cvtss2sd %xmm2, %xmm2
leaq 0xc0(%rsp), %rdi
callq 0xf94b0
movq 0x138(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0xf8fc0
movq 0x138(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0xfa610
movq 0x138(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
callq 0xfa610
movq 0x108(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x187b0
movq 0xb8(%rsp), %rdi
movsd %xmm0, 0x48(%rsp)
addq $0x10, %rdi
callq 0x187b0
movaps %xmm0, %xmm1
movsd 0x48(%rsp), %xmm0
subsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x6c(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x187c0
movq 0xb8(%rsp), %rdi
movsd %xmm0, 0x50(%rsp)
addq $0x10, %rdi
callq 0x187c0
movaps %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
subsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x68(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x187a0
movq 0xb8(%rsp), %rdi
movsd %xmm0, 0x58(%rsp)
addq $0x10, %rdi
callq 0x187a0
movsd 0x58(%rsp), %xmm2
movq 0x60(%rsp), %rdi
movss 0x68(%rsp), %xmm1
movaps %xmm0, %xmm3
movss 0x6c(%rsp), %xmm0
subsd %xmm3, %xmm2
cvtsd2ss %xmm2, %xmm2
callq 0x44cd0
movq 0x108(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x31c70
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x7c(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x31c80
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x78(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x31c90
movq 0x70(%rsp), %rdi
movss 0x78(%rsp), %xmm1
movaps %xmm0, %xmm2
movss 0x7c(%rsp), %xmm0
cvtsd2ss %xmm2, %xmm2
callq 0x47830
movq 0x108(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x31c70
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8c(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x31c80
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x88(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x31c90
movq 0x80(%rsp), %rdi
movss 0x88(%rsp), %xmm1
movaps %xmm0, %xmm2
movss 0x8c(%rsp), %xmm0
cvtsd2ss %xmm2, %xmm2
callq 0x47900
movq 0x108(%rsp), %rax
movq %rax, 0x90(%rsp)
movsd 0x130(%rsp), %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0x108(%rsp), %rdi
xorl %esi, %esi
callq 0x32070
movq 0x90(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x98(%rsp), %xmm0
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
xorl %esi, %esi
callq 0x47a90
movq 0x108(%rsp), %rax
movq %rax, 0xa0(%rsp)
movsd 0x130(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movq 0x108(%rsp), %rdi
movl $0x1, %esi
callq 0x32070
movq 0xa0(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0xa8(%rsp), %xmm0
cvtss2sd %xmm1, %xmm1
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movl $0x1, %esi
callq 0x47a90
movq 0xb8(%rsp), %rdi
addq $0x28, %rdi
leaq 0xf0(%rsp), %rsi
callq 0xcb9d0
movl 0x114(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x114(%rsp)
jmp 0x4beab
movq 0xb8(%rsp), %rdi
movl $0x1, %esi
callq 0x4b240
movq 0xb8(%rsp), %rax
cmpq $0x0, 0x98(%rax)
je 0x4c36e
movq 0xb8(%rsp), %rsi
movq 0x98(%rsi), %rdi
callq 0x311c0
addq $0x148, %rsp            # imm = 0x148
retq
nopw %cs:(%rax,%rax)