//-------------------------------------------------------------------------------------- void SkeletonAnimation::_calcBoneOffsetHeirarchy(float animationTime, SkeletonBone *pBone, const Matrix4f &parentTransform, BoneOffsetMatrixVector& boneOffsetMatrix) { Matrix4f nodeTransformation(pBone->GetTransform()); const SkeletonNodeTrack *pTrack = GetTrack(pBone->GetName()); if(pTrack) nodeTransformation = _calcInterPolatedTransform(pTrack, animationTime); Matrix4f globalTranformation = parentTransform * nodeTransformation; int index = mp_skeleton->GetBoneIndex(pBone->GetName()); if(index != -1) { //通过这种方式来实现,可以用来支持多个骨骼动画的支持 boneOffsetMatrix[index] = boneOffsetMatrix[index] * mp_skeleton->GetGlobalInverseMatrix() * globalTranformation * mp_skeleton->GetBoneOffset(index); } for(unsigned i=0; i < pBone->NumChildren(); ++i) { _calcBoneOffsetHeirarchy(animationTime, (SkeletonBone *)pBone->GetChild(i), globalTranformation, boneOffsetMatrix); } }
void ModelLoader::addMeshesFromNode(const aiScene *scene, const aiNode *currentNode,const glm::mat4 ¤tNodeTransformation, std::shared_ptr<Model<Vertex3DNormTex>> model,const std::vector<std::shared_ptr<Material>> &materials, float scale, bool deleteLocalData) { glm::mat4 nodeTransformation(currentNodeTransformation * aiMatrix4ToGlmMat4(currentNode->mTransformation)); for (unsigned int meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex) { const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[meshIndex]]; std::shared_ptr<Mesh<Vertex3DNormTex>> currentGeneratedMesh(std::make_shared<Mesh<Vertex3DNormTex>>()); currentGeneratedMesh->initialize(); std::vector<unsigned int> indices; for (unsigned int faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) { const aiFace *face(&mesh->mFaces[faceIndex]); for (unsigned int i = 0; i < face->mNumIndices; ++i) { unsigned int currentIndex = face->mIndices[i]; indices.push_back(currentIndex); } } for (unsigned int vertexIndex = 0; vertexIndex < mesh->mNumVertices; ++vertexIndex) { Vertex3DNormTex currentVertex; currentVertex.m_position.x = mesh->mVertices[vertexIndex].x; currentVertex.m_position.y = mesh->mVertices[vertexIndex].y; currentVertex.m_position.z = mesh->mVertices[vertexIndex].z; currentVertex.m_position = glm::vec3(nodeTransformation * glm::vec4(currentVertex.m_position, 1)); if (mesh->HasNormals()) { currentVertex.m_normal.x = mesh->mNormals[vertexIndex].x; currentVertex.m_normal.y = mesh->mNormals[vertexIndex].y; currentVertex.m_normal.z = mesh->mNormals[vertexIndex].z; currentVertex.m_normal = glm::normalize(glm::vec3(glm::transpose(glm::inverse(nodeTransformation)) * glm::vec4(currentVertex.m_normal, 0))); } if (mesh->HasTextureCoords(0)) { currentVertex.m_texCoord.x = mesh->mTextureCoords[0][vertexIndex].x; currentVertex.m_texCoord.y = mesh->mTextureCoords[0][vertexIndex].y; } currentGeneratedMesh->addVertex(currentVertex); } currentGeneratedMesh->setIndices(indices); currentGeneratedMesh->uploadData(deleteLocalData); std::shared_ptr<Material> currentGeneratedMaterial(materials[mesh->mMaterialIndex]); MeshData meshData; meshData.position = glm::vec3(0, 0, 0); model->addMesh(currentGeneratedMesh, currentGeneratedMaterial, meshData); } for (unsigned int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex) { addMeshesFromNode(scene, currentNode->mChildren[childIndex], nodeTransformation, model, materials, scale, deleteLocalData); } }