Logo Search packages:      
Sourcecode: plib version File versions  Download package

ssgLoadASC.cxx

/*
     PLIB - A Suite of Portable Game Libraries
     Copyright (C) 1998,2002  Steve Baker
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later version.
 
     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Library General Public License for more details.
 
     You should have received a copy of the GNU Library General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
     For further information visit http://plib.sourceforge.net

*/

//
// .ASC loader for SSG/PLIB
// ASC = ascii files, used for example by 3DS R4 (the DOS version)
// Written by Wolfram Kuss (Wolfram.Kuss@t-online.de) on 3.10.2004
//
#include  "ssgLocal.h"
#include "ssgLoaderWriterStuff.h" 
#include "ssgParser.h"

#define u32 unsigned int

// These functions return TRUE on success
typedef int AscHandlerFunctionType();


static char *globEmpty="";

static ssgBranch *curr_branch_;

struct AscEntityType
{
  const char * sName;
      AscHandlerFunctionType *HandleEntity;
  bool appearsInsideAMesh;
} ;

void AscLinePreProcessor(char *line)
// there are lines like this
//                                     Page 2
// in *.asc files. They should be completely ignored.

{ char *p = line;
  while((*p == ' ') || (*p == 9))
    p++;
  // p points to the first word (or the line end) now.
  if(ulStrNEqual(p, "Page", strlen("Page")))
  {
    // Since this loader ignores the line structure, 
    // we can also ignore the \n or \r and just "delete" the whole line
    line[0] = 0;
  }
  if(ulStrNEqual(p, "Camera", strlen("Camera")))
    line[0] = 0;
}


static /* const */ ssgLoaderOptions* current_options = NULL ;

static _ssgParserSpec parser_spec =
{
   "\r\n\t ",  // delim_chars_skipable
   "=:",       // delim_chars_non_skipable so that things like "red=0.5" or "vertex 0:" work
   AscLinePreProcessor,      // pre_processor
   "{",          // open_brace_chars - unused
   "}",          // close_brace_chars - unused
   '"',        // quote_char
   '#',          // comment_char - I am not sure there are comments and if so which char starts them
       "//"        // comment_string - I am not sure there are comments and if so which string starts them
} ;

   
static _ssgParser parser;
static ssgBranch* top_branch;

static int Ascii2Int(int &retVal, const char *token, const char* name )
// returns TRUE on success
{
  char *endptr;
  retVal = int(strtol( token, &endptr, 10));
      if ( (endptr == NULL) || (*endptr == 0))
    return TRUE;
      else
      { parser.error("The field %s should contain an integer number but contains %s",name, token) ;
            return FALSE;
      }
}

static int Ascii2UInt(unsigned int &retVal, const char *token, const char* name )
// returns TRUE on success
{
  char *endptr;
  retVal = (unsigned int)(strtol( token, &endptr, 10));
      if ( (endptr == NULL) || (*endptr == 0))
    return TRUE;
      else
      { parser.error("The field %s should contain an integer number but contains %s",name, token) ;
            return FALSE;
      }
}

static int Ascii2Float(SGfloat &retVal, const char *token, const char* name )
// returns TRUE on success
{
  char *endptr;
  retVal = SGfloat(strtod( token, &endptr));
      if ( (endptr == NULL) || (*endptr == 0))
    return TRUE;
      else
      { parser.error("The field %s should contain an integer number but contains %s",name, token) ;
            return FALSE;
      }
}


struct MeshStatusType {
  bool isvalid; // rest of this is valid, IOW I am inside reading a mesh
  char *sName;
  bool mapped;
  bool materialed_but_not_mapped; // only defined if mapped = FALSE
  bool hidden; // unused
  int maxVertex, maxFace, curVertex, curFace;
  void set_sName(char *s);
  // material + smoothing is per poly!!!
} MeshStatus;


void MeshStatusType::set_sName(char *s)
{
  if(sName)
    delete [] sName;
  sName = new char[strlen(s)+1];
  strcpy(sName, s);
}

void CheckIndex(int &i, int max)
{
  if((i<0) || (i>=max))
  { fprintf(stderr, "Mesh '%s': Index %d is not in the range 0 to %d!", MeshStatus.sName, i, max);
    i = 0;
  }
}
 
void CheckWhetherMeshHasEnded();
static int HandleMeshMaterialList(const char *firstToken);
static int HandleMaterialOld(const char *firstToken);
static int HandleTextureFileName(const char *firstToken);

static int HandleAmbient();
static int HandleSolid();
static int HandleNamed();
static int HandleTriMesh();
static int HandleHidden();
static int HandleMapped();
static int HandleVertex();
static int HandleFace();
static int HandleMaterial();
static int HandleSmoothing();
static int HandleDirect();
static int HandlePosition();
static int HandleLight();
static int HandleSpotlight();
static int HandleHotspot ();
static int HandleFalloff ();
static int HandleGlobal ();
// unneeded static int HandleCamera();
static int HandleTarget();
static int HandleBank();
static int HandleNear();

static AscEntityType aEntities[] =
{
  { "Spotlight", HandleSpotlight, FALSE},
  { "Hotspot", HandleHotspot , FALSE},
  { "Falloff", HandleFalloff , FALSE},
  { "Global", HandleGlobal , FALSE},
// unneeded   { "Camera", HandleCamera, FALSE},
  { "Target", HandleTarget, FALSE},
  { "Bank", HandleBank, FALSE},
  { "Near", HandleNear, FALSE},
  { "Ambient", HandleAmbient, FALSE},
  { "Solid", HandleSolid, FALSE},
  { "Named", HandleNamed, FALSE},
  { "Tri-mesh,", HandleTriMesh, TRUE},
  { "Hidden", HandleHidden, TRUE},
  { "Mapped", HandleMapped, TRUE},
  { "Vertex", HandleVertex, TRUE},
  { "Face", HandleFace, TRUE},
  { "Material", HandleMaterial, TRUE},
  { "Smoothing", HandleSmoothing},
  { "Direct", HandleDirect, FALSE},
  { "Position", HandlePosition, FALSE},
  { "Light", HandleLight, FALSE},
  { NULL, NULL}
};


static int ParseEntity(char *token)
// called recursively
// copied from ssgLoadX; A bit (?) of overkill for *.asc.
{ int i=0;

      while(aEntities[i].sName!=NULL)
      { if (!strcmp(token,aEntities[i].sName))
            {     if (aEntities[i].HandleEntity != NULL)
                  {     /*char *sNextToken, *sName=globEmpty;
                        sNextToken=parser.getNextToken(0);
                        if ( parser.eof ) 
                        { parser.error("unexpected end of file\n");
                              return FALSE;
                        }*/
        if(!aEntities[i].appearsInsideAMesh)  
          CheckWhetherMeshHasEnded();
                        if (!aEntities[i].HandleEntity(/*sNextToken*/))
                              return FALSE;
                  }
                  else
                  {
                        parser.error("I am sorry, but Entity-type '%s' is not yet implemented.", aEntities[i].sName);
                        return FALSE ;
                  }
                        
                  break;
            }
            i++;
      }
      if (aEntities[i].sName==NULL)
      {
            parser.error("unexpected token %s", token);
            return FALSE ;
      }
      return TRUE;
}

#define MAX_ASC_MATERIALS 1024

struct AscMaterialType {
  char *sName;
  ssgSimpleState *ss;  
} AscMaterials[MAX_ASC_MATERIALS];
static int noOfAscmaterials=0;


#define MAX_NO_VERTICES_PER_FACE 1000

static class ssgLoaderWriterMesh currentMesh;

static ssgSimpleState *currentState;

// we only need one of these, since obviously the texture name is the only materialproperty in asc:
static ssgSimpleState *untexturedState = NULL; 

extern sgVec4 currentDiffuse;


static int HandleDirect()
// example line:
// "Direct light"
{
  parser.expectNextToken("light");
      return TRUE;
}
/* not needed since handled via the PreProcessor
static int HandleCamera()
// example line:
// Camera (51.944435mm)
{
  float Dummy;
  parser.expectNextToken("(");
      if (!parser.getNextFloat(Dummy, "Camera")) return FALSE;
      parser.expectNextToken("mm)");
      return TRUE;
}
*/
static int HandleTarget()
// example line:
// Target:  X:7.573029 Y:-989.009766 Z:6.24827()
{
  float Dummy;
  parser.expectNextToken(":");
      parser.expectNextToken("X");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Target X")) return FALSE;
      parser.expectNextToken("Y");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Target Y")) return FALSE;
      parser.expectNextToken("Z");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Target Z")) return FALSE;
      return TRUE;
}

static int HandleBank()
// example line:
// Bank angle: 0 degrees
{
  float Dummy;
  parser.expectNextToken("angle");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Bank angle")) return FALSE;
      parser.expectNextToken("degrees");
      return TRUE;
}

static int HandleNear()
// example line:
// Near 0 Far 1000
{
  float Dummy;
  if (!parser.getNextFloat(Dummy, "Near")) return FALSE;
      parser.expectNextToken("Far");
      if (!parser.getNextFloat(Dummy, "Far")) return FALSE;
      return TRUE;
}

static int HandlePosition()
// example line:
// "Position:  X:-534.261475 Y:484.437958 Z:203.464706"
{
  float Dummy;
  parser.expectNextToken(":");
      parser.expectNextToken("X");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "light X")) return FALSE;
      parser.expectNextToken("Y");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "light Y")) return FALSE;
      parser.expectNextToken("Z");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "light Z")) return FALSE;
      return TRUE;

}

static int HandleSpotlight()
// example line:
// "Spotlight to:  X:-1.4 Y:-0.607239 Z:-16.277397"
{
 float Dummy;
  parser.expectNextToken("to");
      parser.expectNextToken(":");
      parser.expectNextToken("X");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Spotlight to X")) return FALSE;
      parser.expectNextToken("Y");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Spotlight to Y")) return FALSE;
      parser.expectNextToken("Z");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Spotlight to Z")) return FALSE;
      return TRUE;
}

static int HandleHotspot ()
// example line:
// "Hotspot size: 54 degrees"
{
  float Dummy;
  parser.expectNextToken("size");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Hotspot size")) return FALSE;
      parser.expectNextToken("degrees");
      return TRUE;
}

static int HandleFalloff ()
// example line:
// "Falloff size: 54.5 degrees"
{
  float Dummy;
  parser.expectNextToken("size");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(Dummy, "Falloff size")) return FALSE;
      parser.expectNextToken("degrees");
      return TRUE;
}

static int HandleGlobal ()
// example line:
// "Global Shadow"
{
  parser.expectNextToken("Shadow");
      return TRUE;
}


static int HandleLight()
// example line:
// "Light color: Red=1 Green=1 Blue=1"
{
  float Dummy;
  parser.expectNextToken("color");
      parser.expectNextToken(":");
      parser.expectNextToken("Red");
      parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Light red")) return FALSE;
      parser.expectNextToken("Green");
      parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Light Green")) return FALSE;
      parser.expectNextToken("Blue");
      parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Light Blue")) return FALSE;
      return TRUE;
}



static int HandleAmbient()
// example line:
// "Ambient light color: Red=0.180392 Green=0.180392 Blue=0.180392"
{
  float Dummy;
      parser.expectNextToken("light");
      parser.expectNextToken("color");
  parser.expectNextToken(":");
      parser.expectNextToken("Red");
  parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Ambient red")) return FALSE;
      parser.expectNextToken("Green");
  parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Ambient green")) return FALSE;
      parser.expectNextToken("Blue");
  parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Ambient blue")) return FALSE;
      return TRUE;
}

static int HandleSolid()
// example line:
// "Solid background color: Red=0.345098 Green=0.6 Blue=0.807843"
{
  parser.expectNextToken("background");
      parser.expectNextToken("color");
  parser.expectNextToken(":");
      parser.expectNextToken("Red");
  parser.expectNextToken("=");
  float Dummy;
      if (!parser.getNextFloat(Dummy, "Background red")) return FALSE;
      parser.expectNextToken("Green");
  parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Background green")) return FALSE;
      parser.expectNextToken("Blue");
  parser.expectNextToken("=");
      if (!parser.getNextFloat(Dummy, "Background blue")) return FALSE;
      return TRUE;
}

static int HandleNamed()
// example line:
// "Named object: "EX1_A""
{
  parser.expectNextToken("object");
  parser.expectNextToken(":");
//  assert(MeshStatus.isvalid); comes before trimesh !
  char *s; // cleaned up sName
  s = parser.getNextToken("Mesh name");
  if(*s=='"')
    s++;
  if(s[strlen(s)-1]=='"')
    s[strlen(s)-1]=0;

  MeshStatus.set_sName(s);

      return TRUE;
}

static int HandleTriMesh()
// example line:
// "Tri-mesh, Vertices: 22     Faces: 18"
{
  parser.expectNextToken("Vertices");
  parser.expectNextToken(":");
  if (!parser.getNextInt(MeshStatus.maxVertex, "Number vertices")) return FALSE;
      parser.expectNextToken("Faces");
  parser.expectNextToken(":");
  if (!parser.getNextInt(MeshStatus.maxFace, "Number faces")) return FALSE;
  if(MeshStatus.isvalid)
  {
    fprintf(stderr, "MeshStatus.isvalid is TRUE. Probably, in the mesh preceding '%s', there are more faces than predicted", MeshStatus.sName);
    return FALSE;
  }
  MeshStatus.isvalid = TRUE;
  MeshStatus.curVertex = -1;
  MeshStatus.curFace = -1;
  MeshStatus.mapped = FALSE;
  MeshStatus.materialed_but_not_mapped = FALSE;
  MeshStatus.hidden = FALSE; // unused
  noOfAscmaterials=0;
  currentState = untexturedState; 

  
      currentMesh.reInit ();
      currentMesh.setName( MeshStatus.sName );
      currentMesh.createVertices( MeshStatus.maxVertex );
  currentMesh.createFaces( MeshStatus.maxFace );

      return TRUE;
}

static int HandleHidden()
// example line:
// "Hidden"
{
  assert(MeshStatus.isvalid);
  MeshStatus.hidden = TRUE; // unused
  return TRUE;
}

static int HandleMapped()
// example line:
// "Mapped"
{
  assert(MeshStatus.isvalid);
      currentMesh.createPerVertexTextureCoordinates2( MeshStatus.maxVertex ) ;
  currentMesh.createMaterials();
  currentMesh.createMaterialIndices( MeshStatus.maxFace );
  MeshStatus.mapped = TRUE; 
      return TRUE;
}

static int HandleSmoothing()
// example line:
// "Smoothing:  1"
{
  int i;
  parser.expectNextToken(":");
      if (!parser.getNextInt(i, "Smoothing")) return FALSE;
      return TRUE;      
}


int SetOrGetMaterial(char *sMatName)
// if exists, gets the index. Else sets sName and creates the ss
{
  char *s; // cleaned up sName
  s = sMatName;
  if(*s=='"')
    s++;
  if(s[strlen(s)-1]=='"')
    s[strlen(s)-1]=0;
  // **** search for it ****
  for(int i=0; i<noOfAscmaterials; i++)
    if(ulStrEqual(s, AscMaterials[i].sName))
      return i;
  // **** not found - create it ****
  AscMaterials[noOfAscmaterials].sName = new char[strlen(s)+1];
  strcpy(AscMaterials[noOfAscmaterials].sName, s);
  AscMaterials[noOfAscmaterials++].ss = currentState  = new ssgSimpleState () ;
  // set "defaults"
      currentState->setOpaque();
      currentState->disable(GL_BLEND);
      currentState->disable(GL_ALPHA_TEST);
      currentState->disable(GL_TEXTURE_2D);
      currentState->enable(GL_COLOR_MATERIAL);
      currentState->enable(GL_LIGHTING);
      currentState->setShadeModel(GL_SMOOTH);
      currentState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f);
      currentState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f);
      currentState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f);
      currentState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f);
      currentState->setShininess(50);
  // set texture
  currentState -> setTexture( current_options -> createTexture( s ) );
  currentState -> setName(s);
  currentState -> enable( GL_TEXTURE_2D );
  currentMesh.addMaterial(&currentState);
  return noOfAscmaterials-1;
}


static int HandleMaterial()
// example line:
// "Material:"BEXHUST""
{
  parser.expectNextToken(":");
  if(!MeshStatus.mapped && !MeshStatus.materialed_but_not_mapped)
  {
    currentMesh.createMaterials();
    currentMesh.createMaterialIndices( MeshStatus.maxFace );
    MeshStatus.materialed_but_not_mapped = TRUE;
  }


      char *sMaterialName = parser.getNextToken("Material name");
  int i = SetOrGetMaterial(sMaterialName);
  currentMesh.addMaterialIndex(i);

      return TRUE;
}

static int HandleVertex()
// example line:
// "Vertex list:"
// *or* (!!)
// "Vertex 0:  X:115.710701     Y:180.000305     Z:-60.796242     U:0.048042     V:0.996284"
{
  char *sNextToken = parser.peekAtNextToken( "vertex list?" );
  if(ulStrEqual("list", sNextToken))
  {
    parser.expectNextToken("list");
    parser.expectNextToken(":");
  }
  else
  {
    sgVec3 vert;
    int i;
    if (!parser.getNextInt(i, "vertex index")) return FALSE;
    assert(MeshStatus.isvalid);
    assert(MeshStatus.maxVertex > i);
    assert(MeshStatus.curVertex == i-1);
    MeshStatus.curVertex ++;
    parser.expectNextToken(":");
    parser.expectNextToken("X");
    parser.expectNextToken(":");
        if (!parser.getNextFloat(vert[0], "X")) return FALSE;
    parser.expectNextToken("Y");
    parser.expectNextToken(":");
    if (!parser.getNextFloat(vert[1], "Y")) return FALSE;
    parser.expectNextToken("Z");
    parser.expectNextToken(":");
    if (!parser.getNextFloat(vert[2], "Z")) return FALSE;
    if(MeshStatus.mapped)
    {
      // read texture coordinates    
              sgVec2 tv;
      parser.expectNextToken("U");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(tv[0], "U")) return FALSE;
      parser.expectNextToken("V");
      parser.expectNextToken(":");
      if (!parser.getNextFloat(tv[1], "V")) return FALSE;
              currentMesh.addPerVertexTextureCoordinate2( tv ) ;
    }
            currentMesh.addVertex(vert);
  }
            
      return TRUE;  
}

static int HandleFace()
// example line:
// "Face list:"
// *or* (!!)
// "Face 0:    A:0 B:10 C:7 AB:1 BC:1 CA:1"
{
  char *sNextToken = parser.peekAtNextToken( "Face list?" );
  if(ulStrEqual("list", sNextToken))
  {
    parser.expectNextToken("list");
    parser.expectNextToken(":");
  }
  else
  {
    int iFace, AB, _BC, CA;
    int aiVertices[3];
        if (!parser.getNextInt(iFace, "Face index")) return FALSE;
    assert(MeshStatus.isvalid);
    assert(MeshStatus.maxFace > iFace);
    assert(MeshStatus.curFace == iFace-1);
    MeshStatus.curFace ++;
    parser.expectNextToken(":");
    parser.expectNextToken("A");
    parser.expectNextToken(":");
        if (!parser.getNextInt(aiVertices[0], "A")) return FALSE;
    CheckIndex(aiVertices[0], MeshStatus.maxVertex);
    parser.expectNextToken("B");
    parser.expectNextToken(":");
        if (!parser.getNextInt(aiVertices[1], "B")) return FALSE;
    CheckIndex(aiVertices[1], MeshStatus.maxVertex);
    parser.expectNextToken("C");
    parser.expectNextToken(":");
        if (!parser.getNextInt(aiVertices[2], "C")) return FALSE;
    CheckIndex(aiVertices[2], MeshStatus.maxVertex); 
    parser.expectNextToken("AB");
    parser.expectNextToken(":");
        if (!parser.getNextInt(AB, "AB")) return FALSE;
    parser.expectNextToken("BC");
    parser.expectNextToken(":");
        if (!parser.getNextInt(_BC, "BC")) return FALSE; // "BC" is already used :-/
    parser.expectNextToken("CA");
    parser.expectNextToken(":");
        if (!parser.getNextInt(CA, "CA")) return FALSE;
    currentMesh.addFaceFromIntegerArray(3, aiVertices); 
  }
  return TRUE;
}


// end todo ##############################################################



/////////////////////////////////////////////////// old
// start alt todo ##############################################################




static int HandleTextureFileName(const char *firstToken)
{/*
        TextureFilename {
    "../image/box_top.gif";
   } #TextureFilename
 */
  char *filename_ptr, *filename = new char [ strlen(firstToken)+1 ] ;
      assert(filename!=NULL);
  strcpy ( filename, firstToken ) ;
      filename_ptr = filename ;
      
      if ( filename_ptr[0] == '"' ) 
            filename_ptr++;
      if (filename_ptr[strlen(filename_ptr)-1] == '"')
            filename_ptr[strlen(filename_ptr)-1] = 0;
  currentState -> setTexture( current_options -> createTexture( filename_ptr ) );
  currentState -> enable( GL_TEXTURE_2D );


      parser.expectNextToken(";");
      parser.expectNextToken("}");
      delete [] filename;
      return TRUE;
}

static int HandleMaterialOld(const char *firstToken)
// return TRUE on success
{ SGfloat power;
  int bFoundTextureFileName = FALSE;
      sgVec4 specularColour, EmissiveColour;

      // read body
      if (! Ascii2Float(currentDiffuse[0], firstToken, "Facecolour R"))
            return FALSE;

      parser.expectNextToken(";");
      if (!parser.getNextFloat(currentDiffuse[1], "Facecolour G")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(currentDiffuse[2], "Facecolour B")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(currentDiffuse[3], "Facecolour A")) return FALSE;
      parser.expectNextToken(";");
      parser.expectNextToken(";");
      if (!parser.getNextFloat(power, "power")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(specularColour[0], "Specular R")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(specularColour[1], "Specular G")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(specularColour[2], "Specular B")) return FALSE;
      specularColour[3] = 0.0;
      parser.expectNextToken(";");
      parser.expectNextToken(";");
      if (!parser.getNextFloat(EmissiveColour[0], "Emissive R")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(EmissiveColour[1], "Emissive G")) return FALSE;
      parser.expectNextToken(";");
      if (!parser.getNextFloat(EmissiveColour[2], "Emissive B")) return FALSE;
      EmissiveColour[3] = 0.0;
      parser.expectNextToken(";");
      parser.expectNextToken(";");

      // create SimpleState

  currentState = new ssgSimpleState () ;

//  currentState -> setMaterial ( GL_AMBIENT, mat -> amb ) ;
  currentState -> setMaterial ( GL_DIFFUSE, currentDiffuse) ;
  currentState -> setMaterial ( GL_SPECULAR, specularColour) ;
  currentState -> setMaterial ( GL_SPECULAR, specularColour[0], 
                                  specularColour[1], specularColour[2], currentDiffuse[3] ) ;
  currentState -> setMaterial ( GL_EMISSION, EmissiveColour[0], 
                                  EmissiveColour[1], EmissiveColour[2], currentDiffuse[3] ) ;
      
      currentState -> setShininess ( power ) ; // Fixme, NIV14: Is that correct?

  currentState -> enable ( GL_COLOR_MATERIAL ) ;
  currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;

  currentState -> enable  ( GL_LIGHTING       ) ;
  currentState -> setShadeModel ( GL_SMOOTH ) ;

  if ( currentDiffuse[3] > 0.0f )
  {
    currentState -> disable ( GL_ALPHA_TEST ) ;
    currentState -> enable  ( GL_BLEND ) ;
    currentState -> setTranslucent () ;
  }
  else
  {
    currentState -> disable ( GL_BLEND ) ;
    currentState -> setOpaque () ;
  }
  currentState -> disable( GL_TEXTURE_2D );



      while(TRUE)
      { char *nextToken =parser.getNextToken(0);
        if (0==strcmp("}", nextToken))
            { currentMesh.addMaterial( &currentState );
                  return TRUE; // Material is finished. success
            }
            
            if ( 0!= strcmp("TextureFilename", nextToken) )
            { parser.error("TextureFilename expected!\n");
                  return FALSE; 
            }
            if ( bFoundTextureFileName )
            { parser.error("Only one TextureFileName per Material please!\n");
                  return FALSE; 
            }
            if (!ParseEntity(nextToken)) // read "TextureFileName"
                  return FALSE;
            bFoundTextureFileName = TRUE;
      }
      return TRUE; //lint !e527
}


static int HandleMeshMaterialList(const char *firstToken)
{
      u32 i, nFaceIndexes, nMaterialsRead = 0, nMaterials;
        
      if (! Ascii2UInt(nMaterials, firstToken, "nMaterials"))
            return FALSE;

      parser.expectNextToken(";");
      currentMesh.createMaterials( nMaterials );
      if (!parser.getNextUInt(nFaceIndexes, "number of Face Indexes"))
            return FALSE;
      currentMesh.createMaterialIndices( nFaceIndexes ) ;
      parser.expectNextToken(";");


      if ( nFaceIndexes > currentMesh.getNumFaces())
      { parser.error("No of face indexes of materiallist (%d) is greater than then no "
                  "of faces (%d)!\n" 
                                          "Therefore the material list is ignored!",
                                          ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces());
        return TRUE; // go on parsing
      }
      if ( nFaceIndexes > currentMesh.getNumFaces())
        parser.message("Informational: No of face indexes of materiallist (%d) is less than then no "
                  "of faces (%d)\n" ,
                                          ( int ) nFaceIndexes, ( int ) currentMesh.getNumFaces());
      for ( i=0 ; i<nFaceIndexes ; i++ )
      {
            int iIndex, j;
            char *ptr;
            if (!parser.getNextInt(iIndex, "Face index"))
                  return FALSE;
            currentMesh.addMaterialIndex ( iIndex ) ;
            // I don't quite know why, but different .X files I have have a 
            // different syntax here, some have one ";" and some two.
            // Therefore, the following code
            for (j=0;j<2;j++)
            { ptr = parser.peekAtNextToken( "," );
              if ( strlen(ptr) == 1)
                        if ( (ptr[0]==',') || (ptr[0]==';') )
                        { ptr = parser.getNextToken( "," ); // ignore this token
                        }
  
            }
      }
      while(TRUE)
      { char *nextToken =parser.getNextToken(0);
        if (0==strcmp("}", nextToken))
            { if ( nMaterialsRead < nMaterials )
                parser.error("Too few Materials!\n");
                  //else      parser.error("Success! MeshMaterialList!\n");
                  return TRUE; // Mesh is finished. success
            }
            if ( 0!= strcmp("Material", nextToken) )
            { parser.error("Material expected!\n");
                  return FALSE; 
            }
            if ( nMaterialsRead >= nMaterials )
            { parser.error("Too many Materials!\n");
                  return FALSE; 
            }
            if (!ParseEntity(nextToken)) // read "Material"
                  return FALSE;
            nMaterialsRead++;
      }
      return TRUE; //lint !e527
}



// end alt todo ##############################################################

void CheckWhetherMeshHasEnded()   
{ if(MeshStatus.isvalid &&
     (MeshStatus.curFace == MeshStatus.maxFace-1) &&
     (MeshStatus.curVertex == MeshStatus.maxVertex-1))
  {
    // end mesh PART FROM MATREEIAL AND SMOOTH
    //u32 i, j, nNoOfVertices, nNoOfVerticesForThisFace, nNoOfFaces;
       
        
        if ( currentState == NULL )
        {   currentState = new ssgSimpleState();
          currentState->setOpaque();
              currentState->disable(GL_BLEND);
              currentState->disable(GL_ALPHA_TEST);
              currentState->disable(GL_TEXTURE_2D);
              currentState->enable(GL_COLOR_MATERIAL);
              currentState->enable(GL_LIGHTING);
              currentState->setShadeModel(GL_SMOOTH);
              currentState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f);
              currentState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f);
              currentState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f);
              currentState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f);
              currentState->setShininess(50);
  /*
              currentState -> setMaterial ( GL_AMBIENT, 0.5, 0.5, 0.5);
        currentState -> setMaterial ( GL_DIFFUSE,  0.7, 0.7, 0.7); // light grey
              currentState -> setMaterial ( GL_SPECULAR, 1.0, 1.0, 1.0);
              currentState -> setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0);
              
              currentState -> setShininess ( 3 ) ; 

              //currentState -> enable ( GL_COLOR_MATERIAL ) ;
              //currentState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;

              currentState -> enable  ( GL_LIGHTING       ) ;
              currentState -> setShadeModel ( GL_SMOOTH ) ;

              currentState -> disable ( GL_BLEND ) ;
              currentState -> setOpaque () ;
              currentState -> disable( GL_TEXTURE_2D );
              */
        }

        currentMesh.addToSSG(
              currentState // Pfusch, kludge. NIV135
              ,
              current_options,
              curr_branch_);
    MeshStatus.isvalid = FALSE;
  }
}

static int parse()
{
  char* token;
  token = parser.getNextToken(0); // getNextToken -> line structure is ignored (IOW line ends are ignored)
  while (! parser.eof )
      { 
            if (!ParseEntity(token))
              return FALSE;
            
            token = parser.getNextToken(0);
      }
  CheckWhetherMeshHasEnded();
  return TRUE ;
}


ssgEntity *ssgLoadASC ( const char *fname, const ssgLoaderOptions* options )
{
  ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ;
  current_options = ssgGetCurrentOptions () ;


  MeshStatus.isvalid=FALSE;
  MeshStatus.sName = NULL;


  untexturedState = new ssgSimpleState;
      untexturedState->setOpaque();
      untexturedState->disable(GL_BLEND);
      untexturedState->disable(GL_ALPHA_TEST);
      untexturedState->disable(GL_TEXTURE_2D);
      untexturedState->enable(GL_COLOR_MATERIAL);
      untexturedState->enable(GL_LIGHTING);
      untexturedState->setShadeModel(GL_SMOOTH);
      untexturedState->setMaterial(GL_AMBIENT , 0.7f, 0.7f, 0.7f, 1.0f);
      untexturedState->setMaterial(GL_DIFFUSE , 0.7f, 0.7f, 0.7f, 1.0f);
      untexturedState->setMaterial(GL_SPECULAR, 1.0f, 1.0f, 1.0f, 1.0f);
      untexturedState->setMaterial(GL_EMISSION, 0.0f, 0.0f, 0.0f, 1.0f);
      untexturedState->setShininess(50);
  untexturedState->ref();

  currentState = untexturedState; 
  top_branch = new ssgBranch ;
      curr_branch_ = top_branch;
      if ( !parser.openFile( fname, &parser_spec ))
      {
    delete top_branch ;
            return 0;
  }
  if ( !parse() )
  {
            delete top_branch ;
            top_branch = 0 ;
  }
//  parse_free();
  parser.closeFile();

  untexturedState->deRef();
  if(untexturedState->getRef()==0)
    delete untexturedState;
  return top_branch ;
}

Generated by  Doxygen 1.6.0   Back to index