inline void rotate(Triangle &t)
{
   if (t[1] < t[0] && t[1] < t[2]) {
      t.Set( t[1], t[2], t[0] );
   } else if (t[2] < t[0]) {
      t.Set( t[2], t[0], t[1] );
   }
}
vector<Triangle> NiSkinPartition::GetTriangles( int partition ) const {
   const SkinPartition&part = skinPartitionBlocks.at(partition);
   if ( part.numStrips == 0 && !part.triangles.empty())
      return part.triangles;

   // Use Strips

   //Create a vector to hold the triangles
   vector<Triangle> triangles;
   int n = 0; // Current triangle

   //Cycle through all strips
   vector< vector<unsigned short> >::const_iterator it;
   Triangle t;
   for (it = part.strips.begin(); it != part.strips.end(); ++it ) {
      //The first three values in the strip are the first triangle
      t.Set( (*it)[0], (*it)[1], (*it)[2] );

      //Only add triangles to the list if none of the vertices match
      if ( t[0] != t[1] && t[0] != t[2] && t[1] != t[2] ) {
         triangles.push_back(t);
      }

      //Move to the next triangle
      ++n;

      //The remaining triangles use the previous two indices as their first two indices.
      for( unsigned int i = 3; i < it->size(); ++i ) {
         //Odd numbered triangles need to be reversed to keep the vertices in counter-clockwise order
         if ( i % 2 == 0 ) {
            t.Set( (*it)[i - 2], (*it)[i - 1], (*it)[i] );
         } else {
            t.Set( (*it)[i], (*it)[i - 1], (*it)[i - 2] );
         }

         //Only add triangles to the list if none of the vertices match
         if ( t[0] != t[1] && t[0] != t[2] && t[1] != t[2] ) {
            triangles.push_back(t);
         }

         //Move to the next triangle
         ++n;
      }
   }

   return triangles;
}