| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- #include "mesh_encoder.h"
- #include "mesh_codec.hpp"
- #include <xxhash.h>
- #include <unordered_set>
- using namespace mesh_codec;
- struct mesh_encoder::impl {
- using cache_set_type =
- std::unordered_set<hash_type>;
- cache_set_type cache_set;
- static data_type encode_mesh(const mesh_ptr &mesh) {
- auto raw = mesh->get_raw_info();
- auto ret_size = sizeof(raw.num_triangles)
- + sizeof(raw.vbo_data.size) + raw.vbo_data.size
- + sizeof(raw.ebo_data.size) + raw.ebo_data.size;
- auto ret = data_type(ret_size, pre_size);
- auto writer = network_writer(ret);
- writer << raw.num_triangles
- << raw.vbo_data.size << raw.vbo_data
- << raw.ebo_data.size << raw.ebo_data;
- assert(writer.empty());
- return ret;
- }
- data_type encode(const mesh_ptr &mesh) {
- // handle no transfer situation
- if (auto no_transfer_any = mesh->get_meta_any(META_MESH_NO_TRANSFER);
- boost::any_cast<bool>(no_transfer_any)) {
- auto name = mesh->get_meta_ext<size_t>(META_SERIES_NAME);
- auto writer = network_writer();
- writer << FLAG_NO_TRANSFER << name;
- return writer.current_data();
- }
- static constexpr auto hash_seed = 0;
- auto ret = encode_mesh(mesh);
- auto id = XXH64(ret.start_ptr(), ret.size, hash_seed);
- auto head = ret.sub_data(-pre_size);
- auto writer = network_writer(head);
- if (cache_set.contains(id)) {
- writer << FLAG_CACHED << id;
- assert(writer.empty());
- return head;
- } else {
- writer << FLAG_NEW << id;
- cache_set.emplace(id);
- assert(writer.empty());
- head = head.extend(ret.size); // recover data
- return head;
- }
- }
- void clear_cache() {
- cache_set.clear();
- }
- };
- mesh_encoder::mesh_encoder()
- : pimpl(std::make_unique<impl>()) {}
- mesh_encoder::~mesh_encoder() = default;
- data_type mesh_encoder::encode(const mesh_ptr &mesh) {
- return pimpl->encode(mesh);
- }
- void mesh_encoder::clear_cache() {
- pimpl->clear_cache();
- }
|