blendShapeMixer.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "blendShapeMixer.h"
  2. #include "..\..\common_h\gmxservice\MeshStructure.h"
  3. #define BS_EPSILON 0.0000001f
  4. GMXBlendShapeMixer::GMXBlendShapeMixer(dword _bsMorphTargetsCount, float * _pMorphTargetsWeights, blendShapeTarget * _pMorphTargets,
  5. dword _bsBonesTransformCount, blendShapeBoneTransform * _pBoneTransforms,
  6. long * _pAnimToGeomBlendShapes_TranslateTable)
  7. {
  8. bsMorphTargetsCount = _bsMorphTargetsCount;
  9. pMorphTargetsWeights = _pMorphTargetsWeights;
  10. pMorphTargets = _pMorphTargets;
  11. bsBonesTransformCount = _bsBonesTransformCount;
  12. pBoneTransforms = _pBoneTransforms;
  13. pAnimToGeomBlendShapes_TranslateTable = _pAnimToGeomBlendShapes_TranslateTable;
  14. }
  15. GMXBlendShapeMixer::~GMXBlendShapeMixer()
  16. {
  17. UnregisterAnimation();
  18. }
  19. //Получить коэфициент блендинга для интересующей кости (многопоточная функция)
  20. float GMXBlendShapeMixer::GetBoneBlend(long boneIndex)
  21. {
  22. long indexInBlendShape = pAnimToGeomBlendShapes_TranslateTable[boneIndex];
  23. if (indexInBlendShape < 0)
  24. {
  25. return 0.0f;
  26. }
  27. float fTotalBoneWeight = 0.0f;
  28. for (dword i = 0; i < bsMorphTargetsCount; i++)
  29. {
  30. blendShapeBoneTransform * morphBonesArray = pMorphTargets[i].frameBones.ptr;
  31. fTotalBoneWeight += pMorphTargetsWeights[i] * morphBonesArray[indexInBlendShape].weightScale;
  32. }
  33. //Joker: странный код, можно без условий тут сделать мне кажется
  34. if (fTotalBoneWeight > BS_EPSILON || fTotalBoneWeight < -BS_EPSILON)
  35. {
  36. return Clampf(fTotalBoneWeight, 0.0f, 1.0f);
  37. }
  38. return 0.0f;
  39. }
  40. //Получить трансформацию кости (многопоточная функция)
  41. void GMXBlendShapeMixer::GetBoneTransform(long boneIndex, Quaternion & rotation, Vector & position, Vector & scale, const Quaternion & prevRotation, const Vector & prevPosition, const Vector & prevScale)
  42. {
  43. long indexInBlendShape = pAnimToGeomBlendShapes_TranslateTable[boneIndex];
  44. if (indexInBlendShape < 0)
  45. {
  46. return;
  47. }
  48. Vector gPos;
  49. gPos.x = 0.0f; gPos.y = 0.0f; gPos.z = 0.0f;
  50. Quaternion gRot;
  51. gRot.x = 0; gRot.y = 0; gRot.z = 0; gRot.w = 0;
  52. float fDivider = 0.0f;
  53. for (dword i = 0; i < bsMorphTargetsCount; i++)
  54. {
  55. float fWeight = pMorphTargetsWeights[i];
  56. if (fWeight <= 0.0f) continue;
  57. blendShapeBoneTransform * morphBonesArray = pMorphTargets[i].frameBones.ptr;
  58. blendShapeBoneTransform & bone = morphBonesArray[indexInBlendShape];
  59. fWeight = fWeight * bone.weightScale;
  60. gPos += (bone.p * fWeight);
  61. gRot += (bone.q * fWeight);
  62. fDivider += fWeight;
  63. }
  64. if (fDivider > BS_EPSILON || fDivider < -BS_EPSILON)
  65. {
  66. position = gPos / fDivider;
  67. }
  68. rotation = gRot;
  69. rotation.Normalize();
  70. scale = 1.0f;
  71. }
  72. //Обновить (только основной поток, второй спит вне цикла исполнения)
  73. void GMXBlendShapeMixer::Update(float dltTime)
  74. {
  75. }
  76. void GMXBlendShapeMixer::RegisterAnimation (IAnimationTransform * _ani, long level)
  77. {
  78. UnregisterAnimation();
  79. if (!_ani->Is(anitype_animation))
  80. {
  81. return;
  82. }
  83. SetAnimation((IAnimation *)_ani);
  84. RegistryBlendStage(level);
  85. }
  86. void GMXBlendShapeMixer::UnregisterAnimation()
  87. {
  88. UnregistryBlendStage();
  89. }