💿🐜 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.

382 lines
12 KiB

  1. /*
  2. * Copyright (C) 2023 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 <engine/render/model.hpp>
  20. #include <engine/resources/resource-loader.hpp>
  21. #include <engine/resources/resource-manager.hpp>
  22. #include <engine/render/vertex-attribute-location.hpp>
  23. #include <engine/math/numbers.hpp>
  24. #include <engine/utility/hash/fnv1a.hpp>
  25. #include <bit>
  26. #include <cstdint>
  27. inline constexpr std::uint16_t vertex_attribute_position = 0b0000000000000001;
  28. inline constexpr std::uint16_t vertex_attribute_uv = 0b0000000000000010;
  29. inline constexpr std::uint16_t vertex_attribute_normal = 0b0000000000000100;
  30. inline constexpr std::uint16_t vertex_attribute_tangent = 0b0000000000001000;
  31. inline constexpr std::uint16_t vertex_attribute_color = 0b0000000000010000;
  32. inline constexpr std::uint16_t vertex_attribute_bone_index = 0b0000000000100000;
  33. inline constexpr std::uint16_t vertex_attribute_bone_weight = 0b0000000001000000;
  34. inline constexpr std::uint16_t vertex_attribute_morph_target = 0b0000000010000000;
  35. template <>
  36. std::unique_ptr<render::model> resource_loader<render::model>::load(::resource_manager& resource_manager, deserialize_context& ctx)
  37. {
  38. // Read vertex format
  39. std::uint16_t vertex_format_flags = 0;
  40. ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&vertex_format_flags), 1);
  41. // Read bones per vertex (if any)
  42. std::uint8_t bones_per_vertex = 0;
  43. if ((vertex_format_flags & vertex_attribute_bone_index) || (vertex_format_flags & vertex_attribute_bone_weight))
  44. {
  45. ctx.read8(reinterpret_cast<std::byte*>(&bones_per_vertex), 1);
  46. }
  47. // Read vertex count
  48. std::uint32_t vertex_count = 0;
  49. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&vertex_count), 1);
  50. // Determine vertex stride
  51. std::size_t vertex_stride = 0;
  52. if (vertex_format_flags & vertex_attribute_position)
  53. {
  54. vertex_stride += sizeof(float) * 3;
  55. }
  56. if (vertex_format_flags & vertex_attribute_uv)
  57. {
  58. vertex_stride += sizeof(float) * 2;
  59. }
  60. if (vertex_format_flags & vertex_attribute_normal)
  61. {
  62. vertex_stride += sizeof(float) * 3;
  63. }
  64. if (vertex_format_flags & vertex_attribute_tangent)
  65. {
  66. vertex_stride += sizeof(float) * 4;
  67. }
  68. if (vertex_format_flags & vertex_attribute_color)
  69. {
  70. vertex_stride += sizeof(float) * 4;
  71. }
  72. if (vertex_format_flags & vertex_attribute_bone_index)
  73. {
  74. vertex_stride += sizeof(std::uint16_t) * bones_per_vertex;
  75. }
  76. if (vertex_format_flags & vertex_attribute_bone_weight)
  77. {
  78. vertex_stride += sizeof(float) * bones_per_vertex;
  79. }
  80. if (vertex_format_flags & vertex_attribute_morph_target)
  81. {
  82. vertex_stride += sizeof(float) * 3;
  83. }
  84. // Allocate vertex data
  85. std::vector<std::byte> vertex_data(vertex_count * vertex_stride);
  86. // Read vertices
  87. if constexpr (std::endian::native == std::endian::little)
  88. {
  89. ctx.read8(vertex_data.data(), vertex_count * vertex_stride);
  90. }
  91. else
  92. {
  93. std::byte* vertex_data_offset = vertex_data.data();
  94. for (std::uint32_t i = 0; i < vertex_count; ++i)
  95. {
  96. if (vertex_format_flags & vertex_attribute_position)
  97. {
  98. ctx.read32<std::endian::little>(vertex_data_offset, 3);
  99. vertex_data_offset += sizeof(float) * 3;
  100. }
  101. if (vertex_format_flags & vertex_attribute_uv)
  102. {
  103. ctx.read32<std::endian::little>(vertex_data_offset, 2);
  104. vertex_data_offset += sizeof(float) * 2;
  105. }
  106. if (vertex_format_flags & vertex_attribute_normal)
  107. {
  108. ctx.read32<std::endian::little>(vertex_data_offset, 3);
  109. vertex_data_offset += sizeof(float) * 3;
  110. }
  111. if (vertex_format_flags & vertex_attribute_tangent)
  112. {
  113. ctx.read32<std::endian::little>(vertex_data_offset, 4);
  114. vertex_data_offset += sizeof(float) * 4;
  115. }
  116. if (vertex_format_flags & vertex_attribute_color)
  117. {
  118. ctx.read32<std::endian::little>(vertex_data_offset, 4);
  119. vertex_data_offset += sizeof(float) * 4;
  120. }
  121. if (vertex_format_flags & vertex_attribute_bone_index)
  122. {
  123. ctx.read16<std::endian::little>(vertex_data_offset, bones_per_vertex);
  124. vertex_data_offset += sizeof(std::uint16_t) * bones_per_vertex;
  125. }
  126. if (vertex_format_flags & vertex_attribute_bone_weight)
  127. {
  128. ctx.read32<std::endian::little>(vertex_data_offset, bones_per_vertex);
  129. vertex_data_offset += sizeof(float) * bones_per_vertex;
  130. }
  131. if (vertex_format_flags & vertex_attribute_morph_target)
  132. {
  133. ctx.read32<std::endian::little>(vertex_data_offset, 3);
  134. vertex_data_offset += sizeof(float) * 3;
  135. }
  136. }
  137. }
  138. // Allocate model
  139. std::unique_ptr<render::model> model = std::make_unique<render::model>();
  140. // Build model vertex buffer
  141. model->get_vertex_buffer() = std::make_shared<gl::vertex_buffer>(gl::buffer_usage::static_draw, vertex_data);
  142. model->set_vertex_offset(0);
  143. model->set_vertex_stride(vertex_stride);
  144. // Free vertex data
  145. vertex_data.clear();
  146. // Build vertex input attributes
  147. std::vector<gl::vertex_input_attribute> attributes(std::popcount(vertex_format_flags));
  148. std::uint32_t vertex_offset = 0;
  149. std::uint32_t attribute_index = 0;
  150. if (vertex_format_flags & vertex_attribute_position)
  151. {
  152. auto& attribute = attributes[attribute_index];
  153. attribute.location = render::vertex_attribute_location::position;
  154. attribute.binding = 0;
  155. attribute.format = gl::format::r32g32b32_sfloat;
  156. attribute.offset = vertex_offset;
  157. vertex_offset += 3 * sizeof(float);
  158. ++attribute_index;
  159. }
  160. if (vertex_format_flags & vertex_attribute_uv)
  161. {
  162. auto& attribute = attributes[attribute_index];
  163. attribute.location = render::vertex_attribute_location::uv;
  164. attribute.binding = 0;
  165. attribute.format = gl::format::r32g32_sfloat;
  166. attribute.offset = vertex_offset;
  167. vertex_offset += 2 * sizeof(float);
  168. ++attribute_index;
  169. }
  170. if (vertex_format_flags & vertex_attribute_normal)
  171. {
  172. auto& attribute = attributes[attribute_index];
  173. attribute.location = render::vertex_attribute_location::normal;
  174. attribute.binding = 0;
  175. attribute.format = gl::format::r32g32b32_sfloat;
  176. attribute.offset = vertex_offset;
  177. vertex_offset += 3 * sizeof(float);
  178. ++attribute_index;
  179. }
  180. if (vertex_format_flags & vertex_attribute_tangent)
  181. {
  182. auto& attribute = attributes[attribute_index];
  183. attribute.location = render::vertex_attribute_location::tangent;
  184. attribute.binding = 0;
  185. attribute.format = gl::format::r32g32b32a32_sfloat;
  186. attribute.offset = vertex_offset;
  187. vertex_offset += 4 * sizeof(float);
  188. ++attribute_index;
  189. }
  190. if (vertex_format_flags & vertex_attribute_color)
  191. {
  192. auto& attribute = attributes[attribute_index];
  193. attribute.location = render::vertex_attribute_location::color;
  194. attribute.binding = 0;
  195. attribute.format = gl::format::r32g32b32a32_sfloat;
  196. attribute.offset = vertex_offset;
  197. vertex_offset += 4 * sizeof(float);
  198. ++attribute_index;
  199. }
  200. if (vertex_format_flags & vertex_attribute_bone_index)
  201. {
  202. auto& attribute = attributes[attribute_index];
  203. attribute.location = render::vertex_attribute_location::bone_index;
  204. attribute.binding = 0;
  205. switch (bones_per_vertex)
  206. {
  207. case 1:
  208. attribute.format = gl::format::r16_uint;
  209. break;
  210. case 2:
  211. attribute.format = gl::format::r16g16_uint;
  212. break;
  213. case 3:
  214. attribute.format = gl::format::r16g16b16_uint;
  215. break;
  216. case 4:
  217. attribute.format = gl::format::r16g16b16a16_uint;
  218. break;
  219. default:
  220. attribute.format = gl::format::undefined;
  221. break;
  222. }
  223. attribute.offset = vertex_offset;
  224. vertex_offset += bones_per_vertex * sizeof(std::uint16_t);
  225. ++attribute_index;
  226. }
  227. if (vertex_format_flags & vertex_attribute_bone_weight)
  228. {
  229. auto& attribute = attributes[attribute_index];
  230. attribute.location = render::vertex_attribute_location::bone_weight;
  231. attribute.binding = 0;
  232. switch (bones_per_vertex)
  233. {
  234. case 1:
  235. attribute.format = gl::format::r32_sfloat;
  236. break;
  237. case 2:
  238. attribute.format = gl::format::r32g32_sfloat;
  239. break;
  240. case 3:
  241. attribute.format = gl::format::r32g32b32_sfloat;
  242. break;
  243. case 4:
  244. attribute.format = gl::format::r32g32b32a32_sfloat;
  245. break;
  246. default:
  247. attribute.format = gl::format::undefined;
  248. break;
  249. }
  250. attribute.offset = vertex_offset;
  251. vertex_offset += bones_per_vertex * sizeof(float);
  252. ++attribute_index;
  253. }
  254. if (vertex_format_flags & vertex_attribute_morph_target)
  255. {
  256. auto& attribute = attributes[attribute_index];
  257. attribute.location = render::vertex_attribute_location::target;
  258. attribute.binding = 0;
  259. attribute.format = gl::format::r32g32b32_sfloat;
  260. attribute.offset = vertex_offset;
  261. // vertex_offset += 3 * sizeof(float);
  262. // ++attribute_index;
  263. }
  264. // Build model vertex array
  265. model->get_vertex_array() = std::make_shared<gl::vertex_array>(attributes);
  266. // Read model bounds
  267. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&model->get_bounds()), 6);
  268. // Read material count
  269. std::uint16_t material_count = 0;
  270. ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&material_count), 1);
  271. // Allocate material groups
  272. model->get_groups().resize(material_count);
  273. // Read materials
  274. for (auto& group: model->get_groups())
  275. {
  276. // Read material name length
  277. std::uint8_t material_name_length = 0;
  278. ctx.read8(reinterpret_cast<std::byte*>(&material_name_length), 1);
  279. // Read material name
  280. std::string material_name(static_cast<std::size_t>(material_name_length), '\0');
  281. ctx.read8(reinterpret_cast<std::byte*>(material_name.data()), material_name_length);
  282. // Generate group ID by hashing material name
  283. group.id = hash::fnv1a32<char>(material_name);
  284. // Set group primitive topology
  285. group.primitive_topology = gl::primitive_topology::triangle_list;
  286. // Read index of first vertex
  287. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&group.first_vertex), 1);
  288. // Read vertex count
  289. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&group.vertex_count), 1);
  290. // Slugify material filename
  291. std::string material_filename = material_name + ".mtl";
  292. std::replace(material_filename.begin(), material_filename.end(), '_', '-');
  293. // Load group material
  294. group.material = resource_manager.load<render::material>(material_filename);
  295. }
  296. // Read skeleton
  297. if ((vertex_format_flags & vertex_attribute_bone_index) || (vertex_format_flags & vertex_attribute_bone_weight))
  298. {
  299. ::skeleton& skeleton = model->get_skeleton();
  300. // Read bone count
  301. std::uint16_t bone_count = 0;
  302. ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&bone_count), 1);
  303. // Resize skeleton
  304. skeleton.add_bones(bone_count);
  305. // Read bones
  306. for (std::uint16_t i = 0; i < bone_count; ++i)
  307. {
  308. // Read bone name
  309. hash::fnv1a32_t bone_name = {};
  310. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&bone_name), 1);
  311. // Read bone parent index
  312. std::uint16_t bone_parent_index = i;
  313. ctx.read16<std::endian::little>(reinterpret_cast<std::byte*>(&bone_parent_index), 1);
  314. // Construct bone transform
  315. bone_transform_type bone_transform;
  316. // Read bone translation
  317. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(bone_transform.translation.data()), 3);
  318. // Read bone rotation
  319. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&bone_transform.rotation.r), 1);
  320. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(bone_transform.rotation.i.data()), 3);
  321. // Set bone scale
  322. bone_transform.scale = {1, 1, 1};
  323. // Read bone length
  324. float bone_length = 0.0f;
  325. ctx.read32<std::endian::little>(reinterpret_cast<std::byte*>(&bone_length), 1);
  326. // Set bone properties
  327. skeleton.set_bone_name(i, bone_name);
  328. skeleton.set_bone_parent(i, bone_parent_index);
  329. skeleton.set_bone_transform(i, bone_transform);
  330. }
  331. // Update skeleton's rest pose
  332. skeleton.update_rest_pose();
  333. }
  334. return model;
  335. }