[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.

scene.cpp 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Skia < lordbanana25 AT mailoo DOT org >
  3. *
  4. * Beerware licensed software - 2015
  5. */
  6. #include <iostream>
  7. #include <time.h>
  8. #include <assimp/cimport.h>
  9. #include <assimp/scene.h>
  10. #include <assimp/postprocess.h>
  11. #include <scene.h>
  12. #include <utils.h>
  13. using namespace std;
  14. const aiNode *getNode(const aiScene *scene, aiString name) {
  15. if (name == scene->mRootNode->mName)
  16. return &(*scene->mRootNode);
  17. else
  18. return getChildNode(name, scene->mRootNode);
  19. }
  20. const aiNode *getChildNode(aiString name, const aiNode *node) {
  21. if (name == node->mName)
  22. return node;
  23. else {
  24. const aiNode *nd = NULL;
  25. for (unsigned int i = 0; i < node->mNumChildren; i++) {
  26. nd = getChildNode(name, node->mChildren[i]);
  27. if (nd != NULL) return nd;
  28. }
  29. return NULL;
  30. }
  31. }
  32. SceneHandler::~SceneHandler() {
  33. aiReleaseImport(scene);
  34. }
  35. SceneHandler::SceneHandler(char *fName, GLuint prog) {
  36. scene = aiImportFile(fName,aiProcessPreset_TargetRealtime_MaxQuality);
  37. if (!scene) {
  38. std::cerr << "Error importing file" << std::endl;
  39. } else {
  40. shaderProg = prog;
  41. get_bounding_box();
  42. scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
  43. scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
  44. scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
  45. float tmp = 0;
  46. tmp = scene_max.x-scene_min.x;
  47. tmp = max(scene_max.y - scene_min.y,tmp);
  48. tmp = max(scene_max.z - scene_min.z,tmp);
  49. scale = 2.f / tmp;
  50. angle = 0;
  51. meshNumber = 0;
  52. meshList = NULL;
  53. isAnimating=false;
  54. initMeshList(scene->mRootNode);
  55. // Shader variable
  56. m_WVPLocation = glGetUniformLocation(prog, "gWVP");
  57. m_WorldMatrixLocation = glGetUniformLocation(prog, "gWorld");
  58. }
  59. }
  60. void SceneHandler::initMeshList(const aiNode* nd){
  61. unsigned int i, j, k;
  62. meshList = (Mesh**) realloc(meshList, (nd->mNumMeshes + meshNumber) * sizeof(Mesh*));
  63. for (i = 0; i < nd->mNumMeshes; ++i) {
  64. const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[i]];
  65. Mesh *newMesh = new Mesh(i, mesh->mNumVertices, mesh->mNumBones, mesh->mNumFaces, shaderProg);
  66. for(j = 0; j < mesh->mNumVertices; j++){
  67. Vertice *newVert = new Vertice(j, mesh->mVertices[j]);
  68. if (mesh->mNormals != NULL) {
  69. newMesh->addVertice(newVert, mesh->mNormals+j, j);
  70. } else {
  71. newMesh->addVertice(newVert, NULL, j);
  72. }
  73. }
  74. for (j = 0; j < mesh->mNumFaces; ++j) {
  75. const struct aiFace* face = &mesh->mFaces[j];
  76. Face *newFace = new Face(face->mNumIndices);
  77. for(k = 0; k < face->mNumIndices; k++) {
  78. newFace->addIndex(face->mIndices[k]);
  79. }
  80. newMesh->addFace(newFace);
  81. }
  82. struct aiBone** bones = mesh->mBones;
  83. for (j = 0; j < mesh->mNumBones; ++j) {
  84. const aiNode *p = getNode(scene, bones[j]->mName);
  85. Bone *tmpBone = NULL;
  86. if (p != NULL) p = p->mParent;
  87. if (p != NULL) tmpBone = new Bone(bones[j]->mName, p->mName, bones[j]->mOffsetMatrix);
  88. else tmpBone = new Bone(bones[j]->mName, aiString(""), bones[j]->mOffsetMatrix);
  89. for(k = 0; k < bones[j]->mNumWeights; k++){
  90. int vertID = bones[j]->mWeights[k].mVertexId;
  91. float weight =bones[j]->mWeights[k].mWeight;
  92. tmpBone->addVertice(vertID);
  93. newMesh->setVertBone(vertID, bones[j]->mName, weight);
  94. }
  95. newMesh->addBone(tmpBone, j);
  96. }
  97. newMesh->initAnimList(scene);
  98. meshList[meshNumber++] = newMesh;
  99. }
  100. for (unsigned int n = 0; n < nd->mNumChildren; ++n) {
  101. initMeshList(nd->mChildren[n]);
  102. }
  103. }
  104. void SceneHandler::resetNumFrame(){
  105. numFrame=0;
  106. m_startTime = clock();
  107. }
  108. void SceneHandler::render() {
  109. int i;
  110. const aiNode *nd = scene->mRootNode;
  111. aiMatrix4x4 m = nd->mTransformation;
  112. double runningTime = double(clock() - m_startTime) / CLOCKS_PER_SEC;
  113. glScalef(scale, scale, scale);
  114. glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
  115. angle += 0.5;
  116. glRotatef(angle, 0, 1, 0);
  117. // add root node transform matrix
  118. aiMatrix4x4 wm;
  119. glGetFloatv(GL_MODELVIEW_MATRIX, &wm.a1);
  120. glUniformMatrix4fv(m_WorldMatrixLocation, 1, GL_TRUE, (const GLfloat*)&wm.a1);
  121. aiTransposeMatrix4(&m);
  122. glPushMatrix();
  123. glMultMatrixf((float*)&m);
  124. glUniformMatrix4fv(m_WVPLocation, 1, GL_TRUE, (const GLfloat*)&m.a1);
  125. // draw all meshes
  126. for (i = 0; i < meshNumber; ++i) {
  127. aiMatrix4x4 ident;
  128. aiMatrix4x4::Scaling(aiVector3D(1, 1, 1), ident);
  129. Mesh *my_mesh = meshList[i];
  130. if (isAnimating) {
  131. if (!my_mesh->updateBoneStateList(runningTime, scene->mRootNode, ident)) {
  132. isAnimating = false;
  133. glUseProgram(0); // This is a pretty ugly hack
  134. }
  135. }
  136. my_mesh->render(isAnimating);
  137. }
  138. glPopMatrix();
  139. }
  140. void SceneHandler::get_bounding_box_for_node (const aiNode* nd,
  141. aiMatrix4x4* trafo
  142. ){
  143. aiMatrix4x4 prev;
  144. unsigned int n = 0, t;
  145. prev = *trafo;
  146. aiMultiplyMatrix4(trafo,&nd->mTransformation);
  147. for (; n < nd->mNumMeshes; ++n) {
  148. const aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
  149. for (t = 0; t < mesh->mNumVertices; ++t) {
  150. aiVector3D tmp = mesh->mVertices[t];
  151. aiTransformVecByMatrix4(&tmp,trafo);
  152. scene_min.x = min(scene_min.x,tmp.x);
  153. scene_min.y = min(scene_min.y,tmp.y);
  154. scene_min.z = min(scene_min.z,tmp.z);
  155. scene_max.x = max(scene_max.x,tmp.x);
  156. scene_max.y = max(scene_max.y,tmp.y);
  157. scene_max.z = max(scene_max.z,tmp.z);
  158. }
  159. }
  160. for (n = 0; n < nd->mNumChildren; ++n) {
  161. get_bounding_box_for_node(nd->mChildren[n], trafo);
  162. }
  163. *trafo = prev;
  164. }
  165. void SceneHandler::get_bounding_box ()
  166. {
  167. aiMatrix4x4 trafo;
  168. aiIdentityMatrix4(&trafo);
  169. scene_min.x = scene_min.y = scene_min.z = 1e10f;
  170. scene_max.x = scene_max.y = scene_max.z = -1e10f;
  171. get_bounding_box_for_node(scene->mRootNode,&trafo);
  172. }