// Copyright 2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "../common/Data.ih"
#include "UnstructuredVolumeShared.h"

inline uniform Node *uniform sibling(uniform Node *uniform node)
{
  uniform InnerNode *uniform parent =
      (uniform InnerNode * uniform) node->parent;

  if (parent->children[0] == node) {
    return parent->children[1];
  } else {
    return parent->children[0];
  }
}

bool pointInAABBTest(const uniform box3fa &box, const vec3f &point);

typedef bool (*intersectAndSamplePrim)(const void *uniform userData,
                                       uniform uint64 id,
                                       float &result,
                                       vec3f pos);

typedef bool (*intersectAndSamplePrimM)(const void *uniform userData,
                                       uniform uint64 numIds,
                                       uniform uint64 *uniform ids,
                                       float &result,
                                       vec3f pos);

typedef bool (*intersectAndGradientPrim)(const void *uniform userData,
                                         uniform uint64 id,
                                         vec3f &result,
                                         vec3f pos);

typedef bool (*intersectAndGradientPrimM)(const void *uniform userData,
                                          uniform uint64 numIds,
                                          uniform uint64 *uniform ids,
                                          vec3f &result,
                                          vec3f pos);

void traverseBVHSingle(uniform Node *uniform root,
                       const void *uniform userPtr,
                       uniform intersectAndSamplePrim sampleFunc,
                       float &result,
                       const vec3f &pos);

void traverseBVHSingle(uniform Node *uniform root,
                       const void *uniform userPtr,
                       uniform intersectAndGradientPrim sampleFunc,
                       vec3f &result,
                       const vec3f &pos);

void traverseBVHMulti(uniform Node *uniform root,
                      const void *uniform userPtr,
                      uniform intersectAndSamplePrimM sampleFunc,
                      float &result,
                      const vec3f &pos);

void traverseBVHMulti(uniform Node *uniform root,
                      const void *uniform userPtr,
                      uniform intersectAndGradientPrimM sampleFunc,
                      vec3f &result,
                      const vec3f &pos);

#define template_intersectRayCell(univary)         \
  univary box1f intersectRayCell_##univary(        \
      const univary vec3f &origin,                 \
      const univary vec3f &direction,              \
      const univary box1f &rangeLimit,             \
      const VKLUnstructuredVolume *uniform volume, \
      const uniform uint64 cellID);

// template_intersectNode(uniform);
template_intersectRayCell(varying);
#undef template_intersectRayCell
