/******************************************/
/*                                        */
/*    RenderWare(TM) Graphics Library     */
/*                                        */
/******************************************/

/*
 * This file is a product of Criterion Software Ltd.
 *
 * This file is provided as is with no warranties of any kind and is
 * provided without any obligation on Criterion Software Ltd.
 * or Canon Inc. to assist in its use or modification.
 *
 * Criterion Software Ltd. and Canon Inc. will not, under any
 * circumstances, be liable for any lost revenue or other damages
 * arising from the use of this file.
 *
 * Copyright (c) 1998. Criterion Software Ltd.
 * All Rights Reserved.
 */

/****************************************************************************
 *                                                                         
 * Hierarchical and morph animation controller
 * Copyright (C) 1998 Criterion Technologies
 *
 * Author  : Damian Scallan 
 *
 * Module  : rpvrmlanim.h
 *                                                                         
 * Purpose : Functions for creating and controlling articulated hierarchical
 *           keyframe animation as well as morph keyframe animation
 *                                                                         
 ****************************************************************************/

#ifndef VRMLANIM_H
#define VRMLANIM_H

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

#include <rwcore.h>
#include <rpworld.h>

#include <rtslerp.h>

/*#include "rpanim.rpe"*/    /* automatically generated header file */

/****************************************************************************
 Global Types
 */
typedef struct RpVRMLAnimInterpolator RpVRMLAnimInterpolator;
struct RpVRMLAnimInterpolator
{
    RwInt32  flags;
    RwInt16  startKeyFrame;
    RwInt16  endKeyFrame;
    RwReal   time;
    RwReal   recipTime;
    RpVRMLAnimInterpolator *next;
};


typedef struct RpVRMLAnimState RpVRMLAnimState;
typedef RwReal (*RpVRMLAnimStateCallBack)(RpVRMLAnimState *animCntrl, RwReal position);
struct RpVRMLAnimState
{
    RwInt32                   numInterpolators;
    RpVRMLAnimInterpolator       *interp;
    RwReal                    position;
    RpVRMLAnimStateCallBack       fpAnimCntrlCB;
    RpVRMLAnimInterpolator       *allInterps;
};

typedef struct RpVRMLRotate RpVRMLRotate;
struct RpVRMLRotate
{
    RwV3d  axis;
    RwReal angle;
};

typedef RpVRMLRotate RpVRMLRotateKey;
typedef RwV3d    RpVRMLTranslateKey;
typedef RwV3d    RpVRMLScaleKey;

typedef struct RpVRMLAnimTransformState RpVRMLAnimTransformState;
struct RpVRMLAnimTransformState
{
    RwMatrix            rotationMat;
    RwMatrix            scaleOrientMat;
    RwV3d               offset;
    RwV3d               translation;
    RwV3d               scale;
};

#if (!defined(RpVRMLAnimTransformStateAssign))
#define RpVRMLAnimTransformStateAssign(_target, _source)             \
    ( *(_target) = *(_source) )
#endif /* (!defined(RpVRMLAnimTransformStateAssign)) */

typedef struct RpVRMLAnimTranslate RpVRMLAnimTranslate;
struct RpVRMLAnimTranslate
{
    RpVRMLAnimState        *translateCntrl;
    RwInt32             numTranslationKeys;
    RpVRMLTranslateKey     *translationKeys;
};

typedef struct RpVRMLAnimRotate RpVRMLAnimRotate;
struct RpVRMLAnimRotate
{
    RpVRMLAnimState        *rotateCntrl;
    RwInt32             numRotationKeys;
    RpVRMLRotateKey        *rotationKeys;
    RtSlerp            *slerp;
};

typedef struct RpVRMLAnimScale RpVRMLAnimScale;
struct RpVRMLAnimScale
{
    RpVRMLAnimState        *scaleCntrl;
    RwInt32             numScaleKeys;
    RpVRMLTranslateKey     *scaleKeys;
};

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

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

extern RwBool                    _rpVrmlAnimPluginAttach(void);

extern RwFrame                  *_rpVrmlFrameAnimOptimize(RwFrame *frame, RwReal delat);

extern RwFrame                  *_rpVrmlFrameAnimSetName(RwFrame *frame, const RwChar *name);
extern RwChar                   *_rpVrmlFrameAnimGetName(const RwFrame *frame);

extern RwFrame                  *_rpVrmlFrameAnimAddTime(RwFrame *frame, RwReal time);
extern RwFrame                  *_rpVrmlFrameAnimSetTranslations(RwFrame *frame, RpVRMLAnimTranslate *translateAnim);
extern RpVRMLAnimTranslate          *_rpVrmlFrameAnimGetTranslations(const RwFrame *frame);
extern RwFrame                  *_rpVrmlFrameAnimSetRotations(RwFrame *frame, RpVRMLAnimRotate *rotateAnim);
extern RpVRMLAnimRotate             *_rpVrmlFrameAnimGetRotations(const RwFrame *frame);
extern RwFrame                  *_rpVrmlFrameAnimSetScales(RwFrame *frame, RpVRMLAnimScale *scaleAnim);
extern RpVRMLAnimScale              *_rpVrmlFrameAnimGetScales(const RwFrame *frame);
extern RwFrame                  *_rpVrmlFrameAnimSetScaleOrients(RwFrame *frame, RpVRMLAnimRotate *scaleOrientAnim);
extern RpVRMLAnimRotate             *_rpVrmlFrameAnimGetScaleOrients(const RwFrame *frame);
extern RpVRMLAnimTransformState     *_rpVrmlFrameAnimGetTransformState(const RwFrame *frame);

/* RpVRMLAnimTranslate */
extern RpVRMLAnimTranslate          *_rpVrmAnimTranslateCreate(void);
extern RwBool                    _rpVrmAnimTranslateDestroy(RpVRMLAnimTranslate *translateAnim);
extern RwInt32                   _rpVrmAnimTranslateGetNumKeys(const RpVRMLAnimTranslate *translateAnim);
extern RpVRMLTranslateKey           *_rpVrmAnimTranslateGetKeys(const RpVRMLAnimTranslate *translateAnim);
extern RpVRMLAnimTranslate          *_rpVrmAnimTranslateAddKeys(RpVRMLAnimTranslate *translateAnim, RwInt32 numKeys);
extern RpVRMLAnimTranslate          *_rpVrmAnimTranslateSetState(RpVRMLAnimTranslate *translateAnim, RpVRMLAnimState *translateCntrl);
extern RpVRMLAnimState              *_rpVrmAnimTranslateGetState(const RpVRMLAnimTranslate *translateAnim);

/* RpVRMLAnimRotate */
extern RpVRMLAnimRotate             *_rpVrmAnimRotateCreate(void);
extern RwBool                    _rpVrmAnimRotateDestroy(RpVRMLAnimRotate *rotateAnim);
extern RwInt32                   _rpVrmAnimRotateGetNumKeys(const RpVRMLAnimRotate *rotateAnim);
extern RpVRMLRotateKey              *_rpVrmAnimRotateGetKeys(const RpVRMLAnimRotate *rotateAnim);
extern RpVRMLAnimRotate             *_rpVrmAnimRotateAddKeys(RpVRMLAnimRotate *rotateAnim, RwInt32 numKeys);
extern RpVRMLAnimRotate             *_rpVrmAnimRotateSetState(RpVRMLAnimRotate *rotateAnim, RpVRMLAnimState *rotateCntrl);
extern RpVRMLAnimState              *_rpVrmAnimRotateGetState(const RpVRMLAnimRotate *rotateAnim);

/* RpVRMLAnimScale */
extern RpVRMLAnimScale              *_rpVrmAnimScaleCreate(void);
extern RwBool                    _rpVrmAnimScaleDestroy(RpVRMLAnimScale *scaleAnim);
extern RwInt32                   _rpVrmAnimScaleGetNumKeys(const RpVRMLAnimScale *scaleAnim);
extern RpVRMLScaleKey               *_rpVrmAnimScaleGetKeys(const RpVRMLAnimScale *scaleAnim);
extern RpVRMLAnimScale              *_rpVrmAnimScaleAddKeys(RpVRMLAnimScale *scaleAnim, RwInt32 numKeys);
extern RpVRMLAnimScale              *_rpVrmAnimScaleSetState(RpVRMLAnimScale *scaleAnim, RpVRMLAnimState *scaleCntrl);
extern RpVRMLAnimState              *_rpVrmAnimScaleGetState(const RpVRMLAnimScale *scaleAnim);

/* RpVRMLAnimState */
extern RpVRMLAnimState              *_rpVrmAnimStateCreate             (RwInt32 numInterpolators);
extern RwBool                    _rpVrmAnimStateDestroy             (RpVRMLAnimState *animCntrl);
extern RpVRMLAnimInterpolator       *_rpVrmAnimStateAddInterpolator    (RpVRMLAnimState *animCntrl, RwInt32 interpNum,
                                                                RwInt16 startKey, RwInt16 endKey, RwReal duration);
extern RwBool                    _rpVrmAnimStateSetCallBack        (RpVRMLAnimState *animCntrl, RpVRMLAnimStateCallBack animCB);
extern RpVRMLAnimStateCallBack       _rpVrmAnimStateGetCallBack        (const RpVRMLAnimState *animCntrl);
extern RwMatrix                 *_rpVrmAnimGetMatrix               (RpVRMLAnimTransformState *compMatrix, RwMatrix *matrix);

#ifdef    __cplusplus
}
#endif /* __cplusplus */

#endif /* VRMLANIM_H */
