mesh_encoder.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "mesh_encoder.h"
  2. #include "mesh_codec.hpp"
  3. #include <xxhash.h>
  4. #include <unordered_set>
  5. using namespace mesh_codec;
  6. struct mesh_encoder::impl {
  7. using cache_set_type =
  8. std::unordered_set<hash_type>;
  9. cache_set_type cache_set;
  10. static data_type encode_mesh(const mesh_ptr &mesh) {
  11. auto raw = mesh->get_raw_info();
  12. auto ret_size = sizeof(raw.num_triangles)
  13. + sizeof(raw.vbo_data.size) + raw.vbo_data.size
  14. + sizeof(raw.ebo_data.size) + raw.ebo_data.size;
  15. auto ret = data_type(ret_size, pre_size);
  16. auto writer = network_writer(ret);
  17. writer << raw.num_triangles
  18. << raw.vbo_data.size << raw.vbo_data
  19. << raw.ebo_data.size << raw.ebo_data;
  20. assert(writer.empty());
  21. return ret;
  22. }
  23. data_type encode(const mesh_ptr &mesh) {
  24. // handle no transfer situation
  25. if (auto no_transfer_any = mesh->get_meta_any(META_MESH_NO_TRANSFER);
  26. boost::any_cast<bool>(no_transfer_any)) {
  27. auto name = mesh->get_meta_ext<size_t>(META_SERIES_NAME);
  28. auto writer = network_writer();
  29. writer << FLAG_NO_TRANSFER << name;
  30. return writer.current_data();
  31. }
  32. static constexpr auto hash_seed = 0;
  33. auto ret = encode_mesh(mesh);
  34. auto id = XXH64(ret.start_ptr(), ret.size, hash_seed);
  35. auto head = ret.sub_data(-pre_size);
  36. auto writer = network_writer(head);
  37. if (cache_set.contains(id)) {
  38. writer << FLAG_CACHED << id;
  39. assert(writer.empty());
  40. return head;
  41. } else {
  42. writer << FLAG_NEW << id;
  43. cache_set.emplace(id);
  44. assert(writer.empty());
  45. head = head.extend(ret.size); // recover data
  46. return head;
  47. }
  48. }
  49. void clear_cache() {
  50. cache_set.clear();
  51. }
  52. };
  53. mesh_encoder::mesh_encoder()
  54. : pimpl(std::make_unique<impl>()) {}
  55. mesh_encoder::~mesh_encoder() = default;
  56. data_type mesh_encoder::encode(const mesh_ptr &mesh) {
  57. return pimpl->encode(mesh);
  58. }
  59. void mesh_encoder::clear_cache() {
  60. pimpl->clear_cache();
  61. }