💿🐜 Antkeeper source code https://antkeeper.com
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.

392 lines
12 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. /*
  2. * Copyright (C) 2017 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper Source Code.
  5. *
  6. * Antkeeper Source Code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper Source Code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "model-loader.hpp"
  20. #include "material-loader.hpp"
  21. #include <fstream>
  22. template <typename T>
  23. inline static void read8(T* result, unsigned char** data)
  24. {
  25. std::uint8_t temp = (*data)[0];
  26. *result = *reinterpret_cast<T*>(&temp);
  27. *data += 1;
  28. }
  29. template <typename T>
  30. inline static void read16(T* result, unsigned char** data)
  31. {
  32. std::uint16_t temp = ((*data)[0] << 0) | ((*data)[1] << 8);
  33. *result = *reinterpret_cast<T*>(&temp);
  34. *data += 2;
  35. }
  36. template <typename T>
  37. inline static void read32(T* result, unsigned char** data)
  38. {
  39. std::uint32_t temp = ((*data)[0] << 0) | ((*data)[1] << 8) | ((*data)[2] << 16) | ((*data)[3] << 24);
  40. *result = *reinterpret_cast<T*>(&temp);
  41. *data += 4;
  42. }
  43. inline static void readString(std::string* result, unsigned char** data)
  44. {
  45. result->resize((*data)[0]);
  46. for (std::size_t i = 0; i < result->size(); ++i)
  47. {
  48. (*result)[i] = (*data)[i + 1];
  49. }
  50. *data += result->size() + 1;
  51. }
  52. ModelLoader::ModelLoader():
  53. materialLoader(nullptr)
  54. {}
  55. ModelLoader::~ModelLoader()
  56. {}
  57. Model* ModelLoader::load(const std::string& filename)
  58. {
  59. // Open file
  60. std::ifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary | std::ifstream::ate);
  61. if (!file.is_open())
  62. {
  63. std::cerr << "ModelLoader::load(): Failed to open model file \"" << filename << "\"" << std::endl;
  64. return nullptr;
  65. }
  66. // Allocate file data buffer
  67. int filesize = file.tellg();
  68. unsigned char* buffer = new unsigned char[filesize];
  69. // Read file data into buffer
  70. file.seekg(0, file.beg);
  71. file.read(reinterpret_cast<char*>(&buffer[0]), filesize);
  72. unsigned char* bufferOffset = &buffer[0];
  73. // Close file
  74. file.close();
  75. // Allocate model data
  76. ModelData* modelData = new ModelData();
  77. SkeletonData* skeletonData = nullptr;
  78. // Allocate material groups
  79. read32(&modelData->groupCount, &bufferOffset);
  80. modelData->groups = new MaterialGroup[modelData->groupCount];
  81. // Read material groups (and calculate triangle count)
  82. std::uint32_t triangleCount = 0;
  83. for (std::size_t i = 0; i < modelData->groupCount; ++i)
  84. {
  85. MaterialGroup* group = &modelData->groups[i];
  86. readString(&group->materialName, &bufferOffset);
  87. read32(&group->indexOffset, &bufferOffset);
  88. read32(&group->triangleCount, &bufferOffset);
  89. // Read bounds
  90. Vector3 min;
  91. Vector3 max;
  92. read32(&min.x, &bufferOffset);
  93. read32(&min.y, &bufferOffset);
  94. read32(&min.z, &bufferOffset);
  95. read32(&max.x, &bufferOffset);
  96. read32(&max.y, &bufferOffset);
  97. read32(&max.z, &bufferOffset);
  98. group->bounds.setMin(min);
  99. group->bounds.setMax(max);
  100. triangleCount += group->triangleCount;
  101. }
  102. // Read vertex format and count
  103. read32(&modelData->vertexFormat, &bufferOffset);
  104. read32(&modelData->vertexCount, &bufferOffset);
  105. // Read bounds
  106. Vector3 min;
  107. Vector3 max;
  108. read32(&min.x, &bufferOffset);
  109. read32(&min.y, &bufferOffset);
  110. read32(&min.z, &bufferOffset);
  111. read32(&max.x, &bufferOffset);
  112. read32(&max.y, &bufferOffset);
  113. read32(&max.z, &bufferOffset);
  114. modelData->bounds.setMin(min);
  115. modelData->bounds.setMax(max);
  116. // Calculate vertex size
  117. std::uint32_t vertexSize =
  118. 3 // Position
  119. + 3 // Normal
  120. + 2 * ((modelData->vertexFormat & UV) != 0) // UV
  121. + 4 * ((modelData->vertexFormat & TANGENT) != 0) // Tangent
  122. + 4 * ((modelData->vertexFormat & TANGENT) != 0) // Bitangent
  123. + 4 * ((modelData->vertexFormat & WEIGHTS) != 0) // Indices
  124. + 4 * ((modelData->vertexFormat & WEIGHTS) != 0); // Weights
  125. // Allocate vertex data
  126. modelData->vertexData = new float[modelData->vertexCount * vertexSize];
  127. // Read vertex data
  128. float* vertexDataOffset = &modelData->vertexData[0];
  129. for (std::size_t i = 0; i < modelData->vertexCount; ++i)
  130. {
  131. for (std::size_t j = 0; j < vertexSize; ++j)
  132. {
  133. read32(vertexDataOffset, &bufferOffset);
  134. ++vertexDataOffset;
  135. }
  136. }
  137. // Allocate index data
  138. std::uint32_t indexCount = triangleCount * 3;
  139. modelData->indexData = new std::uint32_t[indexCount];
  140. // Read index data
  141. for (std::size_t i = 0; i < indexCount; ++i)
  142. {
  143. read32(&modelData->indexData[i], &bufferOffset);
  144. }
  145. // Read skeleton data
  146. if (modelData->vertexFormat & WEIGHTS)
  147. {
  148. // Allocate skeleton data
  149. skeletonData = new SkeletonData();
  150. // Read bone count
  151. read16(&skeletonData->boneCount, &bufferOffset);
  152. // Allocate bones
  153. skeletonData->boneData = new BoneData[skeletonData->boneCount];
  154. // Read bones
  155. for (std::size_t i = 0; i < skeletonData->boneCount; ++i)
  156. {
  157. BoneData* boneData = &skeletonData->boneData[i];
  158. boneData->children = nullptr;
  159. readString(&boneData->name, &bufferOffset);
  160. read16(&boneData->parent, &bufferOffset);
  161. read16(&boneData->childCount, &bufferOffset);
  162. boneData->children = new std::uint16_t[boneData->childCount];
  163. for (std::size_t j = 0; j < boneData->childCount; ++j)
  164. {
  165. read16(&boneData->children[j], &bufferOffset);
  166. }
  167. read32(&boneData->translation.x, &bufferOffset);
  168. read32(&boneData->translation.y, &bufferOffset);
  169. read32(&boneData->translation.z, &bufferOffset);
  170. read32(&boneData->rotation.w, &bufferOffset);
  171. read32(&boneData->rotation.x, &bufferOffset);
  172. read32(&boneData->rotation.y, &bufferOffset);
  173. read32(&boneData->rotation.z, &bufferOffset);
  174. read32(&boneData->length, &bufferOffset);
  175. }
  176. }
  177. // Free file data buffer
  178. delete[] buffer;
  179. GLuint vao;
  180. GLuint vbo;
  181. GLuint ibo;
  182. // Generate and bind VAO
  183. glGenVertexArrays(1, &vao);
  184. glBindVertexArray(vao);
  185. // Generate and bind VBO, then upload vertex data
  186. glGenBuffers(1, &vbo);
  187. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  188. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * modelData->vertexCount, modelData->vertexData, GL_STATIC_DRAW);
  189. // Setup vertex attribute arrays
  190. std::size_t attribOffset = 0;
  191. std::size_t attribSize = 0;
  192. // Vertex position attribute
  193. attribSize = 3;
  194. glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
  195. glVertexAttribPointer(EMERGENT_VERTEX_POSITION, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  196. attribOffset += attribSize;
  197. // Vertex normal attribute
  198. attribSize = 3;
  199. glEnableVertexAttribArray(EMERGENT_VERTEX_NORMAL);
  200. glVertexAttribPointer(EMERGENT_VERTEX_NORMAL, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  201. attribOffset += attribSize;
  202. // Vertex UV attribute
  203. if ((modelData->vertexFormat & UV) != 0)
  204. {
  205. attribSize = 2;
  206. glEnableVertexAttribArray(EMERGENT_VERTEX_TEXCOORD);
  207. glVertexAttribPointer(EMERGENT_VERTEX_TEXCOORD, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  208. attribOffset += attribSize;
  209. }
  210. // Vertex tangent and bitangent attributes
  211. if ((modelData->vertexFormat & TANGENT) != 0)
  212. {
  213. // Tangent
  214. attribSize = 4;
  215. glEnableVertexAttribArray(EMERGENT_VERTEX_TANGENT);
  216. glVertexAttribPointer(EMERGENT_VERTEX_TANGENT, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  217. attribOffset += attribSize;
  218. // Bitangent
  219. attribSize = 4;
  220. glEnableVertexAttribArray(EMERGENT_VERTEX_BITANGENT);
  221. glVertexAttribPointer(EMERGENT_VERTEX_BITANGENT, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  222. attribOffset += attribSize;
  223. }
  224. // Vertex indices and weights attributes
  225. if ((modelData->vertexFormat & TANGENT) != 0)
  226. {
  227. // Indices
  228. attribSize = 4;
  229. glEnableVertexAttribArray(EMERGENT_VERTEX_BONE_INDICES);
  230. glVertexAttribPointer(EMERGENT_VERTEX_BONE_INDICES, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  231. attribOffset += attribSize;
  232. // Weights
  233. attribSize = 4;
  234. glEnableVertexAttribArray(EMERGENT_VERTEX_BONE_WEIGHTS);
  235. glVertexAttribPointer(EMERGENT_VERTEX_BONE_WEIGHTS, attribSize, GL_FLOAT, GL_FALSE, sizeof(float) * vertexSize, (char*)0 + attribOffset * sizeof(float));
  236. attribOffset += attribSize;
  237. }
  238. // Generate and bind IBO, then upload index data
  239. glGenBuffers(1, &ibo);
  240. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
  241. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * indexCount, modelData->indexData, GL_STATIC_DRAW);
  242. // Delete vertex and index data
  243. delete[] modelData->vertexData;
  244. delete[] modelData->indexData;
  245. // Allocate model
  246. Model* model = new Model();
  247. model->setVAO(vao);
  248. model->setVBO(vbo);
  249. model->setIBO(ibo);
  250. model->setVertexFormat(modelData->vertexFormat);
  251. model->setBounds(modelData->bounds);
  252. // Create model groups
  253. for (std::size_t i = 0; i < modelData->groupCount; ++i)
  254. {
  255. ModelLoader::MaterialGroup* modelDataGroup = &modelData->groups[i];
  256. // Allocate model group
  257. Model::Group* modelGroup = new Model::Group();
  258. // Set model group name
  259. modelGroup->name = modelDataGroup->materialName;
  260. // Load material
  261. std::string materialFilename = std::string("data/materials/") + modelDataGroup->materialName + std::string(".mtl");
  262. if (materialLoader != nullptr)
  263. {
  264. modelGroup->material = materialLoader->load(materialFilename);
  265. if (!modelGroup->material)
  266. {
  267. std::cerr << "ModelLoader::load(): Failed to load material file \"" << materialFilename << "\" for model file \"" << filename << "\"" << std::endl;
  268. }
  269. }
  270. else
  271. {
  272. modelGroup->material = nullptr;
  273. std::cerr << "ModelLoader::load(): No valid material loader, material file \"" << materialFilename << "\" not loaded" << std::endl;
  274. }
  275. // Setup model group geometry
  276. modelGroup->indexOffset = modelDataGroup->indexOffset;
  277. modelGroup->triangleCount = modelDataGroup->triangleCount;
  278. modelGroup->bounds = modelDataGroup->bounds;
  279. // Add model group to model
  280. model->addGroup(modelGroup);
  281. }
  282. // Create skeleton
  283. if (skeletonData != nullptr)
  284. {
  285. // Allocate skeleton
  286. Skeleton* skeleton = new Skeleton();
  287. // Construct bone hierarchy from bone data
  288. constructBoneHierarchy(skeleton->getRootBone(), skeletonData->boneData, 0);
  289. // Calculate bind pose
  290. skeleton->calculateBindPose();
  291. // Add skeleton to model
  292. model->setSkeleton(skeleton);
  293. }
  294. // Delete model data groups
  295. delete[] modelData->groups;
  296. // Delete model data
  297. delete modelData;
  298. // Delete skeleton data
  299. if (skeletonData != nullptr)
  300. {
  301. for (std::size_t i = 0; i < skeletonData->boneCount; ++i)
  302. {
  303. delete[] skeletonData->boneData[i].children;
  304. }
  305. delete[] skeletonData->boneData;
  306. delete skeletonData;
  307. }
  308. return model;
  309. }
  310. void ModelLoader::setMaterialLoader(MaterialLoader* materialLoader)
  311. {
  312. this->materialLoader = materialLoader;
  313. }
  314. void ModelLoader::constructBoneHierarchy(Bone* bone, const BoneData* data, std::uint16_t index)
  315. {
  316. bone->setName(data[index].name);
  317. Transform transform;
  318. transform.translation = data[index].translation;
  319. transform.rotation = data[index].rotation;
  320. transform.scale = Vector3(1.0f);
  321. bone->setRelativeTransform(transform);
  322. bone->setLength(data[index].length);
  323. for (std::uint16_t i = 0; i < data[index].childCount; ++i)
  324. {
  325. constructBoneHierarchy(bone->createChild(), data, data[index].children[i]);
  326. }
  327. }