// File: /workspace/github_c_makefile_star2_O0/archer1357[P]Offline-Raytracer/kdtree.c
// Function: buildKdTree
struct KdNode *buildKdTree(const struct BoundingBox *bounds,
                           int primsNum,
                           const float *minBound,
                           const float *maxBound,
                           int maxDepth) {
int curDepth;
  int i,maxPrimsNum;
  float emptyBonus,isectCost,traversalCost;

  int badRefines;
  struct KdBuildStack *buildStack;
  struct KdNode *rootNode;

  curDepth=0;

  // maxDepth=(int)(8.0+1.3*log2((double)primsNum));

  // maxDepth=24;
  // maxDepth+=6;
  // printf("md %i\n",maxDepth);

  isectCost=80.0f;
  traversalCost=1.0f;

  maxPrimsNum=1;
  badRefines=0;

  emptyBonus=0.5f;


  rootNode=(struct KdNode*)malloc(sizeof(struct KdNode));

  buildStack=(struct KdBuildStack*)malloc(sizeof(struct KdBuildStack));
  buildStack->next=0;
  buildStack->primInds=(unsigned int*)malloc(sizeof(int)*primsNum);
  buildStack->primsNum=primsNum;
  buildStack->node=rootNode;
  buildStack->depth=0;//maxDepth;

  for(i=0;i<primsNum;i++) {
     buildStack->primInds[i]=i;
  }

  //
  for(i=0;i<3;i++) {
    buildStack->minBound[i]=minBound[i];
    buildStack->maxBound[i]=maxBound[i];
  }

  //
  while(buildStack) {
    struct KdBuildStack *curBuild;

    //
    curBuild=buildStack;
    buildStack=buildStack->next;

    //

    if(curBuild->depth > curDepth) {
      curDepth=curBuild->depth;
    }
    //

    // printf("start (%g %g %g) (%g %g %g)\n",
    //        curBuild->minBound[0],curBuild->minBound[1],curBuild->minBound[2],
    //        curBuild->maxBound[0],curBuild->maxBound[1],curBuild->maxBound[2]);

    //
    if(curBuild->primsNum <=maxPrimsNum || curBuild->depth==
       maxDepth
       //0
       ) {
      //make leaf
      curBuild->node->type=3;
      curBuild->node->thing.leaf.primsNum=curBuild->primsNum;
      curBuild->node->thing.leaf.primInds=curBuild->primInds;


      // printf("make leaf (%i) @ %i \n",
      //        curBuild->node->thing.leaf.primsNum,
      //        curBuild->depth);
    } else {
      int axis;
      float split;
      unsigned int *leftInds,*rightInds;
      int leftIndsNum,rightIndsNum;
      bool splitResult;
      splitResult=findSplitPlane(bounds,
                                 curBuild->primInds,curBuild->primsNum,
                                 curBuild->minBound,curBuild->maxBound,
                                 emptyBonus,traversalCost,isectCost,
                                 &badRefines,&axis,&split,
                                 &leftInds,&leftIndsNum,
                                 &rightInds,&rightIndsNum);


      if(splitResult) {
        //make branch


        if(rightIndsNum!=0) {
          struct KdBuildStack *rightBuild;
          struct KdNode *rightNode;

          rightBuild=(struct KdBuildStack*)malloc(sizeof(struct KdBuildStack));
          rightNode=(struct KdNode*)malloc(sizeof(struct KdNode));

          rightBuild->node=rightNode;
          rightBuild->primsNum=rightIndsNum;
          rightBuild->primInds=rightInds;
          rightBuild->depth=curBuild->depth +1;//-1;


          memcpy(rightBuild->minBound,curBuild->minBound,sizeof(float)*3);
          memcpy(rightBuild->maxBound,curBuild->maxBound,sizeof(float)*3);
          rightBuild->minBound[axis]=split;

          rightBuild->next=buildStack;
          buildStack=rightBuild;



          curBuild->node->thing.branch.right=rightNode;
        } else {
          curBuild->node->thing.branch.right=0;
        }

        if(leftIndsNum!=0) {
          struct KdBuildStack *leftBuild;
          struct KdNode *leftNode;

          leftBuild=(struct KdBuildStack*)malloc(sizeof(struct KdBuildStack));
          leftNode=(struct KdNode*)malloc(sizeof(struct KdNode));

          leftBuild->node=leftNode;
          leftBuild->primsNum=leftIndsNum;
          leftBuild->primInds=leftInds;
          leftBuild->depth=curBuild->depth +1;//-1;
          memcpy(leftBuild->minBound,curBuild->minBound,sizeof(float)*3);
          memcpy(leftBuild->maxBound,curBuild->maxBound,sizeof(float)*3);
          leftBuild->maxBound[axis]=split;

          leftBuild->next=buildStack;
          buildStack=leftBuild;



          curBuild->node->thing.branch.left=leftNode;
        } else {
          curBuild->node->thing.branch.left=0;
        }

        curBuild->node->type=axis;
        curBuild->node->thing.branch.split=split;

        free(curBuild->primInds);

      } else {
        //make leaf
        curBuild->node->type=3;
        curBuild->node->thing.leaf.primsNum=curBuild->primsNum;
        curBuild->node->thing.leaf.primInds=curBuild->primInds;

      }
    }

    free(curBuild);
  }

  //


  return rootNode;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0xd8, %rsp
movq %rdi, -0x20(%rbp)
movl %esi, -0x24(%rbp)
movq %rdx, -0x30(%rbp)
movq %rcx, -0x38(%rbp)
movl %r8d, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movss 0xda45e(%rip), %xmm0    # 0x4e4920
movss %xmm0, -0x50(%rbp)
movss 0xd8fb5(%rip), %xmm0    # 0x4e3484
movss %xmm0, -0x54(%rbp)
movl $0x1, -0x48(%rbp)
movl $0x0, -0x58(%rbp)
movss 0xd8f7a(%rip), %xmm0    # 0x4e3464
movss %xmm0, -0x4c(%rbp)
movl $0x20, %edi
callq 0x452d20
movq %rax, -0x68(%rbp)
movl $0x40, %edi
callq 0x452d20
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq $0x0, 0x10(%rax)
movslq -0x24(%rbp), %rdi
shlq $0x2, %rdi
callq 0x452d20
movq %rax, %rcx
movq -0x60(%rbp), %rax
movq %rcx, (%rax)
movl -0x24(%rbp), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x68(%rbp), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x60(%rbp), %rax
movl $0x0, 0x20(%rax)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x40a57a
movl -0x44(%rbp), %edx
movq -0x60(%rbp), %rax
movq (%rax), %rax
movslq -0x44(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x40a556
movl $0x0, -0x44(%rbp)
cmpl $0x3, -0x44(%rbp)
jge 0x40a5c8
movq -0x30(%rbp), %rax
movslq -0x44(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movss %xmm0, 0x24(%rax,%rcx,4)
movq -0x38(%rbp), %rax
movslq -0x44(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movq -0x60(%rbp), %rax
movslq -0x44(%rbp), %rcx
movss %xmm0, 0x30(%rax,%rcx,4)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x40a581
jmp 0x40a5ca
cmpq $0x0, -0x60(%rbp)
je 0x40a943
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x70(%rbp), %rax
movl 0x20(%rax), %eax
cmpl -0x40(%rbp), %eax
jle 0x40a5ff
movq -0x70(%rbp), %rax
movl 0x20(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x70(%rbp), %rax
movl 0x8(%rax), %eax
cmpl -0x48(%rbp), %eax
jle 0x40a617
movq -0x70(%rbp), %rax
movl 0x20(%rax), %eax
cmpl -0x3c(%rbp), %eax
jne 0x40a64f
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movl $0x3, (%rax)
movq -0x70(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movl %ecx, 0x10(%rax)
movq -0x70(%rbp), %rax
movq (%rax), %rcx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x8(%rax)
jmp 0x40a935
movq -0x20(%rbp), %rdi
movq -0x70(%rbp), %rax
movq (%rax), %rsi
movq -0x70(%rbp), %rax
movl 0x8(%rax), %edx
movq -0x70(%rbp), %rcx
addq $0x24, %rcx
movq -0x70(%rbp), %r8
addq $0x30, %r8
movss -0x4c(%rbp), %xmm0
movss -0x54(%rbp), %xmm1
movss -0x50(%rbp), %xmm2
leaq -0x58(%rbp), %r9
leaq -0x74(%rbp), %r15
leaq -0x78(%rbp), %r14
leaq -0x80(%rbp), %rbx
leaq -0x8c(%rbp), %r11
leaq -0x88(%rbp), %r10
leaq -0x90(%rbp), %rax
movq %r15, (%rsp)
movq %r14, 0x8(%rsp)
movq %rbx, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x409c80
andb $0x1, %al
movb %al, -0x91(%rbp)
testb $0x1, -0x91(%rbp)
je 0x40a900
cmpl $0x0, -0x90(%rbp)
je 0x40a7c9
movl $0x40, %edi
callq 0x452d20
movq %rax, -0xa0(%rbp)
movl $0x20, %edi
callq 0x452d20
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, 0x18(%rax)
movl -0x90(%rbp), %ecx
movq -0xa0(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x88(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, (%rax)
movq -0x70(%rbp), %rax
movl 0x20(%rax), %ecx
addl $0x1, %ecx
movq -0xa0(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0xa0(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x24(%rcx), %rdx
movq %rdx, 0x24(%rax)
movl 0x2c(%rcx), %ecx
movl %ecx, 0x2c(%rax)
movq -0xa0(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x30(%rcx), %rdx
movq %rdx, 0x30(%rax)
movl 0x38(%rcx), %ecx
movl %ecx, 0x38(%rax)
movss -0x78(%rbp), %xmm0
movq -0xa0(%rbp), %rax
movslq -0x74(%rbp), %rcx
movss %xmm0, 0x24(%rax,%rcx,4)
movq -0x60(%rbp), %rcx
movq -0xa0(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0xa0(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0xa8(%rbp), %rcx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x18(%rax)
jmp 0x40a7d9
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq $0x0, 0x18(%rax)
cmpl $0x0, -0x8c(%rbp)
je 0x40a8c3
movl $0x40, %edi
callq 0x452d20
movq %rax, -0xb0(%rbp)
movl $0x20, %edi
callq 0x452d20
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rcx
movq -0xb0(%rbp), %rax
movq %rcx, 0x18(%rax)
movl -0x8c(%rbp), %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x80(%rbp), %rcx
movq -0xb0(%rbp), %rax
movq %rcx, (%rax)
movq -0x70(%rbp), %rax
movl 0x20(%rax), %ecx
addl $0x1, %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0xb0(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x24(%rcx), %rdx
movq %rdx, 0x24(%rax)
movl 0x2c(%rcx), %ecx
movl %ecx, 0x2c(%rax)
movq -0xb0(%rbp), %rax
movq -0x70(%rbp), %rcx
movq 0x30(%rcx), %rdx
movq %rdx, 0x30(%rax)
movl 0x38(%rcx), %ecx
movl %ecx, 0x38(%rax)
movss -0x78(%rbp), %xmm0
movq -0xb0(%rbp), %rax
movslq -0x74(%rbp), %rcx
movss %xmm0, 0x30(%rax,%rcx,4)
movq -0x60(%rbp), %rcx
movq -0xb0(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0xb0(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0xb8(%rbp), %rcx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x10(%rax)
jmp 0x40a8d3
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq $0x0, 0x10(%rax)
movl -0x74(%rbp), %ecx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movl %ecx, (%rax)
movss -0x78(%rbp), %xmm0
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movss %xmm0, 0x8(%rax)
movq -0x70(%rbp), %rax
movq (%rax), %rdi
callq 0x453060
jmp 0x40a933
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movl $0x3, (%rax)
movq -0x70(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movl %ecx, 0x10(%rax)
movq -0x70(%rbp), %rax
movq (%rax), %rcx
movq -0x70(%rbp), %rax
movq 0x18(%rax), %rax
movq %rcx, 0x8(%rax)
jmp 0x40a935
movq -0x70(%rbp), %rdi
callq 0x453060
jmp 0x40a5ca
movq -0x68(%rbp), %rax
addq $0xd8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)