ObjFile.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "ObjFile.h"
  2. #include "Model3D.h"
  3. #include "Vec2.h"
  4. using namespace Framework;
  5. ObjFile::ObjFile(const char* path)
  6. : ReferenceCounter()
  7. {
  8. file.setDatei(path);
  9. file.open(Datei::Style::lesen);
  10. Text* line = file.leseZeile();
  11. while (line)
  12. {
  13. if (line->positionVon("o ") == 0) objectNames.add(line->getTeilText(2));
  14. line->release();
  15. line = file.leseZeile();
  16. }
  17. file.close();
  18. }
  19. Vec3<int> ObjFile::parseIndex(Text* s)
  20. {
  21. Text* x = s->getTeilText(0, s->positionVon("/"));
  22. Text* y = s->getTeilText(s->positionVon("/") + 1, s->positionVon("/", 1));
  23. Text* z = s->getTeilText(s->positionVon("/", 1) + 1);
  24. Vec3<int> result((int)*x, (int)*y, (int)*z);
  25. x->release();
  26. y->release();
  27. z->release();
  28. s->release();
  29. return result;
  30. }
  31. void ObjFile::readModel(Model3DData* zTarget)
  32. {
  33. Array<Vec3<float>> vertices;
  34. Array<Vec2<float>> textureCoordinates;
  35. Array<Vec3<float>> normals;
  36. Array<Vec3<int>> indices;
  37. // read model info
  38. Text* line = file.leseZeile();
  39. while (line)
  40. {
  41. if (line->positionVon("o ") == 0)
  42. {
  43. line->release();
  44. break;
  45. ;
  46. }
  47. if (line->positionVon("v ") == 0)
  48. {
  49. Text* x = line->getTeilText(2, line->positionVon(" ", 1));
  50. Text* y = line->getTeilText(
  51. line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
  52. Text* z = line->getTeilText(line->positionVon(" ", 2) + 1);
  53. vertices.add(Vec3<float>((float)*x, (float)*y, (float)*z));
  54. x->release();
  55. y->release();
  56. z->release();
  57. }
  58. if (line->positionVon("vt ") == 0)
  59. {
  60. Text* x = line->getTeilText(3, line->positionVon(" ", 1));
  61. Text* y = line->getTeilText(line->positionVon(" ", 1) + 1);
  62. textureCoordinates.add(Vec2<float>((float)*x, (float)*y));
  63. x->release();
  64. y->release();
  65. }
  66. if (line->positionVon("vn ") == 0)
  67. {
  68. Text* x = line->getTeilText(3, line->positionVon(" ", 1));
  69. Text* y = line->getTeilText(
  70. line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
  71. Text* z = line->getTeilText(line->positionVon(" ", 2) + 1);
  72. normals.add(Vec3<float>((float)*x, (float)*y, (float)*z));
  73. x->release();
  74. y->release();
  75. z->release();
  76. }
  77. if (line->positionVon("f ") == 0)
  78. {
  79. // only triangulated meshes ares supported
  80. Text* p1 = line->getTeilText(2, line->positionVon(" ", 1));
  81. Text* p2 = line->getTeilText(
  82. line->positionVon(" ", 1) + 1, line->positionVon(" ", 2));
  83. Text* p3 = line->getTeilText(line->positionVon(" ", 2) + 1);
  84. indices.add(parseIndex(p1));
  85. indices.add(parseIndex(p2));
  86. indices.add(parseIndex(p3));
  87. }
  88. line->release();
  89. line = file.leseZeile();
  90. }
  91. // compute vertex data and index buffer
  92. Array<Vertex3D> modelData;
  93. int* indexList = new int[indices.getEintragAnzahl()];
  94. int rInd = 0;
  95. for (Vec3<int> index : indices)
  96. {
  97. Vertex3D current;
  98. current.id = 0;
  99. current.pos = vertices.get(index.x - 1);
  100. current.tPos = textureCoordinates.get(index.y - 1);
  101. current.normal = normals.get(index.z - 1);
  102. current.knochenId = 0;
  103. int ind = 0;
  104. for (const Vertex3D& other : modelData)
  105. {
  106. if (other.pos == current.pos && other.tPos == current.tPos
  107. && other.normal == current.normal)
  108. break;
  109. ind++;
  110. }
  111. if (modelData.getEintragAnzahl() == ind) modelData.add(current);
  112. indexList[rInd++] = ind;
  113. }
  114. Vertex3D* vertexData = new Vertex3D[modelData.getEintragAnzahl()];
  115. int ind = 0;
  116. for (const Vertex3D& vertex : modelData)
  117. vertexData[ind++] = vertex;
  118. zTarget->setVertecies(vertexData, modelData.getEintragAnzahl());
  119. Polygon3D* polygon = new Polygon3D();
  120. polygon->indexAnz = indices.getEintragAnzahl();
  121. polygon->indexList = indexList;
  122. zTarget->addPolygon(polygon);
  123. }
  124. bool ObjFile::loadModel(const char* name, Model3DData* zTarget)
  125. {
  126. file.open(Datei::Style::lesen);
  127. Text* line = file.leseZeile();
  128. while (line)
  129. {
  130. if (line->positionVon("o ") == 0 && line->positionVon(name) == 2
  131. && line->getLength() == textLength(name) + 3)
  132. {
  133. readModel(zTarget);
  134. line->release();
  135. file.close();
  136. return 1;
  137. }
  138. line->release();
  139. line = file.leseZeile();
  140. }
  141. file.close();
  142. return 0;
  143. }
  144. const RCArray<Text>& ObjFile::getContainedModelNames() const
  145. {
  146. return objectNames;
  147. }