private static CollisionShape ExtractBox_Old( SubMesh subMesh )
 {
     if( DoLog )
     {
         Log( "" );
         Log( string.Format( "Extracting box for submesh {0}", subMesh.Name ) );
     }
     MeshTriangle[] triangles = ExtractSubmeshTriangles( subMesh );
     int count = triangles.Length;
     Plane[] planesUnsorted = new Plane[ 6 ];
     int planeCount = 0;
     // Iterate through the triangles.  For each triangle,
     // determine the plane it belongs to, and find the plane
     // in the array of planes, or if it's not found, add it.
     for( int i = 0; i < count; i++ )
     {
         MeshTriangle t = triangles[ i ];
         bool found = false;
         Plane p = new Plane( t.vertPos[ 0 ], t.vertPos[ 1 ], t.vertPos[ 2 ] );
         NormalizePlane( ref p );
         if( DoLog )
             Log( string.Format( " {0} => plane {1}", t.ToString(), p.ToString() ) );
         for( int j = 0; j < planeCount; j++ )
         {
             Plane pj = planesUnsorted[ j ];
             if( SamePlane( pj, p ) )
             {
                 if( DoLog )
                     Log( string.Format( " plane {0} same as plane {1}", p.ToString(), pj.ToString() ) );
                 found = true;
                 break;
             }
         }
         if( !found )
         {
             if( planeCount < 6 )
             {
                 if( DoLog )
                     Log( string.Format( " plane[{0}] = plane {1}", planeCount, p.ToString() ) );
                 planesUnsorted[ planeCount++ ] = p;
             }
             else
                 Debug.Assert( false,
                              string.Format( "In the definition of box {0}, more than 6 planes were found",
                                            subMesh.Name ) );
         }
     }
     Debug.Assert( planeCount == 6,
                  string.Format( "In the definition of box {0}, fewer than 6 planes were found",
                                subMesh.Name ) );
     // Now recreate the planes array, making sure that
     // opposite faces are 3 planes apart
     Plane[] planes = new Plane[ 6 ];
     bool[] planeUsed = new bool[ 6 ];
     for( int i = 0; i < 6; i++ )
         planeUsed[ i ] = false;
     int planePair = 0;
     for( int i = 0; i < 6; i++ )
     {
         if( !planeUsed[ i ] )
         {
             Plane p1 = planesUnsorted[ i ];
             planes[ planePair ] = p1;
             planeUsed[ i ] = true;
             for( int j = 0; j < 6; j++ )
             {
                 Plane p2 = planesUnsorted[ j ];
                 if( !planeUsed[ j ] && !Orthogonal( p2, p1 ) )
                 {
                     planes[ 3 + planePair++ ] = p2;
                     planeUsed[ j ] = true;
                     break;
                 }
             }
         }
     }
     Debug.Assert( planePair == 3, "Didn't find 3 pairs of parallel planes" );
     // Make sure that the sequence of planes follows the
     // right-hand rule
     if( planes[ 0 ].Normal.Cross( planes[ 1 ].Normal ).Dot( planes[ 3 ].Normal ) < 0 )
     {
         // Swap the first two plane pairs
         Plane p = planes[ 0 ];
         planes[ 0 ] = planes[ 1 ];
         planes[ 1 ] = p;
         p = planes[ 0 + 3 ];
         planes[ 0 + 3 ] = planes[ 1 + 3 ];
         planes[ 1 + 3 ] = p;
         Debug.Assert( planes[ 0 ].Normal.Cross( planes[ 1 ].Normal ).Dot( planes[ 3 ].Normal ) > 0,
                      "Even after swapping, planes don't obey the right-hand rule" );
     }
     // Now we have our 6 planes, sorted so that opposite
     // planes are 3 planes apart, and so they obey the
     // right-hand rule.  This guarantees that corners
     // correspond.  Find the 8 intersections that define the
     // corners.
     Vector3[] corners = new Vector3[ 8 ];
     int cornerCount = 0;
     for( int i = 0; i <= 3; i += 3 )
     {
         Plane p1 = planes[ i ];
         for( int j = 1; j <= 4; j += 3 )
         {
             Plane p2 = planes[ j ];
             for( int k = 2; k <= 5; k += 3 )
             {
                 Plane p3 = planes[ k ];
                 Vector3 corner = -1 * ((p1.D * (p2.Normal.Cross( p3.Normal )) +
                                         p2.D * (p3.Normal.Cross( p1.Normal )) +
                                         p3.D * (p1.Normal.Cross( p2.Normal ))) /
                                        p1.Normal.Dot( p2.Normal.Cross( p3.Normal ) ));
                 Debug.Assert( cornerCount < 8,
                              string.Format( "In the definition of box {0}, more than 8 corners were found",
                                            subMesh.Name ) );
                 if( DoLog )
                     Log( string.Format( "  corner#{0}: {1}", cornerCount, corner.ToString() ) );
                 corners[ cornerCount++ ] = corner;
             }
         }
     }
     Debug.Assert( cornerCount == 8,
                   string.Format( "In the definition of box {0}, fewer than 8 corners were found",
                                 subMesh.Name ) );
     // We know that corners correspond.  Now find the center
     Vector3 center = (corners[ 0 ] + corners[ 7 ]) / 2;
     Debug.Assert( (center - (corners[ 1 ] + corners[ 5 ]) / 2.0f).Length > geometryEpsilon ||
                   (center - (corners[ 2 ] + corners[ 6 ]) / 2.0f).Length > geometryEpsilon ||
                   (center - (corners[ 3 ] + corners[ 7 ]) / 2.0f).Length > geometryEpsilon,
                   string.Format( "In the definition of box {0}, center definition {0} is not consistent",
                                 subMesh.Name, center.ToString() ) );
     // Find the extents
     Vector3 extents = new Vector3( Math.Abs( (corners[ 1 ] - corners[ 0 ]).Length / 2.0f ),
                                   Math.Abs( (corners[ 3 ] - corners[ 1 ]).Length / 2.0f ),
                                   Math.Abs( (corners[ 4 ] - corners[ 0 ]).Length / 2.0f ) );
     if( DoLog )
         Log( string.Format( " extents {0}", extents.ToString() ) );
     // Find the axes
     Vector3[] axes = new Vector3[ 3 ] { (corners[1] - corners[0]).ToNormalized(),
                                        (corners[3] - corners[1]).ToNormalized(),
                                        (corners[4] - corners[0]).ToNormalized() };
     if( DoLog )
     {
         for( int i = 0; i < 3; i++ )
         {
             Log( string.Format( " axis[{0}] {1}", i, axes[ i ] ) );
         }
     }
     // Now, is it an obb or an aabb?  Figure out if the axes
     // point in the same direction as the basis vectors, and
     // if so, the order of the axes
     int[] mapping = new int[ 3 ] { -1, -1, -1 };
     int foundMapping = 0;
     for( int i = 0; i < 3; i++ )
     {
         for( int j = 0; j < 3; j++ )
         {
             if( axes[ i ].Cross( Primitives.UnitBasisVectors[ j ] ).Length < geometryEpsilon )
             {
                 mapping[ i ] = j;
                 foundMapping++;
                 break;
             }
         }
     }
     CollisionShape shape;
     if( foundMapping == 3 )
     {
         // It's an AABB, so build the min and max vectors, in
         // the order that matches the unit basis vector order
         Vector3 min = Vector3.Zero;
         Vector3 max = Vector3.Zero;
         for( int i = 0; i < 3; i++ )
         {
             float e = extents[ i ];
             int j = mapping[ i ];
             min[ j ] = center[ j ] - e;
             max[ j ] = center[ j ] + e;
         }
         shape = new CollisionAABB( min, max );
     }
     else
     {
         Vector3 ruleTest = axes[ 0 ].Cross( axes[ 1 ] );
         if( axes[ 2 ].Dot( ruleTest ) < 0 )
             axes[ 2 ] = -1 * axes[ 2 ];
         // Return the OBB
         shape = new CollisionOBB( center, axes, extents );
     }
     if( DoLog )
         Log( string.Format( "Extraction result: {0}", shape ) );
     return shape;
 }