ConvertToLHProcess.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /** @file Implementation of the post processing step to convert all imported data
  2. * to a left-handed coordinate system.
  3. */
  4. #include "ConvertToLHProcess.h"
  5. #include "../include/aiPostProcess.h"
  6. #include "../include/aiMesh.h"
  7. #include "../include/aiAnim.h"
  8. #include "../include/aiScene.h"
  9. using namespace Assimp;
  10. // The transformation matrix to convert from DirectX coordinates to OpenGL coordinates.
  11. const aiMatrix3x3 Assimp::ConvertToLHProcess::sToOGLTransform(
  12. 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f
  13. );
  14. // The transformation matrix to convert from OpenGL coordinates to DirectX coordinates.
  15. const aiMatrix3x3 Assimp::ConvertToLHProcess::sToDXTransform(
  16. 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f
  17. );
  18. // ------------------------------------------------------------------------------------------------
  19. // Constructor to be privately used by Importer
  20. ConvertToLHProcess::ConvertToLHProcess()
  21. {
  22. // nothing to do here
  23. }
  24. // ------------------------------------------------------------------------------------------------
  25. // Destructor, private as well
  26. ConvertToLHProcess::~ConvertToLHProcess()
  27. {
  28. // nothing to do here
  29. }
  30. // ------------------------------------------------------------------------------------------------
  31. // Returns whether the processing step is present in the given flag field.
  32. bool ConvertToLHProcess::IsActive( unsigned int pFlags) const
  33. {
  34. return (pFlags & aiProcess_ConvertToLeftHanded) != 0;
  35. }
  36. // ------------------------------------------------------------------------------------------------
  37. // Executes the post processing step on the given imported data.
  38. void ConvertToLHProcess::Execute( aiScene* pScene)
  39. {
  40. // Check for an existent root node to proceed
  41. if (NULL == pScene->mRootNode)
  42. return;
  43. // transform the root node of the scene, the other nodes will follow then
  44. ConvertToDX( pScene->mRootNode->mTransformation);
  45. // transform all meshes accordingly
  46. for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  47. ProcessMesh( pScene->mMeshes[a]);
  48. // transform all animation channels affecting the root node as well
  49. for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
  50. {
  51. aiAnimation* anim = pScene->mAnimations[a];
  52. for( unsigned int b = 0; b < anim->mNumBones; b++)
  53. {
  54. aiBoneAnim* boneAnim = anim->mBones[b];
  55. if( strcmp( boneAnim->mBoneName.data, pScene->mRootNode->mName.data) == 0)
  56. ProcessAnimation( boneAnim);
  57. }
  58. }
  59. }
  60. // ------------------------------------------------------------------------------------------------
  61. // Converts a single mesh to left handed coordinates.
  62. void ConvertToLHProcess::ProcessMesh( aiMesh* pMesh)
  63. {
  64. // invert the order of all faces in this mesh
  65. for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
  66. {
  67. aiFace& face = pMesh->mFaces[a];
  68. for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
  69. std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
  70. }
  71. // mirror texture y coordinate
  72. for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
  73. {
  74. if( pMesh->HasTextureCoords( a))
  75. {
  76. for( unsigned int b = 0; b < pMesh->mNumVertices; b++)
  77. pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y;
  78. }
  79. }
  80. // mirror bitangents as well as they're derived from the texture coords
  81. if( pMesh->HasTangentsAndBitangents())
  82. {
  83. for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
  84. pMesh->mBitangents[a] = -pMesh->mBitangents[a];
  85. }
  86. }
  87. // ------------------------------------------------------------------------------------------------
  88. // Converts the given animation to LH coordinates.
  89. void ConvertToLHProcess::ProcessAnimation( aiBoneAnim* pAnim)
  90. {
  91. // position keys
  92. for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
  93. ConvertToDX( pAnim->mPositionKeys[a].mValue);
  94. // rotation keys
  95. for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
  96. {
  97. aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
  98. ConvertToDX( rotmat);
  99. pAnim->mRotationKeys[a].mValue = aiQuaternion( rotmat);
  100. }
  101. }
  102. // ------------------------------------------------------------------------------------------------
  103. // Static helper function to convert a vector/matrix from DX to OGL coords
  104. void ConvertToLHProcess::ConvertToOGL( aiVector3D& poVector)
  105. {
  106. poVector = sToOGLTransform * poVector;
  107. }
  108. // ------------------------------------------------------------------------------------------------
  109. void ConvertToLHProcess::ConvertToOGL( aiMatrix3x3& poMatrix)
  110. {
  111. poMatrix *= sToOGLTransform;
  112. }
  113. // ------------------------------------------------------------------------------------------------
  114. void ConvertToLHProcess::ConvertToOGL( aiMatrix4x4& poMatrix)
  115. {
  116. poMatrix *= aiMatrix4x4( sToOGLTransform);
  117. }
  118. // ------------------------------------------------------------------------------------------------
  119. // Static helper function to convert a vector/matrix from OGL back to DX coords
  120. void ConvertToLHProcess::ConvertToDX( aiVector3D& poVector)
  121. {
  122. poVector = sToDXTransform * poVector;
  123. }
  124. // ------------------------------------------------------------------------------------------------
  125. void ConvertToLHProcess::ConvertToDX( aiMatrix3x3& poMatrix)
  126. {
  127. poMatrix *= sToDXTransform;
  128. }
  129. // ------------------------------------------------------------------------------------------------
  130. void ConvertToLHProcess::ConvertToDX( aiMatrix4x4& poMatrix)
  131. {
  132. aiMatrix4x4 temp(sToDXTransform);
  133. poMatrix *= temp;
  134. }