Hi all,

During the past days I have done some profiling on flightgear. One final 
outcome of that work was, that most time is spent in ssg routines (yes, ssg 
not OpenGL!!). The problems are the huge amount of small leaf nodes we get 
from the ac file loader. That vertex optimization pass makes this a bit 
better but there was still room for improovement.

I have now changed the ac3d file loader to first collect all surface elements 
of a leaf object and then split them to a minimum number of leaf nodes 
according to material and colour properties.

For my local setup (radeon 9100, athlon XP 2400+) this gave me a framerate 
speedup up to 40% (16 fps -> 26fps, for the c172 rendered in a window to not 
hit the ancient radeons fill rate limit). I would guess that the average 
speedup is about 25%-30%.

As a /sideeffect/ it was now easy to implement the crease tag for ac3d files.
Ac3d models look now the same as in ac3d.

Attached is a patch to todays plib anoncvs.

Is sombody there with cvs write access to plib? Can somebody apply this patch, 
please?

     Greetings

            Mathias

-- 
Mathias FrÃhlich, email: [EMAIL PROTECTED]
Index: src/ssg/ssg.h
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssg.h,v
retrieving revision 1.173
diff -u -r1.173 ssg.h
--- src/ssg/ssg.h	4 Oct 2004 18:25:59 -0000	1.173
+++ src/ssg/ssg.h	8 Oct 2004 06:02:41 -0000
@@ -1469,18 +1469,14 @@
   void getTexCoordList ( void **list ) { *list = texcoords -> get ( 0 ) ; } 
   void getColourList   ( void **list ) { *list = colours   -> get ( 0 ) ; } 
 
-  float *getVertex  (int i){ if(i>=getNumVertices())i=getNumVertices()-1;
-                             return (getNumVertices()<=0) ?
-				      _ssgVertex000 : vertices->get(i);}
-  float *getNormal  (int i){ if(i>=getNumNormals())i=getNumNormals()-1;
-			     return (getNumNormals()<=0) ?
-				    _ssgNormalUp    : normals->get(i);}
-  float *getTexCoord(int i){ if(i>=getNumTexCoords())i=getNumTexCoords()-1;
-                             return (getNumTexCoords()<=0) ?
-                                    _ssgTexCoord00  : texcoords->get(i);}
-  float *getColour  (int i){ if(i>=getNumColours())i=getNumColours()-1;
-			     return (getNumColours()<=0) ?
-				    _ssgColourWhite : colours->get(i);}
+  float *getVertex  (int i){ int nv=getNumVertices(); if(i>=nv)i=nv-1;
+                             return (nv<=0) ? _ssgVertex000:vertices->get(i);}
+  float *getNormal  (int i){ int nn=getNumNormals(); if(i>=nn)i=nn-1;
+			     return (nn<=0) ? _ssgNormalUp:normals->get(i);}
+  float *getTexCoord(int i){ int nc=getNumTexCoords(); if(i>=nc)i=nc-1;
+                             return (nc<=0) ? _ssgTexCoord00:texcoords->get(i);}
+  float *getColour  (int i){ int nc=getNumColours(); if(i>=nc)i=nc-1;
+			     return (nc<=0) ? _ssgColourWhite:colours->get(i);}
 
 	ssgVtxArray *getAs_ssgVtxArray ();
 
@@ -1586,9 +1582,8 @@
 
   void getIndexList ( void **list ) { *list = indices  -> get ( 0 ) ; }
 
-  short *getIndex  (int i){ if(i>=getNumIndices())i=getNumIndices()-1;
-                             return (getNumIndices()<=0) ?
-				      &_ssgIndex0 : indices->get(i);}
+  short *getIndex  (int i){ int ni=getNumIndices();if(i>=ni)i=ni-1;
+                             return (ni<=0) ? &_ssgIndex0 : indices->get(i);}
 
 	void removeUnusedVertices();
   virtual ~ssgVtxArray (void) ;
Index: src/ssg/ssgLoadAC.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgLoadAC.cxx,v
retrieving revision 1.34
diff -u -r1.34 ssgLoadAC.cxx
--- src/ssg/ssgLoadAC.cxx	2 Oct 2004 12:12:28 -0000	1.34
+++ src/ssg/ssgLoadAC.cxx	8 Oct 2004 06:02:42 -0000
@@ -23,6 +23,7 @@
 
 
 #include "ssgLocal.h"
+#include "ssgVertSplitter.h"
 
 static FILE *loader_fd ;
 
@@ -35,14 +36,18 @@
 } ;
 
 static int num_materials = 0 ;
-static sgVec3 *vtab = NULL ;
 
-static ssgLoaderOptions* current_options = NULL ;
-static _ssgMaterial    *current_material = NULL ;
-static sgVec4          *current_colour   = NULL ;
-static ssgBranch       *current_branch   = NULL ;
-static char            *current_tfname   = NULL ;
-static char            *current_data     = NULL ;
+static ssgLoaderOptions *current_options        = NULL ;
+static int               current_materialind    = 0 ;
+static ssgBranch        *current_branch         = NULL ;
+static ssgVertexArray   *current_vertexarray    = NULL ;
+static ssgTexCoordArray *current_texcoordarray  = NULL ;
+static ssgIndexArray    *current_triindexarray  = NULL ;
+static ssgIndexArray    *current_matindexarray  = NULL ;
+static ssgIndexArray    *current_flagsarray     = NULL ;
+static char             *current_tfname         = NULL ;
+static char             *current_data           = NULL ;
+static float             current_crease         = 61.0 ;
 
 #define MAX_MATERIALS 1000    /* This *ought* to be enough! */
 static _ssgMaterial   *mlist    [ MAX_MATERIALS ] ;
@@ -52,6 +57,9 @@
 static sgVec2 texrep ;
 static sgVec2 texoff ;
 
+static sgVec2 invalidTexture = { 1e30 } ;
+static sgVec3 zero = { 0.0 } ;
+
 static int do_material ( char *s ) ;
 static int do_object   ( char *s ) ;
 static int do_name     ( char *s ) ;
@@ -285,6 +293,7 @@
 
     sgCopyVec4 ( clist [ num_materials ][ 0 ], rgb ) ;
 
+    _ssgMaterial  *current_material ;
     current_material = mlist [ num_materials ] ;
     sgCopyVec4 ( current_material -> spec, spec ) ;
     sgCopyVec4 ( current_material -> emis, emis ) ;
@@ -296,7 +305,6 @@
   return PARSE_CONT ;
 }
 
-
 static int do_object   ( char *  /* s */ )
 {
 /*
@@ -322,10 +330,180 @@
   current_branch -> addKid ( tr ) ;
   current_branch = tr ;
 
+  current_matindexarray = new ssgIndexArray ;
+  current_flagsarray    = new ssgIndexArray ;
+  current_texcoordarray = new ssgTexCoordArray ;
+  current_vertexarray   = new ssgVertexArray ;
+  current_triindexarray = new ssgIndexArray ;
+
   while ( fgets ( buffer, 1024, loader_fd ) != NULL )
     if ( search ( object_tags, buffer ) == PARSE_POP )
       break ;
 
+  // If he have read some surfaces belonging to that object,
+  // compute normals and distribute the triangels across the materials.
+  int ntris = current_triindexarray -> getNum () / 3;
+  if ( 0 < ntris ) {
+    int i;
+    int nvert = current_vertexarray -> getNum () ;
+
+    // Put the triangles and the current crease angle into the vertex splitter ...
+    ssgVertSplitter split( nvert, ntris );
+    split.setSharpAngle ( current_crease );
+    
+    for ( i = 0 ; i < nvert ; i++ )
+      sgCopyVec3 ( split.vert ( i ), current_vertexarray -> get ( i ) ) ;
+    for ( i = 0 ; i < ntris ; i++ )
+      split.setTri ( i,
+                     * ( current_triindexarray -> get ( 3*i ) ),
+                     * ( current_triindexarray -> get ( 3*i+1 ) ),
+                     * ( current_triindexarray -> get ( 3*i+2 ) ) );
+
+    // ... and let it compute the normals.
+    split.splitAndCalcNormals () ;
+
+    // Cycle through all ssgState/colour combinations and emit leafs from them.
+    for ( int cullface = 0 ; cullface < 2 ; cullface++ ) {
+      for ( int material = 0 ; material < num_materials ; material++ ) {
+        ssgVertexArray* vertexarray = (ssgVertexArray *) current_vertexarray -> clone () ;
+        vertexarray -> ref () ;
+        ssgNormalArray* normalarray = new ssgNormalArray ( nvert ) ;
+        normalarray -> ref () ;
+        ssgTexCoordArray* texcoordarray = (ssgTexCoordArray *) current_texcoordarray -> clone () ;
+        texcoordarray -> ref () ;
+        ssgIndexArray* triindexarray = new ssgIndexArray ( nvert ) ;
+        triindexarray -> ref () ;
+        // Mark all normals as unset using a zero vector. 
+        for ( i = 0 ; i < nvert ; i++ )
+          normalarray -> add ( zero ) ;
+        
+        // For every material/state cycle through all triangles and pick
+        // out those ones with that maternial/state.
+        for ( int tri = 0 ; tri < ntris ; tri++ ) {
+          int triMatindex = * ( current_matindexarray -> get ( tri ) ) ;
+          int triFlags = * ( current_flagsarray -> get ( tri ) ) ;
+          int triCullface = ! ( triFlags & 0x20 ) ;
+
+          if ( triMatindex == material && triCullface == cullface ) {
+            // get the original indices
+            int* triind = split.getTri ( tri ) ;
+            int origtriind[3];
+            for ( int k = 0 ; k < 3 ; k++ )
+              origtriind[k] = triind[k] < nvert ? triind[k] : split.origVert( triind[k] - nvert ) ;
+
+            // Note that copying those values prevents us from a race condion
+            // which occurs when doing something like:
+            // texcoordarray -> add ( texcoordarray -> get ( origtriind[i] ) ) ;
+          
+            // make a local copy of texcoords ...
+            sgVec2 texcoords[3];
+            for ( i = 0 ; i < 3 ; i++ )
+              sgCopyVec2 ( texcoords[i], texcoordarray -> get ( origtriind[i] ) ) ;
+
+            // ... of vertices ...
+            sgVec3 vertices[3];
+            for ( i = 0 ; i < 3 ; i++ )
+              sgCopyVec3 ( vertices[i], split.vert ( origtriind[i] ) ) ;
+
+            int triSmooth = ( triFlags & 0x10 ) ;
+            
+            // ... and of normals.
+            sgVec3 normals[3];
+            if ( triSmooth ) {
+              for ( i = 0 ; i < 3 ; i++ )
+                sgCopyVec3 ( normals[i], split.norm ( triind[i] ) ) ;
+            } else {
+              // If we have flat shading, compute one normal for all.
+              sgSubVec3 ( normals[1], vertices[1], vertices[0] ) ;
+              sgSubVec3 ( normals[2], vertices[2], vertices[0] ) ;
+              sgVectorProductVec3 ( normals[0], normals[1], normals[2] ) ;
+              sgNormaliseVec3 ( normals[0] ) ;
+              sgCopyVec3 ( normals[1], normals[0] ) ;
+              sgCopyVec3 ( normals[2], normals[0] ) ;
+            }
+                      
+
+            for ( i = 0 ; i < 3 ; i++ ) {
+              
+              if ( sgCompareVec3 ( normalarray -> get ( origtriind[i] ), zero, 0.0 ) ) {
+                // Case: not yet initialized. 
+                
+                sgCopyVec3 ( normalarray -> get ( origtriind[i] ), normals[i] ) ;
+                
+                triindexarray -> add ( origtriind[i] ) ;
+                
+              } else if ( sgCompareVec3 ( normalarray -> get ( origtriind[i] ), normals[i], 0.0 ) ) {
+                // Case: initialized and the same as before. 
+                
+                triindexarray -> add ( origtriind[i] ) ;
+                
+              } else {
+                // Case: initialized and different.
+                
+                // Scan for a vertex/normal/texcoord triple matching the required one.
+                // If there exist one, use that.
+                int num = vertexarray -> getNum () ;
+                int replind = -1 ;
+                for ( int l = nvert ; l < num ; l++ ) {
+                  if ( sgCompareVec3( vertices[i], vertexarray -> get ( l ), 0.0 ) &&
+                       sgCompareVec2( texcoordarray -> get ( origtriind[i] ), texcoordarray -> get ( l ), 0.0 ) &&
+                       sgCompareVec3( normals[i], normalarray -> get ( l ), 0.0 ) ) {
+                    replind = l ;
+                  }
+                }
+                
+                // If we have not yet the required triple in our dataset, add it.
+                if ( replind < 0 ) {
+                  vertexarray -> add ( vertices[i] ) ;
+                  normalarray -> add ( normals[i] ) ;
+                  texcoordarray -> add ( texcoords[i] ) ;
+                  replind = num ;
+                }
+                triindexarray -> add ( replind ) ;
+              }
+            }
+          }
+        }
+        
+        if ( 0 < triindexarray -> getNum () ) {
+          ssgColourArray *colour = new ssgColourArray ( 1 ) ;
+          colour -> add ( *clist [ material ] ) ;
+          ssgVtxArray* v = new ssgVtxArray ( GL_TRIANGLES,
+                                             vertexarray,
+                                             normalarray,
+                                             texcoordarray,
+                                             colour,
+                                             triindexarray ) ;
+          v -> removeUnusedVertices();
+          v -> setState ( get_state ( mlist [ material ] ) ) ;
+          v -> setCullFace ( cullface ) ;
+          ssgLeaf* leaf = current_options -> createLeaf ( v, 0 ) ;
+          if ( leaf )
+            tr -> addKid ( leaf ) ;
+        }
+        
+        ssgDeRefDelete ( vertexarray ) ;
+        ssgDeRefDelete ( normalarray ) ;
+        ssgDeRefDelete ( texcoordarray ) ;
+        ssgDeRefDelete ( triindexarray ) ;
+      }
+    }
+  }
+
+  // Cleanup
+  delete current_matindexarray ;
+  current_matindexarray = NULL ;
+  delete current_flagsarray ;
+  current_flagsarray    = NULL ;
+  delete current_vertexarray ;
+  current_vertexarray   = NULL ;
+  delete current_texcoordarray ;
+  current_texcoordarray = NULL ;
+  delete current_triindexarray ;
+  current_triindexarray = NULL ;
+
+  // Process child nodes
+
   int num_kids = last_num_kids ;
 
   for ( int i = 0 ; i < num_kids ; i++ )
@@ -335,6 +513,7 @@
   }
 
   current_branch = (ssgBranch *) old_cb ;
+
   return PARSE_CONT ;
 }
 
@@ -418,8 +597,7 @@
 {
   // the crease angle is not yet used. However, reading the crease line correctly means 
   // *.ac lines with "crease" can now be read.
-  float creaseAngle;
-  if ( sscanf ( s, "%f", & creaseAngle ) != 1 )
+  if ( sscanf ( s, "%f", & current_crease ) != 1 )
     ulSetError ( UL_WARNING, "ac_to_gl: Illegal crease angle." ) ;
 
   return PARSE_CONT ;
@@ -470,23 +648,22 @@
 
   int nv = strtol ( s, NULL, 0 ) ;
  
-  delete [] vtab ;
-
-  vtab = new sgVec3 [ nv ] ;
-
   for ( int i = 0 ; i < nv ; i++ )
   {
+    sgVec3 v;
     fgets ( buffer, 1024, loader_fd ) ;
 
-    if ( sscanf ( buffer, "%f %f %f",
-                          &vtab[i][0], &vtab[i][1], &vtab[i][2] ) != 3 )
+    if ( sscanf ( buffer, "%f %f %f", &v[0], &v[1], &v[2] ) != 3 )
     {
       ulSetError ( UL_FATAL, "ac_to_gl: Illegal vertex record." ) ;
     }
 
-    float tmp  =  vtab[i][1] ;
-    vtab[i][1] = -vtab[i][2] ;
-    vtab[i][2] = tmp ;
+    float tmp  =  v[1] ;
+    v[1] = -v[2] ;
+    v[2] = tmp ;
+
+    current_vertexarray -> add ( v ) ;
+    current_texcoordarray -> add ( invalidTexture ) ;
   }
 
   return PARSE_CONT ;
@@ -525,86 +702,152 @@
 {
   int mat = strtol ( s, NULL, 0 ) ;
 
-  current_material = mlist [ mat ] ;
-  current_colour   = clist [ mat ] ;
+  current_materialind = mat ;
 
   return PARSE_CONT ;
 }
 
-
-static int do_refs     ( char *s )
+static void add_textured_vertex_edge ( short ind, sgVec2 tex )
 {
-  int nrefs = strtol ( s, NULL, 0 ) ;
-  char buffer [ 1024 ] ;
+  // Add a new triangle edge. For that, check for a vertex/texcoord
+  // pair already in the current dataset. Use the already present index if present.
 
-  if ( nrefs == 0 )
-    return PARSE_POP ;
+  bool has_texture = current_tfname != NULL ;
+  if ( sgCompareVec2( tex, current_texcoordarray -> get ( ind ), 0.0 ) || !has_texture ) {
+    // In this case, we have that vertex/texcoord pair already at the index 
+    // within the ac file.
 
-  ssgVertexArray   *vlist = new ssgVertexArray ( nrefs ) ;
-  ssgTexCoordArray *tlist = new ssgTexCoordArray ( nrefs ) ;
- 
-  for ( int i = 0 ; i < nrefs ; i++ )
-  {
-    fgets ( buffer, 1024, loader_fd ) ;
+    current_triindexarray -> add ( ind ) ;
 
-    int vtx ;
-    sgVec2 tc ;
+  } else if ( sgCompareVec2( invalidTexture, current_texcoordarray -> get ( ind ), 0.0 ) ) {
+    // In this case, we have not yet stored a valid texture coordinate
+    // for the vertex at the given index. Just copy the texturecoordinate
+    // value into that place.
 
-    if ( sscanf ( buffer, "%d %f %f", &vtx,
-                                      &tc[0],
-                                      &tc[1] ) != 3 )
-    {
-      ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record." ) ;
+    sgCopyVec2( current_texcoordarray -> get ( ind ), tex ) ;
+
+    current_triindexarray -> add ( ind ) ;
+
+  } else {
+    // Texture coordinate do not match the prevous texcoords stored for this vertex.
+    // Search for a vertex/texcoord pair matching the requested one, if not
+    // yet present, add a new one.
+  
+    int num = current_vertexarray -> getNum () ;
+    for ( int i = 0 ; i < num ; i++ ) {
+      if ( sgCompareVec2( tex, current_texcoordarray -> get ( i ), 0.0 ) &&
+           sgCompareVec3( current_vertexarray -> get ( ind ),
+                          current_vertexarray -> get ( i ), 0.0 ) ) {
+        current_triindexarray -> add ( i ) ;
+        return ;
+      }
     }
 
-    tc[0] *= texrep[0] ;
-    tc[1] *= texrep[1] ;
-    tc[0] += texoff[0] ;
-    tc[1] += texoff[1] ;
+    // Need to copy that before, else we run into a racecondition where
+    // we copy from an location which is already freed.
+    sgVec3 vertex ;
+    sgCopyVec3 ( vertex, current_vertexarray -> get ( ind ) ) ;
+    current_vertexarray -> add ( vertex ) ;
+    current_texcoordarray -> add ( tex ) ;
 
-    tlist -> add ( tc ) ;
-    vlist -> add ( vtab[vtx] ) ;
+    current_triindexarray -> add ( num ) ;
   }
+}
 
-  ssgNormalArray *nrm = new ssgNormalArray ( 1 ) ;
-  ssgColourArray *col = new ssgColourArray ( 1 ) ;
+static int do_refs     ( char *s )
+{
+  int nrefs = strtol ( s, NULL, 0 ) ;
+  char buffer [ 1024 ] ;
 
-  col -> add ( *current_colour ) ;
+  if ( nrefs == 0 )
+    return PARSE_POP ;
+  
+  int type = ( current_flags & 0x0F ) ;
 
-  sgVec3 nm ;
+  // Handle line type objects by creating a single leaf for each line segment.
+  if ( type == 1 || type == 2 ) {
+    ssgIndexArray *ind = new ssgIndexArray ;
+    for ( int i = 0 ; i < nrefs ; i++ )
+    {
+      fgets ( buffer, 1024, loader_fd ) ;
 
-  if ( nrefs < 3 )
-    sgSetVec3 ( nm, 0.0f, 0.0f, 1.0f ) ;
-  else
-    sgMakeNormal ( nm, vlist->get(0), vlist->get(1), vlist->get(2) ) ;
+      int vtx ;
+      float dummy ;
 
-  nrm -> add ( nm ) ;
+      if ( sscanf ( buffer, "%d %f %f", &vtx, &dummy, &dummy ) != 3 )
+      {
+        ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record." ) ;
+      }
 
-  int type = ( current_flags & 0x0F ) ;
-  if ( type >= 0 && type <= 2 )
-  {
-    GLenum gltype = GL_TRIANGLES ;
-    switch ( type )
-    {
-      case 0 : gltype = GL_TRIANGLE_FAN ;
-               break ;
-      case 1 : gltype = GL_LINE_LOOP ;
-               break ;
-      case 2 : gltype = GL_LINE_STRIP ;
-               break ;
-    }
+      ind -> add ( vtx ) ;
+    }    
 
-    ssgVtxTable* vtab = new ssgVtxTable ( gltype,
-      vlist, nrm, tlist, col ) ;
-    vtab -> setState ( get_state ( current_material ) ) ;
-    vtab -> setCullFace ( ! ( (current_flags>>4) & 0x02 ) ) ;
+    ssgColourArray *col = new ssgColourArray ( 1 ) ;
+    col -> add ( *clist [ current_materialind ] ) ;
 
-    ssgLeaf* leaf = current_options -> createLeaf ( vtab, 0 ) ;
+    GLenum gltype = ( type == 1 ) ? GL_LINE_LOOP : GL_LINE_STRIP ;
+    ssgVtxArray *va = new ssgVtxArray ( gltype, (ssgVertexArray *)current_vertexarray -> clone (),
+                                        0, 0, col, ind );
+    va -> removeUnusedVertices();
+    va -> setState ( get_state ( mlist [ current_materialind ] ) ) ;
 
+    ssgLeaf *leaf = current_options -> createLeaf ( va, 0 ) ;
     if ( leaf )
-       current_branch -> addKid ( leaf ) ;
+      current_branch -> addKid ( leaf ) ;
   }
 
+  if ( type == 0 ) {
+    // Handle surface datatypes.
+    // Each surface is triangulated and each triangle is put
+    // into the index array current_triindexarray.
+    int first_vertind = -1 ;
+    int prev_vertind  = 0 ;
+    sgVec2 first_texcoord ;
+    sgVec2 prev_texcoord ;
+    for ( int i = 0 ; i < nrefs ; i++ )
+      {
+        fgets ( buffer, 1024, loader_fd ) ;
+        
+        int vertind ;
+        sgVec2 texcoord ;
+        
+        if ( sscanf ( buffer, "%d %f %f", &vertind,
+                      &texcoord[0],
+                      &texcoord[1] ) != 3 )
+          {
+            ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record." ) ;
+          }
+        
+        texcoord[0] *= texrep[0] ;
+        texcoord[1] *= texrep[1] ;
+        texcoord[0] += texoff[0] ;
+        texcoord[1] += texoff[1] ;
+        
+        // Store the first index texcoord pair.
+        // This one is referenced for every triangle.
+        if ( first_vertind < 0 ) {
+          first_vertind = vertind ;
+          sgCopyVec2( first_texcoord, texcoord );
+        }
+        
+        // When we have read the third vertex index we can emit the first triangle.
+        if ( 2 <= i ) {
+          // Store the edges of the triangle
+          add_textured_vertex_edge ( first_vertind, first_texcoord ) ;
+          add_textured_vertex_edge ( prev_vertind, prev_texcoord ) ;
+          add_textured_vertex_edge ( vertind, texcoord ) ;
+          
+          // Store the material and flags for this surface. 
+          current_matindexarray -> add ( current_materialind );
+          current_flagsarray -> add ( current_flags );
+        }
+        
+        // Copy current -> previous
+        prev_vertind = vertind ;
+        sgCopyVec2( prev_texcoord, texcoord );
+      }
+  }
+  
   return PARSE_POP ;
 }
 
@@ -628,7 +871,6 @@
   ssgBranch *model = new ssgBranch () ;
   model -> addKid ( obj ) ;
   ssgFlatten      ( obj ) ;
-  ssgStripify   ( model ) ;
   return model ;
 }
 
@@ -645,13 +887,12 @@
   current_options -> makeModelPath ( filename, fname ) ;
 
   num_materials = 0 ;
-  vtab = NULL ;
 
-  current_material = NULL ;
-  current_colour   = NULL ;
   current_tfname   = NULL ;
   current_branch   = NULL ;
 
+  current_crease = 61.0 ;
+
   sgSetVec2 ( texrep, 1.0, 1.0 ) ;
   sgSetVec2 ( texoff, 0.0, 0.0 ) ;
 
@@ -698,7 +939,6 @@
 
   delete [] current_tfname ;
   current_tfname = NULL ;
-  delete [] vtab ;
   fclose ( loader_fd ) ;
 
   return current_branch ;
Index: src/ssg/ssgOptimiser.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgOptimiser.cxx,v
retrieving revision 1.35
diff -u -r1.35 ssgOptimiser.cxx
--- src/ssg/ssgOptimiser.cxx	4 Oct 2004 08:18:26 -0000	1.35
+++ src/ssg/ssgOptimiser.cxx	8 Oct 2004 06:02:43 -0000
@@ -869,7 +869,7 @@
   switch ( b_ent -> getNumKids () )
   {
   case 0:
-    if ( b_ent -> getUserData() == NULL )
+    if ( b_ent -> getUserData() == NULL && b_ent -> getName () == NULL )
       safe_replace_kid ( NULL, b_ent, NULL ) ;
     break;
 
@@ -877,7 +877,13 @@
     if ( b_ent -> isA ( ssgTypeBranch () ) &&
 	 b_ent -> getUserData () == NULL )
     {
-      safe_replace_kid ( NULL, b_ent, b_ent -> getKid ( 0 ) ) ;
+      ssgEntity *k = b_ent -> getKid ( 0 ) ;
+      if ( b_ent -> getName () != NULL && k -> getName () != NULL )
+        break;
+      if ( b_ent -> getName () != NULL )
+        k -> setName ( b_ent -> getName () ) ;
+         
+      safe_replace_kid ( NULL, b_ent, k ) ;
     }
     else if ( ! b_ent -> isAKindOf ( ssgTypeSelector () ) &&
 	      b_ent -> getKid ( 0 ) -> isA ( ssgTypeBranch () ) &&
Index: src/ssg/ssgSaveAC.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgSaveAC.cxx,v
retrieving revision 1.20
diff -u -r1.20 ssgSaveAC.cxx
--- src/ssg/ssgSaveAC.cxx	4 May 2004 12:43:54 -0000	1.20
+++ src/ssg/ssgSaveAC.cxx	8 Oct 2004 06:02:43 -0000
@@ -119,7 +119,7 @@
 
   for ( i = 0 ; i < num_tris ; i++ )
   {
-    fprintf ( save_fd, "SURF 0x0\n" ) ;
+    fprintf ( save_fd, "SURF 0x0%x\n", (! vt -> getCullFace () ) << 5 ) ;
     ssgState *s = vt->getState ();
 
     int istate = 0;
Index: src/ssg/ssgTransform.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgTransform.cxx,v
retrieving revision 1.13
diff -u -r1.13 ssgTransform.cxx
--- src/ssg/ssgTransform.cxx	29 Nov 2002 19:39:48 -0000	1.13
+++ src/ssg/ssgTransform.cxx	8 Oct 2004 06:02:43 -0000
@@ -165,33 +165,36 @@
 
 void ssgTransform::setTransform ( sgVec3 xyz )
 {
-  updateTransform () ;
-  sgMakeTransMat4 ( transform, xyz ) ;
-  firsttime       () ; 
-  dirtyBSphere    () ;
+  sgMat4 tmp_trans;
+  sgMakeTransMat4 ( tmp_trans, xyz ) ;
+  setTransform ( tmp_trans ) ;
 }
 
 void ssgTransform::setTransform ( sgCoord *xform )
 {
-  updateTransform () ;
-  sgMakeCoordMat4 ( transform, xform ) ;
-  firsttime       () ; 
-  dirtyBSphere () ;
+  sgMat4 tmp_trans;
+  sgMakeCoordMat4 ( tmp_trans, xform ) ;
+  setTransform ( tmp_trans ) ;
 }
 
 void ssgTransform::setTransform ( sgCoord *xform, float sx, float sy, float sz )
 {
-  updateTransform () ;
-  sgMakeCoordMat4 ( transform, xform ) ;
-  sgScaleVec3     ( transform[0], sx ) ;
-  sgScaleVec3     ( transform[1], sy ) ;
-  sgScaleVec3     ( transform[2], sz ) ;
-  firsttime       () ; 
-  dirtyBSphere () ;
+  sgMat4 tmp_trans;
+  sgMakeCoordMat4 ( tmp_trans, xform ) ;
+  sgScaleVec3     ( tmp_trans[0], sx ) ;
+  sgScaleVec3     ( tmp_trans[1], sy ) ;
+  sgScaleVec3     ( tmp_trans[2], sz ) ;
+  setTransform ( tmp_trans );
 }
 
 void ssgTransform::setTransform ( sgMat4 xform )
 {
+  if ( sgEqualVec4( xform[0], transform[0] ) &&
+       sgEqualVec4( xform[1], transform[1] ) &&
+       sgEqualVec4( xform[2], transform[2] ) &&
+       sgEqualVec4( xform[3], transform[3] ) )
+    return;
+
   updateTransform () ;
   sgCopyMat4      ( transform, xform ) ;
   firsttime       () ; 
Index: src/ssg/ssgVtxArray.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgVtxArray.cxx,v
retrieving revision 1.28
diff -u -r1.28 ssgVtxArray.cxx
--- src/ssg/ssgVtxArray.cxx	13 Sep 2004 12:01:15 -0000	1.28
+++ src/ssg/ssgVtxArray.cxx	8 Oct 2004 06:02:43 -0000
@@ -195,13 +195,13 @@
     return;
   }
   if(normals)
-    if(normals->getNum() != 0)
+    if(1 < normals->getNum())
       doNormals = TRUE;
   if(texcoords)
-    if(texcoords->getNum() != 0)
+    if(1 < texcoords->getNum())
       doTexCoords = TRUE;
   if(colours)
-    if(colours->getNum() != 0)
+    if(1 < colours->getNum())
       doColours = TRUE;
   
   long * oldIndex2NewIndex = new long[vertices->getNum()];
Index: src/ssg/ssgVtxTable.cxx
===================================================================
RCS file: /cvsroot/plib/plib/src/ssg/ssgVtxTable.cxx,v
retrieving revision 1.37
diff -u -r1.37 ssgVtxTable.cxx
--- src/ssg/ssgVtxTable.cxx	13 Sep 2004 11:43:08 -0000	1.37
+++ src/ssg/ssgVtxTable.cxx	8 Oct 2004 06:02:44 -0000
@@ -407,7 +407,9 @@
   */
 
 
-  for ( i = 0 ; i < getNumVertices() ; i++ )
+  int num_vertices = getNumVertices () ;
+  int num_normals = getNumNormals () ;
+  for ( i = 0 ; i < num_vertices ; i++ )
     sgXformPnt3 ( vertices->get(i), vertices->get(i), m ) ;
 
 
@@ -444,17 +446,17 @@
       sgScaleVec3 ( w[2], m[2], scale ) ;
     }
 
-    for ( i = 0 ; i < getNumNormals() ; i++ )
+    for ( i = 0 ; i < num_normals ; i++ )
       sgXformVec3 ( normals->get(i), normals->get(i), w ) ;
   }
   else
-    for ( i = 0 ; i < getNumNormals() ; i++ )
+    for ( i = 0 ; i < num_normals ; i++ )
       sgXformVec3 ( normals->get(i), normals->get(i), m ) ;
 
 
   if ( ( flags & SG_NONORTHO ) )
   {
-    for ( i = 0 ; i < getNumNormals() ; i++ )
+    for ( i = 0 ; i < num_normals ; i++ )
       sgNormaliseVec3 ( normals->get(i) ) ;
   }
 
@@ -468,7 +470,8 @@
   emptyBSphere () ;
   bbox . empty () ;
 
-  for ( int i = 0 ; i < getNumVertices() ; i++ )
+  int num_vertices  = getNumVertices () ;
+  for ( int i = 0 ; i < num_vertices ; i++ )
     bbox . extend ( vertices->get(i) ) ;
 
   extendBSphere ( & bbox ) ;
_______________________________________________
Flightgear-devel mailing list
[EMAIL PROTECTED]
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to