三角ストリップになった頂点インデックス並びを、普通の三角頂点インデックスに展開するための最短変換コードを考えました。もういちいち毎回悩まなくてもいいのです!ループの中に条件判定もないし、おまけにreserveもかましてるので、パフォーマンスも完璧です。
ついでに三角ファンのインデックスが来たとき用の展開用コードもアップしといたがの。
template< class CONT > void DecodeTriangleStripIndex( const int num_index, const CONT& il, vector< int >* iil ) { // il: 三角ストリップ(最初の三角は表側から見てCCWから始まるものとします) if( num_index>2 ){ iil->reserve( (num_index-2)*3 ); for( int i=0; i<num_index-2; ++i ){ iil->push_back( il[ i ] ); iil->push_back( il[ i+1+(i&1) ] ); iil->push_back( il[ i+2-(i&1) ] ); }// i } return; } template< class CONT > void DecodeTriangleFanIndex( const int num_index, const CONT& il, vector< int >* iil ) { // il: 三角ファン(表側から見てCCWで定義されているものとします) if( num_index>2 ){ iil->reserve( (num_index-2)*3 ); for( int i=1; i<num_index-1; ++i ){ iil->push_back( il[ 0 ] ); iil->push_back( il[ i ] ); iil->push_back( il[ i+1 ] ); }// i } return; }
また、フラットシェーディングなんかの場合や、シャープエッジなどの表現の際、インデックスと同じ並びで法線の配列を指定したりするので(glDrawArraysなどでね)、そのような場合にも対応したものが以下だよ。
void DecodeTriangleFanIndex( const int num_index, const CONT& il, const NOR_CONT& nl, vector< int >* iil, vector< Vec3 >* nnl ) { // il: 三角ファン(表側から見てCCWで定義されているものとします) if( num_index>2 ){ nnl->reserve( (num_index-2)*3 ); iil->reserve( (num_index-2)*3 ); for( int i=1; i<num_index-1; ++i ){ iil->push_back( il[ 0 ] ); nnl->push_back( nl[0] ); iil->push_back( il[ i ] ); nnl->push_back( nl[i] ); iil->push_back( il[ i+1 ] ); nnl->push_back( nl[i+1] ); }// i } return; }