Changeset 513
- Timestamp:
- 02/20/08 18:03:47 (11 months ago)
- Files:
-
- branches/morph-targets/libx42make/include/x42make-modelbuilder.h (modified) (4 diffs)
- branches/morph-targets/libx42make/modelbuilder-enumerators.cpp (modified) (3 diffs)
- branches/morph-targets/libx42make/modelbuilder-geometry.cpp (modified) (1 diff)
- branches/morph-targets/libx42make/modelbuilder-influences.cpp (modified) (4 diffs)
- branches/morph-targets/libx42make/modelbuilder-skeleton.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/morph-targets/libx42make/include/x42make-modelbuilder.h
r512 r513 369 369 */ 370 370 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 ); 371 374 372 375 size_t vertex_count() const { return base_shape.size(); } … … 454 457 void rebind_and_remove_influence( const influence_ptr &old_influence, const influence_ptr &new_influence ); 455 458 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 456 469 private: 457 470 int _bone_update_count; … … 494 507 void reset(); 495 508 bool next(); 496 group_ptr current() ;509 group_ptr current() const; 497 510 498 511 private: … … 515 528 void reset(); 516 529 bool next(); 517 size_t current_index() ;518 geometry& current_geometry() ;530 size_t current_index() const; 531 geometry& current_geometry() const; 519 532 520 533 private: branches/morph-targets/libx42make/modelbuilder-enumerators.cpp
r512 r513 94 94 } 95 95 96 group_ptr group_enumerator::current() 96 group_ptr group_enumerator::current() const 97 97 { 98 98 if( !model || cur_lod == end_lod || cur_grp < 0 ) … … 161 161 } 162 162 163 size_t vertex_enumerator::current_index() 163 size_t vertex_enumerator::current_index() const 164 164 { 165 if( !cur_grp )165 if( !cur_grp || cur_idx < 0 ) 166 166 throw error(); 167 167 … … 169 169 } 170 170 171 geometry& vertex_enumerator::current_geometry() 171 geometry& vertex_enumerator::current_geometry() const 172 172 { 173 if( !cur_grp )173 if( !cur_grp || cur_idx < 0 ) 174 174 throw error(); 175 175 branches/morph-targets/libx42make/modelbuilder-geometry.cpp
r512 r513 179 179 for( size_t i = 0; i < morph_targets.size(); i++ ) 180 180 { 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 ); 186 186 187 187 for( size_t i = 0; i < indices.size(); i++ ) 188 188 indices[i] = remap[indices[i]]; 189 } 190 191 std::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 234 void 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 ); 189 303 } 190 304 branches/morph-targets/libx42make/modelbuilder-influences.cpp
r512 r513 119 119 for( vertex_enumerator iter( *this ); iter.next(); ) 120 120 { 121 vertex_weights weights = iter.current_geometry().weights[iter.current_index()];121 vertex_weights &weights = iter.current_geometry().weights[iter.current_index()]; 122 122 123 123 for( size_t i = 0; i < vertex_weights::max_weights; i++ ) … … 126 126 continue; 127 127 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 } 133 142 } 134 143 } … … 143 152 void model_builder::erase_influence( const influence_ptr &influence ) 144 153 { 154 if( !influence ) 155 return; 156 145 157 std::vector< influence_ptr >::iterator pos = 146 158 std::find( influences.begin(), influences.end(), influence ); … … 150 162 } 151 163 164 void 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 173 void 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 182 void 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 191 std::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 209 void 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 152 219 }; 153 220 }; branches/morph-targets/libx42make/modelbuilder-skeleton.cpp
r512 r513 313 313 } 314 314 315 std::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 334 void 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 } 315 343 316 344 };
