

/*           -- FEXW 3D vector engine --
 *        Copyright (c) Mats Byggmastar 1996, 1997
 *
 *      3D Studio object & keyframer reader
 */


#ifndef _3DSREAD_H
#define _3DSREAD_H

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned char  uchar;
typedef unsigned short ushort;
typedef unsigned int   uint;


/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *\
                        3DS reader structures
\* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

typedef struct F3dsVertex
{
    float x,y,z;
    float u,v;              /* texture U,V  */
} F3dsVertex;

typedef struct F3dsFace
{
    ushort p0,p1,p2;
    ushort flags;           /* visibility and U,V wrap flags   */
    ushort material;        /* material index                  */
    uint   smooth;          /* smoothing groups                */
} F3dsFace;

typedef struct F3dsMaterial
{
    char name[20];          /* material name, zero terminated  */
} F3dsMaterial;

typedef struct F3dsValKey   /* one value key  */
{
    float v;                /* value */
    float tens;             /* [1...-1] = tight ... round            */
    float cont;             /* [1...-1] = inverted corners ... box corners */
    float bias;             /* [1...-1] = post shoot ... pre shoot   */
    float easeTo;           /* [0...1]  = speed, coming to key       */
    float easeFrom;         /* [0...1]  = speed, leaving key         */
    ushort flags;
    ushort frame;           /* frame number   */
} F3dsValKey;

typedef struct F3dsPosKey   /* position key   */
{
    float x,y,z;            /* position */
    float tens;             /* [1...-1] = tight ... round            */
    float cont;             /* [1...-1] = inverted corners ... box corners */
    float bias;             /* [1...-1] = post shoot ... pre shoot   */
    float easeTo;           /* [0...1]  = speed, coming to key       */
    float easeFrom;         /* [0...1]  = speed, leaving key         */
    ushort flags;
    ushort frame;           /* frame number   */
} F3dsPosKey;

typedef struct F3dsRotKey   /* rotation key   */
{
    float a,x,y,z;          /* angular displacement (in radians)     */
    float tens;             /* [1...-1] = tight ... round            */
    float cont;             /* [1...-1] = inverted corners ... box corners */
    float bias;             /* [1...-1] = post shoot ... pre shoot   */
    float easeTo;           /* [0...1]  = speed, coming to key       */
    float easeFrom;         /* [0...1]  = speed, leaving key         */
    ushort flags;
    ushort frame;           /* frame number   */
} F3dsRotKey;

typedef struct F3dsMorKey   /* morphing key   */
{
    char  name[16];         /* object name                           */
    float tens;             /* [1...-1] = tight ... round            */
    float cont;             /* [1...-1] = inverted corners ... box corners */
    float bias;             /* [1...-1] = post shoot ... pre shoot   */
    float easeTo;           /* [0...1]  = speed, coming to key       */
    float easeFrom;         /* [0...1]  = speed, leaving key         */
    ushort flags;
    ushort frame;           /* frame number   */
} F3dsMorKey;

typedef struct F3dsHidKey   /* hide key   */
{
    ushort frame;           /* frame number   */
} F3dsHidKey;


typedef struct F3dsObject
{
    ushort faces;           /* number of faces in facelist           */
    ushort vertices;        /* number of vertices in vtxlist         */
    F3dsFace * faclist;
    F3dsVertex * vtxlist;
    float aff[4][3];        /* affine matrix (world -> object space) */
    float wpaff[4][3];      /* world -> pivot space                  */
    float objpivx,objpivy,objpivz; /* object pivot point             */
    char name[16];          /* object name, zero terminated          */
    uchar color;            /* mesh color index [0...63]             */
    float utile,vtile;      /* texture tiling                        */

    /* Keyframer data */
    float trackpivx,trackpivy,trackpivz;   /* track pivot point */
    F3dsPosKey * poslist;   /* position keylist                      */
    F3dsRotKey * rotlist;   /* rotation keylist                      */
    F3dsPosKey * scalist;   /* scale keylist                         */
    F3dsMorKey * morlist;   /* morphing keylist                      */
    F3dsHidKey * hidlist;   /* hide keylist                          */
    ushort poskeys;         /* number of position keys in poslist    */
    ushort rotkeys;         /* number of rotation keys in rotlist    */
    ushort scakeys;         /* number of scale keys in scalist       */
    ushort morkeys;         /* number of morphing keys in morlist    */
    ushort hidkeys;         /* number of hide keys in hidlist        */
    ushort posflags;        /* loop, repeat etc. for position keys   */
    ushort rotflags;        /* loop, repeat etc. for rotation keys   */
    ushort scaflags;        /* loop, repeat etc. for scale keys      */
    ushort morflags;        /* loop, repeat etc. for morphing keys   */
    ushort hidflags;        /* loop, repeat etc. for hide keys       */
    ushort number;          /* object number                         */
    ushort parent;          /* parent object number                  */
    ushort haschild;        /* true if this object has a subtree     */
    ushort flags;           /* hidden object = bit 11                */
} F3dsObject;

typedef struct F3dsCamera
{
    char name[16];          /* camera name, zero terminated  */
    float tx,ty,tz;         /* camera target                 */
    float px,py,pz;         /* camera position               */
    float roll;             /* roll angle in degree          */
    float lens;             /* camera lens in mm             */

    /* Keyframer data */
    F3dsPosKey * tarlist;   /* position keylist of camera target     */
    F3dsPosKey * poslist;   /* position keylist of camera position   */
    F3dsValKey * rollist;   /* value keylist of camera roll angle    */
    F3dsValKey * fovlist;   /* value keylist of camera FOV angle     */
    ushort tarkeys;         /* number of position keys in poslist    */
    ushort poskeys;         /* number of position keys in rotlist    */
    ushort rolkeys;         /* number of value keys in rollist       */
    ushort fovkeys;         /* number of value keys in fovlist       */
    ushort tarflags;        /* loop, repeat etc. for target keys     */
    ushort posflags;        /* loop, repeat etc. for position keys   */
    ushort rolflags;        /* loop, repeat etc. for roll keys       */
    ushort fovflags;        /* loop, repeat etc. for FOV keys        */
    ushort tarnumber;       /* object number for target              */
    ushort posnumber;       /* object number for position            */
    ushort tarparent;       /* parent object number for target       */
    ushort posparent;       /* parent object number for position     */
    ushort flags;           /*                                       */
} F3dsCamera;

typedef struct F3dsLight
{
    char name[16];          /* light name, zero temainated           */
    float x,y,z;            /* light position                        */
    float r,g,b;            /* color                                 */

    /* Keyframer data */
    F3dsPosKey * poslist;   /* position keylist of light position    */
    ushort poskeys;         /* number of position keys in poslist    */
    ushort posflags;        /* loop, repeat etc. for position keys   */
    ushort number;          /* object number                         */
    ushort parent;          /* parent object number                  */
    ushort flags;           /* hidden = bit 11                       */
} F3dsLight;

typedef struct F3dsScene
{
    int objects;            /* number of mesh objects                */
    int materials;          /* number of materials                   */
    int cameras;            /* number of cammeras                    */
    int lights;             /* number of lights                      */
    F3dsObject   * objlist; /* array of objects                      */
    F3dsMaterial * matlist; /* array of materials                    */
    F3dsCamera   * camlist; /* array of cameras                      */
    F3dsLight    * liglist; /* array of lights                       */

    /* Keyframer data */
    uint startframe;        /* animation starting frame number       */
    uint endframe;          /* animation ending frame number         */
} F3dsScene;




/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *\
                        3DS reader
\* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


#define FILE_3DS    0
#define MEMORY_3DS  1

/*
 * Read a 3ds-file from FILE or a memory buffer. Set 'what' to either
 * FILE_3DS or MEMORY_3DS.
 *
 *   'msg'  = pointer to a buffer where possible error message is stored.
 *            Minimum 128 bytes.
 *
 * If from file:
 * 
 *   'ptr'  = pointer to a FILE structure (FILE *) with a newly opened disk file.
 *   'what' = set to FILE_3DS
 *   'size' = not used. Set to 0.
 *
 * If from memory:
 *
 *   'ptr'  = pointer to a memory buffer where a 3ds-file data is stored.
 *   'what' = set to MEMORY_3DS
 *   'size' = size in bytes of the 3ds-file data in the memory buffer.
 *
 * The function returns a pointer to a newly created F3dsScene structure, 
 * containing the loaded 3ds-data. In case of problems, NULL is
 * returned and an error message is written to 'msg'.
 */
F3dsScene * F3dsReadScene(char * msg, void * ptr, int what, uint size);


/*
 * Well...
 */
void F3dsMakeWorldToPivotAff(float aff[4][3], F3dsObject * obj3ds);


/*
 * Swap the Y-Z coordinates in the F3dsScene data.
 */
void F3dsSwapYZ(F3dsScene * scene);


/*
 * Free F3dsScene object that was previously returned by F3dsReadScene().
 */
void F3dsFreeScene(F3dsScene * scene);



#ifdef __cplusplus
};
#endif

#endif  


