Changeset 567
- Timestamp:
- 04/23/08 16:54:32 (9 months ago)
- Files:
-
- branches/morph-targets/libx42make/include/x42make-modelbuilder.h (modified) (2 diffs)
- branches/morph-targets/libx42make/modelbuilder-write.cpp (modified) (2 diffs)
- branches/morph-targets/libx42make/modelbuilder.cpp (modified) (1 diff)
- branches/morph-targets/x42maya/common.h (modified) (1 diff)
- branches/morph-targets/x42maya/modelexporter-gather.cpp (modified) (3 diffs)
- branches/morph-targets/x42maya/modelexporter.cpp (modified) (2 diffs)
- branches/morph-targets/x42maya/modelexporter.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/morph-targets/libx42make/include/x42make-modelbuilder.h
r566 r567 598 598 { 599 599 public: 600 std::vector< group_ptr > groups;601 602 600 uint lod_number() const { return _lod_number; } 603 601 604 602 group_ptr create_group( const std::string &surface_name = std::string(), 605 603 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]; } 606 608 607 609 void split_large_groups( … … 617 619 private: 618 620 uint _lod_number; 621 std::vector< group_ptr > groups; 619 622 620 623 model_builder *owner; branches/morph-targets/libx42make/modelbuilder-write.cpp
r566 r567 460 460 outLod.firstGroup = (u16)groups.size(); 461 461 462 for( size_t i = 0; i < inLod->group s.size(); i++ )462 for( size_t i = 0; i < inLod->group_count(); i++ ) 463 463 { 464 const_group_ptr in = inLod->group s[i];464 const_group_ptr in = inLod->group( i ); 465 465 x42group_t out; 466 466 … … 573 573 const_lod_ptr lod = data.lod( l ); 574 574 575 for( size_t i = 0; i < lod->group s.size(); i++ )575 for( size_t i = 0; i < lod->group_count(); i++ ) 576 576 { 577 const geometry &geom = lod ->group s[i]->geometry;577 const geometry &geom = lod ->group( i )->geometry; 578 578 579 579 if( !geom.is_valid() ) branches/morph-targets/libx42make/modelbuilder.cpp
r566 r567 55 55 const std::string &material_name ) 56 56 { 57 group_ptr ret( new group( owner ) );57 group_ptr ret( new make::group( owner ) ); 58 58 59 59 ret->surface_name = surface_name; branches/morph-targets/x42maya/common.h
r554 r567 147 147 #include "util.h" 148 148 149 #include " translator.h"149 #include "modelexporter.h" 150 150 151 151 #include "X42FileTranslator.h" branches/morph-targets/x42maya/modelexporter-gather.cpp
r566 r567 58 58 } 59 59 60 MObject node_obj = path_node( p );60 MObject node_obj = get_node( p ); 61 61 62 62 //see if we already have this bone in the list 63 63 for( size_t i = 0; i < model.bone_count(); i++ ) 64 64 { 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 ) 66 66 return model.bone( i ); 67 67 } … … 88 88 89 89 stat = pp.pop(); 90 switch( stat )90 switch( stat.statusCode() ) 91 91 { 92 92 case MS::kSuccess: … … 118 118 119 119 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 159 MObject 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 223 uint 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 265 group_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 334 void 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 } 121 359 } 122 360 branches/morph-targets/x42maya/modelexporter.cpp
r566 r567 30 30 { 31 31 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; 32 bool 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 78 bool 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 ); 46 88 } 47 89 … … 241 283 } 242 284 285 void 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 243 297 void model_exporter::add_objects( const export_selection &sel ) 244 298 { branches/morph-targets/x42maya/modelexporter.h
r566 r567 50 50 }; 51 51 52 void check_status( MStatus status ); 53 MObject path_node( const MDagPath &path ); 52 inline void check_status( MStatus status ) 53 { 54 if( status != MS::kSuccess ) 55 throw maya_error( status ); 56 } 57 58 template< typename T > 59 MObject 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 69 template< typename T > 70 T 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 87 template< typename T > 88 T 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 103 bool has_connection( const MPlug &plug, bool incoming, bool outgoing ); 104 bool has_connection( const MObject &obj, const char *attribute, bool incoming, bool outgoing ); 54 105 55 106 typedef make::simple_api_tag< MObject > obj_tag; … … 97 148 98 149 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 ); 99 153 100 154 static const int do_not_split = -1; … … 113 167 make::group_split_limits split_limits; 114 168 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 115 177 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 ); 116 185 }; 117 186
