// File: /workspace/github_cpp_makefile_star2_O2/ingowald[P]closestSurfacePointQueries/examples/aosExample.cpp
// Function: main
int main(int ac, char **av)
  {
    srand48(290374);

    int numTriangles = 1000000;
    float maxEdgeLen = 1.f/(powf(numTriangles,1.f/3.f));
    int numPoints    = 1000000;
    
    // the triangles we're querying to
    std::vector<vec3f> vertex;
    std::vector<vec3i> index;

    for (int i=0;i<numTriangles;i++) {
      const vec3f P(drand48(),drand48(),drand48());
      const vec3f e0 = maxEdgeLen * vec3f(drand48(),drand48(),drand48());
      const vec3f e1 = maxEdgeLen * vec3f(drand48(),drand48(),drand48());
      const int vIdx = vertex.size();
      vertex.push_back(P);
      vertex.push_back(P+e0);
      vertex.push_back(P+e1);
      index.push_back(vec3i(vIdx+0,vIdx+1,vIdx+2));
    }
    // loadTriangleMesh(vertex,index,av[1]);
    
    // the points we're query'ing
    std::vector<vec3f> queryPoint;
    for (int i=0;i<numPoints;i++) {
      int triID = int(drand48()*numTriangles);
      float u = drand48();
      float v = drand48();
      const vec3f A = vertex[index[triID].x];
      const vec3f B = vertex[index[triID].y];
      const vec3f C = vertex[index[triID].z];
      if (u+v >= 1.f) { u = 1-u; v = 1-v; }
      const vec3f pointOnTri = A+u*(B-A)+v*(C-A);
      queryPoint.push_back(pointOnTri + float(0.1f*drand48()*maxEdgeLen)*vec3f(drand48(),drand48(),drand48()));
    }

    // the result of our queries
    std::vector<vec3f>   result_pos;    result_pos.resize(queryPoint.size());
    std::vector<int32_t> result_primID; result_primID.resize(queryPoint.size());
    std::vector<float>   result_dist;   result_dist.resize(queryPoint.size());

    auto begin = std::chrono::system_clock::now();
    // create the actual scene:
    distance_query_scene scene
      = rtdqNewTriangleMeshfi(&vertex[0].x,&vertex[0].y,&vertex[0].z,3,
                              &index[0].x,&index[0].y,&index[0].z,3,
                              index.size());
    auto done_build = std::chrono::system_clock::now();

    // perform the queries - all together, in a single thread
    rtdqComputeClosestPointsfi(scene,
                             &result_pos[0].x,&result_pos[0].y,&result_pos[0].z,3,
                             &result_dist[0],1,
                             &result_primID[0],1,
                             &queryPoint[0].x,&queryPoint[0].y,&queryPoint[0].z,3,
                             numPoints);
    auto done_all = std::chrono::system_clock::now();

    std::chrono::duration<double> buildTime = done_build - begin;
    std::chrono::duration<double> queryTime = done_all   - done_build;
    std::cout << "time to build tree " << buildTime.count() << "s" << std::endl;
    std::cout << "time to query " << numPoints << " points: " << queryTime.count() << "s" << std::endl;
    std::cout << "(this is " << (queryTime.count()/numPoints) << " seconds/prim)" << std::endl;

    rtdqDestroy(scene);
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movl $0x46e46, %edi          # imm = 0x46E46
callq 0x2190
xorps %xmm0, %xmm0
leaq 0xa0(%rsp), %rbx
andq $0x0, 0x10(%rbx)
leaq 0x80(%rsp), %rax
andq $0x0, 0x10(%rax)
movaps %xmm0, (%rbx)
movaps %xmm0, (%rax)
movl $0xf4240, %ebp          # imm = 0xF4240
pushq $0xc
popq %r13
leaq 0x10(%rsp), %r15
leaq 0x30(%rsp), %r12
subl $0x1, %ebp
jb 0x250d
callq 0x20f0
movaps %xmm0, (%rsp)
callq 0x20f0
movaps %xmm0, 0x60(%rsp)
callq 0x20f0
cvtsd2ss %xmm0, %xmm0
movapd (%rsp), %xmm1
unpcklpd 0x60(%rsp), %xmm1       # xmm1 = xmm1[0],mem[0]
cvtpd2ps %xmm1, %xmm1
movlpd %xmm1, 0x10(%rsp)
movss %xmm0, 0x18(%rsp)
callq 0x20f0
movaps %xmm0, 0x60(%rsp)
callq 0x20f0
movaps %xmm0, 0x70(%rsp)
callq 0x20f0
movsd %xmm0, 0x50(%rsp)
callq 0x20f0
movaps %xmm0, (%rsp)
callq 0x20f0
movaps (%rsp), %xmm1
movlhps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
cvtpd2ps %xmm1, %xmm0
movapd %xmm0, (%rsp)
callq 0x20f0
cvtsd2ss %xmm0, %xmm0
movaps (%rsp), %xmm1
mulps 0x4be2(%rip), %xmm1     # 0x7010
movaps %xmm1, (%rsp)
mulss 0x4c06(%rip), %xmm0     # 0x7040
movss %xmm0, 0x4c(%rsp)
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
cqto
movq %r13, %r14
idivq %r13
movq %rax, %r13
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2948
cvtsd2ss 0x50(%rsp), %xmm0
movapd 0x60(%rsp), %xmm1
unpcklpd 0x70(%rsp), %xmm1       # xmm1 = xmm1[0],mem[0]
cvtpd2ps %xmm1, %xmm1
mulss 0x4bbc(%rip), %xmm0     # 0x7040
mulps 0x4b85(%rip), %xmm1     # 0x7010
movsd 0x10(%rsp), %xmm2
addps %xmm1, %xmm2
addss 0x18(%rsp), %xmm0
movlps %xmm2, 0x30(%rsp)
movss %xmm0, 0x38(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2bf2
movsd 0x10(%rsp), %xmm0
movaps (%rsp), %xmm1
addps %xmm0, %xmm1
movss 0x4c(%rsp), %xmm0
addss 0x18(%rsp), %xmm0
movlps %xmm1, 0x30(%rsp)
movss %xmm0, 0x38(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2bf2
leal 0x1(%r13), %eax
movl %r13d, 0x30(%rsp)
addl $0x2, %r13d
movl %eax, 0x34(%rsp)
movl %r13d, 0x38(%rsp)
leaq 0x80(%rsp), %rdi
movq %r12, %rsi
callq 0x2d02
movq %r14, %r13
jmp 0x239d
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rbx
andq $0x0, 0x10(%rbx)
movaps %xmm0, (%rbx)
movl $0xf4240, %r15d         # imm = 0xF4240
leaq 0x30(%rsp), %r14
subl $0x1, %r15d
jb 0x26b4
callq 0x20f0
mulsd 0x4b09(%rip), %xmm0     # 0x7048
cvttsd2si %xmm0, %ebp
callq 0x20f0
movapd %xmm0, (%rsp)
callq 0x20f0
movslq %ebp, %rax
movq 0x80(%rsp), %rsi
imulq $0xc, %rax, %rdi
movslq (%rsi,%rdi), %rcx
movq 0xa0(%rsp), %rax
imulq $0xc, %rcx, %rcx
movslq 0x4(%rsi,%rdi), %rdx
imulq $0xc, %rdx, %rdx
movslq 0x8(%rsi,%rdi), %rsi
imulq $0xc, %rsi, %rsi
movapd (%rsp), %xmm1
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
cvtpd2ps %xmm1, %xmm2
movapd %xmm2, %xmm0
shufps $0x55, %xmm2, %xmm0     # xmm0 = xmm0[1,1],xmm2[1,1]
addss %xmm2, %xmm0
xorl %edi, %edi
ucomiss 0x4a9f(%rip), %xmm0     # 0x7044
movss 0x8(%rax,%rcx), %xmm1
setb %dil
movaps 0x4a6a(%rip), %xmm3     # 0x7020
subps %xmm2, %xmm3
movd %edi, %xmm0
pshufd $0x50, %xmm0, %xmm0     # xmm0 = xmm0[0,0,1,1]
pslld $0x1f, %xmm0
psrad $0x1f, %xmm0
andps %xmm0, %xmm2
pandn %xmm3, %xmm0
por %xmm2, %xmm0
movss 0x8(%rax,%rsi), %xmm2
movss 0x8(%rax,%rdx), %xmm3
unpcklps %xmm2, %xmm3            # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movaps %xmm1, %xmm2
shufps $0x0, %xmm1, %xmm2      # xmm2 = xmm2[0,0],xmm1[0,0]
subps %xmm2, %xmm3
mulps %xmm0, %xmm3
addss %xmm3, %xmm1
shufps $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
addss %xmm1, %xmm3
movaps %xmm3, (%rsp)
movsd (%rax,%rcx), %xmm1
movsd (%rax,%rdx), %xmm2
movsd (%rax,%rsi), %xmm3
subps %xmm1, %xmm2
pshufd $0x0, %xmm0, %xmm4      # xmm4 = xmm0[0,0,0,0]
mulps %xmm2, %xmm4
addps %xmm1, %xmm4
subps %xmm1, %xmm3
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
mulps %xmm3, %xmm0
addps %xmm4, %xmm0
movaps %xmm0, 0x60(%rsp)
callq 0x20f0
mulsd 0x4a10(%rip), %xmm0     # 0x7050
mulsd 0x4a10(%rip), %xmm0     # 0x7058
cvtsd2ss %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
callq 0x20f0
movaps %xmm0, 0x50(%rsp)
callq 0x20f0
movaps 0x50(%rsp), %xmm1
movlhps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
cvtpd2ps %xmm1, %xmm0
movapd %xmm0, 0x50(%rsp)
callq 0x20f0
cvtsd2ss %xmm0, %xmm0
movaps 0x70(%rsp), %xmm2
movaps %xmm2, %xmm1
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
mulps 0x50(%rsp), %xmm1
addps 0x60(%rsp), %xmm1
mulss %xmm2, %xmm0
addss (%rsp), %xmm0
movlps %xmm1, 0x30(%rsp)
movss %xmm0, 0x38(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2bf2
jmp 0x2528
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
andq $0x0, 0x10(%rdi)
movapd %xmm0, (%rdi)
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
cqto
idivq %r13
movq %rax, %rsi
callq 0x296c
leaq 0xe0(%rsp), %rdi
andq $0x0, 0x10(%rdi)
xorpd %xmm0, %xmm0
movapd %xmm0, (%rdi)
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
cqto
idivq %r13
movq %rax, %rsi
callq 0x29a4
xorpd %xmm0, %xmm0
leaq 0xc0(%rsp), %rdi
andq $0x0, 0x10(%rdi)
movapd %xmm0, (%rdi)
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
cqto
idivq %r13
movq %rax, %rsi
callq 0x29d6
callq 0x2030
movq %rax, %r15
movq 0xa0(%rsp), %rdi
leaq 0x4(%rdi), %rsi
leaq 0x8(%rdi), %r10
movq 0x80(%rsp), %r8
movq 0x88(%rsp), %rax
leaq 0x4(%r8), %r9
leaq 0x8(%r8), %r11
subq %r8, %rax
cqto
idivq %r13
subq $0x8, %rsp
pushq $0x3
popq %rcx
movq %r10, %rdx
pushq %rax
pushq $0x3
pushq %r11
callq 0x33e0
addq $0x20, %rsp
movq %rax, %rbx
callq 0x2030
movq %rax, %r14
movq 0x30(%rsp), %rsi
leaq 0x4(%rsi), %rdx
leaq 0x8(%rsi), %rcx
movq 0xc0(%rsp), %r9
movq 0x10(%rsp), %rax
leaq 0x4(%rax), %r10
leaq 0x8(%rax), %r11
pushq $0x1
popq %r12
pushq $0x3
popq %r8
movq %rbx, %rdi
pushq $0xf4240                # imm = 0xF4240
pushq $0x3
pushq %r11
pushq %r10
pushq %rax
pushq %r12
pushq 0x110(%rsp)
pushq %r12
callq 0x3848
addq $0x40, %rsp
callq 0x2030
movq %rax, %r12
movq 0x87ec(%rip), %rdi      # 0xafd8
leaq 0x4875(%rip), %rsi      # 0x7068
callq 0x2100
movq %r14, %rcx
subq %r15, %rcx
cvtsi2sd %rcx, %xmm0
divsd 0x4855(%rip), %xmm0     # 0x7060
movq %rax, %rdi
callq 0x2160
leaq 0x4862(%rip), %rsi      # 0x707c
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x2070
movq 0x87a7(%rip), %rdi      # 0xafd8
leaq 0x4846(%rip), %rsi      # 0x707e
callq 0x2100
movq %rax, %rdi
movl $0xf4240, %esi          # imm = 0xF4240
callq 0x21a0
leaq 0x483c(%rip), %rsi      # 0x708d
movq %rax, %rdi
callq 0x2100
subq %r14, %r12
cvtsi2sd %r12, %xmm0
divsd 0x47f7(%rip), %xmm0     # 0x7060
movq %rax, %rdi
movsd %xmm0, (%rsp)
callq 0x2160
leaq 0x47ff(%rip), %rsi      # 0x707c
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x2070
movq 0x8744(%rip), %rdi      # 0xafd8
leaq 0x47fc(%rip), %rsi      # 0x7097
callq 0x2100
movsd (%rsp), %xmm0
divsd 0x479b(%rip), %xmm0     # 0x7048
movq %rax, %rdi
callq 0x2160
leaq 0x47e5(%rip), %rsi      # 0x70a1
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x3b42
jmp 0x28da
jmp 0x28da
jmp 0x28da
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x31f0
jmp 0x28ef
movq %rax, %rbx
leaq 0xe0(%rsp), %rdi
callq 0x3004
jmp 0x2901
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x2a12
jmp 0x2910
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x2a12
jmp 0x2925
jmp 0x2922
jmp 0x2922
jmp 0x2922
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x2a4e
leaq 0xa0(%rsp), %rdi
callq 0x2a12
movq %rbx, %rdi
callq 0x21b0
nop