#if 0
// ---------------------------- VSOREAD.C -----------------------
// VSpace 3d library.
// Designed and written by Javier Ar‚valo Baeza.
// 3D Object reading (part of vsobject).

#include "vsobject.h"

#include "vsfile.h"
#include "vspix.h"
#include "vspools.h"

#include <stdio.h>


/*
static unsigned short ReadWord(FILE *f) {
    unsigned short v = 0;
    fread(&v, sizeof(v), 1, f);
    return v;
}
*/

static int ReadInt(FILE *f) {
    int v = 0;
    fread(&v, sizeof(v), 1, f);
    return v;
}
static float ReadFloat(FILE *f) {
    float v = 0;
    fread(&v, sizeof(v), 1, f);
    return v;
}
static void Read3Float(FILE *f, float *x, float *y, float *z) {
    float v;
    v = ReadFloat(f);
    if (x != NULL)
        *x = v;
    v = ReadFloat(f);
    if (y != NULL)
        *y = v;
    v = ReadFloat(f);
    if (z != NULL)
        *z = v;
}
static unsigned char ReadByte(FILE *f) {
    unsigned char v = 0;
    fread(&v, sizeof(v), 1, f);
    return v;
}
static void ReadStr(FILE *f, char *s, int size) {
    char buf[200];
    unsigned char l;

    memset(buf, 0, sizeof(buf));
    if (s != NULL) {
        assert(size < 200);
        memset(s, 0, size);
    }
    l = ReadByte(f);
    fread(buf, l+1, 1, f);
    if (s != NULL) {
        strncpy(s, buf, size);
        s[size-1] = '\0';
    }
}

static void ReadNode(VSO_PMesh base, VSO_PMesh pm, VSO_PMaterial matl, FILE *f) {
    int i, j;
    char buf[VSO_OBJNAMELEN];
    float cx, cy, cz;

        // Read object name
    ReadStr(f, pm->name, VSO_OBJNAMELEN);
        // Read parent name
    ReadStr(f, buf, VSO_OBJNAMELEN);
    pm->parent = base;
    if (buf[0] != '\0') {
        for (i = 1; base + i < pm; i++) {
            if (strnicmp(buf, base[i].name, VSO_OBJNAMELEN) == 0) {
                pm->parent = base + i;
                break;
            }
        }
    }

        // Read pivot
    Read3Float(f, &pm->bc.x, &pm->bc.y, &pm->bc.z);
    VSALG_Copy3DMatrix(&pm->bm, &VSALG_UnitMatrix);

        // Read number of vertices and faces.
    pm->nv = ReadInt(f);
    pm->nf = ReadInt(f);

//    printf("%d vertices, %d faces\n", pm->nv, pm->nf);

        // Read location.
    Read3Float(f, &cx, &cy, &cz);

    pm->light = ReadInt(f);
    if (pm->light) {
        Read3Float(f, &pm->rgbl.r, &pm->rgbl.g, &pm->rgbl.b);

//        VSLOG("Node %s is a light of %f, %f, %f\n", pm->name, pm->rgbl.r, pm->rgbl.g, pm->rgbl.b);
        pm->rgbl.intens = 1;
    }

        // Read vertices.
    if (pm->nv > 0) {
        pm->v = NEW(pm->nv*sizeof(*pm->v));
        REQUIRE(pm->v != NULL);
        memset(pm->v, 0, pm->nv*sizeof(*pm->v));
        for (i = 0; i < pm->nv; i++) {
            Read3Float(f, &pm->v[i].v.x, &pm->v[i].v.y, &pm->v[i].v.z);
            pm->v[i].v.x -= pm->bc.x;
            pm->v[i].v.y -= pm->bc.y;
            pm->v[i].v.z -= pm->bc.z;
        }
    }
//    printf("Read vertices.\n");

    if (pm->nf > 0) {
        pm->f = NEW(pm->nf*sizeof(*pm->f));
        REQUIRE(pm->f != NULL);
        memset(pm->f, 0, pm->nf*sizeof(*pm->f));
        for (i = 0; i < pm->nf; i++) {
            int nmat;

                // Read number of vertices in face.
            pm->f[i].nv = ReadInt(f);
            REQUIRE(pm->f[i].nv > 2);
            pm->f[i].v = NEW(pm->f[i].nv*sizeof(*pm->f[i].v));
            REQUIRE(pm->f[i].v != NULL);
            memset(pm->f[i].v, 0, pm->f[i].nv*sizeof(*pm->f[i].v));

                // Read material name
            nmat = ReadInt(f);
            pm->f[i].m = matl + nmat;

                    // Read vertex info
            for (j = 0; j < pm->f[i].nv; j++) {
                    // Vertex index.
                pm->f[i].v[j].nvert = ReadInt(f);
                    // Read texture coordinates.
                pm->f[i].v[j].t.x = 256*65536*ReadFloat(f);
                pm->f[i].v[j].t.y = -256*65536*ReadFloat(f);
            }
        }
    }
//    printf("Read faces.\n");
}

static void AdjustOffsets(VSO_PMesh pm) {
    while (pm != NULL) {
        AdjustOffsets(pm->child);
        if (pm->parent != NULL) {
            VSALG_Sub3D(&pm->bc, &pm->bc, &pm->parent->bc);
                // Clean parent objects, because most probably you want them
                // at the center of the VSO_TObj.
                // Only if the top of the hierarchy is just one object.
            if (pm->parent->name[0] == '\0' && pm->sibling == NULL && pm->parent->child == pm) {
                VSALG_Copy3DVector(&pm->bc, &VSALG_ZeroVector);
            }
        }
        pm = pm->sibling;
    }
}

extern int VSO_ReadVSO(VSO_PObj po, const char *fname) {
    FILE *f;
    VSO_PMesh pm;
    int nt, nm, nn;
    int i;
    char buf[4];

    REQUIRE(po != NULL);
    memset(po, 0, sizeof(*po));
    f = VSF_Open(fname);
    if (f == NULL)
        return -1;

    if (fread(buf, 4, 1, f) != 1 || memcmp(buf, "VSO", 4) != 0) {
        VSF_Close(f);
        return -1;
    }

        // Read materials
    nm = ReadInt(f);
//    VSLOG("Reading %d materials\n", nm);
    po->nmat = nm;
    po->mat = NEW(po->nmat*sizeof(*po->mat));
    REQUIRE(po->nmat <= 0 || po->mat != NULL);
    if (po->mat != NULL)
        memset(po->mat, 0, po->nmat*sizeof(*po->mat));

    for (i = 0; i < nm; i++) {
        char buf[200];
        VSO_PMaterial mat;
        byte r, g, b;

            // Read material name
        ReadStr(f, buf, VSO_MATNAMELEN);
        //VSLOG("Material named %s\n", buf);
            // Read RGB
        r = ReadByte(f);
        g = ReadByte(f);
        b = ReadByte(f);
        mat = po->mat + i;
        mat->c = VSTM_MAKEPIX(r, g, b);
        mat->r = r;
        mat->g = g;
        mat->b = b;
        mat->selflit = ReadFloat(f);
        mat->flags = ReadInt(f);
        mat->tex = NULL;
            // Read texture name
        ReadStr(f, buf, VSO_TEXNAMELEN);
        if (buf[0] != '\0') {
            long pos = ftell(f);

            mat->tex = VSPOOL_LoadTexture(buf);
            if (mat->tex == NULL)
                mat->flags &= ~VSPLYMF_TEX;
            else
                mat->flags |= VSPLYMF_TEX;

            //if (mat->tex != NULL) VSLOG("    Texture named %s read OK\n", buf);
            fseek(f, pos, SEEK_SET);
        }
    }
        // Read nodes
    nn = ReadInt(f);
//    VSLOG("Reading %d nodes\n", nn);
    if (po == NULL)
        return nn;
    po->nmesh = nn + 1;
    po->mesh  = NEW(po->nmesh*sizeof(*po->mesh));
    REQUIRE(po->mesh != NULL);
    memset(po->mesh, 0, po->nmesh*sizeof(*po->mesh));

    VSALG_Copy3DMatrix(&po->mesh[0].bm, &VSALG_UnitMatrix);
    pm = po->mesh + 1;
    for (i = 1; i < po->nmesh; i++, pm++) {
        ReadNode(po->mesh, pm, po->mat, f);
    }
    VSF_Close(f);

        // Build hierarchy.
    pm = po->mesh;
    for (i = 0; i < po->nmesh; i++, pm++) {
        VSO_PMesh ps;
        if (pm->parent != NULL) {
            ps = pm->parent;
            pm->sibling = ps->child;
            ps->child = pm;
        } else if (i > 0) {
            pm->sibling = pm->sibling;
            pm->sibling = pm;
        }
    }
    AdjustOffsets(po->mesh);
//    VSLOG("Read OK\n");
    return nn;
}

#endif