| 458 | } |
| 459 | |
| 460 | void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData) |
| 461 | { |
| 462 | if (aimesh->mNumBones < 1) { |
| 463 | return; |
| 464 | } |
| 465 | |
| 466 | // Store the vertex joint and weight data. |
| 467 | const size_t NumVerts( aimesh->mNumVertices ); |
| 468 | vec4* vertexJointData = new vec4[ NumVerts ]; |
| 469 | vec4* vertexWeightData = new vec4[ NumVerts ]; |
| 470 | int* jointsPerVertex = new int[ NumVerts ]; |
| 471 | for (size_t i = 0; i < NumVerts; ++i) { |
| 472 | jointsPerVertex[i] = 0; |
| 473 | for (size_t j = 0; j < 4; ++j) { |
| 474 | vertexJointData[i][j] = 0; |
| 475 | vertexWeightData[i][j] = 0; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) { |
| 480 | const aiBone* aib = aimesh->mBones[idx_bone]; |
| 481 | |
| 482 | // aib->mName =====> skinRef->jointNames |
| 483 | // Find the node with id = mName. |
| 484 | Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str()); |
| 485 | nodeRef->jointName = nodeRef->id; |
| 486 | |
| 487 | unsigned int jointNamesIndex = 0; |
| 488 | bool addJointToJointNames = true; |
| 489 | for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) { |
| 490 | if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) { |
| 491 | addJointToJointNames = false; |
| 492 | jointNamesIndex = idx_joint; |
| 493 | } |
| 494 | } |
| 495 | |
| 496 | if (addJointToJointNames) { |
| 497 | skinRef->jointNames.push_back(nodeRef); |
| 498 | |
| 499 | // aib->mOffsetMatrix =====> skinRef->inverseBindMatrices |
| 500 | aiMatrix4x4 tmpMatrix4; |
| 501 | CopyValue(aib->mOffsetMatrix, tmpMatrix4); |
| 502 | inverseBindMatricesData.push_back(tmpMatrix4); |
| 503 | jointNamesIndex = static_cast<unsigned int>(inverseBindMatricesData.size() - 1); |
| 504 | } |
| 505 | |
| 506 | // aib->mWeights =====> vertexWeightData |
| 507 | for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) { |
| 508 | unsigned int vertexId = aib->mWeights[idx_weights].mVertexId; |
| 509 | float vertWeight = aib->mWeights[idx_weights].mWeight; |
| 510 | |
| 511 | // A vertex can only have at most four joint weights. Ignore all others. |
| 512 | if (jointsPerVertex[vertexId] > 3) { |
| 513 | continue; |
| 514 | } |
| 515 | |
| 516 | vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex); |
| 517 | vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight; |
no test coverage detected