------------------------------------------------------------------------------------------------ Calculates tangents and bi-tangents for the given mesh
| 101 | // ------------------------------------------------------------------------------------------------ |
| 102 | // Calculates tangents and bi-tangents for the given mesh |
| 103 | bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) { |
| 104 | // we assume that the mesh is still in the verbose vertex format where each face has its own set |
| 105 | // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to |
| 106 | // assert() it here. |
| 107 | // assert( must be verbose, dammit); |
| 108 | |
| 109 | if (pMesh->mTangents) // this implies that mBitangents is also there |
| 110 | return false; |
| 111 | |
| 112 | // If the mesh consists of lines and/or points but not of |
| 113 | // triangles or higher-order polygons the normal vectors |
| 114 | // are undefined. |
| 115 | if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) { |
| 116 | ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes"); |
| 117 | return false; |
| 118 | } |
| 119 | |
| 120 | // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement |
| 121 | if (pMesh->mNormals == nullptr) { |
| 122 | ASSIMP_LOG_ERROR("Failed to compute tangents; need normals"); |
| 123 | return false; |
| 124 | } |
| 125 | if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) { |
| 126 | ASSIMP_LOG_ERROR("Failed to compute tangents; need UV data in channel", configSourceUV); |
| 127 | return false; |
| 128 | } |
| 129 | |
| 130 | const float angleEpsilon = 0.9999f; |
| 131 | |
| 132 | std::vector<bool> vertexDone(pMesh->mNumVertices, false); |
| 133 | const float qnan = get_qnan(); |
| 134 | |
| 135 | // create space for the tangents and bitangents |
| 136 | pMesh->mTangents = new aiVector3D[pMesh->mNumVertices]; |
| 137 | pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices]; |
| 138 | |
| 139 | const aiVector3D *meshPos = pMesh->mVertices; |
| 140 | const aiVector3D *meshNorm = pMesh->mNormals; |
| 141 | const aiVector3D *meshTex = pMesh->mTextureCoords[configSourceUV]; |
| 142 | aiVector3D *meshTang = pMesh->mTangents; |
| 143 | aiVector3D *meshBitang = pMesh->mBitangents; |
| 144 | |
| 145 | // calculate the tangent and bitangent for every face |
| 146 | for (unsigned int a = 0; a < pMesh->mNumFaces; a++) { |
| 147 | const aiFace &face = pMesh->mFaces[a]; |
| 148 | if (face.mNumIndices < 3) { |
| 149 | // There are less than three indices, thus the tangent vector |
| 150 | // is not defined. We are finished with these vertices now, |
| 151 | // their tangent vectors are set to qnan. |
| 152 | for (unsigned int i = 0; i < face.mNumIndices; ++i) { |
| 153 | unsigned int idx = face.mIndices[i]; |
| 154 | vertexDone[idx] = true; |
| 155 | meshTang[idx] = aiVector3D(qnan); |
| 156 | meshBitang[idx] = aiVector3D(qnan); |
| 157 | } |
| 158 | |
| 159 | continue; |
| 160 | } |
nothing calls this directly
no test coverage detected