88 lines
3.3 KiB
C++
88 lines
3.3 KiB
C++
#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_<chunk_pos> &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_<voxel_pos> &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<void(size_t, const std::vector<glm::mat4>&)>& call,
|
|
const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density)
|
|
{
|
|
std::vector<glm::mat4> 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);
|
|
}
|
|
});
|
|
} |