Changeset 513

Show
Ignore:
Timestamp:
02/20/08 18:03:47 (11 months ago)
Author:
phill
Message:

o Wheee!

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/morph-targets/libx42make/include/x42make-modelbuilder.h

    r512 r513  
    369369        */ 
    370370        void remap_vertices( const std::vector< index > &remap ); 
     371 
     372        std::vector< index > get_triangle_list_indices() const; 
     373        void optimize( bool generate_stitched_strips = false ); 
    371374 
    372375        size_t vertex_count() const { return base_shape.size(); } 
     
    454457        void rebind_and_remove_influence( const influence_ptr &old_influence, const influence_ptr &new_influence ); 
    455458 
     459        void unbind_weak_influences( float min_weight, bool renormalize_weights = true ); 
     460        void unbind_excess_influences( size_t max_influences, bool renormalize_weights = true ); 
     461        void normalize_influence_weights(); 
     462 
     463        std::vector< size_t > count_influence_uses() const; 
     464        std::vector< size_t > count_bone_uses() const; 
     465 
     466        void remove_unused_influences(); 
     467        void remove_unused_bones(); 
     468 
    456469private: 
    457470        int _bone_update_count; 
     
    494507        void reset(); 
    495508        bool next(); 
    496         group_ptr current()
     509        group_ptr current() const
    497510 
    498511private: 
     
    515528        void reset(); 
    516529        bool next(); 
    517         size_t current_index()
    518         geometry& current_geometry()
     530        size_t current_index() const
     531        geometry& current_geometry() const
    519532 
    520533private: 
  • branches/morph-targets/libx42make/modelbuilder-enumerators.cpp

    r512 r513  
    9494} 
    9595 
    96 group_ptr group_enumerator::current() 
     96group_ptr group_enumerator::current() const 
    9797{ 
    9898        if( !model || cur_lod == end_lod || cur_grp < 0 ) 
     
    161161} 
    162162 
    163 size_t vertex_enumerator::current_index() 
     163size_t vertex_enumerator::current_index() const 
    164164{ 
    165         if( !cur_grp
     165        if( !cur_grp || cur_idx < 0
    166166                throw error(); 
    167167 
     
    169169} 
    170170 
    171 geometry& vertex_enumerator::current_geometry() 
     171geometry& vertex_enumerator::current_geometry() const 
    172172{ 
    173         if( !cur_grp
     173        if( !cur_grp || cur_idx < 0
    174174                throw error(); 
    175175 
  • branches/morph-targets/libx42make/modelbuilder-geometry.cpp

    r512 r513  
    179179        for( size_t i = 0; i < morph_targets.size(); i++ ) 
    180180        { 
    181                 apply_push_mapping( morph_targets[i]->vertices, remap ); 
    182         } 
    183  
    184         apply_push_mapping( weights, remap ); 
    185         apply_push_mapping( indices, remap ); 
     181                morph_targets[i]->vertices = apply_push_mapping( morph_targets[i]->vertices, remap ); 
     182        } 
     183 
     184        weights = apply_push_mapping( weights, remap ); 
     185        indices = apply_push_mapping( indices, remap ); 
    186186 
    187187        for( size_t i = 0; i < indices.size(); i++ ) 
    188188                indices[i] = remap[indices[i]]; 
     189} 
     190 
     191std::vector< index > geometry::get_triangle_list_indices() const 
     192{ 
     193        switch( prim_type ) 
     194        { 
     195        case primitive_type::triangle_list: 
     196        case primitive_type::triangle_strip: 
     197        case primitive_type::triangle_fan: 
     198                break; 
     199 
     200        default: 
     201                throw error( "Can't get triangle indices for non-triangle geometry." ); 
     202        } 
     203 
     204        size_t elem_count = index_count() ? index_count() : vertex_count(); 
     205        size_t prim_count = (size_t)primitive_type::elems_to_prims( prim_type, (uint)elem_count ); 
     206 
     207        std::vector< index > ret( prim_count * 3 ); 
     208 
     209        if( prim_type == primitive_type::triangle_list && index_count() ) 
     210        { 
     211                if( indices.size() != ret.size() ) 
     212                        throw error( "Odd index count." ); 
     213 
     214                std::copy( indices.begin(), indices.end(), ret.begin() ); 
     215        } 
     216        else 
     217        { 
     218                size_t i = 0; 
     219 
     220                primitive_iterator< index > iter( prim_type, &indices[0], (uint)indices.size() ); 
     221                while( iter.next() ) 
     222                { 
     223                        ret[i + 0] = iter.current( 0 ); 
     224                        ret[i + 1] = iter.current( 1 ); 
     225                        ret[i + 2] = iter.current( 2 ); 
     226 
     227                        i += 3; 
     228                } 
     229        } 
     230 
     231        return ret; 
     232} 
     233 
     234void geometry::optimize( bool generate_stitched_strips ) 
     235{ 
     236        if( !indices.size() ) 
     237                //nothing to do on non-indexed geometry 
     238                return; 
     239 
     240        switch( prim_type ) 
     241        { 
     242        case primitive_type::point_list: 
     243                //nothing to do here 
     244                return; 
     245 
     246        case primitive_type::triangle_list: 
     247        case primitive_type::triangle_strip: 
     248        case primitive_type::triangle_fan: 
     249                break; 
     250 
     251        default: 
     252                //should I bother with this? 
     253                return; 
     254        } 
     255 
     256        if( vertex_count() > index_traits::max_val ) 
     257                //nv's lib can't handle these 
     258                return; 
     259 
     260        nv::DisableRestart(); 
     261        nv::SetCacheSize( nv::CACHESIZE_GEFORCE3 ); 
     262 
     263        if( generate_stitched_strips ) 
     264        { 
     265                nv::SetListsOnly( false ); 
     266                nv::SetStitchStrips( true ); 
     267        } 
     268        else 
     269        { 
     270                nv::SetListsOnly( true ); 
     271        } 
     272 
     273        ushort num_prim_groups; 
     274        nv::PrimitiveGroup *strip, *remap; 
     275 
     276        std::vector< index > tri_indices = get_triangle_list_indices(); 
     277 
     278        nv::GenerateStrips( &tri_indices[0], (uint)tri_indices.size(), &strip, &num_prim_groups ); 
     279        auto_array< nv::PrimitiveGroup > del_strip( strip ); 
     280 
     281        nv::RemapIndices( strip, num_prim_groups, (ushort)vertex_count(), &remap ); 
     282        auto_array< nv::PrimitiveGroup > del_remap( remap ); 
     283 
     284        if( generate_stitched_strips ) 
     285        { 
     286                if( num_prim_groups != 1 ) 
     287                { 
     288                        optimize( false ); //failed strips, give it one more shot as lists 
     289                        return; 
     290                } 
     291                else 
     292                        prim_type = primitive_type::triangle_strip; 
     293        } 
     294        else 
     295                prim_type = primitive_type::triangle_list; 
     296 
     297        //build the remap table (wheee!) 
     298        std::vector< index > remap_table( vertex_count() ); 
     299 
     300        //TODO 
     301 
     302        remap_vertices( remap_table ); 
    189303} 
    190304 
  • branches/morph-targets/libx42make/modelbuilder-influences.cpp

    r512 r513  
    119119        for( vertex_enumerator iter( *this ); iter.next(); ) 
    120120        { 
    121                 vertex_weights weights = iter.current_geometry().weights[iter.current_index()]; 
     121                vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 
    122122 
    123123                for( size_t i = 0; i < vertex_weights::max_weights; i++ ) 
     
    126126                                continue; 
    127127 
    128                         vertex_weight new_weight( new_influence, new_influence ? weights[i].weight() : 0 ); 
    129                         weights.remove( i ); 
    130                         weights.add( new_weight ); 
    131  
    132                         i = 0; //order may have changed, rescan 
     128                        if( new_influence ) 
     129                        { 
     130                                vertex_weight new_weight( new_influence, new_influence ? weights[i].weight() : 0 ); 
     131                                weights.remove( i ); 
     132                                weights.add( new_weight ); 
     133 
     134                                i = 0; //order may have changed, rescan 
     135                        } 
     136                        else 
     137                        { 
     138                                weights.remove( i ); 
     139 
     140                                i--; 
     141                        } 
    133142                } 
    134143        } 
     
    143152void model_builder::erase_influence( const influence_ptr &influence ) 
    144153{ 
     154        if( !influence ) 
     155                return; 
     156 
    145157        std::vector< influence_ptr >::iterator pos = 
    146158                std::find( influences.begin(), influences.end(), influence ); 
     
    150162} 
    151163 
     164void model_builder::unbind_weak_influences( float min_weight, bool renormalize_weights ) 
     165{ 
     166        for( vertex_enumerator iter( *this ); iter.next(); ) 
     167        { 
     168                vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 
     169                weights.trim_weak( min_weight, renormalize_weights ); 
     170        } 
     171} 
     172 
     173void model_builder::unbind_excess_influences( size_t max_influences, bool renormalize_weights ) 
     174{ 
     175        for( vertex_enumerator iter( *this ); iter.next(); ) 
     176        { 
     177                vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 
     178                weights.trim_count( max_influences, renormalize_weights ); 
     179        } 
     180} 
     181 
     182void model_builder::normalize_influence_weights() 
     183{ 
     184        for( vertex_enumerator iter( *this ); iter.next(); ) 
     185        { 
     186                vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 
     187                weights.normalize_weights(); 
     188        } 
     189} 
     190 
     191std::vector< size_t > model_builder::count_influence_uses() const 
     192{ 
     193        std::vector< size_t > ret( influences.size(), 0 ); 
     194 
     195        for( vertex_enumerator iter( *const_cast< model_builder* >( this ) ); iter.next(); ) 
     196        { 
     197                const vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 
     198 
     199                for( size_t i = 0; i < vertex_weights::max_weights; i++ ) 
     200                { 
     201                        if( weights[i].influence() ) 
     202                                ret[weights[i].influence()->_index]++; 
     203                } 
     204        } 
     205 
     206        return ret; 
     207} 
     208 
     209void model_builder::remove_unused_influences() 
     210{ 
     211        std::vector< size_t > use_counts = count_influence_uses(); 
     212        for( size_t i = influences.size(); i--; ) 
     213        { 
     214                if( !use_counts[i] ) 
     215                        influences.erase( influences.begin() + i ); 
     216        } 
     217} 
     218 
    152219}; 
    153220}; 
  • branches/morph-targets/libx42make/modelbuilder-skeleton.cpp

    r512 r513  
    313313} 
    314314 
     315std::vector< size_t > model_builder::count_bone_uses() const 
     316{ 
     317        std::vector< size_t > ret( bones.size(), 0 ); 
     318 
     319        for( size_t i = 0; i < influences.size(); i++ ) 
     320        { 
     321                if( influences[i]->_bone ) 
     322                        ret[influences[i]->_bone->_index]++; 
     323        } 
     324 
     325        for( size_t i = 0; i < tags.size(); i++ ) 
     326        { 
     327                if( tags[i]->_bone ) 
     328                        ret[tags[i]->_bone->_index]++; 
     329        } 
     330 
     331        return ret; 
     332} 
     333 
     334void model_builder::remove_unused_bones() 
     335{ 
     336        std::vector< size_t > use_counts = count_bone_uses(); 
     337        for( size_t i = bones.size(); i--; ) 
     338        { 
     339                if( !use_counts[i] ) 
     340                        bones.erase( bones.begin() + i ); 
     341        } 
     342} 
    315343 
    316344};