Back to index

extremetuxracer  0.5beta
Public Member Functions | Private Member Functions | Private Attributes
pp::ModelAC Class Reference

#include <model_ac.h>

Collaboration diagram for pp::ModelAC:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ModelAC (const char *fileName)
pp::ModelObjectgetModel ()
int getDisplayList ()

Private Member Functions

int loadTexture (const char *fileName)
void prepareRender ()
void render (ModelObject *ob)
void setColor (long matno)
void setSimpleColor (long matno)
int stringToObjectType (std::string &string)
ModelObjectloadObject (FILE *f, ModelObject *parent)
void objectCalculateVertexNormals (ModelObject *ob)
void calculateVertexNormals (ModelObject *ob)
int getTokens (char *s, int *argc, char *argv[])
 bung '\0' chars at the end of tokens and set up the array (tokv) and count (tokc) like argv argc
pp::MaterialgetMaterialFromPalette (int id)
bool readLine (FILE *f)
SurfacereadSurface (FILE *f, Surface *s, ModelObject *ob)
void CalculateTriNormal (pp::Vec3d *v1, pp::Vec3d *v2, pp::Vec3d *v3, pp::Vec3d *n)

Private Attributes

pp::ModelObjectmp_model
int m_tokc
char * ma_tokv [30]
int m_line
char ma_buff [255]
pp::Material ma_palette [255]
int m_numPalette
int m_startMatIndex

Detailed Description

Definition at line 95 of file model_ac.h.


Constructor & Destructor Documentation

pp::ModelAC::ModelAC ( const char *  fileName)

Definition at line 107 of file model_ac.cpp.

 : mp_model(NULL),
   m_tokc(0),
   m_line(0),
   m_numPalette(0),
   m_startMatIndex(0)
{
    FILE *f = fopen(fileName, "r");
   
    if (f == NULL){
              printf("can't open %s\n", fileName);
              return;
    }

    readLine(f);

    if (strncmp(ma_buff, "AC3D", 4)){
              printf("ac_load_ac '%s' is not a valid AC3D file.", fileName);
              fclose(f);
              return;
    }
    m_startMatIndex = m_numPalette;
    mp_model = loadObject(f, NULL);
    fclose(f);
    calculateVertexNormals(mp_model);     
}

Here is the call graph for this function:


Member Function Documentation

void pp::ModelAC::CalculateTriNormal ( pp::Vec3d v1,
pp::Vec3d v2,
pp::Vec3d v3,
pp::Vec3d n 
) [private]

Definition at line 660 of file model_ac.cpp.

{
    double len;

    n->x = (v2->y-v1->y)*(v3->z-v1->z)-(v3->y-v1->y)*(v2->z-v1->z);
    n->y = (v2->z-v1->z)*(v3->x-v1->x)-(v3->z-v1->z)*(v2->x-v1->x);
    n->z = (v2->x-v1->x)*(v3->y-v1->y)-(v3->x-v1->x)*(v2->y-v1->y);
    len = sqrt(n->x*n->x + n->y*n->y + n->z*n->z);

    if (len > 0)
    {
              n->x /= len;
              n->y /= len;
              n->z /= len;  
    }
}

Here is the caller graph for this function:

Definition at line 533 of file model_ac.cpp.

{
    int n;
    objectCalculateVertexNormals(ob);
    if (ob->num_kids)
       for (n = 0; n < ob->num_kids; n++)
           calculateVertexNormals(ob->kids[n]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 135 of file model_ac.cpp.

{
       int list;
    list = glGenLists(1);
    glNewList(list,GL_COMPILE);
       render(mp_model);
    glEndList();
    return(list);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 588 of file model_ac.cpp.

{
    return(&ma_palette[id]);
}

Here is the caller graph for this function:

Definition at line 127 of file model_ac.h.

{return mp_model;}

Here is the caller graph for this function:

int pp::ModelAC::getTokens ( char *  s,
int *  argc,
char *  argv[] 
) [private]

bung '\0' chars at the end of tokens and set up the array (tokv) and count (tokc) like argv argc

Definition at line 543 of file model_ac.cpp.

{
    char *p = s;
    char *st;
    char c;
    //int n;
    int tc;

    tc = 0;
    while ((c=*p) != 0)
    {
       if ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13))
       {
           if (c == '"')
           {
              c = *p++;
              st = p;
              while ((c = *p) && ((c != '"')&&(c != '\n')&& ( c != 13)) )
              {
                  if (c == '\\')
                     strcpy(p, p+1);
                  p++;
              }
              *p=0;
              argv[tc++] = st;
           }
           else
           {
              st = p;
              while ((c = *p) && ((c != ' ') && (c != '\t') && (c != '\n') && ( c != 13)) )
                  p++;
              *p=0;
              argv[tc++] = st;
           }                
       }
       p++;
    }

    *argc = tc;
    return(tc);
}

Here is the caller graph for this function:

ModelObject * pp::ModelAC::loadObject ( FILE *  f,
ModelObject parent 
) [private]

Definition at line 315 of file model_ac.cpp.

{
    char t[20];
       std::string type;
    ModelObject *ob = NULL;

    while (!feof(f))
    {
       readLine(f);

       sscanf(ma_buff, "%s", t);
       type = t;

       if (type=="MATERIAL"){
        double shi, tran;
        Material m;
           
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 22){
            printf("expected 21 params after \"MATERIAL\" - line %d\n", m_line);
           } else {
                     m.name = ma_tokv[1];
                     m.diffuse.r = atof(ma_tokv[3]);
                     m.diffuse.g = atof(ma_tokv[4]);
                     m.diffuse.b = atof(ma_tokv[5]);

                     m.ambient.r = atof(ma_tokv[7]);
                     m.ambient.g = atof(ma_tokv[8]);
                     m.ambient.b = atof(ma_tokv[9]);

                     m.emissive.r = atof(ma_tokv[11]);
                     m.emissive.g = atof(ma_tokv[12]);
                     m.emissive.b = atof(ma_tokv[13]);

                     m.specular.r = atof(ma_tokv[15]);
                     m.specular.g = atof(ma_tokv[16]);
                     m.specular.b = atof(ma_tokv[17]);

                     m.shininess = atof(ma_tokv[19]);
                     m.transparency = atof(ma_tokv[21]);
       
                     shi = atof(ma_tokv[6]);
                     tran = atof(ma_tokv[7]);

                     ma_palette[m_numPalette++] = m;
           }
       } else if (type=="OBJECT"){
              char type[20];
              char str[20];
              ob = new ModelObject;

              sscanf(ma_buff, "%s %s", str, type);
              
              std::string t(type);
              
              ob->type = stringToObjectType(t);
       } else if (type=="data"){
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 2){
                     printf("expected 'data <number>' at line %d\n", m_line);
              } else {
                     char *str;
                     int len;

                     len = atoi(ma_tokv[1]);
                     if (len > 0){
                         str = (char *)malloc(len+1);
                         fread(str, len, 1, f);
                         str[len] = 0;
                         fscanf(f, "\n"); m_line++;
                         ob->data = str;
                         free(str);
                     }
              }
       } else if (type=="name"){
              int numtok = getTokens(ma_buff, &m_tokc, ma_tokv);
              if (numtok != 2){
                     printf("expected quoted name at line %d (got %d tokens)\n", m_line, numtok);
              } else {
                     ob->name = ma_tokv[1];
              }
       } else if (type=="texture"){
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 2){
                     printf("expected quoted texture name at line %d\n", m_line);
              } else {
                     ob->texture = loadTexture(ma_tokv[1]);
              }
       } else if (type=="texrep"){
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 3){
                     printf("expected 'texrep <float> <float>' at line %d\n", m_line);
              } else {
                  ob->texture_repeat_x = atof(ma_tokv[1]);
                  ob->texture_repeat_y = atof(ma_tokv[2]);
              }
       } else if (type=="texoff"){
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 3){
                     printf("expected 'texoff <float> <float>' at line %d\n", m_line);
              } else {
                     ob->texture_offset_x = atof(ma_tokv[1]);
                     ob->texture_offset_y = atof(ma_tokv[2]);
              }
       } else if (type=="rot"){
              double r[9];
              char str2[5];
              int n;

              sscanf(ma_buff, "%s %lf %lf %lf %lf %lf %lf %lf %lf %lf", str2, 
                                   &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] );

              for (n = 0; n < 9; n++){
                     ob->matrix[n] = r[n];
              }
       } else if (type=="loc"){
              char str[5];
              sscanf(ma_buff, "%s %lf %lf %lf", str,
                        &ob->loc.x, &ob->loc.y, &ob->loc.z);                 
       } else if (type=="url"){
              if (getTokens(ma_buff, &m_tokc, ma_tokv) != 2){
                  printf("expected one arg to url at line %d (got %s)\n", m_line, ma_tokv[0]);
              } else {
                     ob->url = ma_tokv[1];
              }
       } else if (type=="numvert"){
              int num, n;
              char str[10];

              sscanf(ma_buff, "%s %d", str, &num);

              if (num > 0){
                     ob->num_vert = num;
                     ob->vertices = new pp::Vertex[num];
                     for (n = 0; n < num; n++){
                            pp::Vertex p;
                            fscanf(f, "%lf %lf %lf\n", &p.vec.x, &p.vec.y, &p.vec.z); m_line++;
                            ob->vertices[n] = p;
                     }

              }
       } else if (type=="numsurf"){
              int num, n;
              char str[10];

              sscanf(ma_buff, "%s %d", str, &num);
              if (num > 0){
                     ob->num_surf = num;
                     ob->surfaces = new Surface[num];

                     for (n = 0; n < num; n++){
                            Surface *news = readSurface(f, &ob->surfaces[n], ob);
                            if (news == NULL){
                                   printf("error whilst reading surface at line: %d\n", m_line);
                                   return(NULL);
                            }
                     }
              }
       } else if (type=="kids"){ 
              int num, n;

              sscanf(ma_buff, "%s %d", t, &num);
                     
              if (num != 0){
                     ob->kids = new ModelObject*[num];
                     ob->num_kids = num;

                     for (n = 0; n < num; n++){
                            ModelObject *k = loadObject(f, ob);

                            if (k == NULL){
                                   printf("error reading expected child object %d of %d at line: %d\n", n+1, num, m_line);
                                   return(ob);
                            } else {
                                   ob->kids[n] = k;
                            }
                     }
           }
           return(ob);
       }

    }
    return(ob);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pp::ModelAC::loadTexture ( const char *  fileName) [private]

Definition at line 146 of file model_ac.cpp.

{
    GLuint texid;
       std::string binding("ac/");
       binding+=fileName;
       
       if(!get_texture_binding( binding.c_str(), &texid )){
              load_and_bind_texture(binding.c_str(),fileName);
              get_texture_binding( binding.c_str(), &texid );
       }
       
       return texid; 
}

Here is the call graph for this function:

Here is the caller graph for this function:

for each vertex in this object

go through each surface

check if this vertex is used in this surface

if it is, use it to create an average normal

Definition at line 496 of file model_ac.cpp.

{
    int s, v, vr;

    for (v = 0; v < ob->num_vert; v++)
    {
       pp::Vec3d n;
       int found = 0;

       for (s = 0; s < ob->num_surf; s++)
       {
           Surface *surf = &ob->surfaces[s];

           for (vr = 0; vr < surf->numVertices; vr++)
              if (surf->vertices[vr] == v)
              {
                  n.x+=surf->normal.x;
                  n.y+=surf->normal.y;
                  n.z+=surf->normal.z;
                  found++;
              }
       }
       if (found > 0)
       {
           n.x /= found;
           n.y /= found;
           n.z /= found;
       }
       ob->vertices[v].normal = n;
    }
}

Here is the caller graph for this function:

void pp::ModelAC::prepareRender ( ) [private]

Definition at line 161 of file model_ac.cpp.

{

    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);

    glDisable( GL_COLOR_MATERIAL ); 

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

}
bool pp::ModelAC::readLine ( FILE *  f) [private]

Definition at line 594 of file model_ac.cpp.

{
    fgets(ma_buff, 255, f); m_line++;
    return(true);
}

Here is the caller graph for this function:

Surface * pp::ModelAC::readSurface ( FILE *  f,
Surface s,
ModelObject ob 
) [private]

Definition at line 601 of file model_ac.cpp.

{
    char t[20];
       std::string type;
       
    while (!feof(f))
    {
       readLine(f);
       sscanf(ma_buff, "%s", t);
       type = t;
              
       if (type=="SURF"){
           int flgs;

           if (getTokens(ma_buff, &m_tokc, ma_tokv) != 2){
                     printf("SURF should be followed by one flags argument\n");
        } else {
                     flgs = strtol(ma_tokv[1], NULL, 0);
                     s->flags = flgs;
              }
       } else if (type=="mat"){
              int mindx;
              sscanf(ma_buff, "%s %d", t, &mindx);
              s->mat = mindx + m_startMatIndex;
       } else if (type=="refs"){
              int num, n;
              int ind;
              double tx, ty;
  
              sscanf(ma_buff, "%s %d", t, &num);        

              s->numVertices = num;
              s->vertices = new int[num]; //(int *)malloc( num * sizeof(int));
              s->uvs = new pp::UV[num];

              for (n = 0; n < num; n++){
                     fscanf(f, "%d %lf %lf\n", &ind, &tx, &ty); m_line++;
                     s->vertices[n] = ind;
                     s->uvs[n].u = tx;
                     s->uvs[n].v = ty;
              }

              // calc surface normal
              if (s->numVertices >= 3)
              CalculateTriNormal(&ob->vertices[s->vertices[0]].vec, 
                            &ob->vertices[s->vertices[1]].vec, 
                            &ob->vertices[s->vertices[2]].vec,
                            &s->normal);

              return(s);
       } else {
              printf("ignoring %s\n", t);
       }
       
    }
    return(NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pp::ModelAC::render ( ModelObject ob) [private]

Definition at line 180 of file model_ac.cpp.

{
    int n, s, sr;
    int st;

    glPushMatrix();

    glTranslated(ob->loc.x, ob->loc.y, ob->loc.z);

    if (ob->texture != -1){
              static int lasttextureset = -1;
 
              glEnable(GL_TEXTURE_2D);

              if (ob->texture != lasttextureset){
                     glBindTexture(GL_TEXTURE_2D, ob->texture);
                     lasttextureset = ob->texture;
              }
       } else {
        glDisable(GL_TEXTURE_2D);
       }

    for (s = 0; s < ob->num_surf; s++){
              Surface *surf = &ob->surfaces[s];

              glNormal3dv((double*)&surf->normal);

              if (surf->flags & SURFACE_TWOSIDED){
                     glDisable(GL_CULL_FACE);
              } else {
                     glEnable(GL_CULL_FACE);
              }
              
              st = surf->flags & 0xf;
              if (st == SURFACE_TYPE_CLOSEDLINE){
                     glDisable(GL_LIGHTING);

                     glBegin(GL_LINE_LOOP);
                     setSimpleColor(surf->mat);
              } else if (st == SURFACE_TYPE_LINE){
                     glDisable(GL_LIGHTING);

                     glBegin(GL_LINE_STRIP);
                     setSimpleColor(surf->mat);
              } else {
                     glEnable(GL_LIGHTING);
                     setColor(surf->mat); 
                     if (surf->numVertices == 3){
                            glBegin(GL_TRIANGLE_STRIP);
                     } else {
                            glBegin(GL_POLYGON);
                     }
              }

              for (sr = 0; sr < surf->numVertices; sr++){
                     pp::Vertex *v = &ob->vertices[surf->vertices[sr]];

                     if (ob->texture > -1){
                            double tu = surf->uvs[sr].u;
                            double tv = surf->uvs[sr].v;

                            double tx = ob->texture_offset_x + tu * ob->texture_repeat_x;
                            double ty = ob->texture_offset_y + tv * ob->texture_repeat_y;

                            glTexCoord2f(tx, ty);
                     }

                     if (surf->flags & SURFACE_SHADED){
                            glNormal3dv((double *)&v->normal);
                     }
                     glVertex3dv((double *)v);
              }
              glEnd();
    }

    if (ob->num_kids){
              for (n = 0; n < ob->num_kids; n++){
              render(ob->kids[n]);
              }
       }
       
       glEnable(GL_TEXTURE_2D);
    glPopMatrix();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pp::ModelAC::setColor ( long  matno) [private]

Definition at line 266 of file model_ac.cpp.

{
    Material *m = getMaterialFromPalette(matno);
    float rgba[4];
    static int lastcolset = -1;

    if (lastcolset == matno)
              return;
    else
       lastcolset = matno;

    rgba[0] = m->diffuse.r;
       rgba[1] = m->diffuse.g;
       rgba[2] = m->diffuse.b;
    rgba[3] = 1.0-m->transparency;
    
       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, rgba);
       
    if ( (1.0-m->transparency) < 1.0)
           {
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_BLEND);
              }
    else
        glDisable(GL_BLEND);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pp::ModelAC::setSimpleColor ( long  matno) [private]

Definition at line 294 of file model_ac.cpp.

{
    Material *m = getMaterialFromPalette(matno);
    glColor3dv((double*)&m->diffuse);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pp::ModelAC::stringToObjectType ( std::string &  string) [private]

Definition at line 301 of file model_ac.cpp.

{
    if (string=="world")
        return(OBJECT_WORLD);
    if (string=="poly")
        return(OBJECT_NORMAL);
    if (string=="group")
        return(OBJECT_GROUP);
    if (string=="light")
        return(OBJECT_LIGHT);
    return(OBJECT_NORMAL);
}

Here is the caller graph for this function:


Member Data Documentation

int pp::ModelAC::m_line [private]

Definition at line 102 of file model_ac.h.

Definition at line 106 of file model_ac.h.

Definition at line 107 of file model_ac.h.

int pp::ModelAC::m_tokc [private]

Definition at line 99 of file model_ac.h.

char pp::ModelAC::ma_buff[255] [private]

Definition at line 103 of file model_ac.h.

Definition at line 105 of file model_ac.h.

char* pp::ModelAC::ma_tokv[30] [private]

Definition at line 100 of file model_ac.h.

Definition at line 97 of file model_ac.h.


The documentation for this class was generated from the following files: