Changeset 511

Show
Ignore:
Timestamp:
02/20/08 11:45:25 (11 months ago)
Author:
phill
Message:

o More work on the skeleton related classes.

Files:

Legend:

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

    r510 r511  
    9898typedef ::boost::intrusive_ptr< const influence > const_influence_ptr; 
    9999 
     100class tag; 
     101typedef ::boost::intrusive_ptr< tag > tag_ptr; 
     102typedef ::boost::intrusive_ptr< const tag > const_tag_ptr; 
     103 
    100104class group; 
    101105typedef ::boost::intrusive_ptr< group > group_ptr; 
     
    187191private: 
    188192        model_builder                   *owner; 
    189  
    190193        size_t                                  _index; 
    191194 
     
    209212{ 
    210213public: 
    211         bone_ptr                        bone; 
    212214        ::x42::math::affine     matrix; 
    213215 
    214 private: 
    215         influence() { } 
     216        bone_ptr bone() const { return _bone; } 
     217        void bone( const bone_ptr &new_bone ); 
     218 
     219        size_t                                  index() const { return _index; } 
     220 
     221private: 
     222        model_builder           *owner; 
     223        size_t                          _index; 
     224 
     225        bone_ptr                        _bone; 
     226 
     227        influence( model_builder *owner ) : owner( owner ) { } 
    216228 
    217229        friend class model_builder; 
     
    222234public: 
    223235        std::string                     name; 
    224         bone_ptr                        bone; 
    225236        ::x42::math::affine     matrix; 
    226237 
    227 private: 
    228         tag() { } 
     238        bone_ptr bone() const { return _bone; } 
     239        void bone( const bone_ptr &new_bone ); 
     240 
     241        size_t                                  index() const { return _index; } 
     242 
     243private: 
     244        model_builder           *owner; 
     245        size_t                          _index; 
     246 
     247        bone_ptr                        _bone; 
     248 
     249        tag( model_builder *owner ) : owner( owner ) { } 
    229250 
    230251        friend class model_builder; 
     
    275296 
    276297        void add( const vertex_weight &weight, bool renormalize_weights = true ); 
     298        void remove( size_t index, bool renormalize_weights = true ); 
    277299        void normalize_weights(); 
    278300 
     
    281303 
    282304        size_t count() const; 
    283         vertex_weight& operator[] ( int index ) { return _weights[index]; } 
    284         const vertex_weight& operator[] ( int index ) const { return _weights[index]; } 
     305        vertex_weight& operator[] ( size_t index ) { if( index >= max_weights ) throw error(); return _weights[index]; } 
     306        const vertex_weight& operator[] ( size_t index ) const { if( index >= max_weights ) throw error(); return _weights[index]; } 
    285307 
    286308private: 
     
    382404{ 
    383405public: 
    384         std::vector< lod_ptr >          lods; 
    385         std::vector< bone_ptr >         bones; 
    386  
    387         animation_tolerances            loose_tolerances; 
    388         animation_tolerances            tight_tolerances; 
     406        std::vector< lod_ptr >                  lods; 
     407        std::vector< bone_ptr >                 bones; 
     408        std::vector< influence_ptr >    influences; 
     409        std::vector< tag_ptr >                  tags; 
     410 
     411        animation_tolerances                    loose_tolerances; 
     412        animation_tolerances                    tight_tolerances; 
    389413 
    390414        model_builder() 
    391415                : loose_tolerances( animation_tolerances::loose_defaults() ), 
    392416                tight_tolerances( animation_tolerances::tight_defaults() ), 
    393                 _bone_update_count( 0 ) 
     417                _bone_update_count( 0 ), _influence_update_count( 0 ), _tag_update_count( 0 ) 
    394418        { 
    395419        } 
     
    399423 
    400424        bone_ptr create_bone( const std::string &name = std::string(), const bone_ptr &parent = bone_ptr() ); 
     425        influence_ptr create_influence( const bone_ptr &bone = bone_ptr(), const ::x42::math::affine &matrix = ::x42::math::affinei() ); 
     426        tag_ptr create_tag( const std::string &name = std::string(), const bone_ptr &bone = bone_ptr(), const ::x42::math::affine &matrix = ::x42::math::affinei() ); 
    401427 
    402428        void begin_bone_update(); //suspends bone validation and sorting 
    403429        void end_bone_update(); //resumes bone validation and sorting 
    404430 
     431        void begin_influence_update(); 
     432        void end_influence_update(); 
     433 
     434        void begin_tag_update(); 
     435        void end_tag_update(); 
     436 
     437        void begin_skeleton_update(); 
     438        void end_skeleton_update(); 
     439 
    405440private: 
    406441        int _bone_update_count; 
     442        int _influence_update_count; 
     443        int _tag_update_count; 
     444 
     445        void validate_bone_prop( const bone_ptr &bone ) const; 
    407446 
    408447        void validate_bone_parent( bone *bone, const bone_ptr &new_parent ) const; 
    409448        void validate_bone_anim_group( bone *bone, uint new_anim_group ) const; 
    410  
    411449        void notify_bone_parent( bone *bone ); 
    412450        void notify_bone_anim_group( bone *bone ); 
    413  
    414451        void validate_bones(); 
    415452        void sort_bones(); 
    416453 
     454        void validate_influence_bone( influence *influence, const bone_ptr &new_bone ) const; 
     455        void notify_influence_bone( influence *influence ); 
     456        void validate_influences(); 
     457 
     458        void validate_tag_bone( tag *tag, const bone_ptr &new_bone ); 
     459        void notify_tag_bone( tag *tag ); 
     460        void validate_tags(); 
     461 
    417462        friend class bone; 
     463        friend class influence; 
     464        friend class tag; 
    418465}; 
    419466 
  • branches/morph-targets/libx42make/local.h

    r440 r511  
    4848#include "batcher.h" 
    4949 
     50#define null NULL 
     51 
    5052#ifdef assert 
    5153#undef assert 
  • branches/morph-targets/libx42make/modelbuilder-geometry.cpp

    r509 r511  
    3434void vertex_weights::add( const vertex_weight &weight, bool renormalize_weights ) 
    3535{ 
     36        struct wt_cmp 
     37        { 
     38                bool operator() ( const vertex_weight &a, const vertex_weight &b ) 
     39                { 
     40                        return a._weight > b._weight; 
     41                } 
     42        }; 
     43 
     44        for( size_t i = 0; i < max_weights; i++ ) 
     45        { 
     46                if( _weights[i]._influence == weight._influence ) 
     47                { 
     48                        //duplicate influences just accumulate 
     49                        vertex_weight tmp( weight._influence, _weights[i]._weight + weight._weight ); 
     50 
     51                        //remove and re-add to get it in the right spot 
     52                        remove( i, false ); 
     53                        add( tmp, renormalize_weights ); 
     54 
     55                        return; 
     56                } 
     57        } 
     58 
     59        //insert into correct position 
    3660        size_t ins_pos; 
    3761        for( ins_pos = 0; ins_pos < max_weights; ins_pos++ ) 
     
    4872 
    4973        _weights[ins_pos] = weight; 
     74 
     75        if( renormalize_weights ) 
     76                normalize_weights(); 
     77} 
     78 
     79void vertex_weights::remove( size_t index, bool renormalize_weights ) 
     80{ 
     81        if( index >= max_weights ) 
     82                return; 
     83 
     84        for( size_t i = max_weights - 1; i > index; i-- ) 
     85                _weights[i - 1] = _weights[i]; 
     86 
     87        _weights[max_weights - 1] = vertex_weight(); 
    5088 
    5189        if( renormalize_weights ) 
  • branches/morph-targets/libx42make/modelbuilder-skeleton.cpp

    r510 r511  
    5151 
    5252/* 
     53        class influence 
     54*/ 
     55 
     56void influence::bone( const bone_ptr &new_bone ) 
     57{ 
     58        owner->validate_influence_bone( this, new_bone ); 
     59 
     60        _bone = new_bone; 
     61 
     62        owner->notify_influence_bone( this ); 
     63} 
     64 
     65/* 
     66        class tag 
     67*/ 
     68 
     69void tag::bone( const bone_ptr &new_bone ) 
     70{ 
     71        owner->validate_tag_bone( this, new_bone ); 
     72 
     73        _bone = new_bone; 
     74 
     75        owner->notify_tag_bone( this ); 
     76} 
     77 
     78/* 
    5379        class model_builder 
    5480*/ 
    5581 
     82void model_builder::validate_bone_prop( const bone_ptr &bone ) const 
     83{ 
     84        if( !bone ) 
     85                return; 
     86 
     87        if( bone->owner != this ) 
     88                throw validation_error( "Bone parent belongs to another model_builder." ); 
     89} 
     90 
     91void model_builder::begin_skeleton_update() 
     92{ 
     93        begin_bone_update(); 
     94        begin_influence_update(); 
     95        begin_tag_update(); 
     96} 
     97 
     98void model_builder::end_skeleton_update() 
     99{ 
     100        end_tag_update(); 
     101        try 
     102        { 
     103                end_influence_update(); 
     104                try 
     105                { 
     106                        end_bone_update(); 
     107                } 
     108                catch( ... ) 
     109                { 
     110                        begin_influence_update(); 
     111                        throw; 
     112                } 
     113        } 
     114        catch( ... ) 
     115        { 
     116                begin_tag_update(); 
     117                throw; 
     118        } 
     119} 
     120 
    56121void model_builder::begin_bone_update() 
    57122{ 
     
    62127{ 
    63128        if( !_bone_update_count ) 
    64                 throw std::exception(); 
    65  
    66         if( !--_bone_update_count
     129                throw error(); 
     130 
     131        if( _bone_update_count == 1
    67132        { 
    68133                validate_bones(); 
    69134                sort_bones(); 
    70135        } 
     136 
     137        _bone_update_count--; 
    71138} 
    72139 
    73140bone_ptr model_builder::create_bone( const std::string &name, const bone_ptr &parent ) 
    74141{ 
     142        validate_bone_parent( null, parent ); 
     143 
    75144        bone_ptr ret( new bone( this ) ); 
    76145 
     
    90159                return; 
    91160 
     161        validate_bone_prop( new_parent ); 
     162 
     163        if( !bone ) 
     164                //validating a parent for a new bone, done 
     165                return; 
     166         
    92167        //check if this would cause a cycle 
    93168        for( bone_ptr p = new_parent; p; p = p->_parent ) 
     
    137212                } 
    138213 
    139                 validate_bone_parent( b.get(), b->_parent.get() ); 
     214                validate_bone_parent( b.get(), b->_parent ); 
    140215                validate_bone_anim_group( b.get(), b->_anim_group ); 
    141216 
     
    199274} 
    200275 
     276void model_builder::begin_influence_update() 
     277{ 
     278        _influence_update_count++; 
     279} 
     280 
     281void model_builder::end_influence_update() 
     282{ 
     283        if( !_influence_update_count ) 
     284                throw error(); 
     285 
     286        if( _influence_update_count == 1 ) 
     287        { 
     288                validate_influences(); 
     289        } 
     290 
     291        _influence_update_count--; 
     292} 
     293 
     294influence_ptr model_builder::create_influence( const bone_ptr &bone, const affine &matrix ) 
     295{ 
     296        validate_influence_bone( null, bone ); 
     297 
     298        influence_ptr ret( new influence( this ) ); 
     299 
     300        ret->_bone = bone; 
     301        ret->matrix = matrix; 
     302 
     303        ret->_index = influences.size(); 
     304        influences.push_back( ret ); 
     305 
     306        return ret; 
     307} 
     308 
     309void model_builder::validate_influence_bone( influence * /* influence */, const bone_ptr &new_bone ) const 
     310{ 
     311        if( _influence_update_count ) 
     312                return; 
     313 
     314        validate_bone_prop( new_bone ); 
     315} 
     316 
     317void model_builder::notify_influence_bone( influence * /* influence */ ) 
     318{ 
     319} 
     320 
     321void model_builder::validate_influences() 
     322{ 
     323        if( _influence_update_count ) 
     324                return; 
     325 
     326        for( size_t i = 0; i < influences.size(); i++ ) 
     327        { 
     328                validate_influence_bone( influences[i].get(), influences[i]->_bone ); 
     329        } 
     330} 
     331 
     332void model_builder::begin_tag_update() 
     333{ 
     334        _tag_update_count++; 
     335} 
     336 
     337void model_builder::end_tag_update() 
     338{ 
     339        if( !_tag_update_count ) 
     340                throw error(); 
     341 
     342        if( _tag_update_count == 1 ) 
     343        { 
     344                validate_tags(); 
     345        } 
     346 
     347        _tag_update_count--; 
     348} 
     349 
     350void model_builder::validate_tag_bone( tag * /* tag */, const bone_ptr &new_bone ) 
     351{ 
     352        if( _tag_update_count ) 
     353                return; 
     354 
     355        validate_bone_prop( new_bone ); 
     356} 
     357 
     358void model_builder::notify_tag_bone( tag * /* tag */ ) 
     359{ 
     360} 
     361 
     362void model_builder::validate_tags() 
     363{ 
     364        if( _tag_update_count ) 
     365                return; 
     366} 
     367 
     368tag_ptr model_builder::create_tag( const std::string &name, const bone_ptr &bone, const affine &matrix ) 
     369{ 
     370        validate_tag_bone( null, bone ); 
     371 
     372        tag_ptr ret( new tag( this ) ); 
     373 
     374        ret->_bone = bone; 
     375        ret->name = name; 
     376        ret->matrix = matrix; 
     377 
     378        ret->_index = tags.size(); 
     379        tags.push_back( ret ); 
     380 
     381        return ret; 
     382} 
     383 
     384 
    201385}; 
    202386};