Changeset 567

Show
Ignore:
Timestamp:
04/23/08 16:54:32 (9 months ago)
Author:
phill
Message:

o More WIP.

Files:

Legend:

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

    r566 r567  
    598598{ 
    599599public:  
    600         std::vector< group_ptr >        groups; 
    601  
    602600        uint lod_number() const { return _lod_number; } 
    603601 
    604602        group_ptr create_group( const std::string &surface_name = std::string(), 
    605603                const std::string &material_name = std::string() ); 
     604 
     605        size_t group_count() const { return groups.size(); } 
     606        group_ptr group( size_t i ) { return groups[i]; } 
     607        const_group_ptr group( size_t i ) const { return groups[i]; } 
    606608 
    607609        void split_large_groups( 
     
    617619private: 
    618620        uint                                            _lod_number; 
     621        std::vector< group_ptr >        groups; 
    619622 
    620623        model_builder                           *owner; 
  • branches/morph-targets/libx42make/modelbuilder-write.cpp

    r566 r567  
    460460                outLod.firstGroup = (u16)groups.size(); 
    461461 
    462                 for( size_t i = 0; i < inLod->groups.size(); i++ ) 
     462                for( size_t i = 0; i < inLod->group_count(); i++ ) 
    463463                { 
    464                         const_group_ptr in = inLod->groups[i]
     464                        const_group_ptr in = inLod->group( i )
    465465                        x42group_t out; 
    466466                         
     
    573573                const_lod_ptr lod = data.lod( l ); 
    574574                 
    575                 for( size_t i = 0; i < lod->groups.size(); i++ ) 
     575                for( size_t i = 0; i < lod->group_count(); i++ ) 
    576576                { 
    577                         const geometry &geom = lod ->groups[i]->geometry; 
     577                        const geometry &geom = lod ->group( i )->geometry; 
    578578 
    579579                        if( !geom.is_valid() ) 
  • branches/morph-targets/libx42make/modelbuilder.cpp

    r566 r567  
    5555        const std::string &material_name ) 
    5656{ 
    57         group_ptr ret( new group( owner ) ); 
     57        group_ptr ret( new make::group( owner ) ); 
    5858 
    5959        ret->surface_name = surface_name; 
  • branches/morph-targets/x42maya/common.h

    r554 r567  
    147147#include "util.h" 
    148148 
    149 #include "translator.h" 
     149#include "modelexporter.h" 
    150150 
    151151#include "X42FileTranslator.h" 
  • branches/morph-targets/x42maya/modelexporter-gather.cpp

    r566 r567  
    5858        } 
    5959 
    60         MObject node_obj = path_node( p ); 
     60        MObject node_obj = get_node( p ); 
    6161 
    6262        //see if we already have this bone in the list 
    6363        for( size_t i = 0; i < model.bone_count(); i++ ) 
    6464        { 
    65                 if( path_node( dag_tag::get_value( model.bone( i )->user_tag ) ) == node_obj ) 
     65                if( get_node( dag_tag::get_value( model.bone( i )->user_tag ) ) == node_obj ) 
    6666                        return model.bone( i ); 
    6767        } 
     
    8888                 
    8989                stat = pp.pop(); 
    90                 switch( stat
     90                switch( stat.statusCode()
    9191                { 
    9292                case MS::kSuccess: 
     
    118118 
    119119        bool static_anim = true; 
    120  
     120        if( parent && get_attribute_value_or_default( node_obj, 
     121                "segmentScaleCompensate", false ) ) 
     122        { 
     123                static_anim = parent->static_bone_hint || 
     124                        !has_connection( node_obj, "inverseScale", true, false ); 
     125        } 
     126 
     127        //hack - IK doesn't connect in the usual way, it just attaches via 
     128        //"message" attribute and sets values directly (which then get keyed) 
     129 
     130        if( has_connection( node_obj, "message", false, true ) ) 
     131                static_anim = false; 
     132 
     133        for( size_t i = 0; static_anim && i < lengthof( anim_attrs ); i++ ) 
     134                static_anim = !has_connection( node_obj, anim_attrs[i], true, false ); 
     135 
     136        bone_ptr ret = model.create_bone( name.asChar(), parent ); 
     137        ret->flags = bone_flags::none; 
     138        ret->static_bone_hint = static_anim; 
     139         
     140        ret->loose_tolerances.position = get_attribute_value_or_default( 
     141                node_obj, "x42_posTol", ret->loose_tolerances.position ); 
     142        ret->loose_tolerances.rotation = get_attribute_value_or_default( 
     143                node_obj, "x42_rotTol", ret->loose_tolerances.rotation ); 
     144        ret->loose_tolerances.scale = get_attribute_value_or_default( 
     145                node_obj, "x42_scaleTol", ret->loose_tolerances.scale ); 
     146         
     147        ret->tight_tolerances.position = get_attribute_value_or_default( 
     148                node_obj, "x42_pinPosTol", ret->tight_tolerances.position ); 
     149        ret->tight_tolerances.rotation = get_attribute_value_or_default( 
     150                node_obj, "x42_pinPosTol", ret->tight_tolerances.rotation ); 
     151        ret->tight_tolerances.scale = get_attribute_value_or_default( 
     152                node_obj, "x42_pinPosTol", ret->tight_tolerances.scale ); 
     153 
     154        ret->user_tag = api_tag_ptr( new dag_tag( p ) ); 
     155 
     156        return ret; 
     157
     158 
     159MObject model_exporter::get_skin_input( const MObject &draw_mesh ) 
     160
     161        MStatus stat; 
     162 
     163        MFnDependencyNode node( draw_mesh, &stat ); 
     164        check_status( stat ); 
     165 
     166        MPlug plug = node.findPlug( "inMesh", true, &stat ); 
     167        check_status( stat ); 
     168 
     169        while( stat == MS::kSuccess ) 
     170        { 
     171                MPlugArray inputs; 
     172                plug.connectedTo( inputs, true, false, &stat ); 
     173                check_status( stat ); 
     174 
     175                if( inputs.length() != 1 ) 
     176                        throw make::error( "too many mesh inputs" ); 
     177 
     178                plug = inputs[0]; 
     179                MObject obj = get_node( plug ); 
     180 
     181                stat = node.setObject( obj ); 
     182                check_status( stat ); 
     183 
     184                switch( obj.apiType() ) 
     185                { 
     186                case MFn::kSkinClusterFilter: 
     187                //case MFn::kJointCluster: 
     188                        return obj; 
     189                } 
     190 
     191                stat = MS::kFailure; //be pessimistic 
     192 
     193                MObject attr_obj = plug.attribute( &stat ); 
     194                check_status( stat ); 
     195 
     196                MFnAttribute attr( attr_obj, &stat ); 
     197                check_status( stat ); 
     198 
     199                MString type_name = node.typeName( &stat ); 
     200                check_status( stat ); 
     201 
     202                MString out_name = attr.name( &stat ); 
     203                check_status( stat ); 
     204 
     205                for( size_t i = 0; i < allowed_skin_mods.size(); i++ ) 
     206                { 
     207                        const dg_nav &nav = allowed_skin_mods[i]; 
     208 
     209                        if( type_name == nav.type && out_name == nav.out_plug ) 
     210                        { 
     211                                plug = node.findPlug( nav.in_plug, true, &stat ); 
     212                                break; 
     213                        } 
     214                } 
     215 
     216                //if we fell out wihtout finding a node to walk through 
     217                //then stat will be kFailure and we'll fall out of the loop 
     218        } 
     219 
     220        return MObject::kNullObj; 
     221
     222 
     223uint model_exporter::get_lod_number( const MObject &mesh ) 
     224
     225        MStatus stat; 
     226 
     227        MFnDependencyNode node( mesh, &stat ); 
     228        check_status( stat ); 
     229 
     230        MPlug lod_plug = node.findPlug( "level_of_detail_number", true, &stat ); 
     231        if( stat ) 
     232        { 
     233                int val; 
     234                if( lod_plug.getValue( val ) == MS::kSuccess ) 
     235                { 
     236                        if( val < 0 ) 
     237                                val = 0; 
     238 
     239                        return (uint)val; 
     240                } 
     241        } 
     242 
     243        MString name = node.name( &stat ); 
     244        check_status( stat ); 
     245 
     246        int idx = name.rindex( '_' ); 
     247 
     248        if( idx == -1 ) 
     249                return 0; 
     250 
     251        idx += 1; 
     252        MString substr = name.substring( idx, name.length() - 1 ); 
     253 
     254        if( !substr.isInt() ) 
     255                return 0; 
     256 
     257        int val = substr.asInt(); 
     258        if( val < 0 ) 
     259                val = 0; 
     260 
     261        return (uint)val; 
     262 
     263
     264 
     265group_ptr model_exporter::get_group_for_set( uint lod_num, const MObject &set_obj ) 
     266
     267        MStatus stat; 
     268 
     269        MFnSet set( set_obj, &stat ); 
     270        check_status( stat ); 
     271 
     272        MString surface_name = set.name( &stat ); 
     273        check_status( stat ); 
     274 
     275        MString shader_name; 
     276 
     277        try 
     278        { 
     279                MPlug shader_plug = set.findPlug( "surfaceShader", true, &stat ); 
     280                check_status( stat ); 
     281 
     282                MPlugArray connected; 
     283                shader_plug.connectedTo( connected, true, false, &stat ); 
     284                check_status( stat ); 
     285 
     286                if( connected.length() != 1 ) 
     287                        throw make::error( "invalid shader connection" ); 
     288 
     289                MFnDependencyNode shader( get_node( connected[0] ), &stat ); 
     290                check_status( stat ); 
     291 
     292                MString type_name = shader.typeName( &stat ); 
     293                check_status( stat ); 
     294 
     295                if( type_name == "Q3Shader" ) 
     296                { 
     297                        MPlug name_plug = shader.findPlug( "shaderName", true, &stat ); 
     298                        check_status( stat ); 
     299 
     300                        stat = name_plug.getValue( shader_name ); 
     301                        check_status( stat ); 
     302                } 
     303                else 
     304                { 
     305                        shader_name = shader.name( &stat ); 
     306                        check_status( stat ); 
     307                } 
     308        } 
     309        catch( ... ) 
     310        { 
     311                MGlobal::displayError( MString( "Error getting shader name for " ) + surface_name ); 
     312                throw; 
     313        } 
     314 
     315        if( shader_name == "lambert1" ) 
     316                return group_ptr(); 
     317 
     318        lod_ptr lod = model.find_or_create_lod( lod_num ); 
     319         
     320        for( size_t i = 0; i < lod->group_count(); i++ ) 
     321        { 
     322                group_ptr grp = lod->group( i ); 
     323 
     324                if( grp->surface_name == surface_name.asChar() ) 
     325                        return grp; 
     326        } 
     327 
     328        group_ptr ret = lod->create_group( surface_name.asChar(), shader_name.asChar() ); 
     329        ret->geometry.prim_type = primitive_type::triangle_list; 
     330 
     331        return ret; 
     332
     333 
     334void model_exporter::add_mesh( const MDagPath &path ) 
     335
     336        MObject skin = get_skin_input( get_node( path ) ); 
     337 
     338        if( !skin.isNull() ) 
     339        { 
     340                switch( skin.apiType() ) 
     341                { 
     342                case MFn::kSkinClusterFilter: 
     343                        add_skinned_mesh( path, skin ); 
     344                        break; 
     345                         
     346                //ToDo: 
     347                //case MFn::kJointCluster: 
     348                        //add_joint_cluster_skinned_mesh( skin, path ); 
     349                        //break; 
     350 
     351                default: 
     352                        throw make::error( "unsupported skin type" ); 
     353                } 
     354        } 
     355        else 
     356        { 
     357                add_rigid_mesh( path ); 
     358        } 
    121359} 
    122360 
  • branches/morph-targets/x42maya/modelexporter.cpp

    r566 r567  
    3030{ 
    3131 
    32 void check_status( MStatus status ) 
    33 
    34         if( status != MS::kSuccess ) 
    35                 throw maya_error( status ); 
    36 
    37  
    38 MObject path_node( const MDagPath &path ) 
    39 
    40         MStatus stat; 
    41          
    42         MObject ret = path.node( &stat ); 
    43         check_status( stat ); 
    44  
    45         return ret; 
     32bool has_connection( const MPlug &plug, bool incoming, bool outgoing ) 
     33
     34        MStatus stat; 
     35 
     36        MPlugArray plugs; 
     37        plug.connectedTo( plugs, incoming, outgoing, &stat ); 
     38        check_status( stat ); 
     39 
     40        if( plugs.length() > 0 ) 
     41                return true; 
     42 
     43        bool array = plug.isArray( &stat ); 
     44        if( array && stat == MS::kSuccess ) 
     45        { 
     46                uint count = plug.numElements( &stat ); 
     47                check_status( stat ); 
     48 
     49                for( uint i = 0; i < count; i++ ) 
     50                { 
     51                        MPlug elem = plug.elementByPhysicalIndex( i, &stat ); 
     52                        check_status( stat ); 
     53 
     54                        if( has_connection( elem, incoming, outgoing ) ) 
     55                                return true; 
     56                } 
     57        } 
     58 
     59        bool compound = plug.isCompound( &stat ); 
     60        if( compound && stat == MS::kSuccess ) 
     61        { 
     62                uint count = plug.numChildren( &stat ); 
     63                check_status( stat ); 
     64 
     65                for( uint i = 0; i < count; i++ ) 
     66                { 
     67                        MPlug child = plug.child( i, &stat ); 
     68                        check_status( stat ); 
     69 
     70                        if( has_connection( child, incoming, outgoing ) ) 
     71                                return true; 
     72                } 
     73        } 
     74 
     75        return false; 
     76
     77 
     78bool has_connection( const MObject &obj, const char *attribute, bool incoming, bool outgoing ) 
     79
     80        MStatus stat; 
     81        MFnDependencyNode depNode( obj, &stat ); 
     82        check_status( stat ); 
     83         
     84        MPlug plug = depNode.findPlug( MString( attribute ), true, &stat ); 
     85        check_status( stat ); 
     86 
     87        return has_connection( plug, incoming, outgoing ); 
    4688} 
    4789 
     
    241283} 
    242284 
     285void model_exporter::allow_skin_modifier( const MString &modifier_type, 
     286        const MString &out_plug, const MString &in_plug ) 
     287{ 
     288        dg_nav nav; 
     289         
     290        nav.type = modifier_type; 
     291        nav.out_plug = out_plug; 
     292        nav.in_plug = in_plug; 
     293 
     294        allowed_skin_mods.push_back( nav ); 
     295} 
     296 
    243297void model_exporter::add_objects( const export_selection &sel ) 
    244298{ 
  • branches/morph-targets/x42maya/modelexporter.h

    r566 r567  
    5050}; 
    5151 
    52 void check_status( MStatus status ); 
    53 MObject path_node( const MDagPath &path ); 
     52inline void check_status( MStatus status ) 
     53
     54        if( status != MS::kSuccess ) 
     55                throw maya_error( status ); 
     56
     57 
     58template< typename T > 
     59MObject get_node( const T &src ) 
     60
     61        MStatus stat; 
     62         
     63        MObject ret = src.node( &stat ); 
     64        check_status( stat ); 
     65 
     66        return ret; 
     67
     68 
     69template< typename T > 
     70T get_attribute_value( const MObject &obj, const char *attribute ) 
     71
     72        MStatus stat; 
     73 
     74        MFnDependencyNode node( obj, &stat ); 
     75        check_status( stat ); 
     76 
     77        MPlug plug = node.findPlug( MString( attribute ), true, &stat ); 
     78        check_status( stat ); //other error codes are, um, errors 
     79 
     80        T val; 
     81        stat = plug.getValue( val ); 
     82        check_status( stat ); 
     83 
     84        return val; 
     85
     86 
     87template< typename T > 
     88T get_attribute_value_or_default( const MObject &obj, const char *attribute, const T &def ) 
     89
     90        try 
     91        { 
     92                return get_attribute_value< T >( obj, attribute ); 
     93        } 
     94        catch( const maya_error &err ) 
     95        { 
     96                if( err.status_code() == MS::kFailure ) 
     97                        return def; 
     98 
     99                throw; 
     100        } 
     101
     102 
     103bool has_connection( const MPlug &plug, bool incoming, bool outgoing ); 
     104bool has_connection( const MObject &obj, const char *attribute, bool incoming, bool outgoing ); 
    54105 
    55106typedef make::simple_api_tag< MObject > obj_tag; 
     
    97148 
    98149        void write_file( std::ostream &out ); 
     150 
     151        void allow_skin_modifier( const MString &modifier_type, 
     152                const MString &out_plug, const MString &in_plug ); 
    99153 
    100154        static const int do_not_split = -1; 
     
    113167        make::group_split_limits split_limits; 
    114168 
     169        struct dg_nav 
     170        { 
     171                MString type;                   //the name of the allowed node 
     172                MString out_plug;               //the plug we're pulling data from 
     173                MString in_plug;                //the plug to follow up stream 
     174        }; 
     175        std::vector< dg_nav > allowed_skin_mods; 
     176 
    115177        bone_ptr import_bone( const MDagPath &path ); 
     178 
     179        MObject get_skin_input( const MObject &draw_mesh ); 
     180        uint get_lod_number( const MObject &mesh ); 
     181        group_ptr get_group_for_set( uint lod_num, const MObject &set_obj ); 
     182 
     183        void add_skinned_mesh( const MDagPath &draw_mesh_path, const MObject &skin_obj ); 
     184        void add_rigid_mesh( const MDagPath &draw_mesh_path ); 
    116185}; 
    117186