1
1

scene.d 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 InstanceData {
  24. Matrix4 transformation;
  25. }
  26. struct Matrix4 {
  27. float[4*4] data;
  28. }
  29. struct MeshDescriptor {
  30. size_t vertexOffset;
  31. size_t vertexCount;
  32. size_t indexOffset;
  33. size_t indexCount;
  34. }
  35. struct ModelDescriptor {
  36. size_t meshDescriptorOffset;
  37. size_t meshDescriptorCount;
  38. }
  39. struct InstanceDescriptor {
  40. size_t modelIndex;
  41. size_t instanceOffset;
  42. size_t instanceCount;
  43. }
  44. struct Scene {
  45. //TODO: use page allocator
  46. VertexData[] vertexData;
  47. IndexData[] indexData;
  48. InstanceData[] instanceData;
  49. MeshDescriptor[] meshDescriptors;
  50. ModelDescriptor[] modelDescriptors;
  51. InstanceDescriptor[] instanceDescriptor;
  52. public:
  53. void construct() pure @safe nothrow @nogc {
  54. }
  55. void destruct() pure @safe nothrow @nogc {
  56. }
  57. public:
  58. size_t vertexCount() const pure @safe nothrow @nogc @property {
  59. return vertexData.length;
  60. }
  61. size_t indexCount() const pure @safe nothrow @nogc @property {
  62. return indexData.length;
  63. }
  64. size_t meshCount() const pure @safe nothrow @nogc @property {
  65. return meshDescriptors.length;
  66. }
  67. size_t modelCount() const pure @safe nothrow @nogc @property {
  68. return modelDescriptors.length;
  69. }
  70. public:
  71. void loadModel(string filePath) {
  72. import std.traits;
  73. import std.string : toStringz;
  74. enum flags = aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType | aiProcess_GenNormals
  75. | aiProcess_PreTransformVertices | aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality
  76. | aiProcess_FindInvalidData | aiProcess_GenUVCoords;
  77. auto importedScene = aiImportFile(filePath.toStringz(), flags ); scope(exit) aiReleaseImport(importedScene);
  78. assert(importedScene !is null);
  79. this.modelDescriptors ~= ModelDescriptor(this.meshCount, importedScene.mNumMeshes);
  80. for(uint m = 0; m < importedScene.mNumMeshes; ++m) {
  81. const(aiMesh*) meshData = importedScene.mMeshes[m];
  82. assert(meshData !is null);
  83. size_t numIndices = 0;
  84. foreach(f; 0..meshData.mNumFaces) {
  85. numIndices += meshData.mFaces[f].mNumIndices;
  86. }
  87. this.meshDescriptors ~= MeshDescriptor(this.vertexCount, meshData.mNumVertices, this.indexCount, numIndices);
  88. foreach(v; 0..meshData.mNumVertices) {
  89. this.vertexData ~= VertexData(
  90. Position(meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z),
  91. Normal(meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z),
  92. (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),
  93. (meshData.mTextureCoords[0] !is null) ? TextureCoordinate(meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y) : TextureCoordinate(0, 0)
  94. );
  95. }
  96. size_t curIndexDataIdx = 0;
  97. foreach(f; 0..meshData.mNumFaces) {
  98. assert(meshData.mFaces !is null);
  99. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  100. assert(meshData.mFaces[f].mIndices !is null);
  101. this.indexData ~= IndexData(meshData.mFaces[f].mIndices[i]);
  102. }
  103. }
  104. }
  105. }
  106. }
  107. version(none) {
  108. struct Scene {
  109. ModelData modelData;
  110. void construct() pure @safe nothrow @nogc {
  111. }
  112. void destruct() pure @safe nothrow @nogc {
  113. }
  114. }
  115. struct MeshData {
  116. VertexData[] vertexData;
  117. IndexData[] indexData;
  118. }
  119. struct ModelData {
  120. string filePath;
  121. MeshData[] meshData;
  122. size_t vertexCount() const @safe {
  123. import std.algorithm : map, reduce;
  124. return meshData.length == 0 ? 0 : meshData.map!("a.vertexData.length").reduce!("a + b");
  125. }
  126. size_t indexCount() const @safe {
  127. import std.algorithm : map, reduce;
  128. return meshData.length == 0 ? 0 : meshData.map!("a.indexData.length").reduce!("a + b");
  129. }
  130. size_t meshCount() const @safe {
  131. return meshData.length;
  132. }
  133. }
  134. //ModelData createCubeModel() {
  135. //}
  136. ModelData loadModelData(string filePath) {
  137. import std.traits;
  138. import std.string : toStringz;
  139. auto scene = aiImportFile(filePath.toStringz(), aiProcess_Triangulate); scope(exit) aiReleaseImport(scene);
  140. ModelData modelData;
  141. modelData.filePath = filePath;
  142. modelData.meshData.length = scene.mNumMeshes;
  143. for(uint m = 0; m < scene.mNumMeshes; ++m) {
  144. const(aiMesh*) meshData = scene.mMeshes[m];
  145. assert(meshData !is null);
  146. size_t cntIndices = 0;
  147. foreach(f; 0..meshData.mNumFaces) {
  148. cntIndices += meshData.mFaces[f].mNumIndices;
  149. }
  150. modelData.meshData[m].vertexData.length = meshData.mNumVertices;
  151. modelData.meshData[m].indexData.length = cntIndices;
  152. foreach(v; 0..meshData.mNumVertices) {
  153. modelData.meshData[m].vertexData[v].position = Position(meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z);
  154. modelData.meshData[m].vertexData[v].normal = Normal(meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z);
  155. if(meshData.mColors[0] !is null) {
  156. 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);
  157. }
  158. else {
  159. modelData.meshData[m].vertexData[v].color = Color(0, 0, 0, 1);
  160. }
  161. if(meshData.mTextureCoords[0] !is null) {
  162. modelData.meshData[m].vertexData[v].textureCoordinate = TextureCoordinate(meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y);
  163. }
  164. else {
  165. modelData.meshData[m].vertexData[v].textureCoordinate = TextureCoordinate(0, 0);
  166. }
  167. }
  168. size_t curIndexDataIdx = 0;
  169. foreach(f; 0..meshData.mNumFaces) {
  170. assert(meshData.mFaces !is null);
  171. foreach(i; 0..meshData.mFaces[f].mNumIndices) {
  172. assert(meshData.mFaces[f].mIndices !is null);
  173. modelData.meshData[m].indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];
  174. }
  175. }
  176. }
  177. return modelData;
  178. }
  179. }