#include "data/data_center.hpp" // before dtor, always keep identity transformation block primitive_data_center_t::primitive_data_center_t() noexcept { this->transform_blocks.acquire(internal::identity_model_matrix); this->transform_blocks.acquire(internal::plane_to_z_pos_1_model_matrix); this->transform_blocks.acquire(internal::plane_to_z_neg_1_model_matrix); // set hashed refcount hive container to individual surface containers this->surfaces[static_cast(surface_type::plane)].emplace(); this->surfaces[static_cast(surface_type::sphere)].emplace(); this->surfaces[static_cast(surface_type::cylinder)].emplace(); } primitive_data_center_t::~primitive_data_center_t() noexcept { this->transform_blocks.release(internal::identity_model_matrix); this->transform_blocks.release(internal::plane_to_z_pos_1_model_matrix); this->transform_blocks.release(internal::plane_to_z_neg_1_model_matrix); } auto primitive_data_center_t::require_transform_block(const internal::paired_model_matrix& matrix) -> internal::paired_model_matrix_ptr_t { auto [iter, _] = this->transform_blocks.acquire(matrix); return make_pointer_wrapper(iter.operator->()); } void primitive_data_center_t::require_surface(surface_type type, const internal::paired_model_matrix_ptr_t& matrix, marked_subface_ptr_t& subface) { switch (type) { case surface_type::plane: { auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); subface.set_ptr(iter.operator->()); subface.set_mark(false); if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); break; } case surface_type::sphere: { auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); subface.set_ptr(iter.operator->()); subface.set_mark(false); if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); break; } case surface_type::cylinder: { auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); subface.set_ptr(iter.operator->()); subface.set_mark(false); if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); break; } default: subface.set_ptr(nullptr); subface.set_mark(false); break; } } void primitive_data_center_t::release_transform_block(const internal::paired_model_matrix& matrix) { this->transform_blocks.release(matrix); } void primitive_data_center_t::release_surface(surface_type type, const marked_subface_ptr_t& subface) { auto subface_ptr = subface.get_ptr(); switch (type) { case surface_type::plane: { auto model_matrices = subface_ptr->model_matrices; std::get(this->surfaces[static_cast(type)]).release(model_matrices); release_transform_block(model_matrices); break; } case surface_type::sphere: { auto model_matrices = subface_ptr->model_matrices; std::get(this->surfaces[static_cast(type)]).release(model_matrices); release_transform_block(model_matrices); break; } case surface_type::cylinder: { auto model_matrices = subface_ptr->model_matrices; std::get(this->surfaces[static_cast(type)]).release(model_matrices); release_transform_block(model_matrices); break; } default: break; } } namespace internal { PE_API primitive* new_primitive(primitive_type type) { switch (type) { case PRIMITIVE_TYPE_SPHERE: return new (mi_malloc(sizeof(sphere_t))) sphere_t(); case PRIMITIVE_TYPE_CYLINDER: return new (mi_malloc(sizeof(cylinder_t))) cylinder_t(); default: return nullptr; } } PE_API primitive* copy_primitive(primitive* ptr) { switch (ptr->get_type()) { case PRIMITIVE_TYPE_SPHERE: return new (mi_malloc(sizeof(sphere_t))) sphere_t(*static_cast(ptr)); case PRIMITIVE_TYPE_CYLINDER: return new (mi_malloc(sizeof(cylinder_t))) cylinder_t(*static_cast(ptr)); default: return nullptr; } } } // namespace internal