// ======================================================================== //
// Copyright 2009-2015 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 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 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 intersect function pointer for uniform rays. */
typedef 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 occlusion function pointer for uniform rays. */
typedef 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 */);


typedef void (*RTCDisplacementFunc)(void* uniform ptr,               /*!< pointer to user data of geometry */
                                    uniform unsigned int geomID,     /*!< ID of geometry to displace */
                                    uniform unsigned int primID,     /*!< ID of primitive of geometry to displace */
                                    uniform const float* uniform u,  /*!< u coordinates (source) */
                                    uniform const float* uniform v,  /*!< v coordinates (source) */
                                    uniform const float* uniform nx, /*!< x coordinates of normal at point to displace (source) */
                                    uniform const float* uniform ny, /*!< y coordinates of normal at point to displace (source) */
                                    uniform const float* uniform nz, /*!< z coordinates of normal at point to displace (source) */
                                    uniform float* uniform px,       /*!< x coordinates of points to displace (source and target) */
                                    uniform float* uniform py,       /*!< y coordinates of points to displace (source and target) */
                                    uniform float* uniform pz,       /*!< z coordinates of points to displace (source and target) */
                                    uniform size_t N                 /*!< number of points to displace */ );


/*! 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 */);

/*! 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);

/*! 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 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);


/*! \brief Sets the displacement function. */
void rtcSetDisplacementFunction (RTCScene scene, uniform unsigned int geomID, uniform RTCDisplacementFunc func, uniform RTCBounds *uniform bounds);

/*! @} */

#endif
