/*
 *  dmphgeom.h - delta morph geometry data and morph targets
 */

#if (!defined(_DMPHGEOM_H))
#define _DMPHGEOM_H

/*===========================================================================*
 *--- Include files ---------------------------------------------------------*
 *===========================================================================*/

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

/*===========================================================================*
 *--- Defines ---------------------------------------------------------------*
 *===========================================================================*/

#define rpDMORPHRLEMAXPACKETSIZE    126

/*===========================================================================*
 *--- Types -----------------------------------------------------------------*
 *===========================================================================*/

/*--- rpDMorphGeometryData -------------------------------------------------
 *
 * This is an extension to RpGeometry. This defines the number of 
 * DMorphTargets.
 */

typedef struct rpDMorphGeometryData rpDMorphGeometryData;

struct rpDMorphGeometryData
{
    /*--- DMorphTargets ---*/
    RwUInt32            numDMorphTargets;
    RpDMorphTarget      *dMorphTargets;

    /*--- Current morph state of the geometry ---*/
    RwReal              *currValues;

};


/*--- rpDMorphRLE --------------------------------------------------------
 *
 * Contains the run length encoding of the delta data.
 */
typedef void rpDMorphRLEDelta;
typedef void rpDMorphRLEData;

typedef struct rpDMorphRLE rpDMorphRLE;
struct rpDMorphRLE
{
    RwUInt8            *code;
    RwUInt32            numCodeElements;
    RwUInt32            numDataElements;
    rpDMorphRLEDelta   *data;
};

typedef rpDMorphRLEDelta *
   (*rpDMorphRLEGenerateDeltaCallBack)(const rpDMorphRLEData  *baseData,
                                       const rpDMorphRLEData  *data,
                                       rpDMorphRLEDelta *delta );

/*--- _RpDMorphTarget -------------------------------------------------------*/
struct RpDMorphTarget
{
    /*--- DMorphTarget ---*/
    RpGeometry            *geometry;    
    RwChar                *name;
    /*RpGeometryFlag        flags;*/
    /*RpGeometryLockMode    lockFlags;*/
    RwUInt32              flags;
    RwUInt32              lockFlags;
    rpDMorphRLE           rle;
    /*--- DMorphGeometry ---*/
    RwV3d                 *vertices;          
    RwV3d                 *normals;
    RwRGBA                *preLightColors;
    RwTexCoords           *texCoords;
    /*--- Bounding sphere ---*/
    RwSphere              boundingSphere;     
};

/*===========================================================================*
 *--- Global variables ------------------------------------------------------*
 *===========================================================================*/

extern RwInt32 rpDMorphGeometryDataOffset;

/*===========================================================================*
 *--- Macros ----------------------------------------------------------------*
 *===========================================================================*/

/*--- Geometry data ---*/
#define RPDMORPHGEOMETRYGETDATA(geometry)                           \
    ((rpDMorphGeometryData **)(((RwUInt8 *)geometry)+                 \
                             (rpDMorphGeometryDataOffset))) 

#define RPDMORPHGEOMETRYGETCONSTDATA(geometry)                      \
    ((const rpDMorphGeometryData **)(((const RwUInt8 *)geometry)+     \
                                   (rpDMorphGeometryDataOffset)))

/*--- Geometry Macros ---
 *
 * These are defined to try and minimize any pain when the Morphing is 
 * fully removed from the RpWorld.
 */
#define RPDMORPHGEOMETRYGETVERTICES(geometry)                       \
    ((geometry)->morphTarget->verts)

#define RPDMORPHGEOMETRYGETNORMALS(geometry)                        \
    ((geometry)->morphTarget->normals)

#define RPDMORPHGEOMETRYGETPRELIGHTCOLORS(geometry)                 \
    ((geometry)->preLitLum)

#define RPDMORPHGEOMETRYGETTEXCOORDS(geometry)                      \
    ((geometry)->texCoords[0])

#define RPDMORPHGEOMETRYGETBOUNDINGSPHERE(geometry)                 \
    ((geometry)->morphTarget->boundingSphere)

#define RPDMORPHGEOMETRYGETNUMBEROFVERTICES(geometry)               \
    ((geometry)->numVertices)

/*===========================================================================*
 *--- Internal plugin functions ---------------------------------------------*
 *===========================================================================*/

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

extern RwBool _rpDMorphGeometryPluginAttach(void);

#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* _DMPHGEOM_H */
