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

#pragma once

#include "rkcommon/math/vec.ih"

#define SCATTERING_SPECULAR_REFLECTION                                         \
  (1 << 0) /*!< perfect specular reflection   */
#define SCATTERING_GLOSSY_REFLECTION                                           \
  (1 << 1) /*!< glossy reflection             */
#define SCATTERING_DIFFUSE_REFLECTION                                          \
  (1 << 2) /*!< diffuse reflection            */
#define SCATTERING_SPECULAR_TRANSMISSION                                       \
  (1 << 3) /*!< perfect specular transmission */
#define SCATTERING_GLOSSY_TRANSMISSION                                         \
  (1 << 4) /*!< glossy transmission           */
#define SCATTERING_DIFFUSE_TRANSMISSION                                        \
  (1 << 5) /*!< diffuse transmission          */

/*! diffuse reflections and transmissions */
#define SCATTERING_DIFFUSE                                                     \
  (SCATTERING_DIFFUSE_REFLECTION | SCATTERING_DIFFUSE_TRANSMISSION)

/*! glossy reflections and transmissions */
#define SCATTERING_GLOSSY                                                      \
  (SCATTERING_GLOSSY_REFLECTION | SCATTERING_GLOSSY_TRANSMISSION)

/*! perfect specular reflections and transmissions */
#define SCATTERING_SPECULAR                                                    \
  (SCATTERING_SPECULAR_REFLECTION | SCATTERING_SPECULAR_TRANSMISSION)

/*! all possible reflections */
#define SCATTERING_REFLECTION                                                  \
  (SCATTERING_DIFFUSE_REFLECTION | SCATTERING_GLOSSY_REFLECTION                \
      | SCATTERING_SPECULAR_REFLECTION)

/*! all possible transmissions */
#define SCATTERING_TRANSMISSION                                                \
  (SCATTERING_DIFFUSE_TRANSMISSION | SCATTERING_GLOSSY_TRANSMISSION            \
      | SCATTERING_SPECULAR_TRANSMISSION)

/*! all non-dirac types */
#define SCATTERING_SMOOTH (SCATTERING_DIFFUSE | SCATTERING_GLOSSY)

/*! no component set */
#define SCATTERING_NONE 0

/*! all components set */
#define SCATTERING_ALL (SCATTERING_REFLECTION | SCATTERING_TRANSMISSION)

OSPRAY_BEGIN_ISPC_NAMESPACE

typedef uint32 Scattering_Type;

struct Scattering_EvalRes
{
  vec3f value; //!< radiance (multiplied by foreshortening factor for BSDFs)
  float pdf;
};

// Note: the pdf of Dirac delta distributions is represented with inf. This is
// possible, because in weight we already cancel the Dirac delta (but still
// account for a changed pdf by e.g. discrete events such as component
// selection).
struct Scattering_SampleRes
{
  vec3f weight; //!< radiance divided by pdf and multiplied by foreshortening
                //!< factor for BSDFs
  vec3f wi;
  float pdf;
  Scattering_Type type;
};

OSPRAY_END_ISPC_NAMESPACE
