[C++] The IN55 project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mesh.cpp 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Skia < lordbanana25 AT mailoo DOT org >
  3. *
  4. * Beerware licensed software - 2015
  5. */
  6. #include <iostream>
  7. #include <mesh.h>
  8. #include <utils.h>
  9. void Mesh::initAnimList(const aiScene *scene) {
  10. animList = (Animation**) malloc(scene->mNumAnimations * sizeof(Animation*));
  11. for (unsigned int i = 0; i < scene->mNumAnimations; i++) {
  12. const aiAnimation *anim = scene->mAnimations[i];
  13. Animation *my_anim = new Animation(boneNb, scene->mAnimations[i]->mDuration, scene->mAnimations[i]->mTicksPerSecond);
  14. for (int j = 0; j < boneNb; j++) {
  15. const aiNodeAnim *nodeAnim = findNodeAnim(anim, getBone(j)->getName());
  16. BoneAnim *boneAnim = new BoneAnim(
  17. nodeAnim->mNumPositionKeys,
  18. nodeAnim->mNumRotationKeys,
  19. nodeAnim->mNumScalingKeys,
  20. getBone(j)->getName());
  21. for (unsigned int k = 0; k < nodeAnim->mNumPositionKeys; k++)
  22. boneAnim->addTrans(nodeAnim->mPositionKeys[k]);
  23. for (unsigned int k = 0; k < nodeAnim->mNumRotationKeys; k++)
  24. boneAnim->addRot(nodeAnim->mRotationKeys[k]);
  25. for (unsigned int k = 0; k < nodeAnim->mNumScalingKeys; k++)
  26. boneAnim->addScal(nodeAnim->mScalingKeys[k]);
  27. my_anim->addBoneAnim(boneAnim);
  28. }
  29. animList[animNb++] = my_anim;
  30. }
  31. };
  32. void Mesh::render(bool anim) {
  33. int i, j;
  34. bool use_normal = false;
  35. if (this->getNormal(0) != NULL) {
  36. use_normal = true;
  37. }
  38. if(use_normal) {
  39. glEnable(GL_LIGHTING);
  40. } else {
  41. glDisable(GL_LIGHTING);
  42. }
  43. // glUniformMatrix4fv(shader_bones, this->getNbBone(), GL_TRUE, boneStateList);
  44. for (i = 0; i < this->getFaceNumber(); i++) {
  45. Face *f = this->getFace(i);
  46. glBegin(f->getType());
  47. for (j = 0; j < f->getIndexNumber(); j++) {
  48. // glPushMatrix();
  49. int index = f->getIndex(j);
  50. if (anim) {
  51. Vertice *v = this->getVertex(index);
  52. aiMatrix4x4 t[4];
  53. glVertexAttribPointer(shader_Normal, 3, GL_FLOAT, GL_FALSE, 0, &this->getNormal(index)->x);
  54. glVertexAttribPointer(shader_Weights, 3, GL_FLOAT, GL_FALSE, 0, v->getBonesWeights());
  55. for (int k = 0; k < v->getBoneNumber(); k++) {
  56. t[k] = boneStateList[this->getBoneIndex(v->getBonesID(k))].Transpose();
  57. }
  58. std::cout << t[0] << "\n";
  59. glVertexAttribPointer(shader_Weights, 3, GL_FLOAT, GL_FALSE, 0, &t);
  60. if (this->getNormal(index) != NULL) {
  61. glVertexAttribPointer(shader_Normal, 3, GL_FLOAT, GL_FALSE, 0, &this->getNormal(index)->x);
  62. }
  63. glVertexAttribPointer(shader_Position, 3, GL_FLOAT, GL_FALSE, 0, &(this->getVertex(index)->getPosition()).x);
  64. } else {
  65. if (this->getNormal(index) != NULL) {
  66. glNormal3fv(&this->getNormal(index)->x);
  67. }
  68. glVertex3fv(&(this->getVertex(index)->getPosition()).x);
  69. }
  70. }
  71. glEnd();
  72. }
  73. }
  74. void CalcInterpolatedScaling(aiVector3D& Out, float AnimationTime, BoneAnim* boneAnim)
  75. {
  76. // we need at least two values to interpolate...
  77. if (boneAnim->getNbScal() == 1) {
  78. Out = boneAnim->getScal(0).mValue;
  79. return;
  80. }
  81. unsigned int ScalingIndex = boneAnim->findScaling(AnimationTime);
  82. unsigned int NextScalingIndex = (ScalingIndex + 1);
  83. float d = boneAnim->getScal(NextScalingIndex).mTime - boneAnim->getScal(ScalingIndex).mTime;
  84. float f = (AnimationTime - (float)boneAnim->getScal(ScalingIndex).mTime) / d;
  85. // assert(f >= 0.0f && f <= 1.0f);
  86. const aiVector3D& StartPositionV = boneAnim->getScal(ScalingIndex).mValue;
  87. const aiVector3D& EndPositionV = boneAnim->getScal(NextScalingIndex).mValue;
  88. Out = (1 - f) * StartPositionV + f * EndPositionV;
  89. }
  90. void CalcInterpolatedPosition(aiVector3D& Out, float AnimationTime, BoneAnim* boneAnim)
  91. {
  92. // we need at least two values to interpolate...
  93. if (boneAnim->getNbTrans() == 1) {
  94. Out = boneAnim->getTrans(0).mValue;
  95. return;
  96. }
  97. unsigned int PositionIndex = boneAnim->findPosition(AnimationTime);
  98. unsigned int NextPositionIndex = (PositionIndex + 1);
  99. float d = boneAnim->getTrans(NextPositionIndex).mTime - boneAnim->getTrans(PositionIndex).mTime;
  100. float f = (AnimationTime - (float)boneAnim->getTrans(PositionIndex).mTime) / d;
  101. // assert(f >= 0.0f && f <= 1.0f);
  102. const aiVector3D& StartPositionV = boneAnim->getTrans(PositionIndex).mValue;
  103. const aiVector3D& EndPositionV = boneAnim->getTrans(NextPositionIndex).mValue;
  104. Out = (1 - f) * StartPositionV + f * EndPositionV;
  105. // *pos = (1-t)*prevKeyframe.mValue + t*nextKeyframe.mValue;
  106. //Out = Out.Normalize();
  107. }
  108. void CalcInterpolatedRotation(aiQuaternion& Out, float AnimationTime, BoneAnim* boneAnim)
  109. {
  110. // we need at least two values to interpolate...
  111. if (boneAnim->getNbRot() == 1) {
  112. Out = boneAnim->getRot(0).mValue;
  113. return;
  114. }
  115. unsigned int RotationIndex = boneAnim->findRotation(AnimationTime);
  116. unsigned int NextRotationIndex = (RotationIndex + 1);
  117. float d = boneAnim->getRot(NextRotationIndex).mTime - boneAnim->getRot(RotationIndex).mTime;
  118. float f = (AnimationTime - (float)boneAnim->getRot(RotationIndex).mTime) / d;
  119. // assert(f >= 0.0f && f <= 1.0f);
  120. const aiQuaternion& StartRotationQ = boneAnim->getRot(RotationIndex).mValue;
  121. const aiQuaternion& EndRotationQ = boneAnim->getRot(NextRotationIndex).mValue;
  122. aiQuaternion::Interpolate(Out, StartRotationQ, EndRotationQ, f);
  123. Out = Out.Normalize();
  124. }
  125. bool Mesh::updateBoneStateList(float AnimationTime, const aiNode* pNode, const aiMatrix4x4& ParentTransform)
  126. {
  127. aiString NodeName(pNode->mName.data);
  128. Animation* anim = animList[currentAnimation];
  129. if (anim->getDuration() <= AnimationTime) return false;
  130. aiMatrix4x4 NodeTransformation(pNode->mTransformation);
  131. BoneAnim* boneAnim = anim->getBoneAnim(NodeName);
  132. if (boneAnim) {
  133. // Interpolate scaling and generate scaling transformation matrix
  134. aiVector3D Scaling;
  135. CalcInterpolatedScaling(Scaling, AnimationTime, boneAnim);
  136. aiMatrix4x4 ScalingM;
  137. aiMatrix4x4::Scaling(aiVector3D(Scaling.x, Scaling.y, Scaling.z), ScalingM);
  138. // Interpolate rotation and generate rotation transformation matrix
  139. aiQuaternion RotationQ;
  140. CalcInterpolatedRotation(RotationQ, AnimationTime, boneAnim);
  141. aiMatrix4x4 RotationM = aiMatrix4x4(RotationQ.GetMatrix());
  142. // Interpolate translation and generate translation transformation matrix
  143. aiVector3D Translation;
  144. CalcInterpolatedPosition(Translation, AnimationTime, boneAnim);
  145. aiMatrix4x4 TranslationM;
  146. aiMatrix4x4::Translation(aiVector3D(Translation.x, Translation.y, Translation.z), TranslationM);
  147. // Combine the above transformations
  148. NodeTransformation = TranslationM * RotationM * ScalingM;
  149. }
  150. aiMatrix4x4 GlobalTransformation = ParentTransform * NodeTransformation;
  151. int BoneIndex = -1;
  152. if ((BoneIndex = getBoneIndex(NodeName)) != -1) {
  153. boneStateList[BoneIndex] = GlobalTransformation * getBone(BoneIndex)->getOffset();
  154. }
  155. for (unsigned int i = 0 ; i < pNode->mNumChildren ; i++) {
  156. this->updateBoneStateList(AnimationTime, pNode->mChildren[i], GlobalTransformation);
  157. }
  158. return true;
  159. }