1
0
Fork 0
Univerxel/src/core/world/Universe.hpp

81 lines
3.0 KiB
C++

#pragma once
#include <variant>
#include "forward.h"
#include "Voxel.hpp"
#include "position.h"
#include "../geometry/Ray.hpp"
#include "../geometry/Shapes.hpp"
namespace world {
/// Whole abstract universe container
class Universe {
public:
virtual ~Universe() {}
/// Distance management
struct options {
/// Radius in chunks to load if missing
uint16_t loadDistance = 5;
/// Radius in chunks to keep in memory
uint16_t keepDistance = 6;
};
/// Universe voxel ray intersection
struct ray_target {
ray_target(area_<voxel_pos> pos, Voxel value, voxel_pos offset):
pos(pos), value(value), offset(offset) { }
area_<voxel_pos> pos;
Voxel value;
voxel_pos offset;
};
/// Universe unloaded chunk ray intersection
struct ray_out_of_range {
ray_out_of_range(area_<chunk_pos> pos, voxel_pos offset):
pos(pos), offset(offset) { }
area_<chunk_pos> pos;
voxel_pos offset;
};
/// Universe ray intersection
/// @return target voxel, unloaded chunk or none
using ray_result = std::variant<std::monostate, ray_target, ray_out_of_range>;
/// Get nearest voxel colliding ray
/// @note ray in world scale
virtual ray_result raycast(const geometry::Ray &ray) const = 0;
/// Check for entity in shape
/// MAYBE: multiarea
virtual bool isAreaFree(const area_<voxel_pos> &pos, geometry::Shape shape, uint16_t radius) const = 0;
/// Check for collision on movement
bool collide(const glm::ifvec3 &pos, const glm::vec3 &vel, int density, float radius = 0) const;
/// Move with collision check
/// @note must remove velocity after colision
bool move(glm::ifvec3 &pos, const glm::vec3 &vel, int density, float radius = 0) const;
/// Entities commun properties
struct Entity {
/// Linear cube of Chunk
/// Size: 1+divide(size)
using area_t = std::vector<std::shared_ptr<Chunk>>;
/// render::Model::Data serialized
using model_t = std::vector<char>;
Entity(const glm::usvec3& size = glm::usvec3(1), const glm::vec3& scale = glm::vec3(1), bool permanant = true):
size(size), scale(scale), permanant(permanant) { }
Entity(const model_t& model, const glm::usvec3& size = glm::usvec3(1), const glm::vec3& scale = glm::vec3(1), bool permanant = true):
size(size), scale(scale), permanant(permanant) { shape = model; }
std::variant<area_t, model_t> shape;
glm::usvec3 size;
glm::vec3 scale;
bool permanant;
struct Instance {
glm::ifvec3 pos;
glm::vec3 velocity;
};
data::generational::vector<Instance> instances;
};
};
}