示例#1
0
    //
    // MQO
    //  面倒なので四角ポリゴンはないものと仮定
    //
    void build_from_mqo(
        mqo_reader::document_type& doc, float scale, DWORD color,
        TextureCache& tc )
    {
        clear();

        // マテリアル
        for( mqo_reader::materials_type::const_iterator i =
                 doc.materials.begin() ;
             i != doc.materials.end() ;
             ++i ) {
            SubModel m;
            m.vb            = NULL;
            m.ib            = NULL;
            m.texture       = NULL;
            if( (*i).texture != "" ) {
                m.texture = tc.get_texture( (*i).texture );
            }

            submodels_.push_back( m );
        }
        {
            // default material
            SubModel m;
            m.vb                            = NULL;
            m.ib                            = NULL;
            submodels_.push_back( m );
        }

        // 頂点, 面
        for( mqo_reader::objdic_type::const_iterator i =
                 doc.objects.begin() ;
             i != doc.objects.end() ;
             ++i ) {
            const mqo_reader::object_type& obj = (*i).second;

            // dictionary:
            //  ( source vertex index, uv ) => destination vertex index
            struct VertexKey {
                int             index;
                D3DXVECTOR2     uv;

                VertexKey(){}
                VertexKey( int aindex, const D3DXVECTOR2& auv )
                    : index( aindex ), uv( auv ) { }

                bool operator<( const VertexKey& a ) const
                {
                    if( index < a.index ) { return true; }
                    if( a.index < index ) { return false; }
                    if( uv.x < a.uv.x ) { return true; }
                    if( a.uv.x < uv.x ) { return false; }
                    return uv.y < a.uv.y;
                }
            };

            std::vector< std::map< VertexKey, int > > used_vertices;
            used_vertices.resize( submodels_.size() );

            // マテリアルごとに使用頂点を分類
            for( mqo_reader::faces_type::const_iterator j =
                     obj.faces.begin() ;
                 j != obj.faces.end() ;
                 ++j ) {
                const mqo_reader::face_type& face = *j;
                int material_index = face.material_index;
                if( material_index == -1 ) {
                    material_index =
                        int( submodels_.size() - 1 );
                }
                int i0 = face.vertex_indices[0];
                int i1 = face.vertex_indices[1];
                int i2 = face.vertex_indices[2];
                D3DXVECTOR2 uv0( face.uv[0].u, face.uv[0].v );
                D3DXVECTOR2 uv1( face.uv[1].u, face.uv[1].v );
                D3DXVECTOR2 uv2( face.uv[2].u, face.uv[2].v );
                                
                std::map< VertexKey, int >& c =
                    used_vertices[material_index];
                c[ VertexKey( i0, uv0 ) ] = -1 ; 
                c[ VertexKey( i1, uv1 ) ] = -1 ; 
                c[ VertexKey( i2, uv2 ) ] = -1 ; 
            }
                        
            // マテリアルごとに使われている頂点を追加
            size_t n = submodels_.size();
            for( size_t i = 0 ; i < n ; i++ ) {
                SubModel& m = submodels_[i];
                std::map< VertexKey, int >& c = used_vertices[i];

                int no = int( m.vertex_source.size() );
                for( std::map< VertexKey, int >::iterator j = c.begin();
                     j != c.end() ;
                     ++j ) {
                    const mqo_reader::vertex_type& src =
                        obj.vertices[(*j).first.index];

                    model_vertex_type dst;
                    dst.position = D3DXVECTOR3(
                        src.x * scale,
                        src.y * scale,
                        src.z * -scale );
                    dst.normal = D3DXVECTOR3( 0, 0, 0 );
                    dst.diffuse = color;
                    dst.uv = (*j).first.uv;
                    m.vertex_source.push_back( dst );

                    (*j).second = no++;
                }
            }

            // マテリアルごとに面を追加
            for( mqo_reader::faces_type::const_iterator j =
                     obj.faces.begin() ;
                 j != obj.faces.end() ;
                 ++j ) {
                const mqo_reader::face_type& face = *j;
                int material_index = face.material_index;
                if( material_index == -1 ) {
                    material_index =
                        int( submodels_.size() - 1 );
                }
                                
                int i0 = face.vertex_indices[0];
                int i1 = face.vertex_indices[1];
                int i2 = face.vertex_indices[2];
                D3DXVECTOR2 uv0( face.uv[0].u, face.uv[0].v );
                D3DXVECTOR2 uv1( face.uv[1].u, face.uv[1].v );
                D3DXVECTOR2 uv2( face.uv[2].u, face.uv[2].v );

                std::map< VertexKey, int >& c =
                    used_vertices[material_index];
                int k0 = c[VertexKey( i0, uv0 )];
                int k1 = c[VertexKey( i1, uv1 )];
                int k2 = c[VertexKey( i2, uv2 )];

                SubModel& m =
                    submodels_[material_index];
                m.index_source.push_back( k0 );
                m.index_source.push_back( k1 );
                m.index_source.push_back( k2 );

                model_vertex_type& v0 = m.vertex_source[ k0 ];
                model_vertex_type& v1 = m.vertex_source[ k1 ];
                model_vertex_type& v2 = m.vertex_source[ k2 ];
                D3DXVECTOR3 normal = cross(
                    v1.position - v0.position,
                    v2.position - v0.position );
                v0.normal += normal;
                v1.normal += normal;
                v2.normal += normal;
            }
        }

        // 法線後処理
        size_t n = submodels_.size();
        for( size_t j = 0 ; j < n ; j++ ) {
            SubModel& m = submodels_[j];
            for( std::vector< model_vertex_type >::iterator i =
                     m.vertex_source.begin() ;
                 i != m.vertex_source.end() ;
                 ++i ) {
                D3DXVec3Normalize( &(*i).normal, &(*i).normal );
            }
        }

        build_submodels();
    }