- Timestamp:
- 05/30/14 18:14:17 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/assimp_loader.cc
r248 r249 270 270 } 271 271 272 assimp_animation* nv::assimp_loader::release_animation( size_t, bool pre_transform, const std::vector< assimp_bone >* bone_data ) 273 { 274 if ( m_scene == nullptr ) return nullptr; 275 const aiScene* scene = (const aiScene*)m_scene; 276 if ( scene->mRootNode == nullptr || scene->mAnimations[0] == nullptr ) return nullptr; 277 assimp_animation* result = new assimp_animation; 278 279 // need resize not to copy! 280 result->nodes.resize( count_nodes( scene->mRootNode ) ); 281 282 const aiNode* root = scene->mRootNode; 283 const aiAnimation* anim = scene->mAnimations[0]; // if implemented, change in load_node also 284 285 result->fps = (float)anim->mTicksPerSecond; 286 result->duration = (float)anim->mDuration; 287 result->pretransformed = pre_transform; 288 289 load_node( result, root, 0, -1 ); 290 result->nodes[0].transform = glm::scale( m_scale, m_scale, m_scale ) * result->nodes[0].transform; 291 292 if ( bone_data ) 293 { 294 std::unordered_map< std::string, uint16 > names; 295 for ( uint16 bi = 0; bi < bone_data->size(); ++bi ) 296 { 297 names[ (*bone_data)[bi].name ] = bi; 298 } 299 300 for ( unsigned i = 0; i < result->nodes.size(); ++i ) 301 { 302 assimp_animated_node_data& node = result->nodes[i]; 303 node.bone_id = -1; 304 auto bi = names.find( node.name ); 305 if ( bi != names.end() ) 306 { 307 node.bone_id = bi->second; 308 } 309 if ( node.parent_id != -1 ) 310 { 311 result->nodes[ node.parent_id ].children.push_back( &node ); 312 } 313 } 314 } 315 316 return result; 317 } 318 319 nv::uint32 nv::assimp_loader::count_nodes( const void* node ) const 320 { 321 const aiNode* ainode = (const aiNode*)node; 322 nv::uint32 count = 1; 323 for ( unsigned i = 0; i < ainode->mNumChildren; ++i ) 324 { 325 count += count_nodes( ainode->mChildren[i] ); 326 } 327 return count; 328 } 329 330 nv::uint32 nv::assimp_loader::load_node( assimp_animation* data, const void* vnode, sint32 this_id, sint32 parent_id ) 331 { 332 const aiScene* scene = (const aiScene*)m_scene; 333 const aiNode* node = (const aiNode*)vnode; 334 string name( node->mName.data ); 335 const aiAnimation* anim = scene->mAnimations[0]; 336 const aiNodeAnim* anode = nullptr; 337 338 for ( unsigned i = 0 ; i < anim->mNumChannels ; i++ ) 339 { 340 anode = anim->mChannels[i]; 341 if ( std::string( anode->mNodeName.data ) == name ) break; 342 anode = nullptr; 343 } 344 345 assimp_animated_node_data& a_data = data->nodes[ this_id ]; 346 347 a_data.name = name; 348 a_data.parent_id = parent_id; 349 a_data.bone_id = -1; 350 a_data.transform = nv::assimp_mat4_cast( node->mTransformation ); 351 352 if (anode) 353 { 354 if ( data->pretransformed ) 355 { 356 a_data.keys = create_transformed_keys( anode, parent_id >= 0 ? data->nodes[ parent_id ].keys : nullptr ); 357 } 358 else 359 { 360 a_data.keys = create_direct_keys( anode ); 361 } 362 } 363 364 nv::uint32 next = this_id + 1; 365 for ( unsigned i = 0; i < node->mNumChildren; ++i ) 366 { 367 next = load_node( data, node->mChildren[i], next, this_id ); 368 } 369 return next; 370 } 371 372 key_animation_data* nv::assimp_loader::create_transformed_keys( const void* vnode, const key_animation_data* parent_keys ) 373 { 374 const aiNodeAnim* node = (const aiNodeAnim*)vnode; 375 size_t max_keys = glm::max( node->mNumPositionKeys, node->mNumRotationKeys ); 376 nv::transform_vector* keys = new nv::transform_vector; 377 for ( unsigned n = 0; n < max_keys; ++n ) 378 { 379 size_t pn = glm::min( node->mNumPositionKeys - 1, n ); 380 size_t rn = glm::min( node->mNumRotationKeys - 1, n ); 381 nv::vec3 pos = nv::assimp_vec3_cast(node->mPositionKeys[pn].mValue); 382 nv::quat rot = nv::assimp_quat_cast(node->mRotationKeys[rn].mValue); 383 nv::transform ptr; 384 if ( parent_keys ) 385 { 386 const nv::transform_vector* pv = (const nv::transform_vector*)parent_keys; 387 if ( pv && pv->size() > 0 ) ptr = pv->get( glm::min( n, pv->size()-1 ) ); 388 } 389 390 nv::vec3 rot_pos = ptr.get_orientation() * pos; 391 pos = ptr.get_position() + rot_pos; 392 rot = glm::normalize( ptr.get_orientation() * rot ); 393 keys->insert( nv::transform( pos, rot ) ); 394 } 395 return keys; 396 } 397 398 key_animation_data* nv::assimp_loader::create_direct_keys( const void* vnode ) 399 { 400 const aiNodeAnim* node = (const aiNodeAnim*)vnode; 401 if ( node->mNumPositionKeys == 0 && node->mNumRotationKeys == 0 && node->mNumScalingKeys == 0 ) return nullptr; 402 key_vectors_prs* keys = new key_vectors_prs; 403 404 for ( unsigned np = 0; np < node->mNumPositionKeys; ++np ) 405 { 406 keys->insert_position( (float)node->mPositionKeys[np].mTime, assimp_vec3_cast(node->mPositionKeys[np].mValue) ); 407 } 408 for ( unsigned np = 0; np < node->mNumRotationKeys; ++np ) 409 { 410 keys->insert_rotation( (float)node->mRotationKeys[np].mTime, assimp_quat_cast(node->mRotationKeys[np].mValue) ); 411 } 412 if ( node->mNumScalingKeys > 0 ) 413 { 414 nv::vec3 scale_vec0 = assimp_vec3_cast( node->mScalingKeys[0].mValue ); 415 float scale_value = glm::length( glm::abs( scale_vec0 - nv::vec3(1,1,1) ) ); 416 if ( node->mNumScalingKeys > 1 || scale_value > 0.001 ) 417 { 418 NV_LOG( nv::LOG_WARNING, "scale key significant!" ); 419 for ( unsigned np = 0; np < node->mNumRotationKeys; ++np ) 420 { 421 keys->insert_scale( (float)node->mScalingKeys[np].mTime, assimp_vec3_cast(node->mScalingKeys[np].mValue) ); 422 } 423 } 424 } 425 return keys; 426 } 427
Note: See TracChangeset
for help on using the changeset viewer.