GenerateMikkTSpaceTangents.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "GenerateMikkTSpaceTangents.h"
  2. #include <assimp/scene.h>
  3. #include <assimp/postprocess.h>
  4. namespace Assimp {
  5. static int get_num_faces(const SMikkTSpaceContext *context);
  6. static int get_num_vertices_of_face(const SMikkTSpaceContext *context, int iFace);
  7. static void get_position(const SMikkTSpaceContext *context, float outpos[], int iFace, int iVert);
  8. static void get_normal(const SMikkTSpaceContext *context, float outnormal[], int iFace, int iVert);
  9. static void get_tex_coords(const SMikkTSpaceContext *context, float outuv[], int iFace, int iVert);
  10. static void set_tspace_basic(const SMikkTSpaceContext *context, const float tangentu[], float fSign, int iFace, int iVert);
  11. static int get_num_faces(const SMikkTSpaceContext *context) {
  12. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  13. const int numFaces = static_cast<int>(currentMesh->mNumFaces);
  14. return numFaces;
  15. }
  16. static int get_num_vertices_of_face(const SMikkTSpaceContext *context, int iFace) {
  17. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  18. const aiFace &face = currentMesh->mFaces[iFace];
  19. return face.mNumIndices;
  20. }
  21. static void get_position(const SMikkTSpaceContext *context, float outpos[], int /*iFace*/, int iVert) {
  22. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  23. const aiVector3D &v = currentMesh->mVertices[static_cast<size_t>(iVert)];
  24. outpos[0] = v.x;
  25. outpos[1] = v.y;
  26. outpos[2] = v.z;
  27. }
  28. static void get_normal(const SMikkTSpaceContext *context, float outnormal[], int /*iFace*/, int iVert) {
  29. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  30. const aiVector3D &n = currentMesh->mNormals[static_cast<size_t>(iVert)];
  31. outnormal[0] = n.x;
  32. outnormal[1] = n.y;
  33. outnormal[2] = n.z;
  34. }
  35. static void get_tex_coords(const SMikkTSpaceContext *context, float outuv[], int /*iFace*/, int iVert) {
  36. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  37. aiVector3D &t = currentMesh->mTextureCoords[static_cast<size_t>(iVert)][0];
  38. if (currentMesh->mNumUVComponents[iVert] == 2) {
  39. outuv[0] = t.x;
  40. outuv[1] = t.y;
  41. } else if (currentMesh->mNumUVComponents[iVert] == 3){
  42. outuv[0] = t.x;
  43. outuv[1] = t.y;
  44. outuv[2] = 0.0;
  45. }
  46. }
  47. static void set_tspace_basic(const SMikkTSpaceContext *context, const float tangentu[], float /*fSign*/, int /*iFace*/, int iVert) {
  48. const aiMesh *currentMesh = static_cast<aiMesh*>(context->m_pUserData);
  49. currentMesh->mTangents[iVert].x = tangentu[0];
  50. currentMesh->mTangents[iVert].y = tangentu[1];
  51. currentMesh->mTangents[iVert].z = tangentu[2];
  52. }
  53. bool GenerateMikkTSpaceTangents::IsActive(unsigned int pFlags) const {
  54. const bool active = (pFlags & aiProcess_CalcTangentSpace) != 0;
  55. if (mActive) {
  56. return active;
  57. }
  58. return false;
  59. }
  60. void GenerateMikkTSpaceTangents::Execute(aiScene* pScene) {
  61. mIface.m_getNumFaces = get_num_faces;
  62. mIface.m_getNumVerticesOfFace = get_num_vertices_of_face;
  63. mIface.m_getNormal = get_normal;
  64. mIface.m_getPosition = get_position;
  65. mIface.m_getTexCoord = get_tex_coords;
  66. mIface.m_setTSpaceBasic = set_tspace_basic;
  67. mContext.m_pInterface = &mIface;
  68. for (size_t i=0; i<pScene->mNumMeshes; ++i) {
  69. aiMesh *mesh = pScene->mMeshes[i];
  70. ExecutePerMesh(mesh);
  71. }
  72. }
  73. void GenerateMikkTSpaceTangents::SetupProperties(const Importer *pImp) {
  74. mActive = pImp->GetPropertyBool(AI_CONFIG_POSTPROCESS_USE_MIKKTSPACE_TANGENTS, false);
  75. }
  76. void GenerateMikkTSpaceTangents::ExecutePerMesh(aiMesh *mesh) {
  77. if (mesh == nullptr) {
  78. return;
  79. }
  80. mContext.m_pUserData = mesh;
  81. genTangSpaceDefault(&mContext);
  82. }
  83. } // namespace Assimp