#include "LocalUniverse.hpp" #include "../../core/data/math.hpp" #include "../contouring/Abstract.hpp" #include "../Window.hpp" #include "../../core/utils/logger.hpp" #include "../../core/world/Area.hpp" using namespace world::client; LocalUniverse::LocalUniverse(server_handle *const handle, const std::string& contour): Universe(contour), handle(handle) { assert(handle != nullptr); for (auto i = 0; i < 500 && !handle->running; i++) { LOG_D("Waiting local server startup"); Window::wait(); } handle->onUpdate = std::function([&](const area_ &pos, const chunk_pos &offset, const world::ChunkContainer &data, geometry::Faces neighbors) { contouring->onUpdate(pos, this->last_chunk - offset, data, neighbors); }); } LocalUniverse::~LocalUniverse() { handle->running = false; } void LocalUniverse::update(voxel_pos pos, float) { if (handle->teleport.has_value() && onTeleport) { pos = handle->teleport.value(); onTeleport(pos); handle->teleport = std::nullopt; } if (handle->message.has_value() && onMessage) { onMessage(handle->message.value()); handle->message = std::nullopt; } const auto cur_chunk = glm::divide(pos); const auto chunkChange = cur_chunk != last_chunk; last_chunk = cur_chunk; if(chunkChange) { for(const auto& area: *handle->areas) { const chunk_pos diff = glm::divide(pos - area.second->getOffset().as_voxel()); for(const auto& chunk: area.second->getChunks()) { contouring->onNotify(std::make_pair(area.first, chunk.first), diff, area.second->getChunks()); } } } contouring->update(pos, *handle->areas); } void LocalUniverse::emit(const action::packet &packet) { handle->emit(packet); } Universe::ray_result LocalUniverse::raycast(const geometry::Ray& ray) const { return handle->raycast(ray); } bool LocalUniverse::isAreaFree(const area_ &pos, const geometry::Shape shape, const uint16_t radius) const { if (const auto it = handle->areas->find(pos.first); it != handle->areas->end()) { const auto center = pos.second + it->second->getOffset().as_voxel(); return !handle->entities->contains([&](entity_id, const Entity &entity) { return entity.instances.contains([&](entity_id, const Entity::Instance &inst) { return geometry::InShape(shape, center, radius, inst.pos.as_voxel(), entity.size); }); }); } else return false; } void LocalUniverse::getEntitiesModels(const std::function&)>& call, const std::optional& frustum, const glm::llvec3& offset, int density) { std::vector mats; handle->entities->iter([&](entity_id eId, const Entity &entity) { entity.instances.iter([&](entity_id iId, const Entity::Instance &inst) { if (eId.index == PLAYER_ENTITY_ID.index && iId.index == PLAYER_ENTITY_ID.index) return; glm::mat4 tmp; if (contouring::Abstract::CullEntity(tmp, entity.size, entity.scale, inst.pos, frustum, offset, density)) mats.push_back(tmp); }); if(!mats.empty()) { call(eId.index, mats); mats.resize(0); } }); }