/****************************************************************************
 *                                                                          *
 *  Module  :   rppatch.c                                                   *
 *                                                                          *
 *  Purpose :   General patch handling.                                     *
 *                                                                          *
 ****************************************************************************/

/**
 * \defgroup rppatch310 RpPatch310
 * \ingroup retired
 *
 * \topic Bezier patch library
 *
 * This library provides effcient evaluation of patches
 */

#ifndef RPPATCH310_H
#define RPPATCH310_H

/****************************************************************************
 Includes
 */

#include "rwcore.h"
#include "rpworld.h"

#include "rpcriter.h"             /* Note: each vendor can choose their own method for
                                   * allocation of unique ID's. This file defines
                                   * the ID's used by Criterion.
                                   */
#include "archive/rppatch310.rpe" /* automatically generated header file */

/****************************************************************************
 Defines
 */

#define RPPATCHATOMICFLAGPATCH    0x01
#define RPPATCHATOMICFLAGMATFX    0x02

#define RPPATCHFLAGQUAD           0x01

/****************************************************************************
 Global Vars
 */

/****************************************************************************
 Global Types
 */

/**
 * \ingroup
 * \typedef RpNodePatchData
 * typedef for struct RpNodePatchData
 */
typedef struct RpNodePatchData RpNodePatchData;

/**
 * \ingroup rppatch310
 * \struct RpNodePatchData
 * structure holding patch data
 */
struct RpNodePatchData
{
    /*
     * The refinement node generates new vertices and so has to interpolate
     * per-vertex attributes from the original set of vertices to generate
     * values for the generated vertices. It can (barycentrically)
     * interpolate any number of additional 'passes' of UVs or RGBAs,
     * provided that:
     * (a) these extra clusters are added by the app at pipeline construction
     *     time through the use of RxPipelineNodeRequestCluster(),
     * (b) the extra UVs/RGBAs are the last clusters added to the node, and
     * (c) all the UVs come before the RGBAs (and there are no other cluster
     *     types sprinkled in amongst the UVs/RGBAs)
     */
    RwBool              patchOn;        /**< patchOn */
    RwInt32             numExtraUVs;    /**< numExtraUVs */
    RwInt32             numExtraRGBAs;  /**< numExtraRGBAs */
};

/**
 * \ingroup rppatch310
 * \typedef RpPatchControlPoints
 * typedef for patch control points structure
 */
typedef struct RpPatchControlPoints RpPatchControlPoints;

/**
 * \ingroup rppatch310
 * \typedef RpPatch
 * typedef for patch structure
 */
typedef struct RpPatch RpPatch;

/**
 * \ingroup rppatch310
 * \typedef RpPatchAtomicLODCallBack
 * typedef for call back function
 */
typedef             RwInt32(*RpPatchAtomicLODCallBack) (RpAtomic *
                                                        atomic);

/****************************************************************************
 Function prototypes
 */

#ifdef __cplusplus
extern              "C"
{
#endif                          /* __cplusplus */

/* Patch creation. */
extern RpPatch *
RpPatchSetNumControlPoints(RpPatch * patch,
                           RwInt32
                           numControlPoints);

extern RpPatch *
RpPatchSetControlPoints(RpPatch * patch,
                        RwV3d * cpt);

extern RpPatch *
RpPatchSetNormals(RpPatch * patch, RwV3d * nrm);

extern RpPatch *
RpPatchSetTexCoords(RpPatch * patch,
                    RwTexCoords * texcoords,
                    RwInt32 index);

extern RpPatch *
RpPatchSetPreLit(RpPatch * patch,
                 RwRGBA * prelit);

extern RpPatch *
RpPatchAddControlIndices(RpPatch * patch,
                         RxVertexIndex * indices,
                         RpMaterial * mat,
                         RwInt32 flag);

extern RpAtomic *
RpPatchAtomicSetPatchGeometry(RpAtomic * atomic,
                              RpPatch * patch,
                              RpGeometry *  geom);

extern RpGeometry *
RpPatchCreateGeometry(RpPatch * patch,
                      RwInt32 flag);

/* Patch LOD selection. */
extern RwBool
    
RpPatchSetAtomicLODCallBack(RpPatchAtomicLODCallBack callback);

extern RwBool
RpPatchSetAtomicLODRange(RwReal minRange, RwReal maxRange);

extern RwBool
RpPatchGetAtomicLODRange(RwReal * minRange, RwReal * maxRange);

extern RwBool
RpPatchSetAtomicLOD(RwInt32 minLOD, RwInt32 maxLOD);

extern RwBool
RpPatchGetAtomicLOD(RwInt32 * minLOD, RwInt32 * maxLOD);

/* Create and destroy a patch. */
extern RpPatch *
RpPatchCreate(void);

extern RwBool       
RpPatchDestroy(RpPatch * patch);

/* Plugin attach. */
extern RwBool       
RpPatchPluginAttach(void);

/* Set and get the patch's propery flag. */
extern RpAtomic *
RpPatchAtomicSetFlags(RpAtomic * atomic,
                      RwInt32 flag);

extern RwInt32
RpPatchAtomicGetFlags(RpAtomic * atomic);

#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

#endif                          /* RPPATCH310_H */
