// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#ifndef __RTCORE_USER_GEOMETRY_ISPH__
#define __RTCORE_USER_GEOMETRY_ISPH__

/*! \ingroup embree_kernel_api_ispc */
/*! \{ */

/*! Type of bounding function. */
typedef unmasked void (*RTCBoundsFunc)(void* uniform ptr,                 /*!< pointer to user data */
                                       uniform size_t item,               /*!< item to calculate bounds for */
                                       uniform RTCBounds& bounds_o        /*!< returns calculated bounds */);

/*! Type of bounding function. */
typedef unmasked void (*RTCBoundsFunc2)(void* uniform userPtr,            /*!< pointer to user data */
                                        void* uniform geomUserPtr,        /*!< pointer to geometry user data */
                                        uniform size_t item,              /*!< item to calculate bounds for */
                                        RTCBounds* uniform bounds_o       /*!< returns calculated bounds */);

/*! Type of bounding function. */
typedef unmasked void (*RTCBoundsFunc3)(void* uniform userPtr,            /*!< pointer to user data */
                                        void* uniform geomUserPtr,        /*!< pointer to geometry user data */
                                        uniform size_t item,              /*!< item to calculate bounds for */
                                        uniform size_t time,              /*!< time to calculate bounds for */
                                        uniform RTCBounds& bounds_o       /*!< returns calculated bounds */);

/*! Type of intersect function pointer for uniform rays. */
typedef unmasked void (*RTCIntersectFuncUniform)(void* uniform ptr,       /*!< pointer to user data */
                                                 uniform RTCRay1& ray,    /*!< ray to intersect */
                                                 uniform size_t item      /*< item to intersect */);

/*! Type of intersect function pointer for varying rays. */
typedef void (*RTCIntersectFuncVarying)(void* uniform ptr,       /*!< pointer to user data */
                                        varying RTCRay& ray,     /*!< ray to intersect */
                                        uniform size_t item      /*< item to intersect */);

/*! Type of intersect function pointer for stream of uniform rays. */
typedef unmasked void (*RTCIntersectFunc1Mp)(void* uniform ptr,              /*!< pointer to geometry user data */
                                             const uniform RTCIntersectContext* uniform context,  /*!< intersection context as passed to rtcIntersect/rtcOccluded */
                                             uniform RTCRay1** uniform ray,  /*!< pointers to rays to intersect */
                                             uniform size_t M,               /*< number of rays in stream */
                                             uniform size_t item             /*< item to intersect */);

/*! Type of intersect function pointer for ray packets of size N. */
typedef unmasked void (*RTCIntersectFuncN)(const uniform int* uniform valid, /*! pointer to valid mask */
                                           void* uniform ptr,                /*!< pointer to geometry user data */
                                           const uniform RTCIntersectContext* uniform context,  /*!< intersection context as passed to rtcIntersect/rtcOccluded */
                                           RTCRayN* uniform rays,               /*!< ray packet of size N */
                                           uniform size_t N,                 /*< number of rays in ray packet */
                                           uniform size_t item              /*< item to intersect */);

/*! Type of occlusion function pointer for uniform rays. */
typedef unmasked void (*RTCOccludedFuncUniform) (void* uniform ptr,       /*!< pointer to user data */ 
                                                 uniform RTCRay1& ray,    /*!< ray to test occlusion */
                                                 uniform size_t item      /*< item to test for occlusion */);

/*! Type of occlusion function pointer for varying rays. */
typedef void (*RTCOccludedFuncVarying) (void* uniform ptr,       /*!< pointer to user data */ 
                                        varying RTCRay& ray,     /*!< ray to test occlusion */
                                        uniform size_t item      /*< item to test for occlusion */);

/*! Type of occlusion function pointer for stream of uniform rays. */
typedef unmasked void (*RTCOccludedFunc1Mp) (void* uniform ptr,             /*!< pointer to geometry user data */ 
                                             const uniform RTCIntersectContext* uniform context,  /*!< intersection context as passed to rtcIntersect/rtcOccluded */
                                             uniform RTCRay1** uniform ray, /*!< pointers to rays to test occlusion */
                                             uniform size_t M,              /*< number of rays in stream */
                                             uniform size_t item            /*< item to test for occlusion */);

/*! Type of occlusion function pointer for ray packets of size N. */
typedef unmasked void (*RTCOccludedFuncN) (const uniform int* uniform valid,  /*! pointer to valid mask */
                                           void* uniform ptr,                 /*!< pointer to geometry user data */ 
                                           const uniform RTCIntersectContext* uniform context,  /*!< intersection context as passed to rtcIntersect/rtcOccluded */
                                           RTCRayN* uniform ray,                 /*!< ray packet of size N */
                                           uniform size_t N,                  /*< number of rays in ray packet*/
                                           uniform size_t item                /*< item to test for occlusion */);


/*! Creates a new user geometry object. This feature makes it possible
 *  to add arbitrary types of geometry to the scene by providing
 *  appropiate intersect and occluded functions, as well as a bounding
 *  box of the implemented geometry. As the rtcIntersect and
 *  rtcOccluded functions support different ray packet sizes, the user
 *  also has to provide different versions of intersect and occluded
 *  function pointers for the different packet sized. However, only
 *  rtcIntersect and rtcOccluded functions of specific packet sizes
 *  are called, it is sufficient to provide only the corresponding
 *  function pointer for the user geometry. However, the functions
 *  provided have to intersect the same geometry. A user data pointer,
 *  that points to a user specified representation of the geometry, is
 *  passed to each intersect and occluded function invokation. */
uniform unsigned int rtcNewUserGeometry (RTCScene scene,                  /*!< the scene the user geometry set is created in */
                                         uniform size_t numGeometries     /*!< the number of geometries contained in the set */);

uniform unsigned int rtcNewUserGeometry2 (RTCScene scene,                 /*!< the scene the user geometry set is created in */
                                          uniform size_t numGeometries,    /*!< the number of geometries contained in the set */
                                          uniform size_t numTimeSteps = 1  /*!< number of motion blur time steps */);

uniform unsigned int rtcNewUserGeometry3 (RTCScene scene,                 /*!< the scene the user geometry set is created in */
                                          uniform RTCGeometryFlags flags,  //!< geometry flags
                                          uniform size_t numGeometries,    /*!< the number of geometries contained in the set */
                                          uniform size_t numTimeSteps = 1  /*!< number of motion blur time steps */);

/*! Sets the bounding function to calculate bounding boxes of the user
 *  geometry items when building spatial index structures. The
 *  calculated bounding box have to be conservative and should be
 *  tight.*/
void rtcSetBoundsFunction (RTCScene scene, uniform unsigned int geomID, uniform RTCBoundsFunc bounds);

/*! Sets the bounding function to calculate bounding boxes of the user
 *  geometry items when building spatial index structures. The
 *  calculated bounding box have to be conservative and should be
 *  tight.*/
void rtcSetBoundsFunction2 (RTCScene scene, uniform unsigned int geomID, uniform RTCBoundsFunc2 bounds, void* uniform userPtr);

/*! Sets the bounding function to calculate bounding boxes of the user
 *  geometry items when building spatial index structures. The
 *  calculated bounding box have to be conservative and should be
 *  tight.*/
void rtcSetBoundsFunction3 (RTCScene scene, uniform unsigned int geomID, uniform RTCBoundsFunc3 bounds, void* uniform userPtr);

/*! Set intersect function for uniform rays. The rtcIntersect1
 *  function will call the passed function for intersecting the user
 *  geometry. */
void rtcSetIntersectFunction1 (RTCScene scene, uniform unsigned int geomID, uniform RTCIntersectFuncUniform intersect);

/*! Set intersect function for varying rays. The rtcIntersect function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetIntersectFunction (RTCScene scene, uniform unsigned int geomID, uniform RTCIntersectFuncVarying intersect);

/*! Set intersect function for stream of rays. The rtcIntersectN function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetIntersectFunction1Mp (RTCScene scene, uniform unsigned geomID, uniform RTCIntersectFunc1Mp intersect);

/*! Set intersect function for ray packets of size N. The rtcIntersectN function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetIntersectFunctionN (RTCScene scene, uniform unsigned geomID, uniform RTCIntersectFuncN intersect);

/*! Set occlusion function for uniform rays. The rtcOccluded1 function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetOccludedFunction1 (RTCScene scene, uniform unsigned int geomID, uniform RTCOccludedFuncUniform occluded);

/*! Set occlusion function for varying rays. The rtcOccluded function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetOccludedFunction (RTCScene scene, uniform unsigned int geomID, uniform RTCOccludedFuncVarying occluded);

/*! Set occlusion function for a stream of single rays. The rtcOccludedN function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetOccludedFunction1Mp (RTCScene scene, uniform unsigned geomID, uniform RTCOccludedFunc1Mp occluded);

/*! Set occlusion function for a ray packets of size N. The rtcOccludedN function
 *  will call the passed function for intersecting the user
 *  geometry. */
void rtcSetOccludedFunctionN (RTCScene scene, uniform unsigned geomID, uniform RTCOccludedFuncN occluded);

/*! @} */

#endif
