/****************************************************************************
 *                                                                          *
 *  Module  :   patchgen.h                                                  *
 *                                                                          *
 *  Purpose :   Support for the creation of RW patches from a set of ctrl   *
 *              points.                                                     *
 *                                                                          *
 ****************************************************************************/

#ifndef PATCHGEN_H
#define PATCHGEN_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.
                                */

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

#define RPPATCHNUMCONTROLINDICES    16

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

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

typedef struct RpPatchNode RpPatchNode;
struct RpPatchNode
{
    RpPatchNode        *next;
    RxVertexIndex       idx[RPPATCHNUMCONTROLINDICES];            /**< control point indices */
    RwInt32             flag;
};

typedef struct RpPatchMaterial RpPatchMaterial;
struct RpPatchMaterial
{
    RpPatchMaterial    *next;

    RpPatchNode        *quadPatch;
    RpPatchNode        *triPatch;

    RwInt32             numQuadPatch;
    RwInt32             numTriPatch;

    RpMaterial         *mat;
    RwInt32             matIdx;
};

struct RpPatch
{
    RwInt32             numQuadPatch;
    RwInt32             numTriPatch;
    RwInt32             numIndex;
    RwInt32             numControlPoints;

    RpPatchMaterial    *patchMat;
    RwInt32             flag;

    RwV3d              *cpt;
    RwV3d              *nrm;

    RwTexCoords        *texCoords[rwMAXTEXTURECOORDS];
    RwRGBA             *preLit;
};

#if (defined (RWDEBUG) && defined (RWVERBOSE))
#if (0 && (defined(_WIN32)))
#define PATCHBOX(_msg)                                                  \
    MessageBox(NULL, _msg, __FILE__,                                    \
               (MB_TASKMODAL | MB_ICONERROR | MB_TOPMOST | MB_OK))
#endif /* (0 && (defined(_WIN32))) */
#if (!defined(PATCHBOX))
#define PATCHBOX(_msg)  RWMESSAGE((_msg))
#endif /* (!defined(PATCHBOX)) */
#endif /* (defined(_WIN32) && defined (RWDEBUG) && defined (RWVERBOSE)) */

#if (!defined(PATCHBOX))
#define PATCHBOX(_msg)         /* No op */
#endif /* (!defined(PATCHBOX)) */

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

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

extern RpMeshHeader *
RpPatchCreateMeshHeader(RpPatch * patch,
                        RwInt32 flag);

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

extern RxPipeline  *
_rpPatchPipelineCreate(void);

#ifdef __cplusplus
}
#endif                          /* __cplusplus */

#endif                          /* PATCHGEN_H */
