Re: OpenFlight (some code)

New Message Reply Date view Thread view Subject view Author view

Angus Dorbie (dorbie++at++bitch.reading.sgi.com)
Mon, 29 Apr 1996 22:09:55 +0100


Oh and incase I haven't convinced you to use the performer loaders, here's some
parsing code, it just PARSES a flight file it doesn't really load anything, the
last time I checked it worked with flight 14 and I've tried to ensure that it
won't break with format updates although it won't recognise new opcodes. It
isn't designed for open flight (don't know whats in that, I expect it's mostly
just a name change), it just reads a flight file, prints lots of info and draws
the vertices in an IrisGL window for fun.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <stdio.h>
#include <errno.h>
#include <gl.h>
#include <unistd.h>

#define FLT_HEADER 1
#define FLT_GROUP 2
#define FLT_LOD 3 /* OBSOLETE */
#define FLT_OBJECT 4
#define FLT_POLYGON 5
#define FLT_ABS_VERTEX 7 /* OBSOLETE */
#define FLT_SHA_VERTEX 8 /* OBSOLETE */
#define FLT_NOR_VERTEX 9 /* OBSOLETE */
#define FLT_PU_LEVEL 10
#define FLT_PO_LEVEL 11
#define FLT_DOF 13 /* OBSOLETE */
#define FLT_DOFF 14
#define FLT_PU_SUB 19
#define FLT_PO_SUB 20
#define FLT_COMMENT 31
#define FLT_COLOUR 32
#define FLT_T0 40
#define FLT_T1 41
#define FLT_T2 42
#define FLT_T3 43
#define FLT_T4 44
#define FLT_T5 45
#define FLT_T6 46
#define FLT_T7 47
#define FLT_T8 48
#define FLT_TRANSFORMATION 49
#define FLT_GEOMETRY 50
#define FLT_BOUNDS 51 /* OBSOLETE */
#define FLT_REPLICATION 60
#define FLT_TEXTURE 64
#define FLT_EYE 65 /* OBSOLETE */
#define FLT_MATERIAL 66
#define FLT_VERTEX_TABLE 67
#define FLT_SHA_VERTEXF 68
#define FLT_NOR_VERTEXF 69
#define FLT_NORTEX_VERTEXF 70
#define FLT_TEX_VERTEXF 71
#define FLT_VERTEX_LIST 72
#define FLT_LODD 73
#define FLT_EYE_POINT 83

#define MAXPOOL 5000

/* local functions */
static float *ReadFlight(char *);
static void clear_record(FILE *);
static void name_and_clear_record(FILE *, int);
static void get_vertex(FILE *, int);
static void draw_axes(void);
static void add_vert(float *);
static void draw_verts(void);

char *indentations[] = {
  "",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " ",
  " "
};

static char *indent;
static float *vpool;
static unsigned long vcount;

main()
{
  foreground();
  prefsize(500, 500);
  winopen("Flight File");
  RGBmode();
  mmode(MVIEWING);
  winconstraints();
  doublebuffer();
  zbuffer(FALSE);
  gconfig();

  subpixel(TRUE);
  pntsize(3.0);
  pntsmooth(SMP_ON | SMP_SMOOTHER);
  linesmooth(SML_ON | SML_SMOOTHER | SML_END_CORRECT);
  blendfunction(BF_SA, BF_MSA);
  perspective(450.0, 1.0, 1.0, 500.0);

  translate(0.0, 0.0, -100.0);
  rot(45.0, 'x');
  rot(30.0, 'y');

  cpack(0xFF000000);

  ReadFlight("test.flt");

  while(1)
    draw_verts();
}

static float *ReadFlight(char *name)
{
  short code;
  int size;
  char buffer[120];
  static int indentnum = 0;
  FILE *flight;

  indent = indentations[indentnum];

  flight = fopen(name, "rb");

  if(!flight)
  {
    printf("Failed to open file %s\n", name);
    exit(1);
  }

  /* 5000 verts x y z nx ny nx u v */
  vpool = (float *)calloc( 8*MAXPOOL, sizeof(float) );
  vcount = 0;

  size = fread((void *)&code, 2, 1, flight);
  while(size > 0)
  {
    draw_verts();
    switch(code)
    {
    case FLT_HEADER:
      printf("%sHEADER\n", indent);
      clear_record(flight);
      break;
    case FLT_GROUP:
      printf("%sGROUP\n", indent);
      name_and_clear_record(flight, 8);
      break;
    case FLT_LOD:
      printf("%sLOD: OBSOLETE\n", indent);
      name_and_clear_record(flight, 8);
      break;
    case FLT_OBJECT:
      printf("%sOBJECT\n", indent);
      name_and_clear_record(flight, 8);
      break;
    case FLT_POLYGON:
      printf("%sPOLYGON\n", indent);
      name_and_clear_record(flight, 8);
      break;
    case FLT_ABS_VERTEX:
      printf("%sABSOLUTE VERTEX: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_SHA_VERTEX:
      printf("%sSHADED VERTEX: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_NOR_VERTEX:
      printf("%sNORMAL VERTEX: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_PU_LEVEL:
      printf("%s{\n", indent);
      clear_record(flight);
      indentnum++;
      indent = indentations[indentnum];
      break;
    case FLT_PO_LEVEL:
      clear_record(flight);
      indentnum--;
      indent = indentations[indentnum];
      printf("%s}\n", indent);
      if(indentnum < 0)
        printf("PUSH/POP ERROR\n");
      break;
    case FLT_DOF:
      printf("%sDEGREE OF FREEDOM: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_DOFF:
      printf("%sDEGREE OF FREEDOM\n", indent);
      clear_record(flight);
      break;
    case FLT_PU_SUB:
      printf("%sCONTROL: PUSH SUBFACE\n", indent);
      clear_record(flight);
      break;
    case FLT_PO_SUB:
      printf("%sCONTROL: POP SUBFACE\n", indent);
      clear_record(flight);
      break;
    case FLT_COMMENT:
      printf("%sCOMMENT\n", indent);
      fread((void *)&code, 2, 1, flight);
      size = fread(buffer, (long)code-4, 1, flight);
      buffer[size] = '\0';
      printf("%s%s\n", indent, buffer);
      break;
    case FLT_COLOUR:
      printf("%sCOLOUR TABLE\n", indent);
      clear_record(flight);
      break;
    case FLT_T0:
    case FLT_T1:
    case FLT_T2:
    case FLT_T3:
    case FLT_T4:
    case FLT_T5:
    case FLT_T6:
    case FLT_T7:
    case FLT_T8:
      printf("%sIndividual transformation\n", indent);
      break;
    case FLT_TRANSFORMATION:
      printf("%sTRANSFORMATION MATRIX\n", indent);
      clear_record(flight);
      break;
    case FLT_BOUNDS:
      printf("%sBOUNDS: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_REPLICATION:
      printf("%sREPLICATION\n", indent);
      clear_record(flight);
      break;
    case FLT_TEXTURE:
      printf("%sTEXTURE\n", indent);
      name_and_clear_record(flight, 80);
      break;
    case FLT_EYE:
      printf("%sEYE: OBSOLETE\n", indent);
      clear_record(flight);
      break;
    case FLT_MATERIAL:
      printf("%sMATERIAL\n", indent);
      clear_record(flight);
      break;
    case FLT_VERTEX_TABLE:
      printf("%sVERTEX TABLE\n", indent);
      clear_record(flight);
      break;
    case FLT_SHA_VERTEXF:
      printf("%sSHADED VERTEX\n", indent);
      get_vertex(flight, FLT_SHA_VERTEXF);
      break;
    case FLT_NOR_VERTEXF:
      printf("%sNORMAL VERTEX\n", indent);
      get_vertex(flight, FLT_NOR_VERTEXF);
      break;
    case FLT_NORTEX_VERTEXF:
      printf("%sNORMAL TEXTURED VERTEX\n", indent);
      get_vertex(flight, FLT_NORTEX_VERTEXF);
      break;
    case FLT_TEX_VERTEXF:
      printf("%sTEXTURED VERTEX\n", indent);
      get_vertex(flight, FLT_TEX_VERTEXF);
      break;
    case FLT_VERTEX_LIST:
      printf("%sVERTEX LIST\n", indent);
      clear_record(flight);
      break;
    case FLT_LODD:
      printf("%sLEVEL OF DETAIL\n", indent);
      clear_record(flight);
      break;
    case FLT_EYE_POINT:
      printf("%sEYE POINT\n", indent);
      clear_record(flight);
      break;
    default:
      printf("%sUNKNOWN RECORD NUMBER: %d\n", indent, code);
      clear_record(flight);
    }
    size = fread((void *)&code, 2, 1, flight);
  }
  fclose(flight);
}

static void clear_record(FILE *flight)
{
short code;

  fread((void *)&code, 2, 1, flight);
    fseek(flight, (long)code-4, SEEK_CUR );
}

static void name_and_clear_record(FILE * flight, int size)
{
short code;
char buffer[120];

  fread((void *)&code, 2, 1, flight);
  fread(buffer, size, 1, flight);
  printf("%sID : %s\n", indent, buffer);
  fseek(flight, (long)code-size-4, SEEK_CUR );
}

static void get_vertex(FILE *flight, int type)
{
short code;
double coords[4];
float newvert[4];

  fread((void *)&code, 2, 1, flight);

  switch(type)
  {
    case FLT_SHA_VERTEXF:
      fseek(flight, (long)code-4, SEEK_CUR );
      break;
    case FLT_NOR_VERTEXF:
      fseek(flight, (long)4, SEEK_CUR );
      fread((void *)coords, 8, 3, flight);
      fseek(flight, (long)code-32, SEEK_CUR );
      newvert[0] = (float) coords[0];
      newvert[1] = (float) coords[2];
      newvert[2] = -(float) coords[1];
      add_vert(newvert);
      break;
    case FLT_NORTEX_VERTEXF:
      fseek(flight, (long)4, SEEK_CUR );
      fread((void *)coords, 8, 3, flight);
      fseek(flight, (long)code-32, SEEK_CUR );
      newvert[0] = (float) coords[0];
      newvert[1] = (float) coords[2];
      newvert[2] = -(float) coords[1];
      add_vert(newvert);
      break;
    case FLT_TEX_VERTEXF:
      fseek(flight, (long)code-4, SEEK_CUR );
      break;
  }
}

static void draw_axes(void)
{
  static float ax[][4] = {
    { 0.0, 0.0, 0.0, 0.0 },
    { 5.0, 0.0, 0.0, 0.0 },
    { 0.0, 5.0, 0.0, 0.0 },
    { 0.0, 0.0, 5.0, 0.0 },
  };

  cpack(0xFFFF0000);

  bgnline();
    v3f(ax[1]);
    v3f(ax[0]);
    v3f(ax[2]);
  endline();
  bgnline();
    v3f(ax[0]);
    v3f(ax[3]);
  endline();
}

static void add_vert(float *newvert)
{
  if(vcount < (MAXPOOL-1))
  {
    if(vpool)
    {
      *(vpool + (vcount * 8)) = *newvert;
      *(vpool + (vcount * 8 +1)) = *(newvert+1);
      *(vpool + (vcount * 8 +2)) = *(newvert+2);
    }

    vcount ++;
  }
  else
    printf("Ignoring Vertex: maximum of %d exceeded\n", MAXPOOL);
}

static void draw_verts(void)
{
int i;
float *vert;

  if(vpool)
  {
    cpack(0xFF000000);
    clear();
    rot(0.5, 'y');

    cpack(0xFFFF0000);
    draw_axes();
    cpack(0xFFFFFFFF);
    bgnpoint();
      for(i=0, vert = vpool; i<vcount; i++, vert += 8)
      {
        v3f(vert);
      }
    endpoint();
    swapbuffers();
  }
}

-- 
Angus Dorbie,
The Reality Centre,
Silicon Graphics Ltd, UK
dorbie++at++reading.sgi.com

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:52:49 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.