// ---------------------------- VSOBJECT.H -----------------------
// VSpace 3d library.
// Designed and written by Javier Ar‚valo Baeza.
// 3D Object mesh handling.

#if 0
#ifndef _VSOBJECT_H_
#define _VSOBJECT_H_

#include "vsalgeb.h"
#include "vspoly.h"
#include "vsdepthl.h"
#include "vsviewp.h"
#include "vscamera.h"
#include "vslight.h"

/*
    Format of VSO file:
     - Removed texture list (what for? NameLists do the job nicely).
     - Changed face material identifier from string to integer.

    ints and floats are 32 bit.
    strings are preceded by a byte with the string length, and terminated
    by a \0.

    (4 char) "VSO", 0
    (int) number of materials
    - Material list:
        (VSO_MATNAMELEN) material name
        (3 byte) R, G, B color of the material
        (int) flags
        (VSO_TEXNAMELEN) texture name for this material
    (int) number of nodes
    - Node List
        (VSO_OBJNAMELEN) Name of node object
        (VSO_OBJNAMELEN) Name of parent node object of this node
        (3 float) Object pivot point
        (int) number of vertices in this object
        (int) number of faces in this object
        (3 float) Object 3D location
        (int) is this a light? ==> 0 vertices and 0 faces.
            (3 float) Light RGB color
        - Vertex list
            (3 float) X, Y, Z of vertex
        - Face list
            (int) number of vertices in this face
//            (VSO_MATNAMELEN) Name of material for this face.
            (int) Number of material for this face.
            - Vertex List
                (int) vertex index number
                (2 float) U, V of texture for this vertex
*/

#ifdef __cplusplus
extern "C" {
#endif

#define VSO_TEXNAMELEN 20
#define VSO_MATNAMELEN 16
#define VSO_OBJNAMELEN 20

typedef VSPLY_TMaterial VSO_TMaterial, *VSO_PMaterial;

typedef struct {
    VSALG_T3DPoint v;   // 3D coordinates of vertex.
    VSALG_T3DPoint n;   // 3D normal at this vertex.
}  VSO_TVertex, *VSO_PVertex;

typedef struct {
    VSALG_T3DPoint v;   // 3D rotated coordinates of vertex.
    VSALG_T2DPoint p;   // 2D projected coordinates of vertex.
    VSALG_TCoord  d[4]; // Distances to the four clipping planes, UDLR.
    VSALG_TCoord iz;    // Inverse of Z.
    VSALG_TCoord a;     // ARGB values.
    VSALG_TCoord r;
    VSALG_TCoord g;
    VSALG_TCoord b;
    byte nfaces;        // Number of faces that have set this vertex visible.
    byte outcodes;      // Outcodes for clipping;
} VSO_TTempVertex, *VSO_PTempVertex;

typedef struct {
    int nvert;          // Index of vertex in object vertex list.
    VSALG_T2DPoint t;   // Texture coordinates.
} VSO_TFaceVertex, *VSO_PFaceVertex;

typedef struct {
    byte nv;            // Number of vertices in face.
    bool visible;       // Dynamic visibility flag.
    byte outcodes;      // Mixed outcodes of vertices (!= 0 => must clip).
    VSALG_T3DPoint  n;  // 3D normal at this face.
    VSO_PMaterial   m;  // Material for this face.
    VSO_PFaceVertex v;  // List of face vertices.
} VSO_TFace, *VSO_PFace;

typedef struct VSO_SMesh {
    char name[VSO_OBJNAMELEN];
    int nv;             // Number of vertices in the mesh.
    int nf;             // Number of faces in the mesh.
    VSO_PVertex v;      // List of vertices in the mesh.
    VSO_PFace   f;      // List of faces in the mesh.

    struct VSO_SMesh *parent;    // Pointer to parent mesh (or NULL).
    struct VSO_SMesh *child;     // Pointer to first child mesh.
    struct VSO_SMesh *sibling;   // Pointer to sibling.
        // Data relative to parent mesh.
    VSALG_T3DPoint bc;  // Base (static) position of mesh coordinate center.
    VSALG_T3DMatrix bm; // Base (static) rotation matrix of mesh.

        // Dynamic: set these fields for hierarchical motion.
    VSALG_T3DPoint  c;  // Dynamic position of mesh coordinate center.
    VSALG_T3DMatrix m;  // Dynamic rotation matrix of mesh.
    bool hidden;        // If this mesh shouldn't be drawn (but yes processed).

    bool light;         // Is this thing a light?
    VSL_TLightRGB rgbl; // Light color.

    VSALG_TCoord  radius;   // For bounding sphere.

} VSO_TMesh, *VSO_PMesh;

typedef struct {
    int       nmesh;
    int       nmat;
    VSO_PMesh     mesh;
    VSO_PMaterial mat;
    dword     flags;
    VSALG_TCoord  radius;   // For bounding sphere.
} VSO_TObj, *VSO_PObj;

#define VSOF_VERYBIG 0x0001


    // Lights should be inserted this way for proper calcs to be made:
    //  - Ambient.
    //  - Other.
    //  - Fog.
#define VSL_MAXLIGHTS 20
extern int         VSO_NLights;
extern VSL_PLight  VSO_Lights[VSL_MAXLIGHTS];

extern VSL_PLight  VSO_AmbientLight;
extern VSL_PLight  VSO_DirectionalLight;
extern VSL_PLight  VSO_FogLight;



extern VSB_PBitmap VSO_LightBitmap;

extern void VSO_CopyRotations(VSO_PMesh mesh);

extern void VSO_RotateHierarchy(VSO_PMesh mesh);

extern VSO_PMesh VSO_FindMeshName(VSO_PMesh mesh, const char *name);

extern void VSO_GenerateNormals(VSO_PMesh pm);

extern VSALG_TCoord VSO_CalcRadius(VSO_PMesh pm);

extern void VSO_DrawHierarchy(VSV_PViewport scr, VSO_PMesh mesh, const VSC_TCamera *cam);

extern bool VSO_DrawMesh(VSV_PViewport scr, VSO_PMesh mesh, const VSC_TCamera *cam);

extern VSDL_PLight VSO_DrawLight(VSV_PViewport scr,
                          VSALG_P3DPoint pos, VSL_PLightRGB rgbl,
                          VSB_PBitmap bm,
                          const VSC_TCamera *cam);

extern void VSO_LightVertex(VSL_PLightRGB vl, VSL_PLight l,
                            VSO_PVertex pv, VSO_PTempVertex ptv);

    // Read VSO mesh object.
extern int VSO_ReadVSO(VSO_PObj po, const char *fname);


#ifdef __cplusplus
}
#endif

#endif

// ---------------------------- VSOBJECT.H -----------------------

#endif