scene.d 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. module three.scene;
  2. public import derelict.assimp3.assimp;
  3. public import std.experimental.logger;
  4. struct Position {
  5. float x, y, z;
  6. }
  7. struct Normal {
  8. float x, y, z;
  9. }
  10. struct Color {
  11. float r, g, b, a;
  12. }
  13. struct TextureCoordinate {
  14. float u, v;
  15. }
  16. struct VertexData {
  17. Position position;
  18. Normal normal;
  19. Color color;
  20. TextureCoordinate textureCoordinate;
  21. }
  22. alias IndexData = uint;
  23. struct MeshDescriptor {
  24. size_t vertexOffset;
  25. size_t vertexCount;
  26. size_t indexOffset;
  27. size_t indexCount;
  28. }
  29. struct ModelDescriptor {
  30. size_t meshDescriptorOffset;
  31. size_t meshDescriptorCount;
  32. }
  33. struct Scene {
  34. //TODO: use page allocator
  35. VertexData[] vertexData;
  36. IndexData[] indexData;
  37. MeshDescriptor[] meshDescriptors;
  38. ModelDescriptor[] modelDescriptors;
  39. public:
  40. void construct() pure @safe nothrow @nogc {
  41. }
  42. void destruct() pure @safe nothrow @nogc {
  43. }
  44. public:
  45. size_t vertexCount() @property {
  46. return vertexData.length;
  47. }
  48. size_t indexCount() @property {
  49. return indexData.length;
  50. }
  51. size_t meshCount() @property {
  52. return meshDescriptors.length;
  53. }
  54. size_t modelCount() @property {
  55. return modelDescriptors.length;
  56. }
  57. public:
  58. void loadModel(string filePath) {
  59. import std.traits;
  60. import std.string : toStringz;
  61. auto importedScene = aiImportFile(filePath.toStringz(), aiProcess_Triangulate); scope(exit) aiReleaseImport(importedScene);
  62. this.modelDescriptors ~= ModelDescriptor(this.meshCount, importedScene.mNumMeshes);
  63. for(uint m = 0; m < importedScene.mNumMeshes; ++m) {
  64. const(aiMesh*) meshData = importedScene.mMeshes[m];
  65. assert(meshData !is null);
  66. size_t numIndices = 0;
  67. foreach(f; 0..meshData.mNumFaces) {
  68. numIndices += meshData.mFaces[f].mNumIndices;
  69. }
  70. this.meshDescriptors ~= MeshDescriptor(this.vertexCount, meshData.mNumVertices, this.indexCount, numIndices);
  71. foreach(v; 0..meshData.mNumVertices) {
  72. this.vertexData ~= VertexData(
  73. Position(meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z),
  74. Normal(meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z),
  75. (meshData.mColors[0] !is null) ? Color(meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a) : Color(0, 0, 0, 1),
  76. (meshData.mTextureCoords[0] !is null) ? TextureCoordinate(meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y) : TextureCoordinate(0, 0)
  77. );
  78. }
  79. size_t curIndexDataIdx = 0;
  80. foreach(f; 0..meshData.mNumFaces) {
  81. assert(meshData.mFaces !is null);
  82. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  83. assert(meshData.mFaces[f].mIndices !is null);
  84. this.indexData ~= IndexData(meshData.mFaces[f].mIndices[i]);
  85. }
  86. }
  87. }
  88. }
  89. }
  90. version(none) {
  91. struct Scene {
  92. ModelData modelData;
  93. void construct() pure @safe nothrow @nogc {
  94. }
  95. void destruct() pure @safe nothrow @nogc {
  96. }
  97. }
  98. struct MeshData {
  99. VertexData[] vertexData;
  100. IndexData[] indexData;
  101. }
  102. struct ModelData {
  103. string filePath;
  104. MeshData[] meshData;
  105. size_t vertexCount() const @safe {
  106. import std.algorithm : map, reduce;
  107. return meshData.length == 0 ? 0 : meshData.map!("a.vertexData.length").reduce!("a + b");
  108. }
  109. size_t indexCount() const @safe {
  110. import std.algorithm : map, reduce;
  111. return meshData.length == 0 ? 0 : meshData.map!("a.indexData.length").reduce!("a + b");
  112. }
  113. size_t meshCount() const @safe {
  114. return meshData.length;
  115. }
  116. }
  117. //ModelData createCubeModel() {
  118. //}
  119. ModelData loadModelData(string filePath) {
  120. import std.traits;
  121. import std.string : toStringz;
  122. auto scene = aiImportFile(filePath.toStringz(), aiProcess_Triangulate); scope(exit) aiReleaseImport(scene);
  123. ModelData modelData;
  124. modelData.filePath = filePath;
  125. modelData.meshData.length = scene.mNumMeshes;
  126. for(uint m = 0; m < scene.mNumMeshes; ++m) {
  127. const(aiMesh*) meshData = scene.mMeshes[m];
  128. assert(meshData !is null);
  129. size_t cntIndices = 0;
  130. foreach(f; 0..meshData.mNumFaces) {
  131. cntIndices += meshData.mFaces[f].mNumIndices;
  132. }
  133. modelData.meshData[m].vertexData.length = meshData.mNumVertices;
  134. modelData.meshData[m].indexData.length = cntIndices;
  135. foreach(v; 0..meshData.mNumVertices) {
  136. modelData.meshData[m].vertexData[v].position = Position(meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z);
  137. modelData.meshData[m].vertexData[v].normal = Normal(meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z);
  138. if(meshData.mColors[0] !is null) {
  139. modelData.meshData[m].vertexData[v].color = Color(meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a);
  140. }
  141. else {
  142. modelData.meshData[m].vertexData[v].color = Color(0, 0, 0, 1);
  143. }
  144. if(meshData.mTextureCoords[0] !is null) {
  145. modelData.meshData[m].vertexData[v].textureCoordinate = TextureCoordinate(meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y);
  146. }
  147. else {
  148. modelData.meshData[m].vertexData[v].textureCoordinate = TextureCoordinate(0, 0);
  149. }
  150. }
  151. size_t curIndexDataIdx = 0;
  152. foreach(f; 0..meshData.mNumFaces) {
  153. assert(meshData.mFaces !is null);
  154. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  155. assert(meshData.mFaces[f].mIndices !is null);
  156. modelData.meshData[m].indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];
  157. }
  158. }
  159. }
  160. return modelData;
  161. }
  162. }